Browse Source

Пробы пера

master
Bogdan Zuy 11 months ago
commit
0e7fad6a87
  1. 7
      .gitignore
  2. 4
      README.md
  3. 113
      ViT16.py
  4. 57
      cifar10.py
  5. 131
      cifar10my.py
  6. 86
      cifral10_2.py
  7. 226
      readme.ipynb

7
.gitignore vendored

@ -0,0 +1,7 @@
/.idea/
/.venv/
__pycache__
/cifar-10-batches-py/
/data/
/cifar-10-python.tar.gz
/cifar10_model.h5

4
README.md

@ -0,0 +1,4 @@
### Dataset source
- https://www.cs.toronto.edu/%7Ekriz/cifar.html
- https://www.cs.toronto.edu/%7Ekriz/cifar-10-python.tar.gz (c58f30108f718f92721af3b95e74349a)

113
ViT16.py

@ -0,0 +1,113 @@
import torch
import torchvision.transforms as transforms
from torchvision.datasets import CIFAR10
from torch.utils.data import DataLoader
from transformers import ViTImageProcessor, ViTForImageClassification, ViTFeatureExtractor
import torch.nn.functional as F
from sklearn.metrics import accuracy_score, classification_report
from torch.optim import AdamW
from torch.nn import CrossEntropyLoss
#import os
#os.environ['PYTORCH_CUDA_ALLOC_CONF'] = 'expandable_segments:True'
# Загрузка предобученной модели ViT-16
# model = ViTForImageClassification.from_pretrained('WinKawaks/vit-small-patch16-224') #-in21k')
processor = ViTImageProcessor.from_pretrained('google/vit-base-patch16-224')
model = ViTForImageClassification.from_pretrained('google/vit-base-patch16-224')
# Изменение количества классов на 10 (для CIFAR-10)
model.classifier = torch.nn.Linear(model.classifier.in_features, 10)
# Перенос модели на GPU, если доступно
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# model.to(device)
model.half().to(device) # Load in half precision
# Преобразования для данных
transform = transforms.Compose([
transforms.Resize((224, 224)), # ViT-16 ожидает изображения размером 224x224
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
# Загрузка данных
train_dataset = CIFAR10(root='./data', train=True, download=True, transform=transform)
test_dataset = CIFAR10(root='./data', train=False, download=True, transform=transform)
# train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
# test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)
# Оптимизатор и функция потерь
optimizer = AdamW(model.parameters(), lr=1e-4)
criterion = CrossEntropyLoss()
# Дообучение модели
model.train()
num_epochs = 10
for epoch in range(num_epochs):
for images, labels in train_loader:
images = images.to(device)
labels = labels.to(device)
optimizer.zero_grad()
outputs = model(images).logits
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print(f'Epoch {epoch+1}/{num_epochs}, Loss: {loss.item()}')
# for epoch in range(num_epochs):
# epoch_loss = 0.0
# for batch_idx, (images, labels) in enumerate(train_loader):
# images = images.to(device)
# labels = labels.to(device)
#
# optimizer.zero_grad()
# outputs = model(images).logits
# loss = criterion(outputs, labels)
# loss.backward()
# optimizer.step()
#
# epoch_loss += loss.item()
#
# # Печать прогресса каждые 10 батчей
# if (batch_idx + 1) % 10 == 0:
# print(f'Epoch {epoch+1}/{num_epochs}, Batch {batch_idx+1}/{len(train_loader)}, Loss: {loss.item()}')
#
# # Печать средней потери за эпоху
# avg_epoch_loss = epoch_loss / len(train_loader)
# print(f'Epoch {epoch+1}/{num_epochs}, Average Loss: {avg_epoch_loss}')
# Функция для оценки модели
def evaluate_model(model, data_loader, device):
model.eval()
all_preds = []
all_labels = []
with torch.no_grad():
for images, labels in data_loader:
images = images.to(device)
labels = labels.to(device)
outputs = model(images).logits
preds = torch.argmax(outputs, dim=1)
all_preds.extend(preds.cpu().numpy())
all_labels.extend(labels.cpu().numpy())
accuracy = accuracy_score(all_labels, all_preds)
report = classification_report(all_labels, all_preds, target_names=train_dataset.classes)
return accuracy, report
# Оценка модели на тестовых данных
accuracy, report = evaluate_model(model, test_loader, device)
print(f'Test Accuracy: {accuracy:.4f}')
print('Classification Report:')
print(report)

57
cifar10.py

@ -0,0 +1,57 @@
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt
print("TensorFlow version:", tf.__version__)
print("CUDA runtime version:", tf.sysconfig.get_build_info()['cuda_version'])
# Load the CIFAR-10 dataset
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()
# Normalize pixel values to be between 0 and 1
train_images, test_images = train_images / 255.0, test_images / 255.0
# Verify the data
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
plt.figure(figsize=(10,10))
for i in range(25):
plt.subplot(5,5,i+1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(train_images[i])
plt.xlabel(class_names[train_labels[i][0]])
plt.show()
# Build the CNN model
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))
# Compile the model
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
# Train the model
history = model.fit(train_images, train_labels, epochs=10,
validation_data=(test_images, test_labels))
# Evaluate the model
plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label = 'val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.ylim([0, 1])
plt.legend(loc='lower right')
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print(test_acc)

131
cifar10my.py

@ -0,0 +1,131 @@
import os
import pickle
import numpy as np
import urllib.request
import tarfile
import matplotlib.pyplot as plt
def download_and_extract_cifar10(data_dir='cifar-10-batches-py'):
url = 'https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz'
filename = 'cifar-10-python.tar.gz'
if not os.path.exists(data_dir):
urllib.request.urlretrieve(url, filename)
with tarfile.open(filename, 'r:gz') as tar:
tar.extractall()
return data_dir
data_dir = download_and_extract_cifar10()
def load_cifar10(data_dir):
def unpickle(file):
with open(file, 'rb') as fo:
dict = pickle.load(fo, encoding='bytes')
return dict
train_data = []
train_labels = []
for i in range(1, 6):
batch = unpickle(os.path.join(data_dir, 'data_batch_' + str(i)))
train_data.append(batch[b'data'])
train_labels.append(batch[b'labels'])
train_data = np.concatenate(train_data).reshape(-1, 3, 32, 32).transpose(0, 2, 3, 1)
train_labels = np.concatenate(train_labels)
test_batch = unpickle(os.path.join(data_dir, 'test_batch'))
test_data = test_batch[b'data'].reshape(-1, 3, 32, 32).transpose(0, 2, 3, 1)
test_labels = np.array(test_batch[b'labels'])
return train_data, train_labels, test_data, test_labels
train_data, train_labels, test_data, test_labels = load_cifar10(data_dir)
# Normalize the data
train_data = train_data / 255.0
test_data = test_data / 255.0
class SimpleNN:
def __init__(self, input_size, hidden_size, output_size):
self.input_size = input_size
self.hidden_size = hidden_size
self.output_size = output_size
# Initialize weights and biases
self.W1 = np.random.randn(input_size, hidden_size) * 0.01
self.b1 = np.zeros((1, hidden_size))
self.W2 = np.random.randn(hidden_size, output_size) * 0.01
self.b2 = np.zeros((1, output_size))
def forward(self, X):
self.Z1 = np.dot(X, self.W1) + self.b1
self.A1 = np.maximum(0, self.Z1) # ReLU activation
self.Z2 = np.dot(self.A1, self.W2) + self.b2
self.A2 = np.exp(self.Z2) / np.sum(np.exp(self.Z2), axis=1, keepdims=True) # Softmax activation
return self.A2
def backward(self, X, y, output):
m = y.shape[0]
self.dZ2 = output
self.dZ2[range(m), y] -= 1
self.dW2 = (1 / m) * np.dot(self.A1.T, self.dZ2)
self.db2 = (1 / m) * np.sum(self.dZ2, axis=0, keepdims=True)
self.dA1 = np.dot(self.dZ2, self.W2.T)
self.dZ1 = np.array(self.dA1, copy=True)
self.dZ1[self.Z1 <= 0] = 0
self.dW1 = (1 / m) * np.dot(X.T, self.dZ1)
self.db1 = (1 / m) * np.sum(self.dZ1, axis=0, keepdims=True)
def update_parameters(self, learning_rate):
self.W1 -= learning_rate * self.dW1
self.b1 -= learning_rate * self.db1
self.W2 -= learning_rate * self.dW2
self.b2 -= learning_rate * self.db2
def compute_loss(self, y, output):
m = y.shape[0]
log_likelihood = -np.log(output[range(m), y])
loss = np.sum(log_likelihood) / m
return loss
def train(model, X, y, learning_rate=0.01, epochs=10):
for epoch in range(epochs):
output = model.forward(X)
loss = model.compute_loss(y, output)
model.backward(X, y, output)
model.update_parameters(learning_rate)
if epoch % 1 == 0:
print(f'Epoch {epoch + 1}, Loss: {loss}')
# Flatten the input data
train_data_flat = train_data.reshape(-1, 32*32*3)
test_data_flat = test_data.reshape(-1, 32*32*3)
# Initialize the model
model = SimpleNN(input_size=32*32*3, hidden_size=128, output_size=10)
# Train the model
train(model, train_data_flat, train_labels, learning_rate=0.01, epochs=10)
def evaluate(model, X, y):
output = model.forward(X)
predictions = np.argmax(output, axis=1)
accuracy = np.mean(predictions == y)
return accuracy
# Evaluate the model on the test data
accuracy = evaluate(model, test_data_flat, test_labels)
test_data_reshaped = test_data_flat.reshape(-1, 32, 32, 3)
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
plt.figure(figsize=(10,10))
for i in range(25):
plt.subplot(5,5,i+1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(test_data_reshaped[i])
plt.xlabel(class_names[test_labels[i]])
plt.show()
print(f'Test Accuracy: {accuracy * 100:.2f}%')

86
cifral10_2.py

@ -0,0 +1,86 @@
import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
import numpy as np
import time
# Загрузка данных CIFAR-10
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
# Нормализация
x_train, x_test = x_train / 255.0, x_test / 255.0
# Аугментация
datagen = ImageDataGenerator(
rotation_range=15,
width_shift_range=0.1,
height_shift_range=0.1,
horizontal_flip=True
)
datagen.fit(x_train)
# Создание модели
model = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(10)
])
# Компиляция модели
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
# Обучение модели
start_time = time.time()
history = model.fit(datagen.flow(x_train, y_train, batch_size=64),
epochs=20,
validation_data=(x_test, y_test))
end_time = time.time()
# Время обучения
training_time = end_time - start_time
print(f"Training time: {training_time:.2f} seconds")
# Оценка модели
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)
print(f"Test accuracy: {test_acc:.4f}")
# Построение графиков
plt.figure(figsize=(12, 4))
# График точности
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='train accuracy')
plt.plot(history.history['val_accuracy'], label='val accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
# График потерь
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='train loss')
plt.plot(history.history['val_loss'], label='val loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
# Документация и комментарии
"""
Этот код загружает данные CIFAR-10, нормализует их, создает и обучает сверточную нейронную сеть.
Используется аугментация данных для улучшения обучения модели.
Модель оценивается на тестовых данных, и строятся графики точности и потерь для анализа обучения.
"""
# Сохранение модели
model.save('cifar10_model.h5')

226
readme.ipynb

@ -0,0 +1,226 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Отчет о проделанной работе\n",
"\n",
"## Введение\n",
"\n",
"Задача: Написать нейронную сеть для распознования набора данных Cifral10\n",
"\n",
"## Загрузка и предобработка данных\n",
"\n",
"В качестве набора данных для обучения используется набор данных (Cifral10)[https://www.cs.toronto.edu/%7Ekriz/cifar.html]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Загрузка данных"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Подготовка данных"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Нормализация\n",
"x_train, x_test = x_train / 255.0, x_test / 255.0\n",
"\n",
"# Аугментация\n",
"datagen = ImageDataGenerator(\n",
" rotation_range=15,\n",
" width_shift_range=0.1,\n",
" height_shift_range=0.1,\n",
" horizontal_flip=True\n",
")\n",
"datagen.fit(x_train)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Создание модели\n",
"\n",
"Для решения задачи используется сверточная нейронная сеть (CNN).\n",
"\n",
"### Архитектура модели\n",
"\n",
"1. **Входной слой**:\n",
" - **Тип слоя**: Сверточный слой (Conv2D).\n",
" - **Фильтры**: 32 фильтра.\n",
" - **Размер ядра**: 3x3.\n",
" - **Функция активации**: ReLU (Rectified Linear Unit).\n",
"\n",
"2. **Слой подвыборки (MaxPooling)**:\n",
" - **Тип слоя**: Слой подвыборки (MaxPooling2D).\n",
" - **Размер окна**: 2x2.\n",
" - **Функция**: Уменьшает размерность выходных данных предыдущего слоя вдвое, выбирая максимальное значение в каждом окне 2x2.\n",
"\n",
"3. **Второй сверточный слой**:\n",
" - **Тип слоя**: Сверточный слой (Conv2D).\n",
" - **Фильтры**: 64 фильтра.\n",
" - **Размер ядра**: 3x3.\n",
" - **Функция активации**: ReLU.\n",
"\n",
"4. **Второй слой подвыборки (MaxPooling)**:\n",
" - **Тип слоя**: Слой подвыборки (MaxPooling2D).\n",
" - **Размер окна**: 2x2.\n",
" - **Функция**: Уменьшает размерность выходных данных предыдущего слоя вдвое.\n",
"\n",
"5. **Третий сверточный слой**:\n",
" - **Тип слоя**: Сверточный слой (Conv2D).\n",
" - **Фильтры**: 64 фильтра.\n",
" - **Размер ядра**: 3x3.\n",
" - **Функция активации**: ReLU.\n",
"\n",
"6. **Слой преобразования (Flatten)**:\n",
" - **Тип слоя**: Слой преобразования (Flatten).\n",
" - **Функция**: Преобразует многомерные выходные данные предыдущего слоя в одномерный вектор.\n",
"\n",
"7. **Полносвязный слой (Dense)**:\n",
" - **Тип слоя**: Полносвязный слой (Dense).\n",
" - **Нейроны**: 64 нейрона.\n",
" - **Функция активации**: ReLU.\n",
"\n",
"8. **Выходной слой (Dense)**:\n",
" - **Тип слоя**: Полносвязный слой (Dense).\n",
" - **Нейроны**: 10 нейронов (по одному для каждого класса в CIFAR-10).\n",
" - **Функция активации**: Отсутствует (логиты).\n",
"\n",
"### Объяснение архитектуры\n",
"\n",
"1. **Сверточные слои (Conv2D)**:\n",
" - Сверточные слои используются для извлечения признаков из изображений. Они применяют фильтры к входным данным, чтобы выделить важные характеристики, такие как края, текстуры и формы.\n",
" - В данной архитектуре используются три сверточных слоя с различным количеством фильтров (32, 64, 64), что позволяет модели извлекать все более сложные признаки на каждом уровне.\n",
"\n",
"2. **Слои подвыборки (MaxPooling2D)**:\n",
" - Слои подвыборки уменьшают размерность данных, сохраняя наиболее важные признаки. Это помогает снизить вычислительную сложность и предотвратить переобучение.\n",
" - В данной архитектуре используются два слоя подвыборки, каждый из которых уменьшает размерность данных вдвое.\n",
"\n",
"3. **Слой преобразования (Flatten)**:\n",
" - Слой преобразования преобразует многомерные данные в одномерный вектор, что необходимо для подачи данных в полносвязные слои.\n",
"\n",
"4. **Полносвязные слои (Dense)**:\n",
" - Полносвязные слои используются для классификации извлеченных признаков. Они соединяют все нейроны предыдущего слоя с каждым нейроном текущего слоя.\n",
" - В данной архитектуре используется один полносвязный слой с 64 нейронами и функцией активации ReLU, а также выходной слой с 10 нейронами (по одному для каждого класса)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model = models.Sequential([\n",
" layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),\n",
" layers.MaxPooling2D((2, 2)),\n",
" layers.Conv2D(64, (3, 3), activation='relu'),\n",
" layers.MaxPooling2D((2, 2)),\n",
" layers.Conv2D(64, (3, 3), activation='relu'),\n",
" layers.Flatten(),\n",
" layers.Dense(64, activation='relu'),\n",
" layers.Dense(10)\n",
"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Компиляция и обучение модели\n",
"\n",
"Предварительно зададим, что будем использовать (оптимизатор)[https://www.tensorflow.org/api_docs/python/tf/keras/optimizers] использующий алгоритм (Adam)[https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/Adam]. [1](https://education.yandex.ru/handbook/ml/article/optimizaciya-v-ml)\n",
"\n",
"В качестве (функции потерь)[https://www.tensorflow.org/api_docs/python/tf/keras/losses] будем использовать функцию (кросс-энтропии)[https://education.yandex.ru/handbook/ml/article/landshaft-funkcii-poter] для эффективного измерения разницы между предсказанными и истинными метками классов хорошо должна подойти (SparseCategoricalCrossentropy)[https://www.tensorflow.org/api_docs/python/tf/keras/losses/SparseCategoricalCrossentropy]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model.compile(optimizer='adam',\n",
" loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n",
" metrics=['accuracy'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Test Accuracy: 0.1000\n",
"Classification Report:\n",
" precision recall f1-score support\n",
"\n",
" airplane 0.10 1.00 0.18 1000\n",
" automobile 0.00 0.00 0.00 1000\n",
" bird 0.00 0.00 0.00 1000\n",
" cat 0.00 0.00 0.00 1000\n",
" deer 0.00 0.00 0.00 1000\n",
" dog 0.00 0.00 0.00 1000\n",
" frog 0.00 0.00 0.00 1000\n",
" horse 0.00 0.00 0.00 1000\n",
" ship 0.00 0.00 0.00 1000\n",
" truck 0.00 0.00 0.00 1000\n",
"\n",
" accuracy 0.10 10000\n",
" macro avg 0.01 0.10 0.02 10000\n",
"weighted avg 0.01 0.10 0.02 10000\n",
"\n",
"---\n",
"\n",
"Test Accuracy: 0.1018\n",
"Classification Report:\n",
" precision recall f1-score support\n",
"\n",
" airplane 0.04 0.01 0.01 1000\n",
" automobile 0.15 0.33 0.21 1000\n",
" bird 0.10 0.07 0.09 1000\n",
" cat 0.11 0.05 0.07 1000\n",
" deer 0.02 0.01 0.01 1000\n",
" dog 0.07 0.07 0.07 1000\n",
" frog 0.25 0.12 0.17 1000\n",
" horse 0.11 0.17 0.14 1000\n",
" ship 0.03 0.06 0.04 1000\n",
" truck 0.16 0.12 0.14 1000\n",
"\n",
" accuracy 0.10 10000\n",
" macro avg 0.11 0.10 0.09 10000\n",
"weighted avg 0.11 0.10 0.09 10000\n",
"\n",
"\n",
"Process finished with exit code 0"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading…
Cancel
Save