diff --git a/labworks/LW3/Report.md b/labworks/LW3/Report.md new file mode 100644 index 0000000..1c640f3 --- /dev/null +++ b/labworks/LW3/Report.md @@ -0,0 +1,846 @@ +# Отчёт по лабораторной работе №3 +## по теме: "Распознавание изображений" + +--- +Выполнили: Бригада 2, Мачулина Д.В., Бирюкова А.С., А-02-22 +--- + +## Задание 1 +### 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 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. Разбиение набора данных на общучающие и тестовые (номер бригады - 2) +```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 = 7) +# вывод размерностей +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) +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() +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Layer (type)Output ShapeParam #
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]) +``` +Loss on test data: 0.04353996366262436 +Accuracy on test data: 0.9876000285148621 + +--- + ### 7. Подача на вход обученной модели тестовых изображений +```python +# вывод тестового изображения и результата распознавания +n = 333 +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)) +``` + +![](http://uit.mpei.ru/git/MachulinaDV/is_dnn/raw/branch/main/labworks/LW2/AE1_train_def.png) + +Real mark: 3 +NN answer: 3 + +```python +# вывод тестового изображения и результата распознавания +n = 222 +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)) +``` + +![](http://uit.mpei.ru/git/MachulinaDV/is_dnn/raw/branch/main/labworks/LW2/AE2_train_def.png) + +Real mark: 2 +NN answer: 2 + +--- +### 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() +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
№(type)precisionrecallf1-scoresupport
00.990.990.99968
11.000.990.991087
20.990.990.991000
30.990.980.991039
40.990.990.99966
50.980.990.99908
60.990.990.99972
70.980.990.981060
80.980.980.981015
90.980.980.98985
accuracy0.9910000
macro avg0.990.990.9910000
weighted avg0.990.990.9910000
+ + +![]() +--- +### 9. Загрузка, предобработка и подача собственных изображения +```python +# загрузка собственного изображения +from PIL import Image +file_data = Image.open('7.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)) +``` +![]() + +```python +# загрузка собственного изображения +from PIL import Image +file_data = Image.open('5.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)) +``` +![]() + +### 10. Загрузка модели из ЛР1. Оценка качества +```python +model = keras.models.load_model("best_model.keras") +model.summary() +``` + + + + + + + + + + + + + + + + + + + + +
Layer (type)Output ShapeParam #
dense_4 (Dense)(None, 300)235,500
dense_5 (Dense)(None, 10)3,010
+ + Total params: 238,512 (931.69 KB) + Trainable params: 238,510 (931.68 KB) + Non-trainable params: 0 (0.00 B) + Optimizer params: 2 (12.00 B) + + +```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 = 7) +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.37091827392578125 +Accuracy on test data: 0.9013000130653381 + +--- +### 11. Сравнение обученной модели сверточной сети и наилучшей модели полносвязной сети + + + + + + + + + + + + + + + + + + + + + + + +
МодельКоличество настраиваемых параметров сетиКоличество эпох обученияКачество классификации тестовой выборки
Сверточная34,826150.9876
Полносвязная238,5121000.9013
+ +Вывод: + + +## Задание 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 = 7) +# вывод размерностей +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() +``` +![]() + +### 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() +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Layer (type)Output ShapeParam #
conv2d (Conv2D)(None, 32, 32, 32)896
batch_normalization_6 (BatchNormalization)(None, 32, 32, 32) 128
conv2d_13 (Conv2D)(None, 32, 32, 32)9,248
batch_normalization_7 (BatchNormalization)(None, 32, 32, 32)128
max_pooling2d_9 (MaxPooling2D)(None, 16, 16, 32)0
dropout_6 (Dropout)(None, 16, 16, 32)0
conv2d_14 (Conv2D)(None, 16, 16, 64)18,496
batch_normalization_8 (BatchNormalization)(None, 16, 16, 64)256
conv2d_15 (Conv2D)(None, 16, 16, 64)32,928
batch_normalization_9 (BatchNormalization)(None, 16, 16, 64)256
max_pooling2d_10 (MaxPooling2D)(None, 8, 8, 64)0
dropout_7 (Dropout)(None, 8, 8, 64)0
flatten_3 (Flatten) (None, 4096)0
dense_6 (Dense)(None, 128)524,416
dropout_8 (Dropout)(None, 128)0
dense_7 (Dense)(None, 10)1,290
+Total params: 592,042 (2.26 MB) + Trainable params: 591,658 (2.26 MB) + Non-trainable params: 384 (1.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) +``` + +### 6. Оценка качества обучения на тестовых данных +```python +scores = model.evaluate(X_test, y_test) +print('Loss on test data:', scores[0]) +print('Accuracy on test data:', scores[1]) +``` + +### 7. Подача на вход обученной модели тестовых изображений +```python +for n in [5,17]: + 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)) +``` +![]() +Real mark: 0 +NN answer: 2 + +![]() +Real mark: 5 +NN answer: 5 + +### 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() +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
classprecisionrecallf1-scoresupport
airplane0.850.860.861013
automobile0.930.910.92989
bird0.750.750.751018
cat0.690.660.671049
deer0.790.780.781009
dog0.730.680.71978
frog0.790.900.84981
horse0.880.840.86986
ship0.890.920.911029
truck0.880.910.89948
accuracy0.8210000
macro avg0.820.820.8210000
weighted avg0.820.820.8210000
+ +![]() + +Вывод: \ No newline at end of file