Сравнить коммиты
4 Коммитов
| Автор | SHA1 | Дата |
|---|---|---|
|
|
1d0184c4cc | 4 недель назад |
|
|
53df99878f | 1 месяц назад |
|
|
03d1666fe7 | 2 месяцев назад |
|
|
fdbf3159c0 | 3 месяцев назад |
@ -0,0 +1,260 @@
|
||||
# Отчет по лабораторной работе № 1
|
||||
|
||||
### Киселёв Матвей, Мамедов Расул А-01-22
|
||||
|
||||
## 1) В среде Google Colab создать новый блокнот (notebook). Импортировать необходимые для работы библиотеки и модули.
|
||||
|
||||
```py
|
||||
import os
|
||||
os.chdir('/content/drive/MyDrive/Colab Notebooks')
|
||||
|
||||
# импорт модулей
|
||||
from tensorflow import keras
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import sklearn
|
||||
```
|
||||
## 2) Загрузить набор данных MNIST, содержащий размеченные изображения рукописных цифр.
|
||||
|
||||
```py
|
||||
# загрузка датасета
|
||||
from keras.datasets import mnist
|
||||
(X_train, y_train), (X_test, y_test) = mnist.load_data()
|
||||
```
|
||||
|
||||
## 3) Разбить набор данных на обучающие и тестовые данные в соотношении 60 000:10 000 элементов. При разбиении параметр random_state выбрать равным (4k – 1), где k – номер бригады. Вывести размерности полученных обучающих и тестовых массивов данных.
|
||||
|
||||
```py
|
||||
# создание своего разбиения датасета
|
||||
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 = 4*6 -1)
|
||||
|
||||
# вывод размерностей
|
||||
print('Shape of X train:', X_train.shape)
|
||||
print('Shape of y train:', X_train.shape)
|
||||
```
|
||||
|
||||
## 4) Вывести первые 4 элемента обучающих данных (изображения и метки цифр).
|
||||
|
||||
```py
|
||||
for i in [0,1,2,3]:
|
||||
# вывод изображения
|
||||
plt.imshow(X_train[i], cmap=plt.get_cmap('gray'))
|
||||
plt.show()
|
||||
|
||||
# вывод метки для этого изображения
|
||||
print(y_train[i])
|
||||
```
|
||||

|
||||
|
||||
6
|
||||
|
||||

|
||||
|
||||
4
|
||||
|
||||

|
||||
|
||||
4
|
||||
|
||||

