Сравнить коммиты

...

33 Коммитов
main ... main

Автор SHA1 Сообщение Дата
LiTek 114a5844e3 Загрузил(а) файлы в 'labworks/LW4'
3 недель назад
LiTek 3751c94e78 Загрузил(а) файлы в 'labworks/LW4/images'
3 недель назад
LiTek c4ccbbb264 Удалить 'labworks/LW4/1.1.png'
3 недель назад
LiTek 90e16ff83f ima
3 недель назад
LiTek 7c0edbd930 report and notebook
3 недель назад
LiTek 739230e0b4 images
3 недель назад
LiTek 107fdd3a90 images
3 недель назад
LiTek 2af590add9 report and ipynb
3 недель назад
LiTek 2388076bb3 Загрузил(а) файлы в 'labworks/LW2'
1 месяц назад
LiTek f61e5095e4 Удалить 'labworks/LW2/lab2.ipynb_'
1 месяц назад
LiTek 485052d2d7 Загрузил(а) файлы в 'labworks/LW2'
1 месяц назад
LiTek 25ae6ba795 Загрузил(а) файлы в 'labworks/LW2/out'
1 месяц назад
LiTek 1d727a9ed5 Загрузил(а) файлы в 'labworks/LW2/out'
1 месяц назад
LiTek cbb988f5d8 Загрузил(а) файлы в 'labworks/LW2'
1 месяц назад
LiTek 57096df00d Загрузил(а) файлы в 'labworks/LW2'
1 месяц назад
LiTek 546c8be241 Загрузил(а) файлы в 'labworks/LW2/images'
1 месяц назад
LiTek 70a5c9bed8 добавлен отчет
1 месяц назад
LiTek c367d3c0be Загрузил(а) файлы в 'labworks/LW2/images'
1 месяц назад
LiTek 1a6c8a5fce Загрузил(а) файлы в 'labworks/LW2/images'
1 месяц назад
LiTek db9191423b Загрузил(а) файлы в 'labworks/LW2/images'
1 месяц назад
LiTek df1edd9e04 добавлены фото
1 месяц назад
LiTek dda1d95ca6 Удалить 'labworks/LW2/picture1_6.png'
1 месяц назад
LiTek a2af49b33d Удалить 'labworks/LW2/picture1_5.png'
1 месяц назад
LiTek 5a41a99220 Удалить 'labworks/LW2/picture1_4.png'
1 месяц назад
LiTek 32dbb8b5bf Удалить 'labworks/LW2/picture1_2.png'
1 месяц назад
LiTek 0b444461f2 Удалить 'labworks/LW2/picture1_1.png'
1 месяц назад
LiTek 11bcc138ee Загрузил(а) файлы в 'labworks/LW2'
1 месяц назад
LiTek 2d09a2fa2b очищены результаты
3 месяцев назад
LiTek 388b70068b Загрузил(а) файлы в 'labworks/LW1/images'
3 месяцев назад
LiTek ff55485d20 Загрузил(а) файлы в 'labworks/LW1/images'
3 месяцев назад
LiTek 7473cb47a7 Загрузил(а) файлы в 'labworks/LW1/images'
3 месяцев назад
LiTek 0a4d898f3f otchet
3 месяцев назад
LiTek 4e44605174 notebook nn
3 месяцев назад

Двоичные данные
labworks/LW1/images/1.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.9 KiB

Двоичные данные
labworks/LW1/images/10.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 168 B

Двоичные данные
labworks/LW1/images/11.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 240 B

Двоичные данные
labworks/LW1/images/12.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.4 KiB

Двоичные данные
labworks/LW1/images/13.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.6 KiB

Двоичные данные
labworks/LW1/images/2.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.7 KiB

Двоичные данные
labworks/LW1/images/3.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.8 KiB

Двоичные данные
labworks/LW1/images/4.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.0 KiB

Двоичные данные
labworks/LW1/images/5.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 25 KiB

Двоичные данные
labworks/LW1/images/6.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.1 KiB

Двоичные данные
labworks/LW1/images/7.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 258 B

Двоичные данные
labworks/LW1/images/8.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 317 B

Двоичные данные
labworks/LW1/images/9.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.3 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

