commit
0e7fad6a87
7 changed files with 624 additions and 0 deletions
@ -0,0 +1,7 @@ |
|||||||
|
/.idea/ |
||||||
|
/.venv/ |
||||||
|
__pycache__ |
||||||
|
/cifar-10-batches-py/ |
||||||
|
/data/ |
||||||
|
/cifar-10-python.tar.gz |
||||||
|
/cifar10_model.h5 |
||||||
@ -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) |
||||||
@ -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) |
||||||
@ -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) |
||||||
@ -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}%') |
||||||
@ -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') |
||||||
@ -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…
Reference in new issue