|
||||
|
||||
3
|
||||
|
||||
## 5) Провести предобработку данных: привести обучающие и тестовые данные к формату, пригодному для обучения нейронной сети. Входные данные должны принимать значения от 0 до 1, метки цифр должны быть закодированы по принципу «one-hot encoding». Вывести размерности предобработанных обучающих и тестовых массивов данных.
|
||||
|
||||
```py
|
||||
# развернем каждое изображение 28*28 в вектор 784
|
||||
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)
|
||||
|
||||
# переведем метки в one-hot
|
||||
from keras.utils import to_categorical
|
||||
y_train = keras.utils.to_categorical(y_train)
|
||||
y_test = keras.utils.to_categorical(y_test)
|
||||
print('Shape of transformed y train:', y_train.shape)
|
||||
num_classes = y_train.shape[1]
|
||||
```
|
||||
|
||||
## 6) Реализовать модель однослойной нейронной сети и обучить ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывести информацию об архитектуре нейронной сети. Вывести график функции ошибки на обучающих и валидационных данных по эпохам.
|
||||
|
||||
```py
|
||||
from keras.models import Sequential
|
||||
from keras.layers import Dense
|
||||
|
||||
# 1. создаем модель - объявляем ее объектом класса Sequential
|
||||
model = Sequential()
|
||||
# 2. добавляем выходной слой
|
||||
model.add(Dense(units=num_classes, activation='softmax'))
|
||||
# 3. компилируем модель
|
||||
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
||||
|
||||
# вывод информации об архитектуре модели
|
||||
print(model.summary())
|
||||
|
||||
# Обучаем модель
|
||||
H = model.fit(X_train, y_train, validation_split=0.1, epochs=50)
|
||||
```
|
||||
|
||||
## 7) Применить обученную модель к тестовым данным. Вывести значение функции ошибки и значение метрики качества классификации на тестовых данных.
|
||||
|
||||
```py
|
||||
# вывод графика ошибки по эпохам
|
||||
plt.plot(H.history['loss'])
|
||||
plt.plot(H.history['val_loss'])
|
||||
plt.grid()
|
||||
plt.xlabel('Epochs')
|
||||
plt.ylabel('loss')
|
||||
plt.legend(['train_loss', 'val_loss'])
|
||||
plt.title('Loss by epochs')
|
||||
plt.show()
|
||||
|
||||
# Оценка качества работы модели на тестовых данных
|
||||
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.2811441123485565
|
||||
|
||||
Accuracy on test data: 0.9204000234603882
|
||||
|
||||
## 8) Добавить в модель один скрытый и провести обучение и тестирование (повторить п. 6–7) при 100, 300, 500 нейронах в скрытом слое. По метрике качества классификации на тестовых данных выбрать наилучшее количество нейронов в скрытом слое. В качестве функции активации нейронов в скрытом слое использовать функцию sigmoid.
|
||||
|
||||
```py
|
||||
# добавляем первый скрытый слой
|
||||
model.add(Dense(units=100, input_dim=num_pixels, activation='sigmoid'))
|
||||
```
|
||||
### 100 нейронов в 1 скрытом слое:
|
||||
|
||||

|
||||
|
||||
### 300 нейронов в 1 скрытом слое:
|
||||
|
||||

|
||||
|
||||
### 500 нейронов в 1 скрытом слое:
|
||||
|
||||

|
||||
|
||||
### Вывод: по наибольшей метрике качества классификации на тестовых данных можно определить, что лучшее количество нейронов в скрытом слое - 100.
|
||||
|
||||
## 9) Добавить в наилучшую архитектуру, определенную в п. 8, второй скрытый слой и провести обучение и тестирование (повторить п. 6–7) при 50 и 100 нейронах во втором скрытом слое. В качестве функции активации нейронов в скрытом слое использовать функцию sigmoid.
|
||||
|
||||
```py
|
||||
# добавляем второй скрытый слой
|
||||
model.add(Dense(units=50, activation='sigmoid'))
|
||||
```
|
||||
|
||||
### 100 нейронов в 1 скрытом слое и 50 во 2 скрытом слое:
|
||||
|
||||

|
||||
|
||||
### 100 нейронов в 1 скрытом слое и 100 во 2 скрытом слое:
|
||||
|
||||

|
||||
|
||||
## 10) Результаты исследования архитектуры нейронной сети занести в таблицу:
|
||||
|
||||
| Кол-во скрытых слоев | Нейроны в 1 слое | Нейроны во 2 слое | Точность |
|
||||
|----------------------|------------------|-------------------|----------|
|
||||
| 0 | - | - | 0.9204 |
|
||||
| 1 | 100 | - | 0.9592 |
|
||||
| 1 | 300 | - | 0.9536 |
|
||||
| 1 | 500 | - | 0.9488 |
|
||||
| 2 | 100 | 50 | 0.9618 |
|
||||
| 2 | 100 | 100 | 0.9603 |
|
||||
|
||||
### Вывод: как видно из таблицы, наилучший результат показала нейросеть с двумя скрытыми слоями, у которой 100 нейронов в первом скрытом слое и 50 во втором.
|
||||
|
||||
## 11) Сохранить наилучшую нейронную сеть на диск. Данную нейронную сеть потребуется загрузить с диска в одной из следующих лабораторных работ.
|
||||
|
||||
```py
|
||||
model.save('best_model.keras')
|
||||
```
|
||||
|
||||
## 12) Для нейронной сети наилучшей архитектуры вывести два тестовых изображения, истинные метки и результат распознавания изображений.
|
||||
|
||||
```py
|
||||
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: ', str(np.argmax(y_test[n])))
|
||||
print('NN answer: ', str(np.argmax(result)))
|
||||
```
|
||||
|
||||

|
||||
|
||||
Real mark: 2
|
||||
|
||||
NN answer: 2
|
||||
|
||||

|
||||
|
||||
Real mark: 0
|
||||
|
||||
NN answer: 0
|
||||
|
||||
## 13) Каждому члену бригады создать собственное изображение рукописной цифры, подобное представленным в наборе MNIST. Цифру выбрать как остаток от деления на 10 числа своего дня рождения (например, 29 февраля → 29 mod 10 = 9). Сохранить изображения. Загрузить, предобработать и подать на вход обученной нейронной сети собственные изображения. Вывести изображения и результаты распознавания.
|
||||
|
||||
```py
|
||||
# загрузка собственного изображения
|
||||
from PIL import Image
|
||||
file_data = Image.open('test5.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 = test_img.reshape(1, num_pixels)
|
||||
# распознавание
|
||||
result = model.predict(test_img)
|
||||
print('I think it\'s ', np.argmax(result))
|
||||
```
|
||||
|
||||

|
||||
|
||||
I think it`s 5
|
||||
|
||||

|
||||
|
||||
I think it`s 3
|
||||
|
||||
## 14) Каждому члену бригады создать копию собственного изображения, отличающуюся от оригинала поворотом на 90 градусов в любую сторону. Сохранить изображения. Загрузить, предобработать и подать на вход обученной нейронной сети измененные изображения. Вывести изображения и результаты распознавания. Сделать выводы по результатам эксперимента.
|
||||
|
||||
```py
|
||||
from PIL import Image
|
||||
file_data = Image.open('test5per.png')
|
||||
file_data = file_data.convert('L') # перевод в градации серого
|
||||
test_img = np.array(file_data)
|
||||
```
|
||||
|
||||

|
||||
|
||||
I think it`s 8
|
||||
|
||||

|
||||
|
||||
I think it`s 4
|
||||
|
||||
### Вывод: первую пару изображений нейросеть смогла правильно распознать, однако их перевёрнутые версии - нет. Это связано с тем, что на вход этой нейросети мы не подавали повёрнутые числа.
|
||||
|
После Ширина: | Высота: | Размер: 6.9 KiB |
|
После Ширина: | Высота: | Размер: 23 KiB |
|
После Ширина: | Высота: | Размер: 7.2 KiB |
|
После Ширина: | Высота: | Размер: 7.1 KiB |
|
После Ширина: | Высота: | Размер: 6.7 KiB |
|
После Ширина: | Высота: | Размер: 6.6 KiB |
|
После Ширина: | Высота: | Размер: 6.6 KiB |
|
После Ширина: | Высота: | Размер: 6.5 KiB |
|
После Ширина: | Высота: | Размер: 7.0 KiB |
|
После Ширина: | Высота: | Размер: 6.6 KiB |
|
После Ширина: | Высота: | Размер: 6.9 KiB |
|
После Ширина: | Высота: | Размер: 24 KiB |
|
После Ширина: | Высота: | Размер: 25 KiB |
|
После Ширина: | Высота: | Размер: 25 KiB |
|
После Ширина: | Высота: | Размер: 25 KiB |
|
После Ширина: | Высота: | Размер: 23 KiB |
|
После Ширина: | Высота: | Размер: 22 KiB |
|
После Ширина: | Высота: | Размер: 22 KiB |
|
После Ширина: | Высота: | Размер: 34 KiB |
|
После Ширина: | Высота: | Размер: 33 KiB |
|
После Ширина: | Высота: | Размер: 31 KiB |
|
После Ширина: | Высота: | Размер: 36 KiB |
|
После Ширина: | Высота: | Размер: 75 KiB |
|
После Ширина: | Высота: | Размер: 45 KiB |
|
После Ширина: | Высота: | Размер: 114 KiB |
|
После Ширина: | Высота: | Размер: 90 KiB |
|
После Ширина: | Высота: | Размер: 97 KiB |
|
После Ширина: | Высота: | Размер: 109 KiB |
|
После Ширина: | Высота: | Размер: 68 KiB |
|
После Ширина: | Высота: | Размер: 80 KiB |
@ -0,0 +1,348 @@
|
||||
# Отчет по лабораторной работе № 2
|
||||
|
||||
### Киселёв Матвей, Мамедов Расул А-01-22
|
||||
### Вариант 10
|
||||
|
||||
## 1) В среде Google Colab создать новый блокнот (notebook). Импортировать необходимые для работы библиотеки и модули.
|
||||
|
||||
```py
|
||||
import os
|
||||
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab2')
|
||||
|
||||
import numpy as np
|
||||
import lab02_lib as lib
|
||||
```
|
||||
## 2) Сгенерировать индивидуальный набор двумерных данных в пространстве признаков с координатами центра (k, k), где k – номер бригады. Вывести полученные данные на рисунок и в консоль.
|
||||
|
||||
```py
|
||||
# генерация датасета
|
||||
data = lib.datagen(10, 10, 1000, 2)
|
||||
|
||||
# вывод данных и размерности
|
||||
print('Исходные данные:')
|
||||
print(data)
|
||||
print('Размерность данных:')
|
||||
print(data.shape)
|
||||
```
|
||||

|
||||
|
||||
### Исходные данные:
|
||||
[[10.1127864 9.99999352]
|
||||
[10.05249217 9.87350749]
|
||||
[10.1316048 10.05250118]
|
||||
...
|
||||
[10.03841171 10.0442026 ]
|
||||
[ 9.91528464 10.06201318]
|
||||
[10.09181138 9.92258731]]
|
||||
### Размерность данных:
|
||||
(1000, 2)
|
||||
|
||||
## 3) Создать и обучить автокодировщик AE1 простой архитектуры, выбрав небольшое количество эпох обучения. Зафиксировать в таблице вида количество скрытых слоёв и нейронов в них.
|
||||
|
||||
```py
|
||||
# обучение AE1
|
||||
patience = 300
|
||||
ae1_trained, IRE1, IREth1 = lib.create_fit_save_ae(data,'out/AE1.h5','out/AE1_ire_th.txt',
|
||||
1000, False, patience)
|
||||
```
|
||||
|
||||
## 4) Зафиксировать ошибку MSE, на которой обучение завершилось. Построить график ошибки реконструкции обучающей выборки. Зафиксировать порог ошибки реконструкции – порог обнаружения аномалий.
|
||||
```
|
||||
Epoch 1000/1000
|
||||
- loss: 58.5663
|
||||
```
|
||||
|
||||
```py
|
||||
# Построение графика ошибки реконструкции
|
||||
lib.ire_plot('training', IRE1, IREth1, 'AE1')
|
||||
```
|
||||

|
||||
|
||||
## 5) Создать и обучить второй автокодировщик AE2 с усложненной архитектурой, задав большее количество эпох обучения.
|
||||
|
||||
```py
|
||||
# обучение AE2
|
||||
ae2_trained, IRE2, IREth2 = lib.create_fit_save_ae(data,'out/AE2.h5','out/AE2_ire_th.txt',
|
||||
3000, False, patience)
|
||||
```
|
||||
|
||||
## 6) Зафиксировать ошибку MSE, на которой обучение завершилось. Построить график ошибки реконструкции обучающей выборки. Зафиксировать второй порог ошибки реконструкции – порог обнаружения аномалий.
|
||||
```
|
||||
Epoch 3000/3000
|
||||
- loss: 0.0165
|
||||
```
|
||||
|
||||
```py
|
||||
# Построение графика ошибки реконструкции
|
||||
lib.ire_plot('training', IRE2, IREth2, 'AE2')
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 7) Рассчитать характеристики качества обучения EDCA для AE1 и AE2. Визуализировать и сравнить области пространства признаков, распознаваемые автокодировщиками AE1 и AE2. Сделать вывод о пригодности AE1 и AE2 для качественного обнаружения аномалий.
|
||||
|
||||
```py
|
||||
# построение областей покрытия и границ классов
|
||||
# расчет характеристик качества обучения
|
||||
numb_square = 20
|
||||
xx, yy, Z1 = lib.square_calc(numb_square, data, ae1_trained, IREth1, '1', True)
|
||||
```
|
||||
|
||||
```
|
||||
amount: 22
|
||||
amount_ae: 308
|
||||
```
|
||||
|
||||

