Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
28
Добавлен:
18.07.2022
Размер:
1.17 Mб
Скачать

Отчет по лабораторной работе № 3

по дисциплине «Интеллектуальные системы»

на тему «Распознавание изображений»

Цель работы

Получить практические навыки создания, обучения и применения сверточных нейронных сетей для распознавания изображений. Познакомиться с классическими показателями качества классификации.

Задание 1

1) В среде Google Colab создадим новый блокнот. Импортируем необходимые для работы библиотеки и модули.

import os

os.chdir('/content/drive/MyDrive/Colab Notebooks/IS_LR3')

# импорт модулей

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

2) Загрузим набор данных MNIST, содержащий размеченные изображения рукописных цифр.

# загрузка датасета

from keras.datasets import mnist

(X_train, y_train), (X_test, y_test) = mnist.load_data()

1

3) Разобьем набор данных на обучающие (train) и тестовые (test) данные в соотношении 60000:10000 элементов. При разбиении параметр random_state выберем равным (4*22 – 1) = = 87. Выведем размерности полученных обучающих и тестовых массивов данных.

# создание своего разбиения датасета

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 = 87)

# вывод размерностей

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)

Результат:

Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz 11493376/11490434 [==============================] - 0s 0us/step 11501568/11490434 [==============================] - 0s 0us/step

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». Выведем размерности предобработанных обучающих и тестовых массивов данных.

# Зададим параметры данных и модели

2

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) Реализуем модель сверточной нейронной сети и обучим ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Выведем информацию об архитектуре нейронной сети.

# создаем модель 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))

3

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)

18496

max_pooling2d_1 (MaxPooling (None, 5, 5, 64)

 

0

2D)

 

 

 

 

dropout (Dropout)

(None, 5, 5, 64)

0

 

 

flatten (Flatten)

(None, 1600)

0

 

 

dense (Dense)

(None, 10)

16010

 

=================================================================

Total params: 34,826 Trainable params: 34,826 Non-trainable params: 0

_________________________________________________________________

# компилируем и обучаем модель batch_size = 128

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)

4

Результат:

Epoch 15/15

422/422 [==============================] - 37s 87ms/step - loss: 0.0206 - accuracy: 0.9934 - val_loss: 0.0283 - val_accuracy: 0.9913

6) Оценим качество обучения на тестовых данных. Выведем значение функции ошибки и значение метрики качества классификации на тестовых данных.

# Оценка качества работы модели на тестовых данных scores = model.evaluate(X_test, y_test)

print('Loss on test data:', scores[0]) print('Accuracy on test data:', scores[1])

Результат:

313/313 [==============================] - 3s 8ms/step - loss: 0.0337 - accuracy: 0.9900 Loss on test data: 0.033651165664196014

Accuracy on test data: 0.9900000095367432

7) Подадим на вход обученной модели два тестовых изображения. Выведем изображения, истинные метки и результаты распознавания.

# вывод тестового изображения и результата распознавания n = 87

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))

Результат:

NN output: [[1.8994561e-09 9.9997437e-01 1.9214222e-06 1.4394224e-11 1.0481855e-05 3.1840541e-10 2.4228148e-09 1.0422922e-05 2.8613138e-06 1.3936267e-09]]

5

Real mark: 1

NN answer: 1

# вывод тестового изображения и результата распознавания n = 86

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))

Результат:

NN output: [[1.3139387e-15 3.7731544e-15 3.4353822e-09 1.2818173e-09 2.6459586e-16 2.9080759e-11 2.0733557e-14 2.0914493e-16 1.0000000e+00 1.4831038e-10]]

Real mark: 8

NN answer: 8

8) Выведем отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки.

# истинные метки классов 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))

6

# вычисление матрицы ошибок

conf_matrix = confusion_matrix(true_labels, predicted_labels)

# красивая отрисовка матрицы ошибок в виде "тепловой карты" make_confusion_matrix(conf_matrix, percent=False, figsize=(10,10))

Результат:

precision recall f1-score support

0

1.00

1.00

1.00

997

1

0.99

1.00

0.99

1118

2

0.99

0.99

0.99

986

3

0.99

0.98

0.99

1041

4

0.99

1.00

0.99

955

5

0.99

0.99

0.99

887

6

1.00

0.99

0.99

1019

7

0.99

0.99

0.99

1013

8

0.99

0.99

0.99

1016

9

0.99

0.98

0.98

968

accuracy

 

 

0.99

 

10000

macro avg

0.99 0.99

0.99

10000

weighted avg

0.99

0.99

 

0.99

10000

7

9) Загрузим, предобработаем и подадим на вход обученной нейронной сети собственное изображение, созданное при выполнении лабораторной работы №1. Выведем изображение и результат распознавания.

#загрузка собственного изображения from PIL import Image

file_data = Image.open('test.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))

Результат:

8

I think it's 3

10) Сравним обученную модель сверточной сети и наилучшую модель полносвязной сети из лабораторной работы №1.

Количество настраиваемых параметров:

1)сверточной сети: 34826;

2)наилучшей полносвязной сети (100 нейронов в первом слое, 300 нейронов во втором слое): (784 + 1)*100 + (100 + 1)*300 + (300 + 1)*10 = 111810.

Следовательно, у наилучшей полносвязной сети примерно в 3,2 раза больше настраиваемых параметров, чем у сверточной сети.

Количество эпох обучения:

1)сверточной сети: 15 эпох;

2)наилучшей полносвязной сети: 100 эпох.

Следовательно, для качественного обучения наилучшей полносвязной сети потребовалось примерно в 6,7 раз больше эпох обучения, чем сверточной сети.

Качество классификации тестовой выборки:

1) у сверточной сети:

метрика качества = 0,990;

ошибка на тестовых данных = 0,034.

2) у наилучшей полносвязной сети:

метрика качества = 0,962;

ошибка на тестовых данных = 0,140.

9

Сверточная сеть верно распознала тестовые изображения и собственное изображение цифры, поданное на ее вход. Наилучшая полносвязная сеть верно распознала одно из двух тестовых изображений и собственное изображение цифры, поданное на ее вход.

Для сверточной сети значения параметров Precision, Recall, F1-score, рассчитанные для каждого из 10 классов, близки к идеальному значению, равному единице. Невзвешенное среднее и взвешенное среднее значения этих параметров также близки к идеальным.

Таким образом, можно сделать вывод, что для сверточной сети требуется меньше настраиваемых параметров и эпох обучения, чем для полносвязной сети, при этом значение метрики качества у нее выше, а ошибка на тестовых данных меньше, чем у полносвязной сети. Для распознавания изображений цифр целесообразно применять сверточную нейронную сеть.

10

Соседние файлы в папке Лабораторные работы