@ -0,0 +1,223 @@
# Отчет по лабораторной работе 1
## Ли Тэ Хо, Синявский Степан А-02-22
## Бригада 3
### Пункт 1
В среде GoogleColab создали новый блокнот(notebook).Импортировали необходимые для работы библиотеки и модули.
```python
from google.colab import drive
drive.mount('/content/drive')
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, содержащий размеченные изображения рукописных цифр.
```python
from keras.datasets import mnist
```
### Пункт 3
Разбили набор данных на обучающие и тестовые данные в соотношении 60000:10000 элементов. При разбиении параметр random_state выбрали 11.
Вывели размерности полученных обучающих и тестовых массивов данных.
```python
(X_train,y_train),(X_test,y_test)=mnist.load_data()
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=11)
#вывод размерностей
print('Shape of X train:',X_train.shape)
print('Shape of y train:',y_train.shape)
```
Shape of X train: (60000, 28, 28)
Shape of y train: (60000,)
### Пункт 4
Вывели первые 4 элемента обучающих данных
```python
#вывод изображения
plt.imshow(X_train[1],cmap=plt.get_cmap('gray'))
plt.show()
print(y_train[1])
plt.imshow(X_train[2],cmap=plt.get_cmap('gray'))
plt.show()
print(y_train[2])
plt.imshow(X_train[3],cmap=plt.get_cmap('gray'))
plt.show()
print(y_train[3])
plt.imshow(X_train[4],cmap=plt.get_cmap('gray'))
plt.show()
print(y_train[4])
```
![photo](images/1.png)
![photo](images/2.png)
![photo](images/3.png)
![photo](images/4.png)
### Пункт 5
Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения нейронной сети.
Входные данные должны принимать значения от 0 до 1, метки цифрдолжны быть закодированы по принципу «one-hotencoding».Вывели размерности предобработанных обучающих и тестовых массивов данных.
```python
#развернем каждое изображение 8*228 в вектор 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)
```
Shape of transformed X train: (60000, 784)
```python
#переведем метки в one-hot
import keras.utils
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]
```
Shape of transformed y train: (60000, 10)
### Пункт 6
Реализовали модель однослойной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети. Вывели график функции ошибки на обучающих и валидационных данных по эпохам.
```python
from keras.models import Sequential
from keras.layers import Dense
model_1 = Sequential()
model_1.add(Dense(units=num_classes, input_dim=num_pixels, activation='softmax'))
model_1.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
# вывод информации об архитектуре модели
print(model_1.summary())
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ dense (Dense) │ (None, 10) │ 7,850 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
Total params: 7,850 (30.66 KB)
Trainable params: 7,850 (30.66 KB)
Non-trainable params: 0 (0.00 B)
None
# Обучаем модель
H = model_1.fit(X_train, y_train, validation_split=0.1, epochs=50)
# вывод графика ошибки по эпохам
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()
```
![photo](images/5.png)
```python
# Оценка качества работы модели на тестовых данных
scores = model_1.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
313/313 ━━━━━━━━━━━━━━━━━━━━ 3s 8ms/step - accuracy: 0.9219 - loss: 0.2787
Loss on test data: 0.2803967595100403
Accuracy on test data: 0.9203000068664551
### Таблица с результатами тестирования нейросетевых моделей
| Количество скрытых слоёв | Количество нейронов в первом скрытом слое | Количество нейронов во втором скрытом слое | Значение метрики качества классификации |
|---------------------------|-------------------------------------------|--------------------------------------------|-----------------------------------------|
| 0 | - | - | 0.9203000068664551 |
| 1 | 100 | - | 0.9416999816894531 |
| | 300 | - | 0.9345999956130981 |
| | 500 | - | 0.9279000163078308 |
| 2 | (наилучшее из п.8) | 50 | 0.9402999877929688 |
| | (наилучшее из п.8) | 100 | 0.9420999884605408 |
По полученным результатам можно сказать, что лучшая архитектура НН это - с двумя скрытыми слоями, с 100 нейронами на первом скрытом слое, и со 100 на втором скрытом слое.
### Пункт 11
Сохранили наилучшую нейронную сеть на диск.
```python
model_5.save('best_model.keras')
```
### Пункт 12
Вывели результаты тестирования модели
```python
# вывод тестового изображения и результата распознавания 1
n = 123
result = model_5.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)))
```
![photo](images/6.png)
Real mark: 0
NN answer: 0
### Пункт 13
Создали собственные изображения чисел
![photo](images/7.png)
![photo](images/8.png)
Сохранили их и подали на вход для распознования
```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()
```
![photo](images/9.png)
```python
# предобработка
test_img = test_img / 255
test_img = test_img.reshape(1, num_pixels)
# распознавание
result = model_5.predict(test_img)
print('I think it\'s ', np.argmax(result))
```
I think it's 5
### Пункт 14
Создали копию нарисованных чисел и повернем их на 90 градусов. Протестируем работу нейронной сети.
![photo](images/10.png)
![photo](images/11.png)
```python
file_data = Image.open('2_1.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_5.predict(test_img)
print('I think it\'s ', np.argmax(result))
```
![photo](images/12.png)
I think it's 4
![photo](images/13.png)
I think it's 7
Нейросеть неправильно определила повернутые изображения цифр. Она не определяет саму цифру, для нее ориентация не имеет значения, 1 это вертикальная черта, а повернутая 1 это просто горизонтальная черта.

Разница между файлами не показана из-за своего большого размера Загрузить разницу

@ -0,0 +1,4 @@
2.72 2.72
3.28 2.71
2.70 3.29
3.30 3.27

Двоичные данные
labworks/LW2/images/picture1_1.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 41 KiB

Двоичные данные
labworks/LW2/images/picture1_10.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 21 KiB

Двоичные данные
labworks/LW2/images/picture1_11.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 30 KiB

Двоичные данные
labworks/LW2/images/picture1_12.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 27 KiB

Двоичные данные
labworks/LW2/images/picture1_13.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 22 KiB

Двоичные данные
labworks/LW2/images/picture1_2.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 68 KiB

Двоичные данные
labworks/LW2/images/picture1_3.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 101 KiB

Двоичные данные
labworks/LW2/images/picture1_4.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 32 KiB

Двоичные данные
labworks/LW2/images/picture1_5.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 77 KiB

Двоичные данные
labworks/LW2/images/picture1_6.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 87 KiB

Двоичные данные
labworks/LW2/images/picture1_7.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 30 KiB

Двоичные данные
labworks/LW2/images/picture1_8.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 61 KiB

Двоичные данные
labworks/LW2/images/picture1_9.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 71 KiB

Двоичные данные
labworks/LW2/images/picture2_1.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 84 KiB

Двоичные данные
labworks/LW2/images/picture2_2.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 94 KiB

Двоичные данные
labworks/LW2/images/picture2_3.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 51 KiB

Двоичные данные
labworks/LW2/images/picture2_4.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 51 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Двоичные данные
labworks/LW2/out/AE1.h5

Двоичный файл не отображается.

Двоичные данные
labworks/LW2/out/AE2.h5

Двоичный файл не отображается.

Двоичные данные
labworks/LW2/out/AE3_V1.h5

Двоичный файл не отображается.

Двоичные данные
labworks/LW2/out/AE3_V2.h5

Двоичный файл не отображается.

@ -0,0 +1,5 @@
------------Оценка качества AE2 С ПОМОЩЬЮ НОВЫХ МЕТРИК------------
Approx = 0.8076923076923076
Excess = 0.23809523809523808
Deficit = 0.0
Coating = 1.0