|
||||

|
||||
```
|
||||
Оценка качества AE1
|
||||
IDEAL = 0. Excess: 13.0
|
||||
IDEAL = 0. Deficit: 0.0
|
||||
IDEAL = 1. Coating: 1.0
|
||||
summa: 1.0
|
||||
IDEAL = 1. Extrapolation precision (Approx): 0.07142857142857142
|
||||
```
|
||||
|
||||
```py
|
||||
# построение областей покрытия и границ классов
|
||||
# расчет характеристик качества обучения
|
||||
numb_square = 20
|
||||
xx, yy, Z2 = lib.square_calc(numb_square, data, ae2_trained, IREth2, '2', True)
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
amount: 22
|
||||
amount_ae: 39
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
```
|
||||
Оценка качества AE2
|
||||
IDEAL = 0. Excess: 0.7727272727272727
|
||||
IDEAL = 0. Deficit: 0.0
|
||||
IDEAL = 1. Coating: 1.0
|
||||
summa: 1.0
|
||||
IDEAL = 1. Extrapolation precision (Approx): 0.5641025641025641
|
||||
```
|
||||
|
||||
```py
|
||||
# сравнение характеристик качества обучения и областей аппроксимации
|
||||
lib.plot2in1(data, xx, yy, Z1, Z2)
|
||||
```
|
||||

|
||||
|
||||
## 8) Если автокодировщик AE2 недостаточно точно аппроксимирует область обучающих данных, то подобрать подходящие параметры автокодировщика и повторить шаги (6) – (8).
|
||||
|
||||
### Вывод: автокодировщик AE2 достаточно точно аппроксимирует область обучающих данных
|
||||
|
||||
## 9) Изучить сохраненный набор данных и пространство признаков. Создать тестовую выборку, состоящую, как минимум, из 4ёх элементов, не входящих в обучающую выборку. Элементы должны быть такими, чтобы AE1 распознавал их как норму, а AE2 детектировал как аномалии.
|
||||
|
||||
```py
|
||||
# загрузка тестового набора
|
||||
data_test = np.loadtxt('data_test.txt', dtype=float)
|
||||
print(data_test)
|
||||
```
|
||||
|
||||
```
|
||||
[[8.5 8.5]
|
||||
[8.2 8.2]
|
||||
[7.7 7.7]
|
||||
[9.3 8.8]]
|
||||
```
|
||||
|
||||
## 10) Применить обученные автокодировщики AE1 и AE2 к тестовым данным и вывести значения ошибки реконструкции для каждого элемента тестовой выборки относительно порога на график и в консоль.
|
||||
|
||||
```py
|
||||
# тестирование АE1
|
||||
predicted_labels1, ire1 = lib.predict_ae(ae1_trained, data_test, IREth1)
|
||||
|
||||
lib.anomaly_detection_ae(predicted_labels1, ire1, IREth1)
|
||||
lib.ire_plot('test', ire1, IREth1, 'AE1')
|
||||
```
|
||||
```
|
||||
Аномалий не обнаружено
|
||||
```
|
||||

|
||||
|
||||
```py
|
||||
# тестирование АE2
|
||||
predicted_labels2, ire2 = lib.predict_ae(ae2_trained, data_test, IREth2)
|
||||
|
||||
lib.anomaly_detection_ae(predicted_labels2, ire2, IREth2)
|
||||
lib.ire_plot('test', ire2, IREth2, 'AE2')
|
||||
```
|
||||
|
||||
```
|
||||
i Labels IRE IREth
|
||||
0 [1.] [1.99] 0.47
|
||||
1 [1.] [2.42] 0.47
|
||||
2 [1.] [3.12] 0.47
|
||||
3 [1.] [1.28] 0.47
|
||||
Обнаружено 4.0 аномалий
|
||||
```
|
||||

|
||||
|
||||
## 11) Визуализировать элементы обучающей и тестовой выборки в областях пространства признаков, распознаваемых автокодировщиками AE1 и AE2.
|
||||
|
||||
```py
|
||||
# построение областей аппроксимации и точек тестового набора
|
||||
lib.plot2in1_anomaly(data, xx, yy, Z1, Z2, data_test)
|
||||
```
|
||||

|
||||
|
||||
|
||||
|
||||
## 12) Результаты исследования занести в таблицу:
|
||||
|
||||
| | Количество скрытых слоев | Количество нейронов в скрытых слоях | Количество эпох обучения | Ошибка MSE_stop| Порог ошибки реконструкции| Значение показателя Excess| Значение показателя Approx| Количество обнаруженных аномалий|
|
||||
|-----|------------------|-------------------|----------|----------|----------|----------|----------|----------|
|
||||
| АЕ1 | 1 | 1 | 1000 |58.5663 | |13.0 |0.0714 |0 |
|
||||
| АЕ2 | 5 | 4 2 1 2 4 | 3000 |0.0165 |0.47 |0.7727 |0.5641 |4 |
|
||||
|
||||
|
||||
## 13) Для качественного обнаружения аномалий в данны сделать выводы о требованиях к:
|
||||
### - данным для обучения: должны быть без аномалий
|
||||
### - архитектуре автокодировщика: бутылочное горлышко, 5 нейронов - оптимально
|
||||
### - количеству эпох обучения: 3000 с patience 300
|
||||
### - ошибке MSE_stop, приемлемой для останова обучения: 0.0165 - приемлемое значение
|
||||
### - ошибке реконструкции обучающей выборки (порогу обнаружения аномалий): 0.47 - приемлемое значение
|
||||
### - характеристикам качества обучения EDCA одноклассового классификатора: Excess - 0.773, Deficit - 0.0, Coating - 1.0, Approx - 0.564
|
||||
|
||||
|
||||
# Задание 2:
|
||||
## 1) Изучить описание своего набора реальных данных, что он из себя представляет;
|
||||
|
||||
### Letter
|
||||
Исходный набор данных Letter Recognition Data Set из репозитория машинного
|
||||
обучения UCI представляет собой набор данных для многоклассовой классификации.
|
||||
Набор предназначен для распознавания черно-белых пиксельных прямоугольников как
|
||||
одну из 26 заглавных букв английского алфавита, где буквы алфавита представлены в
|
||||
16 измерениях. Чтобы получить данные, подходящие для обнаружения аномалий, была
|
||||
произведена подвыборка данных из 3 букв, чтобы сформировать нормальный класс, и
|
||||
случайным образом их пары были объединены так, чтобы их размерность удваивалась.
|
||||
Чтобы сформировать класс аномалий, случайным образом были выбраны несколько
|
||||
экземпляров букв, которые не входят нормальный класс, и они были объединены с
|
||||
экземплярами из нормального класса. Процесс объединения выполняется для того,
|
||||
чтобы сделать обнаружение более сложным, поскольку каждый аномальный пример
|
||||
также будет иметь некоторые нормальные значения признаков.
|
||||
|
||||
## 2) Загрузить многомерную обучающую выборку реальных данных name_train.txt.
|
||||
```py
|
||||
# загрузка выборок
|
||||
train = np.loadtxt('letter_train.txt', dtype=float)
|
||||
```
|
||||
## 3) Вывести полученные данные и их размерность в консоли.
|
||||
|
||||
```py
|
||||
print('train:\n', train)
|
||||
print('train.shape:', np.shape(train))
|
||||
```
|
||||
|
||||
```
|
||||
train:
|
||||
[[ 6. 10. 5. ... 10. 2. 7.]
|
||||
[ 0. 6. 0. ... 8. 1. 7.]
|
||||
[ 4. 7. 5. ... 8. 2. 8.]
|
||||
...
|
||||
[ 7. 10. 10. ... 8. 5. 6.]
|
||||
[ 7. 7. 10. ... 6. 0. 8.]
|
||||
[ 3. 4. 5. ... 9. 5. 5.]]
|
||||
train.shape: (1500, 32)
|
||||
```
|
||||
## 4) Создать и обучить автокодировщик с подходящей для данных архитектурой. Выбрать необходимое количество эпох обучения.
|
||||
|
||||
```py
|
||||
from time import time
|
||||
|
||||
patience = 5000
|
||||
start = time()
|
||||
ae3_v1_trained, IRE3_v1, IREth3_v1 = lib.create_fit_save_ae(train,'out/AE3_V1.h5','out/AE3_v1_ire_th.txt',
|
||||
100000, False, patience, early_stopping_delta = 0.001)
|
||||
print("Время на обучение: ", time() - start)
|
||||
```
|
||||
|
||||
## 5) Зафиксировать ошибку MSE, на которой обучение завершилось. Построить график ошибки реконструкции обучающей выборки. Зафиксировать порог ошибки реконструкции – порог обнаружения аномалий.
|
||||
|
||||
```
|
||||
Epoch 100000/100000
|
||||
- loss: 0.2571
|
||||
```
|
||||
|
||||
```py
|
||||
# Построение графика ошибки реконструкции
|
||||
lib.ire_plot('training', IRE3_v1, IREth3_v1, 'AE3_v1')
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 6) Сделать вывод о пригодности обученного автокодировщика для качественного обнаружения аномалий. Если порог ошибки реконструкции слишком велик, то подобрать подходящие параметры автокодировщика и повторить шаги (4) – (6).
|
||||
|
||||
### Вывод: обученный автокодировщик пригоден для качественного обнаружения аномалий. Порог ошибки реконструкции достаточно мал.
|
||||
|
||||
## 7) Изучить и загрузить тестовую выборку name_test.txt.
|
||||
|
||||
```py
|
||||
# загрузка выборок
|
||||
test = np.loadtxt('letter_test.txt', dtype=float)
|
||||
```
|
||||
|
||||
```py
|
||||
print('\n test:\n', test)
|
||||
print('test.shape:', np.shape(test))
|
||||
```
|
||||
|
||||
```
|
||||
test:
|
||||
[[ 8. 11. 8. ... 7. 4. 9.]
|
||||
[ 4. 5. 4. ... 13. 8. 8.]
|
||||
[ 3. 3. 5. ... 8. 3. 8.]
|
||||
...
|
||||
[ 4. 9. 4. ... 8. 3. 8.]
|
||||
[ 6. 10. 6. ... 9. 8. 8.]
|
||||
[ 3. 1. 3. ... 9. 1. 7.]]
|
||||
test.shape: (100, 32)
|
||||
```
|
||||
|
||||
## 8) Подать тестовую выборку на вход обученного автокодировщика для обнаружения аномалий. Вывести график ошибки реконструкции элементов тестовой выборки относительно порога.
|
||||
|
||||
```py
|
||||
# тестирование АE3
|
||||
predicted_labels3_v1, ire3_v1 = lib.predict_ae(ae3_v1_trained, test, IREth3_v1)
|
||||
```
|
||||
|
||||
```py
|
||||
# Построение графика ошибки реконструкции
|
||||
lib.ire_plot('test', ire3_v1, IREth3_v1, 'AE3_v1')
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 9) Если результаты обнаружения аномалий не удовлетворительные (обнаружено менее 70% аномалий), то подобрать подходящие параметры автокодировщика и повторить шаги (4) – (9).
|
||||
|
||||
```py
|
||||
# тестирование АE3
|
||||
lib.anomaly_detection_ae(predicted_labels3_v1, IRE3_v1, IREth3_v1)
|
||||
```
|
||||
|
||||
```
|
||||
Обнаружено 84.0 аномалий
|
||||
```
|
||||
|
||||
## 10) Параметры наилучшего автокодировщика и результаты обнаружения аномалий занести в таблицу:
|
||||
|
||||
|Dataset name | Количество скрытых слоев | Количество нейронов в скрытых слоях | Количество эпох обучения | Ошибка MSE_stop| Порог ошибки реконструкции| % обнаруженных аномалий |
|
||||
|-----|------------------|-------------------|----------|----------|----------|----------|
|
||||
| Letter | 7 | 56 28 14 7 14 28 56 | 100000 |0.2571 |6.97 |84 |
|
||||
|
||||
|
||||
## 11) Для качественного обнаружения аномалий в случае, когда размерность пространства признаков высока. Сделать выводы о требованиях к:
|
||||
### - данным для обучения: должны быть без аномалий
|
||||
### - архитектуре автокодировщика: бутылочное горлышко, 7 нейронов - оптимально
|
||||
### - количеству эпох обучения: не менее 100000
|
||||
### - ошибке MSE_stop, приемлемой для останова обучения: 0.2571 - приемлемое значение
|
||||
### - ошибке реконструкции обучающей выборки (порогу обнаружения аномалий): 6.97 - приемлемое значение
|
||||
|
После Ширина: | Высота: | Размер: 45 KiB |
|
После Ширина: | Высота: | Размер: 21 KiB |
|
После Ширина: | Высота: | Размер: 12 KiB |
|
После Ширина: | Высота: | Размер: 12 KiB |
|
После Ширина: | Высота: | Размер: 60 KiB |
|
После Ширина: | Высота: | Размер: 7.3 KiB |
|
После Ширина: | Высота: | Размер: 7.0 KiB |
|
После Ширина: | Высота: | Размер: 30 KiB |
|
После Ширина: | Высота: | Размер: 6.6 KiB |
|
После Ширина: | Высота: | Размер: 6.7 KiB |
|
После Ширина: | Высота: | Размер: 13 KiB |
|
После Ширина: | Высота: | Размер: 122 KiB |
|
После Ширина: | Высота: | Размер: 68 KiB |
@ -0,0 +1,500 @@
|
||||
# Отчёт по лабораторной работе №3
|
||||
|
||||
### Киселёв Матвей, Мамедов Расул А-01-22
|
||||
### Вариант 6
|
||||
|
||||
## Задание 1
|
||||
|
||||
## 1) В среде Google Colab создать новый блокнот (notebook). Импортировать необходимые для работы библиотеки и модули.
|
||||
|
||||
```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) Разбить набор данных на обучающие и тестовые данные в соотношении 60 000:10 000 элементов. При разбиении параметр random_state выбрать равным (4k – 1), где k –номер бригады. Вывести размерности полученных обучающих и тестовых массивов данных.
|
||||
|
||||
```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 = 23)
|
||||
# вывод размерностей
|
||||
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
|
||||
|
||||
# Расширяем размерность входных данных, чтобы каждое изображение имело
|
||||
# размерность (высота, ширина, количество каналов)
|
||||
|
||||
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()
|
||||
```
|
||||

