commit e726898cb182d0c1423bb48c4000fdd0d6bfc432 Author: ishutinayi Date: Mon Dec 8 21:39:39 2025 +0300 lw3 added diff --git a/dE.docx b/dE.docx new file mode 100644 index 0000000..efc212f Binary files /dev/null and b/dE.docx differ diff --git a/lw3 is/pics/i1.png b/lw3 is/pics/i1.png new file mode 100644 index 0000000..7d4dac5 Binary files /dev/null and b/lw3 is/pics/i1.png differ diff --git a/lw3 is/pics/i2.png b/lw3 is/pics/i2.png new file mode 100644 index 0000000..e3aeca5 Binary files /dev/null and b/lw3 is/pics/i2.png differ diff --git a/lw3 is/pics/i3.png b/lw3 is/pics/i3.png new file mode 100644 index 0000000..9d64ef0 Binary files /dev/null and b/lw3 is/pics/i3.png differ diff --git a/lw3 is/pics/i4.png b/lw3 is/pics/i4.png new file mode 100644 index 0000000..8bc9ae5 Binary files /dev/null and b/lw3 is/pics/i4.png differ diff --git a/lw3 is/pics/i5.png b/lw3 is/pics/i5.png new file mode 100644 index 0000000..c06f48e Binary files /dev/null and b/lw3 is/pics/i5.png differ diff --git a/lw3 is/pics/i6.png b/lw3 is/pics/i6.png new file mode 100644 index 0000000..6f5f960 Binary files /dev/null and b/lw3 is/pics/i6.png differ diff --git a/lw3 is/report.md b/lw3 is/report.md new file mode 100644 index 0000000..46b6294 --- /dev/null +++ b/lw3 is/report.md @@ -0,0 +1,529 @@ +## Лабораторная работа №3 ИС. Распознавание изображений + +#### Выполнили: Ишутина Е. И., Голубев Т. Л. + +В работе проводится исследование моделей глубокого обучения при классификации изображений. Рассматривались два набора данных: MNIST с черно-белыми изображениями цифр, и CIFAR-10 с цветными изображениями десяти классов (cat, deer, truck и т.д.) размерности 32×32 пикселя. Для обоих наборов была выполнена нормализация и приведение меток классов к формату one-hot. + +One-hot - кодирование данных в виде вектора, содержащего столько элементов, сколько существует классов. Все элементы равны нулю (или близки) кроме значения на позиции, соответствующей истинному классу (там значение ближе к единице). Такой формат нужен в нейронных сетях, где выходной слой формирует распределение вероятностей по классам. + +Для набора MNIST обучена сверточная нейронная сеть, а затем произведено её сравнение с лучшей полносвязной моделью из ЛР1. Для набора CIFAR-10 была реализована модель сверточной нейронной сети и оценена результативность ее работы. + +## Задание 1 +#### *1. В среде Google Colab создать новый блокнот (notebook). Импортировать необходимые для работы библиотеки и модули* + +Подключены библиотеки. Создана рабочая директория на Google Диске и зафиксированы генераторы случайных чисел для обеспечения воспроизводимости результатов. + +```python +from google.colab import drive +drive.mount('/content/drive') + +import os +os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab3') + +import numpy as np +import matplotlib.pyplot as plt + +from tensorflow import keras +from tensorflow.keras import layers +from tensorflow.keras.models import Sequential + +from sklearn.metrics import classification_report, confusion_matrix, ConfusionMatrixDisplay +from sklearn.model_selection import train_test_split + +import tensorflow as tf +tf.random.set_seed(123) +np.random.seed(123) +``` +```python +Mounted at /content/drive +``` +#### *2. Загрузить набор данных MNIST, содержащий размеченные изображения рукописных цифр.* + +Загружен набор данных MNIST, включающий 70 000 размеченных изображений рукописных цифр размерностью 28×28 пикселей. Набор состоял из 60 000 изображений обучающей выборки и 10 000 изображений тестовой выборки, при этом каждой матрице пикселей соответствовала метка класса от 0 до 9. После загрузки обе части набора были объединены в единые массивы данных, чтобы потом выполнить разбиение согласно варианту задания. + +```python +from keras.datasets import mnist + +(X_train_full, y_train_full), (X_test_full, y_test_full) = mnist.load_data() + +X = np.concatenate((X_train_full, X_test_full), axis=0) +y = np.concatenate((y_train_full, y_test_full), axis=0) +``` +```python +Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz +11490434/11490434 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step +``` + +#### *3. Разбить набор данных на обучающие и тестовые данные в соотношении 60000:10000 элементов. При разбиении параметр random_state выбрать равным (4k–1), где k – номер бригады. Вывести размерности полученных обучающих и тестовых массивов данных.* + +```python +k = 5 +random_state = 4 * k - 1 + +X_train, X_test, y_train, y_test = train_test_split( + X, y, train_size=60000, test_size=10000, random_state=random_state, shuffle=True +) + +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) +``` +Выведенные размерности подтвердили корректность проведённого разбиения и соответствие полученных массивов заданным параметрам. +```python +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». Вывести размерности предобработанных обучающих и тестовых массивов данных.* + +Значения пикселей приведены к диапазону [0, 1], метки классов были преобразованы в формат one-hot, где каждый класс представлен вектором длины десять. + +```python +num_classes = 10 +input_shape = (28, 28, 1) + +# приведение значений к диапазону [0,1] +X_train = X_train.astype('float32') / 255.0 +X_test = X_test.astype('float32') / 255.0 + +# добавление размерности каналов +X_train = np.expand_dims(X_train, -1) +X_test = np.expand_dims(X_test, -1) + +# one-hot кодирование меток +y_train_cat = keras.utils.to_categorical(y_train, num_classes) +y_test_cat = keras.utils.to_categorical(y_test, num_classes) + +print('Shape of transformed X_train:', X_train.shape) +print('Shape of transformed y_train:', y_train_cat.shape) +print('Shape of transformed X_test:', X_test.shape) +print('Shape of transformed y_test:', y_test_cat.shape) +``` +Выведенные размерности подтвердили корректное преобразование изображений в тензоры формы 28×28×1 и меток в матрицы 60000×10 и 10000×10 для обучающей и тестовой выборок соответственно. + +```python +Shape of transformed X_train: (60000, 28, 28, 1) +Shape of transformed y_train: (60000, 10) +Shape of transformed X_test: (10000, 28, 28, 1) +Shape of transformed y_test: (10000, 10) +``` + +#### *5. Реализовать модель сверточной нейронной сети и обучить ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывести информацию об архитектуре нейронной сети.* +Пояснения по коду: +* batch_size – размер батча (количество изображений, обрабатываемых одновременно за один шаг градиентного спуска). Используется Sequential API, где слои добавляются один за другим. Это удобно для простых последовательных моделей CNN. + +* Conv2D(32, (3,3)): 32 фильтра размером 3×3, которые будут сканировать изображение. + +* input_shape=input_shape: форма входных данных (например, (28,28,1) для серых изображений MNIST). + +* MaxPooling2D(2,2) уменьшает размерность признаков в 2 раза, выбирая максимум в каждом окне 2×2. + +* Dropout(0.5) случайным образом отключает 50% нейронов во время обучения, чтобы уменьшить переобучение. + +```python +batch_size = 512 +epochs = 15 + +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.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) +model.summary() + +history = model.fit(X_train, y_train_cat, batch_size=batch_size, epochs=epochs, validation_split=0.1) +``` + +```python +/usr/local/lib/python3.12/dist-packages/keras/src/layers/convolutional/base_conv.py:113: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead. + super().__init__(activity_regularizer=activity_regularizer, **kwargs) + +Model: "sequential" +| Layer (type) | Output shape | Param # | +|----------------------------|----------------------|---------| +| conv2d (Conv2D) | (None, 26, 26, 32) | 320 | +| max_pooling2d (MaxPooling) | (None, 13, 13, 32) | 0 | +| conv2d_1 (Conv2D) | (None, 11, 11, 64) | 18,496 | +| max_pooling2d_1 (MaxPooling) | (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) +``` + +#### *6. Оценить качество обучения на тестовых данных. Вывести значение функции ошибки и значение метрики качества классификациина тестовых данных.* + +```python +scores = model.evaluate(X_test, y_test_cat, verbose=2) +print('Loss on test data:', scores[0]) +print('Accuracy on test data:', scores[1]) +``` +```python +313/313 - 3s - 8ms/step - accuracy: 0.9879 - loss: 0.0402 +Loss on test data: 0.04024936258792877 +Accuracy on test data: 0.9879000186920166 +``` +Vодель обучена хорошо и показывает высокое качество на тестовой выборке. + +#### *7. Подать на вход обученной модели два тестовых изображения. Вывести изображения, истинные метки и результаты распознавания.* +Пояснения по коду: +* Берём два изображения из тестового набора (с индексами 0 и 1). +* X_test[n:n+1] — формируем батч из одного изображения. +* model.predict() возвращает вектор вероятностей для каждого класса (10 элементов для цифр 0–9). +* NN output vector показывает вероятности для всех 10 классов. + +```python +indices = [0, 1] +for n in indices: + result = model.predict(X_test[n:n+1]) + plt.figure() + plt.imshow(X_test[n].reshape(28,28), cmap='gray') + plt.title(f"Real: {y_test[n]} Pred: {np.argmax(result)}") + plt.axis('off') + plt.show() + print('NN output vector:', result) + print('Real mark:', y_test[n]) + print('NN answer:', np.argmax(result)) +``` + +![image](pics/i1.png) +```python +NN output vector: [[3.5711860e-08 3.5435047e-11 6.5117740e-07 7.4699518e-09 5.9110135e-08 + 1.4115658e-03 9.9851364e-01 2.6488631e-12 7.4022493e-05 2.6488609e-10]] +Real mark: 6 +NN answer: 6 +``` +![image](pics/i2.png) +```python +NN output vector: [[9.2878885e-08 3.3229617e-06 4.1963812e-04 3.1485452e-04 1.7722991e-09 + 2.6501787e-09 5.7302459e-13 9.9888808e-01 1.0063148e-05 3.6401587e-04]] +Real mark: 7 +NN answer: 7 +``` +Как видно, модель верно распознала случайно выбранные две цифры. В выходном векторе у всех значений, кроме позиции верного класса, были значения порядка 10^-4 - 10^-13. Значение для верного класса близко к единице. + +#### *8. Вывести отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки.* + +* Precision = 0.99 для класса 0 означает, что почти все объекты, которые сеть предсказала как «0», действительно 0. Recall 1.00 для класса 0 означает, что сеть нашла все объекты «0» в тестовой выборке. +Accuracy (общая точность) = 0.99 дает понять, что модель правильно классифицирует 99% изображений. + + +* В матрице ошибок основная часть значений находится на диагонали, а значит, большинство предсказаний верные. С помощью небольших ошибок вне диагоналей можно понять, какие числа нейросеть «путает». Например, сеть может перепутать «4» и «9», или «3» и «5», если они визуально похожи. + +```python +true_labels = y_test +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() +``` +```python +precision recall f1-score support + + 0 0.99 1.00 0.99 969 + 1 0.99 0.99 0.99 1155 + 2 0.99 0.98 0.98 969 + 3 0.99 0.99 0.99 1032 + 4 1.00 0.98 0.99 1016 + 5 0.98 0.99 0.98 898 + 6 0.99 0.99 0.99 990 + 7 0.98 0.99 0.99 1038 + 8 0.99 0.98 0.99 913 + 9 0.99 0.98 0.98 1020 + + accuracy 0.99 10000 + macro avg 0.99 0.99 0.99 10000 +weighted avg 0.99 0.99 0.99 10000 +``` +![image](pics/i3.png) + +#### *9. Загрузить, предобработать и подать на вход обученной нейронной сети собственное изображение, созданное при выполнении лабораторной работы №1. Вывести изображение и результат распознавания.* + +```python +from PIL import Image + +img_path = '../5.png' + +file_data = Image.open(img_path) +file_data = file_data.convert('L') # перевод в градации серого +test_img = np.array(file_data) + +plt.imshow(test_img, cmap='gray') +plt.axis('off') +plt.show() + +# нормализация и изменение формы +test_proc = test_img.astype('float32') / 255.0 +test_proc = np.reshape(test_proc, (1, 28, 28, 1)) + +result = model.predict(test_proc) +print("NN output vector:", result) +print("I think it's", np.argmax(result)) +``` + +![image](pics/i4.png) + +```python +NN output vector: [[1.5756325e-12 5.2755486e-15 1.4891595e-10 7.3797599e-07 1.8559115e-12 + 9.9998915e-01 3.5407410e-08 5.2025315e-12 1.5018414e-06 8.6681475e-06]] +I think it's 5 +``` + +### 10. Загрузить с диска модель, сохраненную при выполнении лабораторной работы №1. Вывести информацию об архитектуре модели.Повторить для этой модели п.6. + +При работе с моделью из ЛР1 необходимо взять данные в исходном формате, иначе получится двойная нормализация. В CNN данные нормализовались на этапе подготовки к сети (X/255.0 и reshape к (28,28,1)), но модель из ЛР1 ожидала плоский вектор 784 элементов на изображение. + +```python +# возьмём оригинальные X, y — до всех преобразований для CNN +(X_train_full, y_train_full), (X_test_full, y_test_full) = mnist.load_data() + +# объединим, чтобы сделать то же разбиение, что и в ЛР1 +X_all = np.concatenate((X_train_full, X_test_full), axis=0) +y_all = np.concatenate((y_train_full, y_test_full), axis=0) + +from sklearn.model_selection import train_test_split +X_train_l1, X_test_l1, y_train_l1, y_test_l1 = train_test_split( + X_all, y_all, train_size=60000, test_size=10000, random_state=19 +) + +# теперь — подготовка данных ЛР1 +X_test_lr1 = X_test_l1.reshape((X_test_l1.shape[0], 28*28)).astype('float32') / 255.0 +y_test_lr1 = keras.utils.to_categorical(y_test_l1, 10) + +# оценка модели +scores_lr1 = model_lr1.evaluate(X_test_lr1, y_test_lr1, verbose=2) +print(scores_lr1) +``` +Точность уменьшилась, так как в ЛР1 использовалась полносвязная сеть, а не сверточная. Сверточные сети лучше извлекают признаки у изображений, а потому дают большую точность. +```python +313/313 - 2s - 6ms/step - accuracy: 0.9445 - loss: 0.1969 +[0.1968761384487152, 0.9445000290870667] +``` + +### 11. Сравнить обученную модель сверточной сети и наилучшую модель полносвязной сети из лабораторной работы №1 по следующим показателям: количество настраиваемых параметров в сети, количество эпох обучения, качество классификации тестовой выборки. Сделать выводы по результатам применения сверточной нейронной сети для распознавания изображений. + +```python +# загрузка сохранённой модели ЛР1 +model_lr1_path = '../best_model_2x100.h5' +model_lr1 = load_model(model_lr1_path) +model_lr1.summary() + +# подготовка тестового набора для модели ЛР1 +X_test_l1 = X_test_l1.reshape((X_test_l1.shape[0], 28 * 28)).astype('float32') / 255.0 +y_test_l1_cat = keras.utils.to_categorical(y_test_l1, 10) + +# оценка модели ЛР1 +scores_lr1 = model_lr1.evaluate(X_test_l1, y_test_l1_cat, verbose=2) +print('LR1 model - Loss:', scores_lr1[0]) +print('LR1 model - Accuracy:', scores_lr1[1]) + +# оценка сверточной модели ЛР3 +scores_conv = model.evaluate(X_test, y_test_cat, verbose=2) +print('Conv model - Loss:', scores_conv[0]) +print('Conv model - Accuracy:', scores_conv[1]) + +# вывод числа параметров обеих моделей +print('LR1 model parameters:', model_lr1.count_params()) +print('Conv model parameters:', model.count_params()) +``` +В MLP (ЛР1) количество параметров = 89610, а в CNN (ЛР3) оно равно 34826. CNN имеет значительно меньше параметров, примерно в 2,5 раза меньше, чем MLP. Это произошло потому, что в сверточных слоях параметры делятся по ядрам свертки и применяются к локальным областям изображения, что снижает избыточность. MLP полностью соединяет все нейроны между слоями, а значит, имеет больше весов. Меньшее число параметров влечет к меньшей вероятности переобучения и более экономное использование памяти. + +Значение функции потерь у CNN почти в 5 раз меньше, что указывает на лучшее соответствие предсказаний истинным меткам. + +```python +WARNING:absl:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model. +Model: "sequential_9" + +| Layer (type) | Output shape | Param # | +|--------------|--------------|---------| +| dense_18 | (None, 100) | 78,500 | +| dense_19 | (None, 100) | 10,100 | +| dense_20 | (None, 10) | 1,010 | + +Total params: 89,612 (350.05 KB) +Trainable params: 89,610 (350.04 KB) +Non-trainable params: 0 (0.00 B) +Optimizer params: 2 (12.00 B) +313/313 - 3s - 9ms/step - accuracy: 0.9445 - loss: 0.1969 +LR1 model - Loss: 0.1968761384487152 +LR1 model - Accuracy: 0.9445000290870667 +313/313 - 6s - 20ms/step - accuracy: 0.9879 - loss: 0.0402 +Conv model - Loss: 0.04024936258792877 +Conv model - Accuracy: 0.9879000186920166 +LR1 model parameters: 89610 +Conv model parameters: 34826 +``` + +## Задание 2. +#### *1–3. Загрузка CIFAR-10 и разбиение 50 000 : 10 000, вывод 25 изображений* + +CIFAR-10 — это стандартный набор цветных изображений маленького размера (32×32 пикселя) с 10 классами объектов, включая транспорт, животных и птиц, предназначенный для задач классификации изображений. + +Аналогично заданию №1, данные нормализуются и преобразовываются в формат one-hot. +```python +from keras.datasets import cifar10 + +(X_train_c, y_train_c), (X_test_c, y_test_c) = cifar10.load_data() + +print('Shapes (original):', X_train_c.shape, y_train_c.shape, X_test_c.shape, y_test_c.shape) + +class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', + 'dog', 'frog', 'horse', 'ship', 'truck'] + +# вывод 25 изображений +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_c[i]) + plt.xlabel(class_names[y_train_c[i][0]]) +plt.show() +``` +```python +Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz +170498071/170498071 ━━━━━━━━━━━━━━━━━━━━ 4s 0us/step +Shapes (original): (50000, 32, 32, 3) (50000, 1) (10000, 32, 32, 3) (10000, 1) +``` +![image](pics/i5.png) + +#### *4. Предобработка CIFAR-10 (нормализация и one-hot)* + +```python +num_classes = 10 +input_shape_cifar = (32, 32, 3) + +X_train_c = X_train_c.astype('float32') / 255.0 +X_test_c = X_test_c.astype('float32') / 255.0 + +y_train_c_cat = keras.utils.to_categorical(y_train_c, num_classes) +y_test_c_cat = keras.utils.to_categorical(y_test_c, num_classes) + +print('Transformed shapes:', X_train_c.shape, y_train_c_cat.shape, X_test_c.shape, y_test_c_cat.shape) +``` +```python +Transformed shapes: (50000, 32, 32, 3) (50000, 10) (10000, 32, 32, 3) (10000, 10) +``` + +#### *5. Реализация и обучение сверточной сети для CIFAR-10* + +Используются три слоя Conv2D с увеличивающимся числом фильтров (32 → 64 → 128) для извлечения признаков с изображений CIFAR-10. Между сверточными слоями используются MaxPooling2D для уменьшения размерности и концентрации на важных признаках. + +```python +model_cifar = Sequential() +model_cifar.add(layers.Conv2D(32, (3,3), activation='relu', input_shape=input_shape_cifar)) +model_cifar.add(layers.MaxPooling2D((2,2))) +model_cifar.add(layers.Conv2D(64, (3,3), activation='relu')) +model_cifar.add(layers.MaxPooling2D((2,2))) +model_cifar.add(layers.Conv2D(128, (3,3), activation='relu')) +model_cifar.add(layers.MaxPooling2D((2,2))) +model_cifar.add(layers.Flatten()) +model_cifar.add(layers.Dense(128, activation='relu')) +model_cifar.add(layers.Dropout(0.5)) +model_cifar.add(layers.Dense(num_classes, activation='softmax')) + +model_cifar.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) +model_cifar.summary() + +batch_size = 512 +epochs = 20 +history_cifar = model_cifar.fit(X_train_c, y_train_c_cat, batch_size=batch_size, epochs=epochs, validation_split=0.1) +``` + + +```python +/usr/local/lib/python3.12/dist-packages/keras/src/layers/convolutional/base_conv.py:113: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead. + super().__init__(activity_regularizer=activity_regularizer, **kwargs) +Model: "sequential_1" + +| Layer (type) | Output Shape | Param # | +| ------------------------------ | ------------------ | ------- | +| conv2d_2 (Conv2D) | (None, 30, 30, 32) | 896 | +| max_pooling2d_2 (MaxPooling2D) | (None, 15, 15, 32) | 0 | +| conv2d_3 (Conv2D) | (None, 13, 13, 64) | 18,496 | +| max_pooling2d_3 (MaxPooling2D) | (None, 6, 6, 64) | 0 | +| conv2d_4 (Conv2D) | (None, 4, 4, 128) | 73,856 | +| max_pooling2d_4 (MaxPooling2D) | (None, 2, 2, 128) | 0 | +| flatten_1 (Flatten) | (None, 512) | 0 | +| dense_1 (Dense) | (None, 128) | 65,664 | +| dropout_1 (Dropout) | (None, 128) | 0 | +| dense_2 (Dense) | (None, 10) | 1,290 | + + Total params: 160,202 (625.79 KB) + Trainable params: 160,202 (625.79 KB) + Non-trainable params: 0 (0.00 B) +``` +#### *6. Оценка качества на тестовой выборке CIFAR-10* + +```python +scores_cifar = model_cifar.evaluate(X_test_c, y_test_c_cat, verbose=2) +print('CIFAR - Loss on test data:', scores_cifar[0]) +print('CIFAR - Accuracy on test data:', scores_cifar[1]) +``` +```python +313/313 - 8s - 26ms/step - accuracy: 0.6855 - loss: 0.8885 +CIFAR - Loss on test data: 0.8884508609771729 +CIFAR - Accuracy on test data: 0.6855000257492065 +``` + +#### *7-8. Подать два тестовых изображения: одно верно, другое ошибочно. Вывести отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки* + +```python +print(classification_report(true_cifar, preds_cifar, target_names=class_names)) + +conf_matrix_cifar = confusion_matrix(true_cifar, preds_cifar) +display = ConfusionMatrixDisplay(confusion_matrix=conf_matrix_cifar, + display_labels=class_names) + +plt.figure(figsize=(10,10)) # figsize задаётся здесь +display.plot(cmap='Blues', colorbar=False) # без figsize +plt.xticks(rotation=45) +plt.show() +``` +```python + precision recall f1-score support + + airplane 0.78 0.66 0.71 1000 + automobile 0.82 0.81 0.81 1000 + bird 0.61 0.55 0.58 1000 + cat 0.49 0.43 0.46 1000 + deer 0.62 0.67 0.64 1000 + dog 0.51 0.71 0.59 1000 + frog 0.81 0.73 0.77 1000 + horse 0.72 0.71 0.71 1000 + ship 0.77 0.82 0.80 1000 + truck 0.80 0.76 0.78 1000 + + accuracy 0.69 10000 + macro avg 0.69 0.69 0.69 10000 +weighted avg 0.69 0.69 0.69 10000 + +
+``` +![image](pics/i6.png) + + +Для CIFAR-10 точность составила ~68.55%, что ниже, чем для MNIST, из-за большей сложности изображений (цветные, более сложные объекты). +Видно, что классы cat и dog хуже распознаются (точность 0.49 и 0.51), а automobile, ship, truck распознаются лучше (~0.8). +Матрица ошибок (ConfusionMatrixDisplay) позволяет визуально увидеть, какие классы чаще путаются между собой (например, cat и dog). + +## Вывод +Проведенное исследование показало, что сверточные нейронные сети превосходят полносвязные модели в задачах распознавания изображений. Для MNIST сверточная сеть достигла точности 98,79% при меньшем числе параметров (34 826 против 89 610 у MLP), что обеспечивает более экономное использование памяти и снижает риск переобучения. + +На более сложном наборе CIFAR-10 сеть показала точность 68,55%, при этом объекты с визуально схожими признаками, например кошки и собаки, распознаются хуже, чем однозначные объекты, такие как автомобили и корабли. Результаты демонстрируют, что сверточные сети эффективно извлекают признаки из изображений и обеспечивают высокое качество классификации, особенно на структурированных данных, хотя для сложных цветных изображений требуется более глубокая архитектура или дополнительные методы улучшения обучения. \ No newline at end of file