@ -0,0 +1,417 @@
# Отчёт по лабораторной работе №2
**Ли Тэ Хо, Синявский Степан — А-02-22**
---
## Задание 1
### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули.
```python
# импорт модулей
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab2')
import numpy as np
import lab02_lib as lib
```
### 2) Сгенерировали индивидуальный набор двумерных данных в пространстве признаков с координатами центра 3, 3), где 3 – номер бригады. Вывели полученные данные на рисунок и в консоль.
```python
# генерация датасета
data = lib.datagen(3, 3, 1000, 2)
# вывод данных и размерности
print('Исходные данные:')
print(data)
print('Размерность данных:')
print(data.shape)
```
![Training set](images/picture1_1.png)
```
Исходные данные:
[[3.01497028 2.9872143 ]
[2.95216438 2.93247766]
[2.9281138 2.80160426]
...
[3.10976374 2.91251936]
[3.16677716 2.95397464]
[3.00503898 3.17135038]]
Размерность данных:
(1000, 2)
```
### 3) Создали и обучили автокодировщик AE1 простой архитектуры, выбрав небольшое количество эпох обучения. Зафиксировали в таблице вида табл.1 количество скрытых слоёв и нейронов в них
```python
# обучение AE1
patience = 300
ae1_trained, IRE1, IREth1 = lib.create_fit_save_ae(data,'out/AE1.h5','out/AE1_ire_th.txt',
1000, True, patience)
```
### 4) Зафиксировали ошибку MSE, на которой обучение завершилось. Построили график ошибки реконструкции обучающей выборки. Зафиксировали порог ошибки реконструкции – порог обнаружения аномалий.
Ошибка MSE_AE1 = 1.4393
```python
# Построение графика ошибки реконструкции
lib.ire_plot('training', IRE1, IREth1, 'AE1')
```
![IRE for training set. AE1](images/picture1_2.png)
### 5) Создали и обучили второй автокодировщик AE2 с усложненной архитектурой, задав большее количество эпох обучения
```python
# обучение AE2
ae2_trained, IRE2, IREth2 = lib.create_fit_save_ae(data,'out/AE2.h5','out/AE2_ire_th.txt',
3000, True, patience)
```
### 6) Зафиксировали ошибку MSE, на которой обучение завершилось. Построили график ошибки реконструкции обучающей выборки. Зафиксировали второй порог ошибки реконструкции – порог обнаружения аномалий.
Ошибка MSE_AE2 = 0.0102
```python
# Построение графика ошибки реконструкции
lib.ire_plot('training', IRE2, IREth2, 'AE2')
```
![IRE for training set. AE1](images/picture1_3.png)
### 7) Рассчитали характеристики качества обучения EDCA для AE1 и AE2. Визуализировали и сравнили области пространства признаков, распознаваемые автокодировщиками AE1 и AE2. Сделали вывод о пригодности AE1 и AE2 для качественного обнаружения аномалий.
```python
# построение областей покрытия и границ классов
# расчет характеристик качества обучения
numb_square = 20
xx, yy, Z1 = lib.square_calc(numb_square, data, ae1_trained, IREth1, '1', True)
```
![Autoencoder AE1. Training set. Class boundary](images/picture1_4.png)
```
amount: 21
amount_ae: 226
```
![Площади множеств Xt и Xd AE1](images/picture1_5.png)
![EDCA AE1](images/picture1_6.png)
```
Оценка качества AE1
IDEAL = 0. Excess: 9.761904761904763
IDEAL = 0. Deficit: 0.0
IDEAL = 1. Coating: 1.0
summa: 1.0
IDEAL = 1. Extrapolation precision (Approx): 0.09292035398230088
```
```python
# построение областей покрытия и границ классов
# расчет характеристик качества обучения
numb_square = 20
xx, yy, Z2 = lib.square_calc(numb_square, data, ae2_trained, IREth2, '2', True)
```
![Autoencoder AE2. Training set. Class boundary](images/picture1_7.png)
```
amount: 21
amount_ae: 26
```
![Площади множеств Xt и Xd AE1](images/picture1_8.png)
![EDCA AE1](images/picture1_9.png)
```
Оценка качества AE2
IDEAL = 0. Excess: 0.23809523809523808
IDEAL = 0. Deficit: 0.0
IDEAL = 1. Coating: 1.0
summa: 1.0
IDEAL = 1. Extrapolation precision (Approx): 0.8076923076923076
```
```python
# сравнение характеристик качества обучения и областей аппроксимации
lib.plot2in1(data, xx, yy, Z1, Z2)
```
![Сравнение обучения AE1 и AE2](images/picture1_10.png)
### 8) Если автокодировщик AE2 недостаточно точно аппроксимирует область обучающих данных, то подобрать подходящие параметры автокодировщика и повторить шаги (6) – (8).
Полученные показатели EDCA для автокодировщика AE2 нас устраивают.
### 9) Изучили сохраненный набор данных и пространство признаков. Создали тестовую выборку, состоящую, как минимум, из 4ёх элементов, не входящих в обучающую выборку. Элементы должны быть такими, чтобы AE1 распознавал их как норму, а AE2 детектировал как аномалии.
```python
# загрузка тестового набора
data_test = np.loadtxt('data_test.txt', dtype=float)
print(data_test)
```
```
[[2.72 2.72]
[3.28 2.71]
[2.7 3.29]
[3.3 3.27]]
```
### 10) Применили обученные автокодировщики AE1 и AE2 к тестовым данным и вывели значения ошибки реконструкции для каждого элемента тестовой выборки относительно порога на график и в консоль.
```python
# тестирование АE1
predicted_labels1, ire1 = lib.predict_ae(ae1_trained, data_test, IREth1)
```
```python
# тестирование АE1
lib.anomaly_detection_ae(predicted_labels1, ire1, IREth1)
lib.ire_plot('test', ire1, IREth1, 'AE1')
```
```
i Labels IRE IREth
0 [0.] [1.33] 2.0
1 [0.] [1.59] 2.0
2 [0.] [1.87] 2.0
3 [1.] [2.07] 2.0
Обнаружено 1.0 аномалий
```
![IRE fir test set. AE1](images/picture1_11.png)
```python
# тестирование АE2
predicted_labels2, ire2 = lib.predict_ae(ae2_trained, data_test, IREth2)
```
```python
# тестирование АE2
lib.anomaly_detection_ae(predicted_labels2, ire2, IREth2)
lib.ire_plot('test', ire2, IREth2, 'AE2')
```
```
i Labels IRE IREth
0 [1.] [0.39] 0.38
1 [1.] [0.4] 0.38
2 [1.] [0.42] 0.38
3 [1.] [0.41] 0.38
Обнаружено 4.0 аномалий
```
![IRE fir test set. AE2](images/picture1_12.png)
### 11) Визуализировали элементы обучающей и тестовой выборки в областях пространства признаков, распознаваемых автокодировщиками AE1 и AE2.
```python
# построение областей аппроксимации и точек тестового набора
lib.plot2in1_anomaly(data, xx, yy, Z1, Z2, data_test)
```
![Сравнение теста AE1 и AE2](images/picture1_13.png)
### 12) Результаты исследования занесли в таблицу:
Табл. 1 Результаты задания №1
| | Количество<br>скрытых слоев | Количество<br>нейронов в скрытых слоях | Количество<br>эпох обучения | Ошибка<br>MSE_stop | Порог ошибки<br>реконструкции | Значение показателя<br>Excess | Значение показателя<br>Approx | Количество обнаруженных<br>аномалий |
|-----:|------------------------------|----------------------------------------|-----------------------------|--------------------|-------------------------------|-------------------------------|--------------------------------|-------------------------------------|
| AE1 | 1 | 1 | 1000 | 1.4393 | 2 | 9.76 | 0.0929 | 1 |
| AE2 | 5 | 3,2,1,2,3 | 3000 | 0.0108 | 0.38 | 0.238 | 0.80 | 4 |
### 13) Сделаем выводы о требованиях к:
- данным для обучения,
- архитектуре автокодировщика,
- количеству эпох обучения,
- ошибке MSE_stop, приемлемой для останова обучения,
- ошибке реконструкции обучающей выборки (порогу обнаружения
аномалий),
- характеристикам качества обучения EDCA одноклассового
классификатора для качественного обнаружения аномалий в данных.
1) Для качественного обнаружения аномалий обучающая выборка должна содержать только нормальные данные и быть однородной.
2) Архитектура должна быть достаточно сложной, чтобы адекватно аппроксимировать форму области нормальных данных. Слишком простые сети (как AE1) даже на тех же данных дают огромное превышение области и практически не описывают реальную структуру выборки.
3) Количество эпох для качественного обучения сети должно быть около 3000, это обеспечит более качественную реконструкцию.
4) Значение MSE_stop должно быть умеренным — не слишком большим, чтобы избежать недообучения, и не слишком маленьким, чтобы избежать переобучения. AE2 с MSE_stop ≈ 0.01 показывает оптимальное качество.
5) Порог должен быть максимально низким и стабильным, чтобы корректно отделять нормальные объекты от аномальных. Значение порога в районе 0.38.
6) Значение Excess не больше 0.4, значение Deficit равное 0, значение Coating равное 1, значение Approx не меньше 0.75
## Задание 2
### 1) Изучить описание своего набора реальных данных, что он из себя представляет
Бригада 3 => набор данных Cardio. Это реальный набор данных, который состоит из измерений частоты сердечных сокращений плода и
сокращений матки на кардиотокограммах, классифицированных экспертами
акушерами. Исходный набор данных предназначен для классификации. В нем
представлено 3 класса: «норма», «подозрение» и «патология». Для обнаружения
аномалий класс «норма» принимается за норму, класс «патология» принимается за
аномалии, а класс «подозрение» был отброшен.
| Количество<br>признаков | Количество<br>примеров | Количество<br>нормальных примеров | Количество<br>аномальных примеров |
|-------------------------:|-----------------------:|----------------------------------:|-----------------------------------:|
| 21 | 1764 | 1655 | 109 |
### 2) Загрузить многомерную обучающую выборку реальных данных Cardio.txt.
```python
# загрузка обчуающей выборки
train = np.loadtxt('cardio_train.txt', dtype=float)
```
### 3) Вывести полученные данные и их размерность в консоли.
```python
print('train:\n', train)
print('train.shape:', np.shape(train))
```
```
train:
[[ 0.00491231 0.69319077 -0.20364049 ... 0.23149795 -0.28978574
-0.49329397]
[ 0.11072935 -0.07990259 -0.20364049 ... 0.09356344 -0.25638541
-0.49329397]
[ 0.21654639 -0.27244466 -0.20364049 ... 0.02459619 -0.25638541
1.1400175 ]
...
[ 0.85144861 -0.91998844 -0.20364049 ... 0.57633422 -0.65718941
1.1400175 ]
[ 0.85144861 -0.91998844 -0.20364049 ... 0.57633422 -0.62378908
-0.49329397]
[ 1.0630827 -0.51148142 -0.16958144 ... 0.57633422 -0.65718941
-0.49329397]]
train.shape: (1654, 21)
```
### 4) Создать и обучить автокодировщик с подходящей для данных архитектурой. Выбрать необходимое количество эпох обучения.
```python
# **kwargs
# verbose_every_n_epochs - отображать прогресс каждые N эпох (по умолчанию - 1000)
# early_stopping_delta - дельта для ранней остановки (по умолчанию - 0.01)
# early_stopping_value = значение для ранней остановки (по умолчанию - 0.0001)
from time import time
patience = 4000
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, verbose_every_n_epochs = 1000, early_stopping_delta = 0.001)
print("Время на обучение: ", time() - start)
```
### 5) Зафиксировать ошибку MSE, на которой обучение завершилось. Построить график ошибки реконструкции обучающей выборки. Зафиксировать порог ошибки реконструкции – порог обнаружения аномалий.
Скрытых слоев 7, нейроны: 48->36->24->12->24->36->48
Ошибка MSE_AE3_v1 = 0.0073
```python
# Построение графика ошибки реконструкции
lib.ire_plot('training', IRE3_v1, IREth3_v1, 'AE3_v1')
```
![IRE for training set. AE3_v1](images/picture2_1.png)
### 6) Сделать вывод о пригодности обученного автокодировщика для качественного обнаружения аномалий. Если порог ошибки реконструкции слишком велик, то подобрать подходящие параметры автокодировщика и повторить шаги (4) – (6).
```python
# **kwargs
# verbose_every_n_epochs - отображать прогресс каждые N эпох (по умолчанию - 1000)
# early_stopping_delta - дельта для ранней остановки (по умолчанию - 0.01)
# early_stopping_value = значение для ранней остановки (по умолчанию - 0.0001)
from time import time
patience = 4000
start = time()
ae3_v2_trained, IRE3_v2, IREth3_v2 = lib.create_fit_save_ae(train,'out/AE3_V2.h5','out/AE3_v2_ire_th.txt',
100000, False, patience, early_stopping_delta = 0.001, verbose_every_n_epochs = 1000)
print("Время на обучение: ", time() - start)
```
Скрытых слоев 11, нейроны: 48->40->36->30->24->12->24->30->36->40->48
Ошибка MSE_AE3_v1 = 0.0065
```python
# Построение графика ошибки реконструкции
lib.ire_plot('training', IRE3_v2, IREth3_v2, 'AE3_v2')
```
![IRE for training set. AE3_v2](images/picture2_2.png)
### 7) Изучить и загрузить тестовую выборку Cardio.txt.
```python
#загрузка тестовой выборки
test = np.loadtxt('cardio_test.txt', dtype=float)
print('\n test:\n', test)
print('test.shape:', np.shape(test))
```
```
test:
[[ 0.21654639 -0.65465178 -0.20364049 ... -2.0444214 4.987467
-0.49329397]
[ 0.21654639 -0.5653379 -0.20364049 ... -2.1133887 6.490482
-0.49329397]
[-0.3125388 -0.91998844 6.9653692 ... -1.1478471 3.9186563
-0.49329397]
...
[-0.41835583 -0.91998844 -0.16463485 ... -1.4926834 0.24461959
-0.49329397]
[-0.41835583 -0.91998844 -0.15093411 ... -1.4237162 0.14441859
-0.49329397]
[-0.41835583 -0.91998844 -0.20364049 ... -1.2857816 3.5846529
-0.49329397]]
test.shape: (109, 21)
```
### 8) Подать тестовую выборку на вход обученного автокодировщика для обнаружения аномалий. Вывести график ошибки реконструкции элементов тестовой выборки относительно порога.
```python
# тестирование АE3
predicted_labels3_v1, ire3_v1 = lib.predict_ae(ae3_v1_trained, test, IREth3_v1)
```
```python
# Построение графика ошибки реконструкции
lib.ire_plot('test', ire3_v1, IREth3_v1, 'AE3_v1')
```
![IRE for test set. AE3_v1](images/picture2_3.png)
```python
# тестирование АE3
predicted_labels3_v2, ire3_v2 = lib.predict_ae(ae3_v2_trained, test, IREth3_v2)
```
```python
# Построение графика ошибки реконструкции
lib.ire_plot('test', ire3_v2, IREth3_v2, 'AE3_v2')
```
![IRE for test set. AE3_v2](images/picture2_4.png)
```python
# тестирование АE2
lib.anomaly_detection_ae(predicted_labels3_v1, IRE3_v1, IREth3_v1)
```
Для AE3_v1 точность составляет 63%
```python
# тестирование АE2
lib.anomaly_detection_ae(predicted_labels3_v2, IRE3_v2, IREth3_v2)
```
Для AE3_v2 точность составляет 82%
### 9) Если результаты обнаружения аномалий не удовлетворительные (обнаружено менее 70% аномалий), то подобрать подходящие параметры автокодировщика и повторить шаги (4) – (9).
Результаты обнаружения аномалий удовлетворены.
### 10) Параметры наилучшего автокодировщика и результаты обнаружения аномалий занести в таблицу:
Табл. 2 Результаты задания №2
| Dataset name | Количество<br>скрытых слоев | Количество<br>нейронов в скрытых слоях | Количество<br>эпох обучения | Ошибка<br>MSE_stop | Порог ошибки<br>реконструкции | % обнаруженных<br>аномалий |
|:-------------|:-----------------------------|:----------------------------------------|:-----------------------------|:-------------------|:-------------------------------|:---------------------------|
| Cardio | 11 | 48, 40, 36, 30, 24, 12, 24, 30, 36, 40, 48 | 100000 | 0.0065 | 1.4 | 82% |
### 11) Сделать выводы о требованиях к:
- данным для обучения,
- архитектуре автокодировщика,
- количеству эпох обучения,
- ошибке MSE_stop, приемлемой для останова обучения,
- ошибке реконструкции обучающей выборки (порогу обнаружения
аномалий) для качественного обнаружения аномалий в случае, когда размерность пространства признаков высока.
1) Данные для обучения должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение.
2) Большая размерность датасета требует более сложной архитектуры. Оптимальный размер 9-11 скрытых слоев.
3) В рамках данного набора данных оптимальное кол-во эпох 100000 с patience 4000 эпох.
4) Оптимальная ошибка MSE-stop лежит в районе 0.001, желательно не меньше для предотвращения переобучения
5) Значение порога не больше 1.4, он является достаточным, чтобы отделять норму от аномалий.