|
||||
|
||||
```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 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step - accuracy: 0.9909 - loss: 0.0257
|
||||
Loss on test data: 0.02905484288930893
|
||||
Accuracy on test data: 0.9904999732971191
|
||||
```
|
||||
|
||||
## 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))
|
||||
```
|
||||

|
||||
```
|
||||
Real mark: 2
|
||||
NN answer: 2
|
||||
```
|
||||

|
||||
```
|
||||
Real mark: 9
|
||||
NN answer: 9
|
||||
```
|
||||
|
||||
## 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 ━━━━━━━━━━━━━━━━━━━━ 1s 2ms/step
|
||||
precision recall f1-score support
|
||||
|
||||
0 0.99 1.00 0.99 997
|
||||
1 1.00 0.99 1.00 1164
|
||||
2 0.99 0.98 0.99 1030
|
||||
3 0.99 0.99 0.99 1031
|
||||
4 0.99 0.99 0.99 967
|
||||
5 0.98 0.99 0.99 860
|
||||
6 0.99 1.00 0.99 977
|
||||
7 0.98 0.99 0.99 1072
|
||||
8 0.99 0.98 0.99 939
|
||||
9 0.99 0.98 0.98 963
|
||||
|
||||
accuracy 0.99 10000
|
||||
macro avg 0.99 0.99 0.99 10000
|
||||
weighted avg 0.99 0.99 0.99 10000
|
||||
```
|
||||

