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