Troyanov Daniil 1 неделю назад
Родитель dac4716238
Сommit 4d582975e4

Двоичные данные
labworks/LW3/2.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 315 B

Двоичные данные
labworks/LW3/7.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 273 B

Двоичные данные
labworks/LW3/best_mnist_model.keras

Двоичный файл не отображается.

Двоичные данные
labworks/LW3/images/1.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.9 KiB

Двоичные данные
labworks/LW3/images/2.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.0 KiB

Двоичные данные
labworks/LW3/images/3.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 31 KiB

Двоичные данные
labworks/LW3/images/4.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.7 KiB

Двоичные данные
labworks/LW3/images/5.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.6 KiB

Двоичные данные
labworks/LW3/images/6.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 121 KiB

Двоичные данные
labworks/LW3/images/7.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 11 KiB

Двоичные данные
labworks/LW3/images/8.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 12 KiB

Двоичные данные
labworks/LW3/images/9.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 61 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

@ -0,0 +1,612 @@
# Отчёт по лабораторной работе №3
**Троянов Д.С., Чернов Д.Е. — А-01-22**
---
## Задание 1
### 1) Подготовка рабочей среды и импорт библиотек
Инициализируем рабочую среду и подключаем необходимые библиотеки для работы с нейронными сетями и обработки данных. Также настраиваем SSL для корректной загрузки датасетов.
```python
# Подключение необходимых библиотек и модулей
import os
import ssl
# Обход проблемы с SSL сертификатами на macOS
ssl._create_default_https_context = ssl._create_unverified_context
# Для работы в Google Colab раскомментируйте следующую строку:
# os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab3')
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.metrics import ConfusionMatrixDisplay
```
### 2) Загрузка датасета MNIST
Загружаем стандартный набор данных MNIST, который содержит изображения рукописных цифр от 0 до 9 с соответствующими метками.
```python
# Импорт и загрузка датасета MNIST
from keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()
```
### 3) Разделение данных на обучающую и тестовую выборки
Производим собственное разбиение датасета в соотношении 60 000:10 000. Для воспроизводимости результатов используем параметр random_state = 3 (вычисляется как 4k - 1, где k = 1 - номер нашей бригады). Выводим размерности полученных массивов данных.
```python
# Создание собственного разбиения датасета
from sklearn.model_selection import train_test_split
# Объединение исходных обучающей и тестовой выборок в единый набор
X = np.concatenate((X_train, X_test))
y = np.concatenate((y_train, y_test))
# Разделение на обучающую и тестовую выборки согласно заданию
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size = 10000,
train_size = 60000,
random_state = 3)
# Вывод размерностей полученных массивов
print('Shape of X train:', X_train.shape)
print('Shape of y train:', y_train.shape)
print('Shape of X test:', X_test.shape)
print('Shape of y test:', y_test.shape)
```
```
Shape of X train: (60000, 28, 28)
Shape of y train: (60000,)
Shape of X test: (10000, 28, 28)
Shape of y test: (10000,)
```
### 4) Предобработка данных
Выполняем нормализацию пикселей изображений (приведение к диапазону [0, 1]) и преобразование меток в формат one-hot encoding для корректной работы с категориальной функцией потерь. Выводим размерности предобработанных массивов данных.
```python
# Определение параметров данных и модели
num_classes = 10
input_shape = (28, 28, 1)
# Нормализация значений пикселей: приведение к диапазону [0, 1]
X_train = X_train / 255
X_test = X_test / 255
# Добавление размерности канала для корректной работы с Conv2D слоями
# Преобразование из (высота, ширина) в (высота, ширина, каналы)
X_train = np.expand_dims(X_train, -1)
X_test = np.expand_dims(X_test, -1)
print('Shape of transformed X train:', X_train.shape)
print('Shape of transformed X test:', X_test.shape)
# Преобразование меток в формат one-hot encoding
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print('Shape of transformed y train:', y_train.shape)
print('Shape of transformed y test:', y_test.shape)
```
```
Shape of transformed X train: (60000, 28, 28, 1)
Shape of transformed X test: (10000, 28, 28, 1)
Shape of transformed y train: (60000, 10)
Shape of transformed y test: (10000, 10)
```
### 5) Построение и обучение сверточной нейронной сети
Создаем архитектуру сверточной нейронной сети с использованием сверточных слоев, пулинга и регуляризации. Обучаем модель на подготовленных данных с выделением части данных для валидации. Выводим информацию об архитектуре нейронной сети.
```python
# Создание модели сверточной нейронной сети
model = Sequential()
model.add(layers.Conv2D(32, kernel_size=(3, 3), activation="relu", input_shape=input_shape))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Conv2D(64, kernel_size=(3, 3), activation="relu"))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Dropout(0.5))
model.add(layers.Flatten())
model.add(layers.Dense(num_classes, activation="softmax"))
model.summary()
```
**Model: "sequential"**
| Layer (type) | Output Shape | Param # |
|--------------------------------|---------------------|--------:|
| conv2d (Conv2D) | (None, 26, 26, 32) | 320 |
| max_pooling2d (MaxPooling2D) | (None, 13, 13, 32) | 0 |
| conv2d_1 (Conv2D) | (None, 11, 11, 64) | 18,496 |
| max_pooling2d_1 (MaxPooling2D) | (None, 5, 5, 64) | 0 |
| dropout (Dropout) | (None, 5, 5, 64) | 0 |
| flatten (Flatten) | (None, 1600) | 0 |
| dense (Dense) | (None, 10) | 16,010 |
**Total params:** 34,826 (136.04 KB)
**Trainable params:** 34,826 (136.04 KB)
**Non-trainable params:** 0 (0.00 B)
```python
# Компиляция и обучение модели
batch_size = 512
epochs = 15
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)
```
### 6) Оценка качества модели на тестовых данных
Проводим финальную оценку обученной модели на независимой тестовой выборке, получая значения функции потерь и точности классификации.
```python
# Оценка качества работы обученной модели на тестовой выборке
scores = model.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
```
313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - accuracy: 0.9884 - loss: 0.0409
Loss on test data: 0.04092026501893997
Accuracy on test data: 0.9883999824523926
```
### 7) Демонстрация работы модели на отдельных примерах
Визуализируем результаты распознавания для двух тестовых изображений, сравнивая предсказания модели с истинными метками.
```python
# Визуализация результатов распознавания для двух тестовых изображений
for n in [3,26]:
result = model.predict(X_test[n:n+1])
print('NN output:', result)
plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))
plt.show()
print('Real mark: ', np.argmax(y_test[n]))
print('NN answer: ', np.argmax(result))
```
![MNIST тестовое изображение - цифра 6](images/1.png)
```
Real mark: 6
NN answer: 6
```
![MNIST тестовое изображение - цифра 3](images/2.png)
```
Real mark: 3
NN answer: 3
```
### 8) Детальный анализ качества классификации
Генерируем подробный отчет о качестве классификации и строим матрицу ошибок для визуального анализа работы модели по каждому классу.
```python
# Получение истинных и предсказанных меток для всех тестовых данных
true_labels = np.argmax(y_test, axis=1)
# Предсказанные метки классов
predicted_labels = np.argmax(model.predict(X_test), axis=1)
# Вывод подробного отчета о качестве классификации
print(classification_report(true_labels, predicted_labels))
# Построение и визуализация матрицы ошибок
conf_matrix = confusion_matrix(true_labels, predicted_labels)
# Отрисовка матрицы ошибок в виде "тепловой карты"
display = ConfusionMatrixDisplay(confusion_matrix=conf_matrix)
display.plot()
plt.show()
```
```
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 5ms/step
precision recall f1-score support
0 1.00 0.99 1.00 1001
1 0.99 1.00 0.99 1143
2 0.99 0.99 0.99 987
3 0.99 0.99 0.99 1023
4 0.99 0.99 0.99 974
5 1.00 0.98 0.99 907
6 0.99 0.99 0.99 974
7 0.98 0.99 0.99 1032
8 0.98 0.98 0.98 1006
9 0.98 0.99 0.98 953
accuracy 0.99 10000
macro avg 0.99 0.99 0.99 10000
weighted avg 0.99 0.99 0.99 10000
```
![Матрица ошибок для MNIST](images/3.png)
### 9) Тестирование на собственных изображениях
Загружаем и обрабатываем собственные изображения цифр, созданные ранее, и проверяем способность модели их корректно распознавать.
```python
# Загрузка и обработка собственных изображений
from PIL import Image
for name_image in ['2.png', '7.png']:
file_data = Image.open(name_image)
file_data = file_data.convert('L') # Перевод в градации серого
test_img = np.array(file_data)
# Вывод собственного изображения
plt.imshow(test_img, cmap=plt.get_cmap('gray'))
plt.show()
# Предобработка
test_img = test_img / 255
test_img = np.reshape(test_img, (1,28,28,1))
# Распознавание
result = model.predict(test_img)
print('I think it\'s', np.argmax(result))
```
![Собственное изображение - цифра 2](images/4.png)
```
I think it's 2
```
![Собственное изображение - цифра 7](images/5.png)
```
I think it's 7
```
### 10) Сравнение с моделью из предыдущей лабораторной работы
Загружаем сохраненную полносвязную нейронную сеть из лабораторной работы №1 и оцениваем ее производительность на тех же тестовых данных для последующего сравнения.
```python
model_lr1 = keras.models.load_model("best_mnist_model.keras")
model_lr1.summary()
```
**Model: "sequential"**
| Layer (type) | Output Shape | Param # |
|------------------|-------------:|--------:|
| dense (Dense) | (None, 10) | 7,850 |
**Total params:** 7,852 (30.68 KB)
**Trainable params:** 7,850 (30.66 KB)
**Non-trainable params:** 0 (0.00 B)
**Optimizer params:** 2 (12.00 B)
```python
# Подготовка данных для полносвязной сети (преобразование изображений в векторы)
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size = 10000,
train_size = 60000,
random_state = 3)
num_pixels = X_train.shape[1] * X_train.shape[2]
X_train = X_train.reshape(X_train.shape[0], num_pixels) / 255
X_test = X_test.reshape(X_test.shape[0], num_pixels) / 255
print('Shape of transformed X train:', X_train.shape)
print('Shape of transformed X train:', X_test.shape)
# Преобразование меток в формат one-hot encoding
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print('Shape of transformed y train:', y_train.shape)
print('Shape of transformed y test:', y_test.shape)
```
```
Shape of transformed X train: (60000, 784)
Shape of transformed X train: (10000, 784)
Shape of transformed y train: (60000, 10)
Shape of transformed y test: (10000, 10)
```
```python
# Оценка качества работы модели на тестовых данных
scores = model_lr1.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
```
313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 3ms/step - accuracy: 0.9233 - loss: 0.2863
Loss on test data: 0.28625616431236267
Accuracy on test data: 0.92330002784729
```
### 11) Сравнительный анализ моделей
Сравниваем сверточную нейронную сеть с полносвязной сетью по ключевым показателям: количеству параметров, времени обучения и качеству классификации. Делаем выводы по результатам применения сверточной нейронной сети для распознавания изображений.
**Таблица сравнения моделей:**
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|----------|-------------------------------------|---------------------------|-----------------------------------------|
| Сверточная | 34 826 | 15 | accuracy: 0.988; loss: 0.041 |
| Полносвязная | 7 852 | 50 | accuracy: 0.923; loss: 0.286 |
**Выводы:**
На основе проведенного анализа можно заключить, что сверточная нейронная сеть демонстрирует существенные преимущества перед полносвязной сетью при решении задач распознавания изображений:
1. **Эффективность параметров**: Сверточная сеть имеет больше параметров (34 826 против 7 852), но при этом показывает значительно лучшие результаты, что говорит о более эффективном использовании параметров для извлечения пространственных признаков.
2. **Скорость обучения**: Для достижения высокого качества сверточной сети требуется в 3.3 раза меньше эпох обучения (15 против 50), что существенно сокращает время обучения.
3. **Точность классификации**: Сверточная сеть показывает более высокую точность (98.8% против 92.3%) и значительно меньшую функцию потерь (0.041 против 0.286). Разница в точности составляет 6.5 процентных пункта, что является существенным улучшением.
4. **Обобщающая способность**: Сверточная сеть демонстрирует лучшую способность к обобщению, что видно из более низкой функции потерь на тестовых данных.
Эти результаты подтверждают, что архитектура сверточных сетей, учитывающая пространственную структуру изображений через операции свертки и пулинга, является более подходящим выбором для задач компьютерного зрения, несмотря на большее количество параметров.
## Задание 2
### Работа с датасетом CIFAR-10
Повторяем основные этапы задания 1, но используем датасет CIFAR-10, содержащий цветные изображения объектов 10 различных классов.
Особенности выполнения:
- Разделение данных производится в соотношении 50 000:10 000
- После разделения визуализируем 25 изображений из обучающей выборки
- При демонстрации работы модели выбираем примеры так, чтобы одно изображение распознавалось корректно, а другое - ошибочно
### 1) Загрузка датасета CIFAR-10
Загружаем набор данных CIFAR-10, который содержит цветные изображения размером 32x32 пикселя, разделенные на 10 классов: самолет, автомобиль, птица, кошка, олень, собака, лягушка, лошадь, корабль, грузовик.
```python
# Импорт и загрузка датасета CIFAR-10
from keras.datasets import cifar10
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
```
### 2) Разделение данных на обучающую и тестовую выборки
Создаем собственное разбиение датасета CIFAR-10 в соотношении 50 000:10 000. Используем random_state = 3 для воспроизводимости результатов (k = 1 - номер нашей бригады). Выводим размерности полученных массивов данных.
```python
# Создание собственного разбиения датасета
# Объединение исходных выборок
X = np.concatenate((X_train, X_test))
y = np.concatenate((y_train, y_test))
# Разделение на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size = 10000,
train_size = 50000,
random_state = 3)
# Вывод размерностей
print('Shape of X train:', X_train.shape)
print('Shape of y train:', y_train.shape)
print('Shape of X test:', X_test.shape)
print('Shape of y test:', y_test.shape)
```
```
Shape of X train: (50000, 32, 32, 3)
Shape of y train: (50000, 1)
Shape of X test: (10000, 32, 32, 3)
Shape of y test: (10000, 1)
```
### Визуализация примеров из обучающей выборки
Отображаем сетку из 25 изображений из обучающей выборки с подписями соответствующих классов для визуального ознакомления с данными.
```python
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(X_train[i])
plt.xlabel(class_names[y_train[i][0]])
plt.show()
```
![Сетка из 25 изображений CIFAR-10](images/6.png)
### 3) Предобработка данных CIFAR-10
Нормализуем значения пикселей и преобразуем метки в формат one-hot encoding для работы с категориальной функцией потерь. Выводим размерности предобработанных массивов данных.
```python
# Определение параметров данных и модели
num_classes = 10
input_shape = (32, 32, 3)
# Нормализация значений пикселей: приведение к диапазону [0, 1]
X_train = X_train / 255
X_test = X_test / 255
print('Shape of transformed X train:', X_train.shape)
print('Shape of transformed X test:', X_test.shape)
# Преобразование меток в формат one-hot encoding
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print('Shape of transformed y train:', y_train.shape)
print('Shape of transformed y test:', y_test.shape)
```
```
Shape of transformed X train: (50000, 32, 32, 3)
Shape of transformed X test: (10000, 32, 32, 3)
Shape of transformed y train: (50000, 10)
Shape of transformed y test: (10000, 10)
```
### 4) Построение и обучение сверточной сети для CIFAR-10
Создаем более сложную архитектуру сверточной сети с использованием батч-нормализации и нескольких блоков свертки для работы с цветными изображениями. Обучаем модель на подготовленных данных с выделением части данных для валидации.
```python
# Создание модели сверточной нейронной сети
model = Sequential()
# Блок 1
model.add(layers.Conv2D(32, (3, 3), padding="same",
activation="relu", input_shape=input_shape))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(32, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.25))
# Блок 2
model.add(layers.Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.25))
# Блок 3
model.add(layers.Conv2D(128, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(128, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.4))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(num_classes, activation="softmax"))
model.summary()
```
**Model: "sequential_9"**
| Layer (type) | Output Shape | Param # |
|--------------------------------------------|-------------------|---------:|
| conv2d_41 (Conv2D) | (None, 32, 32, 32) | 896 |
| batch_normalization_6 (BatchNormalization) | (None, 32, 32, 32) | 128 |
| conv2d_42 (Conv2D) | (None, 32, 32, 32) | 9,248 |
| batch_normalization_7 (BatchNormalization) | (None, 32, 32, 32) | 128 |
| max_pooling2d_26 (MaxPooling2D) | (None, 16, 16, 32) | 0 |
| dropout_24 (Dropout) | (None, 16, 16, 32) | 0 |
| conv2d_43 (Conv2D) | (None, 16, 16, 64) | 18,496 |
| batch_normalization_8 (BatchNormalization) | (None, 16, 16, 64) | 256 |
| conv2d_44 (Conv2D) | (None, 16, 16, 64) | 36,928 |
| batch_normalization_9 (BatchNormalization) | (None, 16, 16, 64) | 256 |
| max_pooling2d_27 (MaxPooling2D) | (None, 8, 8, 64) | 0 |
| dropout_25 (Dropout) | (None, 8, 8, 64) | 0 |
| conv2d_45 (Conv2D) | (None, 8, 8, 128) | 73,856 |
| batch_normalization_10 (BatchNormalization)| (None, 8, 8, 128) | 512 |
| conv2d_46 (Conv2D) | (None, 8, 8, 128) | 147,584 |
| batch_normalization_11 (BatchNormalization)| (None, 8, 8, 128) | 512 |
| max_pooling2d_28 (MaxPooling2D) | (None, 4, 4, 128) | 0 |
| dropout_26 (Dropout) | (None, 4, 4, 128) | 0 |
| flatten_9 (Flatten) | (None, 2048) | 0 |
| dense_17 (Dense) | (None, 128) | 262,272 |
| dropout_27 (Dropout) | (None, 128) | 0 |
| dense_18 (Dense) | (None, 10) | 1,290 |
**Total params:** 552,362 (2.11 MB)
**Trainable params:** 551,466 (2.10 MB)
**Non-trainable params:** 896 (3.50 KB)
```python
# Компиляция и обучение модели
batch_size = 64
epochs = 50
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)
```
### 5) Оценка качества модели на тестовых данных
Оцениваем финальную производительность обученной модели на тестовой выборке CIFAR-10.
```python
# Оценка качества работы модели на тестовых данных
scores = model.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
```
313/313 ━━━━━━━━━━━━━━━━━━━━ 7s 22ms/step - accuracy: 0.8553 - loss: 0.5210
Loss on test data: 0.5209607481956482
Accuracy on test data: 0.8553000092506409
```
### 6) Демонстрация работы модели на отдельных примерах
Визуализируем результаты распознавания для двух тестовых изображений: одно должно быть распознано корректно, другое - ошибочно.
```python
# Визуализация результатов распознавания для двух тестовых изображений
for n in [3,14]:
result = model.predict(X_test[n:n+1])
print('NN output:', result)
plt.imshow(X_test[n].reshape(32,32,3), cmap=plt.get_cmap('gray'))
plt.show()
print('Real mark: ', np.argmax(y_test[n]))
print('NN answer: ', np.argmax(result))
```
![CIFAR-10 тестовое изображение](images/7.png)
```
Real mark: 6
NN answer: 6
```
![CIFAR-10 тестовое изображение - олень (ошибочно распознано)](images/8.png)
```
Real mark: 4
NN answer: 5
```
### 7) Детальный анализ качества классификации CIFAR-10
Генерируем подробный отчет о качестве классификации и строим матрицу ошибок для анализа работы модели по каждому классу.
```python
# Получение истинных и предсказанных меток для всех тестовых данных
true_labels = np.argmax(y_test, axis=1)
# Предсказанные метки классов
predicted_labels = np.argmax(model.predict(X_test), axis=1)
# Вывод подробного отчета о качестве классификации
print(classification_report(true_labels, predicted_labels, target_names=class_names))
# Построение и визуализация матрицы ошибок
conf_matrix = confusion_matrix(true_labels, predicted_labels)
# Отрисовка матрицы ошибок в виде "тепловой карты"
fig, ax = plt.subplots(figsize=(6, 6))
disp = ConfusionMatrixDisplay(confusion_matrix=conf_matrix,display_labels=class_names)
disp.plot(ax=ax, xticks_rotation=45) # Поворот подписей по X и приятная палитра
plt.tight_layout() # Чтобы всё влезло
plt.show()
```
```
313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step
precision recall f1-score support
airplane 0.84 0.91 0.87 1007
automobile 0.95 0.91 0.93 1037
bird 0.83 0.79 0.81 1030
cat 0.77 0.65 0.70 990
deer 0.83 0.82 0.82 966
dog 0.72 0.83 0.77 1009
frog 0.90 0.89 0.89 972
horse 0.87 0.89 0.88 991
ship 0.95 0.92 0.93 990
truck 0.89 0.93 0.91 1008
accuracy 0.85 10000
macro avg 0.86 0.85 0.85 10000
weighted avg 0.86 0.85 0.85 10000
```
![Матрица ошибок для CIFAR-10](images/9.png)
**Выводы по результатам классификации CIFAR-10:**
Разработанная сверточная нейронная сеть показала хорошие результаты при классификации цветных изображений из датасета CIFAR-10. Модель достигла точности классификации 85.5% (accuracy: 0.855, loss: 0.521) на тестовой выборке, а в детальном отчете о классификации показала accuracy 0.85, что является достойным результатом для данной задачи, учитывая сложность различения объектов в низком разрешении (32x32 пикселя) и наличие 10 различных классов.
Использование батч-нормализации и dropout-регуляризации позволило улучшить обобщающую способность модели и предотвратить переобучение. Архитектура с тремя блоками сверточных слоев эффективно извлекает иерархические признаки из изображений, что подтверждается полученными метриками качества.
Загрузка…
Отмена
Сохранить