|
||||
|
||||
## 9) Загрузить, предобработать и подать на вход обученной нейронной сети собственное изображение, созданное при выполнении лабораторной работы №1. Вывести изображение и результат распознавания.
|
||||
|
||||
```python
|
||||
# загрузка собственного изображения
|
||||
from PIL import Image
|
||||
|
||||
for name_image in ['test3.png', 'test5.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))
|
||||
```
|
||||

|
||||
```
|
||||
I think it's 3
|
||||
```
|
||||

|
||||
```
|
||||
I think it's 5
|
||||
```
|
||||
|
||||
## 10) Загрузить с диска модель, сохраненную при выполнении лабораторной работы №1. Вывести информацию об архитектуре модели. Повторить для этой модели п. 6.
|
||||
|
||||
```python
|
||||
model_lr1 = keras.models.load_model("model_1h100_2h50.keras")
|
||||
|
||||
model_lr1.summary()
|
||||
```
|
||||

|
||||
|
||||
|
||||
```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 = 23)
|
||||
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_lr1.evaluate(X_test, y_test)
|
||||
print('Loss on test data:', scores[0])
|
||||
print('Accuracy on test data:', scores[1])
|
||||
```
|
||||
```
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.9576 - loss: 0.1293
|
||||
Loss on test data: 0.13758081197738647
|
||||
Accuracy on test data: 0.9567000269889832
|
||||
```
|
||||
|
||||
## 11) Сравнить обученную модель сверточной сети и наилучшую модель полносвязной сети из лабораторной работы №1 по следующим показателям:
|
||||
### - количество настраиваемых параметров в сети
|
||||
### - количество эпох обучения
|
||||
### - качество классификации тестовой выборки.
|
||||
## Сделать выводы по результатам применения сверточной нейронной сети для распознавания изображений.
|
||||
|
||||
|
||||
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|
||||
|----------|-------------------------------------|---------------------------|-----------------------------------------|
|
||||
| Сверточная | 34 826 | 15 | accuracy:0.991 ; loss:0.029 |
|
||||
| Полносвязная | 84 062 | 50 | accuracy:0.957 ; loss:0.138 |
|
||||
|
||||
|
||||
### Вывод: сравнивая результаты применения двух сетей, можно сделать вывод, что сверточная НС лучше справляется с задачами распознования изображений, чем полносвязная.
|
||||
|
||||
## Задание 2
|
||||
|
||||
## В новом блокноте выполнить п. 1–8 задания 1, изменив набор данных MNIST на CIFAR-10, содержащий размеченные цветные изображения объектов, разделенные на 10 классов.
|
||||
|
||||
## 1) Загрузить набор данных CIFAR-10.
|
||||
|
||||
```python
|
||||
# загрузка датасета
|
||||
from keras.datasets import cifar10
|
||||
|
||||
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
|
||||
```
|
||||
|
||||
## 2) Разбить набор данных на обучающие и тестовые данные в соотношении 50 000:10 000 элементов. При разбиении параметр random_state выбрать равным (4k – 1), где k –номер бригады. Вывести размерности полученных обучающих и тестовых массивов данных.
|
||||
|
||||
```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 = 23)
|
||||
# вывод размерностей
|
||||
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)
|
||||
```
|
||||
|
||||
```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()
|
||||
```
|
||||

