From d8e74008f3806036fcd3780545a33da09b2e53cc Mon Sep 17 00:00:00 2001 From: ShchipkovMY Date: Sun, 30 Nov 2025 16:12:38 +0000 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8=D0=BB(?= =?UTF-8?q?=D0=B0)=20=D0=BD=D0=B0=20'labworks/LW3/report.md'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labworks/LW3/report.md | 527 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 526 insertions(+), 1 deletion(-) diff --git a/labworks/LW3/report.md b/labworks/LW3/report.md index 2e65efe..c460eee 100644 --- a/labworks/LW3/report.md +++ b/labworks/LW3/report.md @@ -1 +1,526 @@ -a \ No newline at end of file +# Отчёт по лабораторной работе №3 + +--- + +## Щипков Матвей, Железнов Артем, Ледовской Михаил, Бригада 7, А-02-22 + +## Задание 1 + +### 1. Создание блокнота и настройка среды + +```python +import os +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 + +```python +# загрузка датасета +from keras.datasets import mnist +(X_train, y_train), (X_test, y_test) = mnist.load_data() +``` + +--- + +### 3. Разбиение набора данных на общучающие и тестовые (Бригада 7) + +```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 = 27) +# вывод размерностей +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. Предобработка данных + +```python +# Зададим параметры данных и модели +num_classes = 10 +input_shape = (28, 28, 1) + +# Приведение входных данных к диапазону [0, 1] +X_train = X_train / 255 +X_test = X_test / 255 + +# Расширяем размерность входных данных, чтобы каждое изображение имело +# размерность (высота, ширина, количество каналов) + +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 +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) + +hape 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() +``` + +![photo](http://uit.mpei.ru/git/ShchipkovMY/is_dnn/src/branch/main/labworks/LW3/photo/f1.PNG) + +```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]) +``` + +Loss on test data: 0.03765992447733879 +Accuracy on test data: 0.9890999794006348 + +--- + +### 7. Подача на вход обученной модели тестовых изображений + +```python +# вывод тестового изображения и результата распознавания +n = 555 +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)) +``` + +![photo](http://uit.mpei.ru/git/ShchipkovMY/is_dnn/src/branch/main/labworks/LW3/photo/f2.PNG) + +```python +# вывод тестового изображения и результата распознавания +n = 404 +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)) +``` + +![photo](http://uit.mpei.ru/git/ShchipkovMY/is_dnn/src/branch/main/labworks/LW3/photo/f3.PNG) + +--- + +### 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() +``` + +![photo](http://uit.mpei.ru/git/ShchipkovMY/is_dnn/src/branch/main/labworks/LW3/photo/f4.PNG) + +### 9. Загрузка, предобработка и подача собственных изображения + +```python +# загрузка собственного изображения +from PIL import Image +file_data = Image.open('five_3011.png') +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)) +``` + +![photo](http://uit.mpei.ru/git/ShchipkovMY/is_dnn/src/branch/main/labworks/LW3/photo/f5.PNG) + +```python +# загрузка собственного изображения +from PIL import Image +file_data = Image.open('three_3011.png') +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)) +``` + +![photo](http://uit.mpei.ru/git/ShchipkovMY/is_dnn/src/branch/main/labworks/LW3/photo/f6.PNG) + +--- + +### 10. Загрузка модели из ЛР1. Оценка качества + +```python +model = keras.models.load_model("best_model.keras") +model.summary() +``` + +![photo](http://uit.mpei.ru/git/ShchipkovMY/is_dnn/src/branch/main/labworks/LW3/photo/f7.PNG) + +```python +# развернем каждое изображение 28*28 в вектор 784 +X_train, X_test, y_train, y_test = train_test_split(X, y, + test_size = 10000, + train_size = 60000, + random_state = 27) +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 +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.evaluate(X_test, y_test) +print('Loss on test data:', scores[0]) +print('Accuracy on test data:', scores[1]) +``` + +Loss on test data: 0.19266724586486816 +Accuracy on test data: 0.9459999799728394 + +--- + +### 11. Сравнение обученной модели сверточной сети и наилучшей модели полносвязной сети + + + + + + + + + + + + + + + + + + + + + + + + +
МодельКоличество настраиваемых параметров сетиКоличество эпох обученияКачество классификации тестовой выборки
Сверточная34.826150.9890
Полносвязная89.6121000.9459
+ +Вывод: Проведённая лабораторная работа показала, что свёрточная нейронная сеть значительно эффективнее справляется с задачей распознавания изображений. Она достигла качества классификации 0.9890 всего за 15 эпох обучения и при 35 параметрах, тогда как полносвязной сети для результата 0.9459 потребовалось 100 эпох и 89 параметров. + +## Задание 2 + +### В новом блокноте выполнили п.1-8 задания 1, изменив набор данных MNIST на CIFAR-10 + +### 1. Создание блокнота и настройка среды + +```python +from google.colab import drive +drive.mount('/content/drive') +import os +os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab3') + +from tensorflow import keras +from tensorflow.keras.models import Sequential +from tensorflow.keras import layers +import matplotlib.pyplot as plt +import numpy as np +from sklearn.metrics import classification_report, confusion_matrix +from sklearn.metrics import ConfusionMatrixDisplay +``` + +### 2.Загрузка набора данных и его разбиение на ообучащие и тестовые + +```python +# загрузка датасета +from keras.datasets import cifar10 +(X_train, y_train), (X_test, y_test) = cifar10.load_data() +``` + +```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 = 50000, + random_state = 27) +# вывод размерностей +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) + +### 3. Вывод изображений с подписями классов + +```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() +``` + +![photo](http://uit.mpei.ru/git/ShchipkovMY/is_dnn/src/branch/main/labworks/LW3/photo/f8.PNG) + +### 4. Предобработка данных + +```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 +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) + +--- + +### 5. Реализация и обучение модели свёрточной нейронной сети + +```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)) + +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() +``` + +![photo](http://uit.mpei.ru/git/ShchipkovMY/is_dnn/src/branch/main/labworks/LW3/photo/f9.PNG) + +```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) +``` + +### 6. Оценка качества обучения на тестовых данных + +```python +scores = model.evaluate(X_test, y_test) +print('Loss on test data:', scores[0]) +print('Accuracy on test data:', scores[1]) +``` + +Loss on test data: 0.6117131114006042 +Accuracy on test data: 0.821399986743927 + +--- + +### 7. Подача на вход обученной модели тестовых изображений + +```python +# вывод двух тестовых изображений и результатов распознавания + +for n in [2,15]: + 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)) + +``` + +![photo](http://uit.mpei.ru/git/ShchipkovMY/is_dnn/src/branch/main/labworks/LW3/photo/f10.PNG) + +![photo](http://uit.mpei.ru/git/ShchipkovMY/is_dnn/src/branch/main/labworks/LW3/photo/f11.PNG) + +--- + +### 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, 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() +``` + +![photo](http://uit.mpei.ru/git/ShchipkovMY/is_dnn/src/branch/main/labworks/LW3/photo/f12.PNG) + +![photo](http://uit.mpei.ru/git/ShchipkovMY/is_dnn/src/branch/main/labworks/LW3/photo/f13.PNG) + + +**Вывод**: Модель нейронной сети, обученная на датасете CIFAR-10, показала достойный результат с точностью распознавания 82%. При этом её показатель оказался ниже, чем у модели, созданной для MNIST. Такое различие объясняется характером данных: классификация цветных изображений заметно сложнее, чем чёрно-белых цифр. Для повышения качества распознавания в случае CIFAR-10 целесообразно усложнять архитектуру сети: увеличивать число слоёв и эпох обучения, а также расширять обучающую выборку (в данной работе она составляла 50 000 примеров).