Двоичные данные
labworks/LW3/images/1.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.7 KiB

Двоичные данные
labworks/LW3/images/2.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.6 KiB

Двоичные данные
labworks/LW3/images/3.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 31 KiB

Двоичные данные
labworks/LW3/images/4.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.4 KiB

Двоичные данные
labworks/LW3/images/5.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.8 KiB

Двоичные данные
labworks/LW3/images/6.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 117 KiB

Двоичные данные
labworks/LW3/images/7.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 12 KiB

Двоичные данные
labworks/LW3/images/8.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 12 KiB

Двоичные данные
labworks/LW3/images/9.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 60 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

@ -0,0 +1,554 @@
# Отчёт по лабораторной работе №3
**Ли Тэ Хо, Синявский Степан — А-02-22**
***Бригада 3***
---
## Задание 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)=11, где k=3 –номер бригады. Вывели размерности полученных обучающих и тестовых массивов данных.
```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 = 11)
# вывод размерностей
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()
```
**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) | 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])
```
```
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step - accuracy: 0.9909 - loss: 0.0413
Loss on test data: 0.041157860308885574
Accuracy on test data: 0.9873999953269958
```
### 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))
```
![picture](images/1.png)
```
Real mark: 2
NN answer: 2
```
![picture](images/2.png)
```
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 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step
precision recall f1-score support
0 0.99 1.00 0.99 1018
1 0.99 0.99 0.99 1098
2 0.99 0.98 0.98 1010
3 0.99 0.98 0.98 992
4 0.99 0.98 0.99 998
5 0.99 0.99 0.99 951
6 0.99 0.99 0.99 933
7 0.98 0.99 0.98 1010
8 0.99 0.99 0.99 960
9 0.98 0.99 0.98 1030
accuracy 0.99 10000
macro avg 0.99 0.99 0.99 10000
weighted avg 0.99 0.99 0.99 10000
```
![picture](images/3.png)
### 9) Загрузили, предобработали и подали на вход обученной нейронной сети собственное изображение, созданное при выполнении лабораторной работы №1. Вывели изображение и результат распознавания.
```python
# загрузка собственного изображения
from PIL import Image
for name_image in ['2.png', '5.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))
```
![picture](images/4.png)
```
I think it's 2
```
![picture](images/5.png)
```
I think it's 5
```
### 10) Загрузили с диска модель, сохраненную при выполнении лабораторной работы №1. Вывели информацию об архитектуре модели. Повторили для этой модели п. 6.
```python
model_lr1 = keras.models.load_model("best_model.keras")
model_lr1.summary()
```
**Model: "sequential_10"**
| Layer (type) | Output Shape | Param # |
|------------------|-------------:|--------:|
| dense_14 (Dense) | (None, 100) | 78,500 |
| dense_15 (Dense) | (None, 50) | 10,100 |
| dense_16 (Dense) | (None, 10) | 1,010 |
**Total params:** 89,612 (350.05 KB)
**Trainable params:** 89,610 (350.04 KB)
**Non-trainable params:** 0 (0.00 B)
**Optimizer params:** 2 (12.00 B)
```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 = 11)
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.9406 - loss: 0.2055
Loss on test data: 0.1955890655517578
Accuracy on test data: 0.9426000118255615
```
### 11) Сравнили обученную модель сверточной сети и наилучшую модель полносвязной сети из лабораторной работы №1 по следующим показателям:
### - количество настраиваемых параметров в сети
### - количество эпох обучения
### - качество классификации тестовой выборки.
### Сделали выводы по результатам применения сверточной нейронной сети для распознавания изображений.
Таблица1:
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|----------|-------------------------------------|---------------------------|-----------------------------------------|
| Сверточная | 34 826 | 15 | accuracy:0.987 ; loss:0.0413 |
| Полносвязная | 89 612 | 50 | accuracy:0.943 ; loss:0.2055 |
##### По полученной таблице можно сделать выводы о том, что сверточная модель лучше по всем показателям, она имеет более высокое качество классификации, мненьшее время обученя, а также вдвое меньше параметров.
## Задание 2
### В новом блокноте выполнили п. 2–8 задания 1, изменив набор данных MNIST на CIFAR-10, содержащий размеченные цветные изображения объектов, разделенные на 10 классов.
### При этом:
### - в п. 3 разбиение данных на обучающие и тестовые произвели в соотношении 50 000:10 000
### - после разбиения данных (между п. 3 и 4) вывели 25 изображений из обучающей выборки с подписями классов
### - в п. 7 одно из тестовых изображений должно распознаваться корректно, а другое – ошибочно.
### 1) Загрузили набор данных CIFAR-10, содержащий цветные изображения размеченные на 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)=23, где k=6 –номер бригады. Вывели размерности полученных обучающих и тестовых массивов данных.
```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 = 11)
# вывод размерностей
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)
```
### Вывели 25 изображений из обучающей выборки с подписью классов.
```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()
```
![picture](images/6.png)
### 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()
```
**Model: "sequential_9"**
| Layer (type) | Output Shape | Param # |
|--------------------------------------------|-------------------|---------:|
| conv2d_41 (Conv2D) | (None, 32, 32, 32) | 896 |
| batch_normalization_6 (BatchNormalization) | (None, 32, 32, 32) | 128 |
| conv2d_42 (Conv2D) | (None, 32, 32, 32) | 9,248 |
| batch_normalization_7 (BatchNormalization) | (None, 32, 32, 32) | 128 |
| max_pooling2d_26 (MaxPooling2D) | (None, 16, 16, 32) | 0 |
| dropout_24 (Dropout) | (None, 16, 16, 32) | 0 |
| conv2d_43 (Conv2D) | (None, 16, 16, 64) | 18,496 |
| batch_normalization_8 (BatchNormalization) | (None, 16, 16, 64) | 256 |
| conv2d_44 (Conv2D) | (None, 16, 16, 64) | 36,928 |
| batch_normalization_9 (BatchNormalization) | (None, 16, 16, 64) | 256 |
| max_pooling2d_27 (MaxPooling2D) | (None, 8, 8, 64) | 0 |
| dropout_25 (Dropout) | (None, 8, 8, 64) | 0 |
| conv2d_45 (Conv2D) | (None, 8, 8, 128) | 73,856 |
| batch_normalization_10 (BatchNormalization)| (None, 8, 8, 128) | 512 |
| conv2d_46 (Conv2D) | (None, 8, 8, 128) | 147,584 |
| batch_normalization_11 (BatchNormalization)| (None, 8, 8, 128) | 512 |
| max_pooling2d_28 (MaxPooling2D) | (None, 4, 4, 128) | 0 |
| dropout_26 (Dropout) | (None, 4, 4, 128) | 0 |
| flatten_9 (Flatten) | (None, 2048) | 0 |
| dense_17 (Dense) | (None, 128) | 262,272 |
| dropout_27 (Dropout) | (None, 128) | 0 |
| dense_18 (Dense) | (None, 10) | 1,290 |
**Total params:** 552,362 (2.11 MB)
**Trainable params:** 551,466 (2.10 MB)
**Non-trainable params:** 896 (3.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)
```
### 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 ━━━━━━━━━━━━━━━━━━━━ 7s 10ms/step - accuracy: 0.8615 - loss: 0.4696
Loss on test data: 0.4909549355506897
Accuracy on test data: 0.857200026512146
```
### 6) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания.
```python
# вывод двух тестовых изображений и результатов распознавания
for n in [3,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))
```
![picture](images/7.png)
```
Real mark: 4
NN answer: 5
```
![picture](images/8.png)
```
Real mark: 2
NN answer: 2
```
### 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 ━━━━━━━━━━━━━━━━━━━━ 4s 10ms/step
precision recall f1-score support
airplane 0.89 0.86 0.87 1000
automobile 0.94 0.93 0.93 1019
bird 0.80 0.84 0.82 972
cat 0.78 0.66 0.72 1014
deer 0.84 0.84 0.84 980
dog 0.76 0.81 0.79 1051
frog 0.90 0.87 0.89 1043
horse 0.89 0.89 0.89 1018
ship 0.91 0.94 0.92 945
truck 0.86 0.94 0.90 958
accuracy 0.86 10000
macro avg 0.86 0.86 0.86 10000
weighted avg 0.86 0.86 0.86 10000
```
![picture](images/9.png)
#### По результатам классификации датасета CIFAR-10 созданной сверточной моделью можно сделать вывод, что она довольно неплохо справилась с задачей. Полученные метрики оценки качества имеют показатели в районе 0.85.