|
||||
|
||||
## 3) Провести предобработку данных: привести обучающие и тестовые данные к формату, пригодному для обучения сверточной нейронной сети. Входные данные принимают значения от 0 до 1, метки цифр закодированы по принципу «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
|
||||
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) Реализовать модель сверточной нейронной сети и обучить ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывести информацию об архитектуре нейронной сети.
|
||||
|
||||
```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()
|
||||
```
|
||||

|
||||
|
||||
```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) Оценить качество обучения на тестовых данных. Вывести значение функции ошибки и значение метрики качества классификации на тестовых данных.
|
||||
|
||||
```python
|
||||
# Оценка качества работы модели на тестовых данных
|
||||
scores = model.evaluate(X_test, y_test)
|
||||
print('Loss on test data:', scores[0])
|
||||
print('Accuracy on test data:', scores[1])
|
||||
```
|
||||
```
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.8507 - loss: 0.5097
|
||||
Loss on test data: 0.4886781871318817
|
||||
Accuracy on test data: 0.8521999716758728
|
||||
```
|
||||
|
||||
## 6) Подать на вход обученной модели два тестовых изображения. Вывести изображения, истинные метки и результаты распознавания.
|
||||
|
||||
```python
|
||||
# вывод двух тестовых изображений и результатов распознавания
|
||||
|
||||
for n in [1,10]:
|
||||
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: 8
|
||||
NN answer: 8
|
||||
```
|
||||

|
||||
```
|
||||
Real mark: 3
|
||||
NN answer: 3
|
||||
```
|
||||
|
||||
## 7) Вывести отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки.
|
||||
|
||||
```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 ━━━━━━━━━━━━━━━━━━━━ 5s 9ms/step
|
||||
precision recall f1-score support
|
||||
|
||||
airplane 0.86 0.88 0.87 986
|
||||
automobile 0.94 0.93 0.94 971
|
||||
bird 0.75 0.85 0.80 1043
|
||||
cat 0.83 0.64 0.72 1037
|
||||
deer 0.78 0.90 0.83 969
|
||||
dog 0.78 0.75 0.76 979
|
||||
frog 0.83 0.92 0.87 1025
|
||||
horse 0.92 0.83 0.87 948
|
||||
ship 0.93 0.93 0.93 1003
|
||||
truck 0.94 0.90 0.92 1039
|
||||
|
||||
accuracy 0.85 10000
|
||||
macro avg 0.86 0.85 0.85 10000
|
||||
weighted avg 0.86 0.85 0.85 10000
|
||||
```
|
||||

|
||||
|
||||
### Вывод: полученные метрики оценки качества имеют показатели около 0.85. Из этого можно сделать вывод, что сверточная модель хорошо справилась с задачей классификации датасета CIFAR-10.
|
||||
|
После Ширина: | Высота: | Размер: 14 KiB |
|
После Ширина: | Высота: | Размер: 21 KiB |
@ -0,0 +1,315 @@
|
||||
# Отчёт по лабораторной работе №4
|
||||
|
||||
### Киселёв Матвей, Мамедов Расул А-01-22
|
||||
### Вариант 6
|
||||
|
||||
### 1) В среде Google Colab создать новый блокнот (notebook). Настроить блокнот для работы с аппаратным ускорителем GPU.
|
||||
```python
|
||||
# импорт модулей
|
||||
import os
|
||||
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab4')
|
||||
|
||||
from tensorflow import keras
|
||||
from tensorflow.keras import layers
|
||||
from tensorflow.keras.models import Sequential
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
```
|
||||
```python
|
||||
import tensorflow as tf
|
||||
device_name = tf.test.gpu_device_name()
|
||||
if device_name != '/device:GPU:0':
|
||||
raise SystemError('GPU device not found')
|
||||
print('Found GPU at: {}'.format(device_name))
|
||||
```
|
||||
```
|
||||
Found GPU at: /device:GPU:0
|
||||
```
|
||||
|
||||
### 2) Загрузить набор данных IMDb, содержащий оцифрованные отзывы на фильмы, размеченные на два класса: позитивные и негативные. При загрузке набора данных параметр seed выбрать равным (4k – 1), где k – номер бригады. Вывести размеры полученных обучающих и тестовых массивов данных.
|
||||
|
||||
```python
|
||||
# загрузка датасета
|
||||
from keras.datasets import imdb
|
||||
|
||||
vocabulary_size = 5000
|
||||
index_from = 3
|
||||
|
||||
(X_train, y_train), (X_test, y_test) = imdb.load_data(
|
||||
path="imdb.npz",
|
||||
num_words=vocabulary_size,
|
||||
skip_top=0,
|
||||
maxlen=None,
|
||||
seed=23,
|
||||
start_char=1,
|
||||
oov_char=2,
|
||||
index_from=index_from
|
||||
)
|
||||
|
||||
# вывод размерностей
|
||||
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: (25000,)
|
||||
Shape of y train: (25000,)
|
||||
Shape of X test: (25000,)
|
||||
Shape of y test: (25000,)
|
||||
```
|
||||
|
||||
### 3) Вывести один отзыв из обучающего множества в виде списка индексов слов. Преобразовать список индексов в текст и вывести отзыв в виде текста. Вывести длину отзыва. Вывести метку класса данного отзыва и название класса (1 – Positive, 0 – Negative).
|
||||
|
||||
```python
|
||||
# создание словаря для перевода индексов в слова
|
||||
# заргузка словаря "слово:индекс"
|
||||
word_to_id = imdb.get_word_index()
|
||||
# уточнение словаря
|
||||
word_to_id = {key:(value + index_from) for key,value in word_to_id.items()}
|
||||
word_to_id["<PAD>"] = 0
|
||||
word_to_id["<START>"] = 1
|
||||
word_to_id["<UNK>"] = 2
|
||||
word_to_id["<UNUSED>"] = 3
|
||||
# создание обратного словаря "индекс:слово"
|
||||
id_to_word = {value:key for key,value in word_to_id.items()}
|
||||
```
|
||||
```python
|
||||
print(X_train[23])
|
||||
print('len:',len(X_train[23]))
|
||||
```
|
||||
```
|
||||
[1, 14, 20, 9, 290, 149, 48, 25, 358, 2, 120, 318, 302, 50, 26, 49, 221, 2057, 10, 10, 1212, 39, 15, 45, 801, 2, 2, 363, 2396, 7, 2, 209, 2327, 283, 8, 4, 425, 10, 10, 45, 24, 290, 3613, 972, 4, 65, 198, 40, 3462, 1224, 2, 23, 6, 4457, 225, 24, 76, 50, 8, 895, 19, 45, 164, 204, 5, 24, 55, 318, 38, 92, 140, 11, 18, 4, 65, 33, 32, 43, 168, 33, 4, 302, 10, 10, 17, 47, 77, 1046, 12, 188, 6, 117, 2, 33, 4, 130, 2, 4, 2, 7, 87, 3709, 2199, 7, 35, 2504, 5, 33, 211, 320, 2504, 132, 190, 48, 25, 2754, 4, 1273, 2, 45, 6, 1682, 8, 2, 42, 24, 8, 2, 10, 10, 32, 11, 32, 45, 6, 542, 3709, 22, 290, 319, 18, 15, 1288, 5, 15, 584]
|
||||
len: 146
|
||||
```
|
||||
```python
|
||||
review_as_text = ' '.join(id_to_word[id] for id in X_train[23])
|
||||
print(review_as_text)
|
||||
print('len:',len(review_as_text))
|
||||
```
|
||||
```
|
||||
<START> this movie is worth watching if you enjoy <UNK> over special effects there are some interesting visuals br br aside from that it's typical <UNK> <UNK> hollywood fare of <UNK> without substance true to the title br br it's not worth picking apart the story that's like performing brain <UNK> on a dinosaur there's not much there to begin with it's nothing original and not very special so don't go in for the story at all just look at the effects br br as has been mentioned it got a little <UNK> at the end <UNK> the <UNK> of great fx treatment of an invisible and at times half invisible man however if you ignore the standard <UNK> it's a sight to <UNK> or not to <UNK> br br all in all it's a decent fx film worth seeing for that purpose and that alone
|
||||
len: 763
|
||||
```
|
||||
|
||||
|
||||
### 4) Вывести максимальную и минимальную длину отзыва в обучающем множестве.
|
||||
|
||||
```python
|
||||
print('MAX Len: ',len(max(X_train, key=len)))
|
||||
print('MIN Len: ',len(min(X_train, key=len)))
|
||||
```
|
||||
```
|
||||
MAX Len: 2494
|
||||
MIN Len: 11
|
||||
```
|
||||
|
||||
### 5) Провести предобработку данных. Выбрать единую длину, к которой будут приведены все отзывы. Короткие отзывы дополнить спецсимволами, а длинные обрезать до выбранной длины.
|
||||
|
||||
```python
|
||||
# предобработка данных
|
||||
from tensorflow.keras.utils import pad_sequences
|
||||
max_words = 500
|
||||
X_train = pad_sequences(X_train, maxlen=max_words, value=0, padding='pre', truncating='post')
|
||||
X_test = pad_sequences(X_test, maxlen=max_words, value=0, padding='pre', truncating='post')
|
||||
```
|
||||
|
||||
### 6) Повторить п. 4.
|
||||
|
||||
```python
|
||||
print('MAX Len: ',len(max(X_train, key=len)))
|
||||
print('MIN Len: ',len(min(X_train, key=len)))
|
||||
```
|
||||
```
|
||||
MAX Len: 500
|
||||
MIN Len: 500
|
||||
```
|
||||
|
||||
### 7) Повторить п. 3. Сделать вывод о том, как отзыв преобразовался после предобработки.
|
||||
```python
|
||||
print(X_train[23])
|
||||
print('len:',len(X_train[23]))
|
||||
```
|
||||
```
|
||||
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 1 14 20 9 290 149 48 25 358 2
|
||||
120 318 302 50 26 49 221 2057 10 10 1212 39 15 45
|
||||
801 2 2 363 2396 7 2 209 2327 283 8 4 425 10
|
||||
10 45 24 290 3613 972 4 65 198 40 3462 1224 2 23
|
||||
6 4457 225 24 76 50 8 895 19 45 164 204 5 24
|
||||
55 318 38 92 140 11 18 4 65 33 32 43 168 33
|
||||
4 302 10 10 17 47 77 1046 12 188 6 117 2 33
|
||||
4 130 2 4 2 7 87 3709 2199 7 35 2504 5 33
|
||||
211 320 2504 132 190 48 25 2754 4 1273 2 45 6 1682
|
||||
8 2 42 24 8 2 10 10 32 11 32 45 6 542
|
||||
3709 22 290 319 18 15 1288 5 15 584]
|
||||
len: 500
|
||||
```
|
||||
|
||||
```python
|
||||
review_as_text = ' '.join(id_to_word[id] for id in X_train[23])
|
||||
print(review_as_text)
|
||||
print('len:',len(review_as_text))
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
<PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <START> this movie is worth watching if you enjoy <UNK> over special effects there are some interesting visuals br br aside from that it's typical <UNK> <UNK> hollywood fare of <UNK> without substance true to the title br br it's not worth picking apart the story that's like performing brain <UNK> on a dinosaur there's not much there to begin with it's nothing original and not very special so don't go in for the story at all just look at the effects br br as has been mentioned it got a little <UNK> at the end <UNK> the <UNK> of great fx treatment of an invisible and at times half invisible man however if you ignore the standard <UNK> it's a sight to <UNK> or not to <UNK> br br all in all it's a decent fx film worth seeing for that purpose and that alone
|
||||
len: 2887
|
||||
|
||||
```
|
||||
### В начало отзыва добавились токены PAD в количестве, необходимом для достижения длины в 500 индексов.
|
||||
|
||||
### 8) Вывести предобработанные массивы обучающих и тестовых данных и их размерности.
|
||||
|
||||
```python
|
||||
# вывод данных
|
||||
print('X train: \n',X_train)
|
||||
print('X train: \n',X_test)
|
||||
|
||||
# вывод размерностей
|
||||
print('Shape of X train:', X_train.shape)
|
||||
print('Shape of X test:', X_test.shape)
|
||||
```
|
||||
```
|
||||
X train:
|
||||
[[ 0 0 0 ... 6 52 106]
|
||||
[ 0 0 0 ... 87 22 231]
|
||||
[ 0 0 0 ... 6 158 158]
|
||||
...
|
||||
[ 0 0 0 ... 1005 4 1630]
|
||||
[ 0 0 0 ... 9 6 991]
|
||||
[ 0 0 0 ... 7 32 58]]
|
||||
X train:
|
||||
[[ 0 0 0 ... 4 2 2]
|
||||
[ 0 0 0 ... 6 2 123]
|
||||
[ 0 0 0 ... 2 11 831]
|
||||
...
|
||||
[ 1 14 402 ... 819 45 131]
|
||||
[ 0 0 0 ... 17 1540 2]
|
||||
[ 1 17 6 ... 1026 362 37]]
|
||||
Shape of X train: (25000, 500)
|
||||
Shape of X test: (25000, 500)
|
||||
|
||||
```
|
||||
|
||||
### 9) Реализовать модель рекуррентной нейронной сети, состоящей из слоев Embedding, LSTM, Dropout, Dense, и обучить ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывести информацию об архитектуре нейронной сети. Добиться качества обучения по метрике accuracy не менее 0.8.
|
||||
|
||||
```python
|
||||
embed_dim = 32
|
||||
lstm_units = 64
|
||||
|
||||
model = Sequential()
|
||||
model.add(layers.Embedding(input_dim=vocabulary_size, output_dim=embed_dim, input_length=max_words, input_shape=(max_words,)))
|
||||
model.add(layers.LSTM(lstm_units))
|
||||
model.add(layers.Dropout(0.5))
|
||||
model.add(layers.Dense(1, activation='sigmoid'))
|
||||
|
||||
model.summary()
|
||||
```
|
||||

|
||||
|
||||
```python
|
||||
# компиляция и обучение модели
|
||||
batch_size = 64
|
||||
epochs = 3
|
||||
model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"])
|
||||
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.2)
|
||||
```
|
||||
```
|
||||
Epoch 1/3
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 11s 22ms/step - accuracy: 0.6255 - loss: 0.6261 - val_accuracy: 0.8294 - val_loss: 0.3905
|
||||
Epoch 2/3
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 6s 21ms/step - accuracy: 0.8643 - loss: 0.3334 - val_accuracy: 0.8626 - val_loss: 0.3467
|
||||
Epoch 3/3
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 6s 19ms/step - accuracy: 0.8877 - loss: 0.2905 - val_accuracy: 0.8722 - val_loss: 0.3317
|
||||
|
||||
<keras.src.callbacks.history.History at 0x78f347b1fb30>
|
||||
```
|
||||
```python
|
||||
test_loss, test_acc = model.evaluate(X_test, y_test)
|
||||
print(f"\nTest accuracy: {test_acc}")
|
||||
```
|
||||
```
|
||||
782/782 ━━━━━━━━━━━━━━━━━━━━ 7s 9ms/step - accuracy: 0.8640 - loss: 0.3313
|
||||
|
||||
Test accuracy: 0.8622000217437744
|
||||
```
|
||||
|
||||
### 10) Оценить качество обучения на тестовых данных:
|
||||
### - вывести значение метрики качества классификации на тестовых данных,
|
||||
### - вывести отчет о качестве классификации тестовой выборки.
|
||||
### - построить ROC-кривую по результату обработки тестовой выборки и вычислить площадь под ROC-кривой (AUC ROC).
|
||||
|
||||
```python
|
||||
#значение метрики качества классификации на тестовых данных
|
||||
print(f"\nTest accuracy: {test_acc}")
|
||||
```
|
||||
```
|
||||
Test accuracy: 0.8622000217437744
|
||||
```
|
||||
|
||||
```python
|
||||
#отчет о качестве классификации тестовой выборки
|
||||
y_score = model.predict(X_test)
|
||||
y_pred = [1 if y_score[i,0]>=0.5 else 0 for i in range(len(y_score))]
|
||||
|
||||
from sklearn.metrics import classification_report
|
||||
print(classification_report(y_test, y_pred, labels = [0, 1], target_names=['Negative', 'Positive']))
|
||||
```
|
||||
```
|
||||
precision recall f1-score support
|
||||
|
||||
Negative 0.83 0.91 0.87 12500
|
||||
Positive 0.90 0.81 0.86 12500
|
||||
|
||||
accuracy 0.86 25000
|
||||
macro avg 0.87 0.86 0.86 25000
|
||||
weighted avg 0.87 0.86 0.86 25000
|
||||
```
|
||||
|
||||
```python
|
||||
#построение ROC-кривой и AUC ROC
|
||||
from sklearn.metrics import roc_curve, auc
|
||||
|
||||
fpr, tpr, thresholds = roc_curve(y_test, y_score)
|
||||
plt.plot(fpr, tpr)
|
||||
plt.grid()
|
||||
plt.xlabel('False Positive Rate')
|
||||
plt.ylabel('True Positive Rate')
|
||||
plt.title('ROC')
|
||||
plt.show()
|
||||
print('AUC ROC:', auc(fpr, tpr))
|
||||
```
|
||||

|
||||
```
|
||||
AUC ROC: 0.9370553728000001
|
||||
```
|
||||
|
||||
### 11) Сделать выводы по результатам применения рекуррентной нейронной сети для решения задачи определения тональности текста.
|
||||
|
||||
### Показатель accuracy превышает требуемый порог 0.8, а значение AUC ROC > 0.9 показывает высокую способность модели различать два класса. Таким образом, рекуррентная нейронная сеть хорошо справилась с задачей определения тональности текста.
|
||||