Двоичные данные
labworks/LW4/images/1.1.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 21 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

@ -0,0 +1,335 @@
# Отчёт по лабораторной работе №4
**Ли Тэ Хо, Синявский Степан — А-02-22**
**Бригада 3**
---
## Задание 1
### 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)=11, где k=3 – номер бригады. Вывели размеры полученных обучающих и тестовых массивов данных.
```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=11,
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[26])
print('len:',len(X_train[26]))
```
```
[1, 2489, 723, 2, 9, 399, 2301, 11, 551, 2, 29, 47, 1391, 6, 1692, 15, 29, 70, 361, 8, 97, 35, 3258, 40, 6, 2, 106, 42, 2, 4298, 64, 8, 28, 15, 3258, 796, 2, 11, 6, 275, 1622, 21, 50, 26, 148, 33, 27, 2301, 2, 15, 81, 24, 40, 42, 2, 7, 27, 4646, 5, 80, 81, 845, 12, 304, 8, 67, 15, 29, 152, 3115, 103, 6, 1196, 2, 15, 238, 28, 1894, 27, 2, 2489, 2, 1068, 8, 2181, 27, 1692, 23, 309, 17, 873, 183, 140, 2357, 355, 5, 29, 9, 2, 83, 6, 2699, 1765, 2, 625, 2691, 1229, 80, 516, 10, 10, 11, 2, 279, 12, 286, 141, 6, 52, 326, 8, 796, 106, 4, 2, 132, 11, 4, 172, 1269, 13, 296, 4, 2223, 994, 7, 4, 2223, 5, 3176, 7, 4, 2223, 50, 186, 8, 30, 64, 38, 111, 102, 44, 551, 2, 5, 4, 4616, 3388, 302, 12, 70, 28, 23, 4, 406, 648, 15, 31, 415, 144, 30, 93, 8, 4325, 11, 6, 289, 42, 689, 251, 810, 146, 24, 252, 51, 148, 1893, 18, 4, 20, 1029, 17, 68, 2436, 819, 18, 4, 2, 132, 21, 76, 7, 12, 9, 38, 729, 8, 4, 2223, 102, 15, 12, 566, 30, 2691, 2, 190, 4, 2, 132, 218, 60, 754, 17, 52, 17, 4, 249, 7, 4, 2223, 2355, 10, 10, 1371, 112, 1905, 4981, 4, 2, 132, 47, 450, 85, 712, 15, 66, 1487, 4, 3129, 7, 4, 20, 6, 194, 1834, 13, 28, 9, 19, 2, 2, 11, 4, 485, 240, 141, 6, 2, 1995, 15, 24, 64, 81, 13, 24, 459, 44, 27, 2073, 13, 165, 3663, 18, 12, 696, 177, 1066, 1083, 2, 5, 2, 1602, 26, 220, 17, 78, 507, 38, 1904, 5, 753, 36, 983, 551, 11, 192, 225, 55, 117, 8, 79, 2229, 44, 137, 149, 4, 2, 132, 4, 816, 475, 24, 55, 906, 4, 168, 475, 13, 62, 1634, 76, 7, 12, 17, 2, 4, 114, 475, 727, 4, 206, 475, 50, 218, 101, 444, 14, 9, 31, 8, 798, 10, 10, 2994, 13, 296, 4, 2, 132, 2864, 6, 1039, 7, 4, 736, 1067, 750, 2, 390, 163, 538, 137, 24, 35, 1557, 55, 400, 4, 2, 4, 20, 475, 4, 128, 4, 3179, 2, 4, 493, 569, 220, 32, 7, 68, 3734, 19, 4, 2, 132, 637, 202, 12, 6, 55, 2, 470, 457, 23, 61, 3179, 675, 2407]
len: 413
```
```python
review_as_text = ' '.join(id_to_word[id] for id in X_train[26])
print(review_as_text)
print('len:',len(review_as_text))
```
```
<START> professor paul <UNK> is doing research in matter <UNK> he has developed a machine that he can use to make an object like a <UNK> watch or <UNK> disappear only to have that object re <UNK> in a different location but there are those at his research <UNK> that do not like or <UNK> of his experiments and will do whatever it takes to see that he doesn't succeed after a failed <UNK> that might have saved his <UNK> professor <UNK> decides to test his machine on himself as expected things go horribly wrong and he is <UNK> into a heavily scared <UNK> whose mere touch will kill br br in <UNK> maybe it wasn't such a good idea to re watch the <UNK> man in the same week i watched the fly return of the fly and curse of the fly there seems to be only so many movies about matter <UNK> and the potentially horrendous effects it can have on the human body that one person should be made to endure in a three or four day period i'm not sure what those responsible for the movie list as their source material for the <UNK> man but much of it is so similar to the fly movies that it cannot be mere <UNK> however the <UNK> man isn't even nearly as good as the worst of the fly trilogy br br besides being terribly unoriginal the <UNK> man has several other problems that really hurt the enjoyment of the movie a big issue i have is with <UNK> <UNK> in the lead he's such a <UNK> ass that not only do i not care about his suffering i actually root for it supporting cast members mary <UNK> and <UNK> allen are almost as bad they're so bland and dull they hardly matter in fact there's very little to get excited about while watching the <UNK> man the soundtrack – not very memorable the look – i would describe much of it as <UNK> the plot – predictable the action – there isn't any overall this is one to avoid br br fortunately i watched the <UNK> man via a copy of the mystery science theater <UNK> episode funny stuff while not an absolute very often the <UNK> the movie – the better the mst3k <UNK> the guys hit almost all of their marks with the <UNK> man i'll give it a very <UNK> 4 5 on my mst3k rating scale
len: 2113
```
### 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[26])
print('len:',len(X_train[26]))
```
```
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 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 2489 723 2 9 399 2301 11 551 2 29
47 1391 6 1692 15 29 70 361 8 97 35 3258 40 6
2 106 42 2 4298 64 8 28 15 3258 796 2 11 6
275 1622 21 50 26 148 33 27 2301 2 15 81 24 40
42 2 7 27 4646 5 80 81 845 12 304 8 67 15
29 152 3115 103 6 1196 2 15 238 28 1894 27 2 2489
2 1068 8 2181 27 1692 23 309 17 873 183 140 2357 355
5 29 9 2 83 6 2699 1765 2 625 2691 1229 80 516
10 10 11 2 279 12 286 141 6 52 326 8 796 106
4 2 132 11 4 172 1269 13 296 4 2223 994 7 4
2223 5 3176 7 4 2223 50 186 8 30 64 38 111 102
44 551 2 5 4 4616 3388 302 12 70 28 23 4 406
648 15 31 415 144 30 93 8 4325 11 6 289 42 689
251 810 146 24 252 51 148 1893 18 4 20 1029 17 68
2436 819 18 4 2 132 21 76 7 12 9 38 729 8
4 2223 102 15 12 566 30 2691 2 190 4 2 132 218
60 754 17 52 17 4 249 7 4 2223 2355 10 10 1371
112 1905 4981 4 2 132 47 450 85 712 15 66 1487 4
3129 7 4 20 6 194 1834 13 28 9 19 2 2 11
4 485 240 141 6 2 1995 15 24 64 81 13 24 459
44 27 2073 13 165 3663 18 12 696 177 1066 1083 2 5
2 1602 26 220 17 78 507 38 1904 5 753 36 983 551
11 192 225 55 117 8 79 2229 44 137 149 4 2 132
4 816 475 24 55 906 4 168 475 13 62 1634 76 7
12 17 2 4 114 475 727 4 206 475 50 218 101 444
14 9 31 8 798 10 10 2994 13 296 4 2 132 2864
6 1039 7 4 736 1067 750 2 390 163 538 137 24 35
1557 55 400 4 2 4 20 475 4 128 4 3179 2 4
493 569 220 32 7 68 3734 19 4 2 132 637 202 12
6 55 2 470 457 23 61 3179 675 2407]
len: 500
```
```python
review_as_text = ' '.join(id_to_word[id] for id in X_train[26])
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> <START> professor paul <UNK> is doing research in matter <UNK> he has developed a machine that he can use to make an object like a <UNK> watch or <UNK> disappear only to have that object re <UNK> in a different location but there are those at his research <UNK> that do not like or <UNK> of his experiments and will do whatever it takes to see that he doesn't succeed after a failed <UNK> that might have saved his <UNK> professor <UNK> decides to test his machine on himself as expected things go horribly wrong and he is <UNK> into a heavily scared <UNK> whose mere touch will kill br br in <UNK> maybe it wasn't such a good idea to re watch the <UNK> man in the same week i watched the fly return of the fly and curse of the fly there seems to be only so many movies about matter <UNK> and the potentially horrendous effects it can have on the human body that one person should be made to endure in a three or four day period i'm not sure what those responsible for the movie list as their source material for the <UNK> man but much of it is so similar to the fly movies that it cannot be mere <UNK> however the <UNK> man isn't even nearly as good as the worst of the fly trilogy br br besides being terribly unoriginal the <UNK> man has several other problems that really hurt the enjoyment of the movie a big issue i have is with <UNK> <UNK> in the lead he's such a <UNK> ass that not only do i not care about his suffering i actually root for it supporting cast members mary <UNK> and <UNK> allen are almost as bad they're so bland and dull they hardly matter in fact there's very little to get excited about while watching the <UNK> man the soundtrack – not very memorable the look – i would describe much of it as <UNK> the plot – predictable the action – there isn't any overall this is one to avoid br br fortunately i watched the <UNK> man via a copy of the mystery science theater <UNK> episode funny stuff while not an absolute very often the <UNK> the movie – the better the mst3k <UNK> the guys hit almost all of their marks with the <UNK> man i'll give it a very <UNK> 4 5 on my mst3k rating scale
len: 2635
```
#### После обработки в начало отзыва добавилось необходимое количество токенов <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 2 2]
[ 0 0 0 ... 10 10 2]
[ 1 14 22 ... 171 153 303]
...
[ 0 0 0 ... 17 2199 1262]
[ 0 0 0 ... 606 5 1356]
[ 0 0 0 ... 1026 5 804]]
X train:
[[ 0 0 0 ... 10 10 2]
[ 0 0 0 ... 43 1044 710]
[ 0 0 0 ... 35 744 23]
...
[ 0 0 0 ... 184 1543 616]
[ 0 0 0 ... 38 2 78]
[ 0 0 0 ... 5 2 2]]
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()
```
**Model: "sequential"**
| Layer (type) | Output Shape | Param # |
| ----------------------- | --------------- | ------: |
| embedding_4 (Embedding) | (None, 500, 32) | 160,000 |
| lstm_4 (LSTM) | (None, 64) | 24,832 |
| dropout_4 (Dropout) | (None, 64) | 0 |
| dense_4 (Dense) | (None, 1) | 65 |
**Total params:** 184,897 (722.25 KB)
**Trainable params:** 184,897 (722.25 KB)
**Non-trainable params:** 0 (0.00 B)
```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 ━━━━━━━━━━━━━━━━━━━━ 13s 23ms/step - accuracy: 0.6613 - loss: 0.5831 - val_accuracy: 0.8470 - val_loss: 0.3631
Epoch 2/3
313/313 ━━━━━━━━━━━━━━━━━━━━ 18s 25ms/step - accuracy: 0.8749 - loss: 0.3133 - val_accuracy: 0.7728 - val_loss: 0.5550
Epoch 3/3
313/313 ━━━━━━━━━━━━━━━━━━━━ 7s 21ms/step - accuracy: 0.8655 - loss: 0.3285 - val_accuracy: 0.8696 - val_loss: 0.3508
<keras.src.callbacks.history.History at 0x7a8f3a94e2a0>
```
```python
test_loss, test_acc = model.evaluate(X_test, y_test)
print(f"\nTest accuracy: {test_acc}")
```
```
782/782 ━━━━━━━━━━━━━━━━━━━━ 9s 11ms/step - accuracy: 0.8611 - loss: 0.3604
Test accuracy: 0.8602399826049805
```
### 10) Оценили качество обучения на тестовых данных:
### - вывели значение метрики качества классификации на тестовых данных
### - вывели отчет о качестве классификации тестовой выборки
### - построили ROC-кривую по результату обработки тестовой выборки и вычислили площадь под ROC-кривой (AUC ROC)
```python
#значение метрики качества классификации на тестовых данных
print(f"\nTest accuracy: {test_acc}")
```
```
Test accuracy: 0.8602399826049805
```
```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.82 0.92 0.87 12500
Positive 0.91 0.80 0.85 12500
accuracy 0.86 25000
macro avg 0.86 0.86 0.86 25000
weighted avg 0.86 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))
```
![picture](images/1.1.png)
```
AUC ROC: 0.9378295648
```
### 11) Сделали выводы по результатам применения рекуррентной нейронной сети для решения задачи определения тональности текста.
Таблица1:
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|----------|-------------------------------------|---------------------------|-----------------------------------------|
| Рекуррентная | 184 897 | 3 | accuracy:0.860 ; loss:0.3604 ; AUC ROC:0.9378 |
#### По полученной таблице можно сделать вывод о хорошей способности рекуррентной нейронной сети определять тональности текста, это подтверждает показатель accuracy = 0.860, который превышает заданный порог в 0.8
#### Значение AUC ROC = 0.9378 (> 0.9) показывает, что нейронная сеть уверенно различает тональности (правильно ставит позитивный класс ниже негативного).
Загрузка…
Отмена
Сохранить