Сравнить коммиты
3 Коммитов
| Автор | SHA1 | Дата | |
|---|---|---|---|
|
|
964549a094 | ||
| b344e76a21 | |||
|
|
047d249b1f |
17
README.md
@@ -1,27 +1,14 @@
|
||||
# Интеллектуальные системы
|
||||
|
||||
|
||||
## <a href="https://docs.google.com/spreadsheets/d/1E1vXKs7ZLeZcsPQiLG2JUh6mjsG6mXnmtFT58aCQul0/edit?usp=sharing">Журнал</a>
|
||||
|
||||
## Лабораторные работы
|
||||
|
||||
1. [Архитектура и обучение глубоких нейронных сетей](labworks/LW1)
|
||||
2. [Обнаружение аномалий](labworks/LW2)
|
||||
3. [Распознавание изображений](labworks/LW3)
|
||||
4. [Распознавание последовательностей](labworks/LW4)
|
||||
|
||||
<!--
|
||||
|
||||
### Лабораторная работа №3
|
||||
|
||||
* [Задание](labworks/LW3/IS_Lab03_2023.pdf)
|
||||
* [Методические указания](labworks/LW3/IS_Lab03_Metod_2023.pdf)
|
||||
* <a href="https://youtube.com/playlist?list=PLZDCDMGmelH-pHt-Ij0nImVrOmj8DYKbB" target="_blank">Плейлист с видео о сверточных сетях (крутая визуализация)</a>
|
||||
|
||||
### Лабораторная работа №4
|
||||
|
||||
* [Задание](labworks/LW4/IS_Lab04_2023.pdf)
|
||||
* [Методические указания](labworks/LW4/IS_Lab04_Metod_2023.pdf)
|
||||
|
||||
-->
|
||||
|
||||
## Архив материалов курса
|
||||
В 2021–2022 годах материалы выкладывались <a href="https://uii.bitbucket.io/study/courses/#:~:text=Интеллектуальные%20системы%20(глубокие%20нейронные%20сети)" target="_blank">на этой странице</a>.
|
||||
|
||||
Двоичные данные
labworks/LW1/1.png
|
До Ширина: | Высота: | Размер: 22 KiB |
Двоичные данные
labworks/LW1/10.png
|
До Ширина: | Высота: | Размер: 7.6 KiB |
Двоичные данные
labworks/LW1/11.png
|
До Ширина: | Высота: | Размер: 6.3 KiB |
Двоичные данные
labworks/LW1/190.png
|
До Ширина: | Высота: | Размер: 6.3 KiB |
Двоичные данные
labworks/LW1/2.png
|
До Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
labworks/LW1/3.png
|
До Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
labworks/LW1/4.png
|
До Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
labworks/LW1/5.png
|
До Ширина: | Высота: | Размер: 27 KiB |
Двоичные данные
labworks/LW1/6.png
|
До Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
labworks/LW1/690.png
|
До Ширина: | Высота: | Размер: 7.6 KiB |
Двоичные данные
labworks/LW1/7.png
|
До Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
labworks/LW1/8.png
|
До Ширина: | Высота: | Размер: 8.0 KiB |
Двоичные данные
labworks/LW1/9.png
|
До Ширина: | Высота: | Размер: 7.0 KiB |
@@ -1,4 +1,11 @@
|
||||
## Лабораторныа работа №1
|
||||
|
||||
## Архитектура и обучение глубоких нейронных сетей
|
||||
|
||||
* [Задание](IS_Lab01_2023.pdf)
|
||||
|
||||
* [Методические указания](IS_Lab01_Metod_2023.pdf)
|
||||
|
||||
* <a href="https://youtube.com/playlist?list=PLfdZ2TeaMzfzlpZ60rbaYU_epH5XPNbWU" target="_blank"><s>Какие нейроны, что вообще происходит?</s> Рекомендуется к просмотру для понимания (4 видео)</a>
|
||||
|
||||
* <a href="https://www.youtube.com/watch?v=FwFduRA_L6Q" target="_blank">Почувствуйте себя пионером нейронных сетей в области распознавания образов</a>
|
||||
Двоичные данные
labworks/LW1/images/1.png
|
До Ширина: | Высота: | Размер: 22 KiB |
Двоичные данные
labworks/LW1/images/10.png
|
До Ширина: | Высота: | Размер: 7.6 KiB |
Двоичные данные
labworks/LW1/images/11.png
|
До Ширина: | Высота: | Размер: 6.3 KiB |
Двоичные данные
labworks/LW1/images/190 (2).png
|
До Ширина: | Высота: | Размер: 208 B |
Двоичные данные
labworks/LW1/images/190.png
|
До Ширина: | Высота: | Размер: 6.3 KiB |
Двоичные данные
labworks/LW1/images/2.png
|
До Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
labworks/LW1/images/3.png
|
До Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
labworks/LW1/images/4.png
|
До Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
labworks/LW1/images/5.png
|
До Ширина: | Высота: | Размер: 27 KiB |
Двоичные данные
labworks/LW1/images/6.png
|
До Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
labworks/LW1/images/690 (1).png
|
До Ширина: | Высота: | Размер: 333 B |
Двоичные данные
labworks/LW1/images/690.png
|
До Ширина: | Высота: | Размер: 7.6 KiB |
Двоичные данные
labworks/LW1/images/7.png
|
До Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
labworks/LW1/images/8.png
|
До Ширина: | Высота: | Размер: 8.0 KiB |
Двоичные данные
labworks/LW1/images/9.png
|
До Ширина: | Высота: | Размер: 7.0 KiB |
@@ -1,610 +0,0 @@
|
||||
# Отчет по лабораторной работе №1
|
||||
Касимов Азамат, Немыкин Никита, А-01-22
|
||||
|
||||
## 1. В среде GoogleColab создали блокнот(notebook.ipynb).
|
||||
```
|
||||
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
|
||||
```
|
||||
from keras.datasets import mnist
|
||||
(X_train, y_train), (X_test, y_test) = mnist.load_data()
|
||||
```
|
||||
|
||||
## 3. Разбиение набора данных на обучающие и тестовые
|
||||
```
|
||||
from sklearn.model_selection import train_test_split
|
||||
```
|
||||
* объединяем в один набор
|
||||
```
|
||||
X = np.concatenate((X_train, X_test))
|
||||
y = np.concatenate((y_train, y_test))
|
||||
```
|
||||
* разбиваем по вариантам
|
||||
```
|
||||
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size = 10000,train_size = 60000, random_state = 27)
|
||||
```
|
||||
|
||||
* Вывод размерностей
|
||||
```
|
||||
print('Shape of X train:', X_train.shape)
|
||||
print('Shape of y train:', y_train.shape)
|
||||
```
|
||||
|
||||
> Shape of X train: (60000, 28, 28)
|
||||
> Shape of y train: (60000,)
|
||||
|
||||
## 4. Вывод элементов обучающих данных
|
||||
* Создаем subplot для 4 изображений
|
||||
```
|
||||
fig, axes = plt.subplots(1, 4, figsize=(10, 3))
|
||||
|
||||
for i in range(4):
|
||||
axes[i].imshow(X_train[i], cmap=plt.get_cmap('gray'))
|
||||
axes[i].set_title(f'Label: {y_train[i]}')
|
||||
|
||||
# Добавляем метку как заголовок
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 5. Предобработка данных
|
||||
* развернем каждое изображение 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)
|
||||
```
|
||||
|
||||
> Shape of transformed X train: (60000, 784)
|
||||
|
||||
* переведем метки в one-hot
|
||||
```
|
||||
from keras.utils import to_categorical
|
||||
y_train = to_categorical(y_train)
|
||||
y_test = 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. Реализация и обучение однослойной нейронной сети
|
||||
```
|
||||
from keras.models import Sequential
|
||||
from keras.layers import Dense
|
||||
```
|
||||
|
||||
* 6.1. создаем модель - объявляем ее объектом класса Sequential
|
||||
```
|
||||
model_1 = Sequential()
|
||||
model_1.add(Dense(units=num_classes,input_dim=num_pixels, activation='softmax'))
|
||||
```
|
||||
* 6.2. компилируем модель
|
||||
```
|
||||
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) '
|
||||
|
||||
* Обучаем модель
|
||||
```
|
||||
history = model_1.fit(
|
||||
X_train, y_train,
|
||||
validation_split=0.1,
|
||||
epochs=50
|
||||
)
|
||||
```
|
||||
|
||||
* Выводим график функции ошибки
|
||||
```
|
||||
plt.figure(figsize=(12, 5))
|
||||
|
||||
plt.subplot(1, 2, 1)
|
||||
plt.plot(history.history['loss'], label='Обучающая ошибка')
|
||||
plt.plot(history.history['val_loss'], label='Валидационная ошибка')
|
||||
plt.title('Функция ошибки по эпохам')
|
||||
plt.xlabel('Эпохи')
|
||||
plt.ylabel('Categorical Crossentropy')
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 7. Применение модели к тестовым данным
|
||||
```
|
||||
scores=model_1.evaluate(X_test,y_test)
|
||||
print('Lossontestdata:',scores[0])
|
||||
print('Accuracyontestdata:',scores[1])
|
||||
```
|
||||
|
||||
> - accuracy: 0.9206 - loss: 0.2956
|
||||
>Lossontestdata: 0.2900226414203644
|
||||
>Accuracyontestdata: 0.9222000241279602
|
||||
|
||||
## 8. Добавили один скрытый слой и повторили п. 6-7
|
||||
* при 100 нейронах в скрытом слое
|
||||
```
|
||||
model_2l_100 = Sequential()
|
||||
model_2l_100.add(Dense(units=100,input_dim=num_pixels, activation='sigmoid'))
|
||||
model_2l_100.add(Dense(units=num_classes, activation='softmax'))
|
||||
|
||||
model_2l_100.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
||||
|
||||
print("Архитектура нейронной сети:")
|
||||
model_2l_100.summary()
|
||||
```
|
||||
|
||||
> Архитектура нейронной сети:
|
||||
>Model: "sequential_9"
|
||||
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
>│ dense_1 (Dense) │ (None, 100) │ 78,500 │
|
||||
>├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
>│ dense_2 (Dense) │ (None, 10) │ 1,010 │
|
||||
>└─────────────────────────────────┴────────────────────────┴───────────────┘
|
||||
> Total params: 79,510 (310.59 KB)
|
||||
> Trainable params: 79,510 (310.59 KB)
|
||||
> Non-trainable params: 0 (0.00 B)
|
||||
|
||||
* Обучаем модель
|
||||
```
|
||||
history_2l_100 = model_2l_100.fit(
|
||||
X_train, y_train,
|
||||
validation_split=0.1,
|
||||
epochs=50
|
||||
)
|
||||
```
|
||||
|
||||
* Выводим график функции ошибки
|
||||
```
|
||||
plt.figure(figsize=(12, 5))
|
||||
|
||||
plt.subplot(1, 2, 1)
|
||||
plt.plot(history_2l_100.history['loss'], label='Обучающая ошибка')
|
||||
plt.plot(history_2l_100.history['val_loss'], label='Валидационная ошибка')
|
||||
plt.title('Функция ошибки по эпохам')
|
||||
plt.xlabel('Эпохи')
|
||||
plt.ylabel('Categorical Crossentropy')
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
scores_2l_100=model_2l_100.evaluate(X_test,y_test)
|
||||
print('Lossontestdata:',scores_2l_100[0]) #значение функции ошибки
|
||||
print('Accuracyontestdata:',scores_2l_100[1]) #значение метрики качества
|
||||
```
|
||||
|
||||
> - accuracy: 0.9436 - loss: 0.2091
|
||||
>Lossontestdata: 0.20427274703979492
|
||||
>Accuracyontestdata: 0.9438999891281128 '
|
||||
|
||||
* при 300 нейронах в скрытом слое
|
||||
```
|
||||
model_2l_300 = Sequential()
|
||||
model_2l_300.add(Dense(units=300,input_dim=num_pixels, activation='sigmoid'))
|
||||
model_2l_300.add(Dense(units=num_classes, activation='softmax'))
|
||||
|
||||
model_2l_300.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
||||
|
||||
print("Архитектура нейронной сети:")
|
||||
model_2l_300.summary()
|
||||
```
|
||||
|
||||
> Архитектура нейронной сети:
|
||||
>Model: "sequential_3"
|
||||
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
>│ dense_5 (Dense) │ (None, 300) │ 235,500 │
|
||||
>├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
>│ dense_6 (Dense) │ (None, 10) │ 3,010 │
|
||||
>└─────────────────────────────────┴────────────────────────┴───────────────┘
|
||||
> Total params: 238,510 (931.68 KB)
|
||||
> Trainable params: 238,510 (931.68 KB)
|
||||
> Non-trainable params: 0 (0.00 B)
|
||||
|
||||
* Обучаем модель
|
||||
```
|
||||
history_2l_300 = model_2l_300.fit(
|
||||
X_train, y_train,
|
||||
validation_split=0.1,
|
||||
epochs=50
|
||||
)
|
||||
```
|
||||
|
||||
* Выводим график функции ошибки
|
||||
```
|
||||
plt.figure(figsize=(12, 5))
|
||||
|
||||
plt.subplot(1, 2, 1)
|
||||
plt.plot(history_2l_300.history['loss'], label='Обучающая ошибка')
|
||||
plt.plot(history_2l_300.history['val_loss'], label='Валидационная ошибка')
|
||||
plt.title('Функция ошибки по эпохам')
|
||||
plt.xlabel('Эпохи')
|
||||
plt.ylabel('Categorical Crossentropy')
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
scores_2l_300=model_2l_300.evaluate(X_test,y_test)
|
||||
print('Lossontestdata:',scores_2l_300[0]) #значение функции ошибки
|
||||
print('Accuracyontestdata:',scores_2l_300[1]) #значение метрики качества
|
||||
```
|
||||
|
||||
> - accuracy: 0.9365 - loss: 0.2352
|
||||
>Lossontestdata: 0.23040874302387238
|
||||
>Accuracyontestdata: 0.9372000098228455
|
||||
|
||||
* при 500 нейронах в скрытом слое
|
||||
```
|
||||
model_2l_500 = Sequential()
|
||||
model_2l_500.add(Dense(units=500,input_dim=num_pixels, activation='sigmoid'))
|
||||
model_2l_500.add(Dense(units=num_classes, activation='softmax'))
|
||||
|
||||
model_2l_500.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
||||
|
||||
print("Архитектура нейронной сети:")
|
||||
model_2l_500.summary()
|
||||
```
|
||||
|
||||
> Архитектура нейронной сети:
|
||||
>Model: "sequential_4"
|
||||
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
>│ dense_7 (Dense) │ (None, 500) │ 392,500 │
|
||||
>├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
>│ dense_8 (Dense) │ (None, 10) │ 5,010 │
|
||||
>└─────────────────────────────────┴────────────────────────┴───────────────┘
|
||||
> Total params: 397,510 (1.52 MB)
|
||||
> Trainable params: 397,510 (1.52 MB)
|
||||
> Non-trainable params: 0 (0.00 B)
|
||||
|
||||
* Обучаем модель
|
||||
```
|
||||
history_2l_500 = model_2l_500.fit(
|
||||
X_train, y_train,
|
||||
validation_split=0.1,
|
||||
epochs=50
|
||||
)
|
||||
```
|
||||
|
||||
* Выводим график функции ошибки
|
||||
```
|
||||
plt.figure(figsize=(12, 5))
|
||||
|
||||
plt.subplot(1, 2, 1)
|
||||
plt.plot(history_2l_500.history['loss'], label='Обучающая ошибка')
|
||||
plt.plot(history_2l_500.history['val_loss'], label='Валидационная ошибка')
|
||||
plt.title('Функция ошибки по эпохам')
|
||||
plt.xlabel('Эпохи')
|
||||
plt.ylabel('Categorical Crossentropy')
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
scores_2l_500=model_2l_500.evaluate(X_test,y_test)
|
||||
print('Lossontestdata:',scores_2l_500[0]) #значение функции ошибки
|
||||
print('Accuracyontestdata:',scores_2l_500[1]) #значение метрики качества
|
||||
```
|
||||
|
||||
> - accuracy: 0.9290 - loss: 0.2572
|
||||
>Lossontestdata: 0.25275251269340515
|
||||
>Accuracyontestdata: 0.9301000237464905
|
||||
|
||||
Как мы видим, лучшая метрика получилась равной 0.9438999891281128 при архитектуре со 100 нейронами в скрытом слое, поэтому для дальнейших пунктов используем ее.
|
||||
|
||||
## 9. Добавили второй скрытый слой
|
||||
* при 50 нейронах во втором скрытом слое
|
||||
```
|
||||
model_3l_100_50 = Sequential()
|
||||
model_3l_100_50.add(Dense(units=100, input_dim=num_pixels, activation='sigmoid'))
|
||||
model_3l_100_50.add(Dense(units=50, activation='sigmoid'))
|
||||
model_3l_100_50.add(Dense(units=num_classes, activation='softmax'))
|
||||
|
||||
model_3l_100_50.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
||||
|
||||
print("Архитектура нейронной сети:")
|
||||
model_3l_100_50.summary()
|
||||
```
|
||||
|
||||
> Архитектура нейронной сети:
|
||||
>Model: "sequential_5"
|
||||
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
>│ dense_9 (Dense) │ (None, 100) │ 78,500 │
|
||||
>├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
>│ dense_10 (Dense) │ (None, 50) │ 5,050 │
|
||||
>├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
>│ dense_11 (Dense) │ (None, 10) │ 510 │
|
||||
>└─────────────────────────────────┴────────────────────────┴───────────────┘
|
||||
> Total params: 84,060 (328.36 KB)
|
||||
> Trainable params: 84,060 (328.36 KB)
|
||||
> Non-trainable params: 0 (0.00 B)
|
||||
|
||||
* Обучаем модель
|
||||
```
|
||||
history_3l_100_50 = model_3l_100_50.fit(
|
||||
X_train, y_train,
|
||||
validation_split=0.1,
|
||||
epochs=50
|
||||
)
|
||||
```
|
||||
|
||||
* Выводим график функции ошибки
|
||||
```
|
||||
plt.figure(figsize=(12, 5))
|
||||
|
||||
plt.subplot(1, 2, 1)
|
||||
plt.plot(history_3l_100_50.history['loss'], label='Обучающая ошибка')
|
||||
plt.plot(history_3l_100_50.history['val_loss'], label='Валидационная ошибка')
|
||||
plt.title('Функция ошибки по эпохам')
|
||||
plt.xlabel('Эпохи')
|
||||
plt.ylabel('Categorical Crossentropy')
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
scores_3l_100_50=model_3l_100_50.evaluate(X_test,y_test)
|
||||
print('Lossontestdata:',scores_3l_100_50[0])
|
||||
print('Accuracyontestdata:',scores_3l_100_50[1])
|
||||
```
|
||||
|
||||
> - accuracy: 0.9423 - loss: 0.2074
|
||||
>Lossontestdata: 0.20320768654346466
|
||||
>Accuracyontestdata: 0.9427000284194946
|
||||
|
||||
* при 100 нейронах во втором скрытом слое
|
||||
```
|
||||
model_3l_100_100 = Sequential()
|
||||
model_3l_100_100.add(Dense(units=100, input_dim=num_pixels, activation='sigmoid'))
|
||||
model_3l_100_100.add(Dense(units=100, activation='sigmoid'))
|
||||
model_3l_100_100.add(Dense(units=num_classes, activation='softmax'))
|
||||
|
||||
model_3l_100_100.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
||||
|
||||
print("Архитектура нейронной сети:")
|
||||
model_3l_100_100.summary()
|
||||
```
|
||||
|
||||
> Архитектура нейронной сети:
|
||||
>Model: "sequential_6"
|
||||
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
>│ dense_12 (Dense) │ (None, 100) │ 78,500 │
|
||||
>├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
>│ dense_13 (Dense) │ (None, 100) │ 10,100 │
|
||||
>├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
>│ dense_14 (Dense) │ (None, 10) │ 1,010 │
|
||||
>└─────────────────────────────────┴────────────────────────┴───────────────┘
|
||||
> Total params: 89,610 (350.04 KB)
|
||||
> Trainable params: 89,610 (350.04 KB)
|
||||
> Non-trainable params: 0 (0.00 B) '
|
||||
|
||||
* Обучаем модель
|
||||
```
|
||||
history_3l_100_100 = model_3l_100_100.fit(
|
||||
X_train, y_train,
|
||||
validation_split=0.1,
|
||||
epochs=50
|
||||
)
|
||||
```
|
||||
|
||||
* Выводим график функции ошибки
|
||||
```
|
||||
plt.figure(figsize=(12, 5))
|
||||
|
||||
plt.subplot(1, 2, 1)
|
||||
plt.plot(history_3l_100_100.history['loss'], label='Обучающая ошибка')
|
||||
plt.plot(history_3l_100_100.history['val_loss'], label='Валидационная ошибка')
|
||||
plt.title('Функция ошибки по эпохам')
|
||||
plt.xlabel('Эпохи')
|
||||
plt.ylabel('Categorical Crossentropy')
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
scores_3l_100_100=model_3l_100_100.evaluate(X_test,y_test)
|
||||
print('Lossontestdata:',scores_3l_100_100[0])
|
||||
print('Accuracyontestdata:',scores_3l_100_100[1])
|
||||
```
|
||||
|
||||
> - accuracy: 0.9435 - loss: 0.2058
|
||||
>Lossontestdata: 0.2007063776254654
|
||||
>Accuracyontestdata: 0.9431999921798706
|
||||
|
||||
Количество Количество нейронов в Количество нейронов во Значение метрики
|
||||
скрытых слоев первом скрытом слое втором скрытом слое качества классификации
|
||||
0 - - 0.9222000241279602
|
||||
1 100 - 0.9438999891281128
|
||||
1 300 - 0.9372000098228455
|
||||
1 500 - 0.9301000237464905
|
||||
2 100 50 0.9427000284194946
|
||||
2 100 100 0.9431999921798706
|
||||
|
||||
Наилучшую точность (0.9467999935150146) показала модель содержащая 100 нейронов в скрытом слое.
|
||||
|
||||
## 11. Сохранение наилучшей модели на диск
|
||||
```
|
||||
model_2l_100.save(filepath='best_model.keras')
|
||||
```
|
||||
|
||||
## 12. Вывод тестовых изображений и результатов распознаваний
|
||||
```
|
||||
n = 150
|
||||
result = model_2l_100.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)))
|
||||
```
|
||||
|
||||
> NN output: [[3.86779779e-04 3.69515050e-08 2.03053992e-06 1.15266894e-05
|
||||
> 1.57332561e-05 4.79512411e-04 7.92529917e-08 9.95542467e-01
|
||||
> 1.50878295e-05 3.54681048e-03]]
|
||||

|
||||
>Real mark: 7
|
||||
>NN answer: 7
|
||||
|
||||
```
|
||||
n = 810
|
||||
result = model_2l_100.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)))
|
||||
```
|
||||
|
||||
> NN output: [[8.1927046e-06 9.8501807e-01 4.7102575e-03 1.5754283e-03 5.3024664e-06
|
||||
> 2.3075400e-03 6.3471968e-04 7.6599965e-05 5.5682263e-03 9.5791329e-05]]
|
||||

|
||||
>Real mark: 1
|
||||
>NN answer: 1 '
|
||||
|
||||
## 12. Тестирование на собственных изображениях
|
||||
* загрузка 1 собственного изображения
|
||||
```
|
||||
from PIL import Image
|
||||
file_1_data = Image.open('ИИЛР1_6.png')
|
||||
file_1_data = file_1_data.convert('L') #перевод в градации серого
|
||||
test_1_img = np.array(file_1_data)
|
||||
```
|
||||
|
||||
* вывод собственного изображения
|
||||
```
|
||||
plt.imshow(test_1_img, cmap=plt.get_cmap('gray'))
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
* предобработка
|
||||
```
|
||||
test_1_img = test_1_img / 255
|
||||
test_1_img = test_1_img.reshape(1, num_pixels)
|
||||
```
|
||||
|
||||
* распознавание
|
||||
```
|
||||
result_1 = model_2l_100.predict(test_1_img)
|
||||
print('I think it\'s', np.argmax(result_1))
|
||||
```
|
||||
> I think it's 6
|
||||
|
||||
* тест 2 изображения
|
||||
```
|
||||
file_2_data = Image.open('ИИЛР1_1.png')
|
||||
file_2_data = file_2_data.convert('L') #перевод в градации серого
|
||||
test_2_img = np.array(file_2_data)
|
||||
|
||||
plt.imshow(test_2_img, cmap=plt.get_cmap('gray'))
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
test_2_img = test_2_img / 255
|
||||
test_2_img = test_2_img.reshape(1, num_pixels)
|
||||
|
||||
result_2 = model.predict(test_2_img)
|
||||
print('I think it\'s', np.argmax(result_2))
|
||||
```
|
||||
|
||||
> I think it's 1
|
||||
|
||||
Сеть не ошиблась и корректно распознала обе цифры на изображениях
|
||||
|
||||
## 14. Тестирование на собственных повернутых изображениях
|
||||
```
|
||||
file_190_data = Image.open('ИИЛР1_690.png')
|
||||
file_190_data = file_190_data.convert('L') #перевод в градации серого
|
||||
test_190_img = np.array(file_190_data)
|
||||
|
||||
plt.imshow(test_190_img, cmap=plt.get_cmap('gray'))
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
test_190_img = test_190_img / 255
|
||||
test_190_img = test_190_img.reshape(1, num_pixels)
|
||||
|
||||
result_190 = model_2l_100.predict(test_190_img)
|
||||
print('I think it\'s', np.argmax(result_190))
|
||||
```
|
||||
|
||||
> I think it's 2
|
||||
|
||||
```
|
||||
file_290_data = Image.open('ИИЛР1_190.png')
|
||||
file_290_data = file_290_data.convert('L') #перевод в градации серого
|
||||
test_290_img = np.array(file_290_data)
|
||||
|
||||
plt.imshow(test_290_img, cmap=plt.get_cmap('gray'))
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
test_290_img = test_290_img / 255
|
||||
test_290_img = test_290_img.reshape(1, num_pixels)
|
||||
|
||||
result_290 = model.predict(test_290_img)
|
||||
print('I think it\'s', np.argmax(result_290))
|
||||
```
|
||||
|
||||
> I think it's 4
|
||||
|
||||
При повороте изображений сеть не распознала цифры правильно. Так как она не обучалась на повернутых изображениях.
|
||||
@@ -1,4 +1,11 @@
|
||||
## Лабораторныа работа №2
|
||||
|
||||
## Обнаружение аномалий
|
||||
|
||||
* [Задание](IS_Lab02_2023.pdf)
|
||||
|
||||
* [Методические указания](IS_Lab02_Metod_2023.pdf)
|
||||
|
||||
* [Наборы данных](data)
|
||||
|
||||
* [Библиотека для автокодировщиков](lab02_lib.py)
|
||||
Двоичные данные
labworks/LW2/images/1.png
|
До Ширина: | Высота: | Размер: 41 KiB |
Двоичные данные
labworks/LW2/images/10.png
|
До Ширина: | Высота: | Размер: 21 KiB |
Двоичные данные
labworks/LW2/images/11.png
|
До Ширина: | Высота: | Размер: 27 KiB |
Двоичные данные
labworks/LW2/images/12.png
|
До Ширина: | Высота: | Размер: 34 KiB |
Двоичные данные
labworks/LW2/images/13.png
|
До Ширина: | Высота: | Размер: 22 KiB |
Двоичные данные
labworks/LW2/images/14.png
|
До Ширина: | Высота: | Размер: 92 KiB |
Двоичные данные
labworks/LW2/images/15.png
|
До Ширина: | Высота: | Размер: 100 KiB |
Двоичные данные
labworks/LW2/images/16.png
|
До Ширина: | Высота: | Размер: 56 KiB |
Двоичные данные
labworks/LW2/images/17.png
|
До Ширина: | Высота: | Размер: 52 KiB |
Двоичные данные
labworks/LW2/images/2.png
|
До Ширина: | Высота: | Размер: 50 KiB |
Двоичные данные
labworks/LW2/images/3.png
|
До Ширина: | Высота: | Размер: 109 KiB |
Двоичные данные
labworks/LW2/images/4.png
|
До Ширина: | Высота: | Размер: 33 KiB |
Двоичные данные
labworks/LW2/images/5.png
|
До Ширина: | Высота: | Размер: 88 KiB |
Двоичные данные
labworks/LW2/images/6.png
|
До Ширина: | Высота: | Размер: 102 KiB |
Двоичные данные
labworks/LW2/images/7.png
|
До Ширина: | Высота: | Размер: 30 KiB |
Двоичные данные
labworks/LW2/images/8.png
|
До Ширина: | Высота: | Размер: 62 KiB |
Двоичные данные
labworks/LW2/images/9.png
|
До Ширина: | Высота: | Размер: 74 KiB |
@@ -29,12 +29,14 @@ from pandas import DataFrame
|
||||
from sklearn.metrics import precision_score, recall_score, f1_score, confusion_matrix
|
||||
from tensorflow.keras.models import Sequential
|
||||
from tensorflow.keras.layers import Dense, Activation
|
||||
from tensorflow.keras.callbacks import Callback
|
||||
|
||||
|
||||
|
||||
visual = True
|
||||
verbose_show = False
|
||||
|
||||
|
||||
# generate 2d classification dataset
|
||||
def datagen(x_c, y_c, n_samples, n_features):
|
||||
|
||||
@@ -91,8 +93,27 @@ class EarlyStoppingOnValue(tensorflow.keras.callbacks.Callback):
|
||||
)
|
||||
return monitor_value
|
||||
|
||||
|
||||
class VerboseEveryNEpochs(Callback):
|
||||
def __init__(self, every_n_epochs=1000, verbose=1):
|
||||
super().__init__()
|
||||
self.every_n_epochs = every_n_epochs
|
||||
self.verbose = verbose
|
||||
|
||||
def on_epoch_end(self, epoch, logs=None):
|
||||
if (epoch + 1) % self.every_n_epochs == 0:
|
||||
if self.verbose:
|
||||
print(f"\nEpoch {epoch + 1}/{self.params['epochs']}")
|
||||
if logs:
|
||||
log_str = ", ".join([f"{k}: {v:.4f}" for k, v in logs.items()])
|
||||
print(f" - {log_str}")
|
||||
|
||||
|
||||
#создание и обучение модели автокодировщика
|
||||
def create_fit_save_ae(cl_train, ae_file, irefile, epohs, verbose_show, patience):
|
||||
def create_fit_save_ae(cl_train, ae_file, irefile, epohs, verbose_show, patience, **kwargs):
|
||||
verbose_every_n_epochs = kwargs.get('verbose_every_n_epochs', 1000)
|
||||
early_stopping_delta = kwargs.get('early_stopping_delta', 0.01)
|
||||
early_stopping_value = kwargs.get('early_stopping_value', 0.0001)
|
||||
|
||||
size = cl_train.shape[1]
|
||||
#ans = '2'
|
||||
@@ -140,22 +161,28 @@ def create_fit_save_ae(cl_train, ae_file, irefile, epohs, verbose_show, patience
|
||||
|
||||
optimizer = tensorflow.keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False)
|
||||
ae.compile(loss='mean_squared_error', optimizer=optimizer)
|
||||
error_stop = 0.0001
|
||||
epo = epohs
|
||||
|
||||
early_stopping_callback_on_error = EarlyStoppingOnValue(monitor='loss', baseline=error_stop)
|
||||
early_stopping_callback_on_improving = tensorflow.keras.callbacks.EarlyStopping(monitor='loss',
|
||||
min_delta=0.0001, patience = patience,
|
||||
verbose=1, mode='auto',
|
||||
baseline=None,
|
||||
restore_best_weights=False)
|
||||
history_callback = tensorflow.keras.callbacks.History()
|
||||
|
||||
verbose = 1 if verbose_show else 0
|
||||
|
||||
early_stopping_callback_on_error = EarlyStoppingOnValue(monitor='loss', baseline=early_stopping_value)
|
||||
early_stopping_callback_on_improving = tensorflow.keras.callbacks.EarlyStopping(monitor='loss',
|
||||
min_delta=early_stopping_delta, patience = patience,
|
||||
verbose=verbose, mode='min',
|
||||
baseline=None,
|
||||
restore_best_weights=True)
|
||||
history_callback = tensorflow.keras.callbacks.History()
|
||||
|
||||
history_object = ae.fit(cl_train, cl_train,
|
||||
batch_size=cl_train.shape[0],
|
||||
epochs=epo,
|
||||
callbacks=[early_stopping_callback_on_error, history_callback,
|
||||
early_stopping_callback_on_improving],
|
||||
callbacks=[
|
||||
early_stopping_callback_on_error,
|
||||
history_callback,
|
||||
early_stopping_callback_on_improving,
|
||||
VerboseEveryNEpochs(every_n_epochs=verbose_every_n_epochs),
|
||||
],
|
||||
verbose=verbose)
|
||||
ae_trainned = ae
|
||||
ae_pred = ae_trainned.predict(cl_train)
|
||||
|
||||
@@ -1,688 +0,0 @@
|
||||
# Отчёт по лабораторной работе №2
|
||||
|
||||
**Касимов Азамат, Немыкин Никита — А-01-22**
|
||||
|
||||
---
|
||||
|
||||
## Задание 1
|
||||
|
||||
### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули.
|
||||
|
||||
```python
|
||||
# импорт модулей
|
||||
import os
|
||||
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab2')
|
||||
```
|
||||
|
||||
```python
|
||||
import lab02_lib as lib
|
||||
```
|
||||
|
||||
### 2) Сгенерировали индивидуальный набор двумерных данных в пространстве признаков с координатами центра (6, 6), где 6 – номер бригады. Вывели полученные данные на рисунок и в консоль.
|
||||
|
||||
```python
|
||||
# генерация датасета
|
||||
data = lib.datagen(6, 6, 1000, 2)
|
||||
|
||||
# вывод данных и размерности
|
||||
print('Исходные данные:')
|
||||
print(data)
|
||||
print('Размерность данных:')
|
||||
print(data.shape)
|
||||
```
|
||||
|
||||

|
||||
|
||||
```output
|
||||
Исходные данные:
|
||||
[[5.85155463 5.90866047]
|
||||
[5.89835027 5.87217268]
|
||||
[5.95502834 6.13788939]
|
||||
...
|
||||
[5.97194799 6.15187645]
|
||||
[6.24367408 6.18137502]
|
||||
[6.04890409 6.24554664]]
|
||||
Размерность данных:
|
||||
(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 = 16.0985
|
||||
|
||||
```python
|
||||
# Построение графика ошибки реконструкции
|
||||
lib.ire_plot('training', IRE1, IREth1, 'AE1')
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 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.0112
|
||||
|
||||
```python
|
||||
# Построение графика ошибки реконструкции
|
||||
lib.ire_plot('training', IRE2, IREth2, 'AE2')
|
||||
```
|
||||
|
||||

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

|
||||
|
||||
```output
|
||||
amount: 21
|
||||
amount_ae: 301
|
||||
```
|
||||
|
||||

|
||||
|
||||

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

|
||||
|
||||
```output
|
||||
amount: 21
|
||||
amount_ae: 36
|
||||
```
|
||||
|
||||

|
||||
|
||||

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

|
||||
|
||||
### 8) Если автокодировщик AE2 недостаточно точно аппроксимирует область обучающих данных, то подобрать подходящие параметры автокодировщика и повторить шаги (6) – (8).
|
||||
|
||||
Полученные показатели EDCA для автокодировщика AE2 нас устраивают.
|
||||
|
||||
### 9) Изучили сохраненный набор данных и пространство признаков. Создали тестовую выборку, состоящую, как минимум, из 4ёх элементов, не входящих в обучающую выборку. Элементы должны быть такими, чтобы AE1 распознавал их как норму, а AE2 детектировал как аномалии.
|
||||
|
||||
```python
|
||||
# загрузка тестового набора
|
||||
data_test = np.loadtxt('data_test.txt', dtype=float)
|
||||
print(data_test)
|
||||
```
|
||||
|
||||
```output
|
||||
[[4.85155463 4.90866047]
|
||||
[4.89835027 4.87217268]
|
||||
[4.95502834 4.13788939]
|
||||
[4.9958611 4.8697867 ]]
|
||||
```
|
||||
|
||||
### 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')
|
||||
```
|
||||
|
||||
```output
|
||||
Аномалий не обнаружено
|
||||
```
|
||||
|
||||

|
||||
|
||||
```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')
|
||||
```
|
||||
|
||||
```output
|
||||
|
||||
i Labels IRE IREth
|
||||
0 [1.] [1.48] 0.44
|
||||
1 [1.] [1.47] 0.44
|
||||
2 [1.] [2.04] 0.44
|
||||
3 [1.] [1.41] 0.44
|
||||
Обнаружено 4.0 аномалий
|
||||
```
|
||||
|
||||

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

|
||||
|
||||
### 12) Результаты исследования занесли в таблицу:
|
||||
Табл. 1 Результаты задания №1
|
||||
|
||||
| | Количество<br>скрытых слоев | Количество<br>нейронов в скрытых слоях | Количество<br>эпох обучения | Ошибка<br>MSE_stop | Порог ошибки<br>реконструкции | Значение показателя<br>Excess | Значение показателя<br>Approx | Количество обнаруженных<br>аномалий |
|
||||
|-----:|------------------------------|----------------------------------------|-----------------------------|--------------------|-------------------------------|-------------------------------|--------------------------------|-------------------------------------|
|
||||
| AE1 | 1 | 1 | 1000 | 16.0985 | 6 | 13.333333333333334 | 0.06976744186046512 | 0 |
|
||||
| AE2 | 5 | 3,2,1,2,3 | 3000 | 0.0112 | 0.44 | 0.7142857142857143 | 0.5833333333333335 | 4 |
|
||||
|
||||
### 13) Сделали выводы о требованиях к:
|
||||
- данным для обучения,
|
||||
- архитектуре автокодировщика,
|
||||
- количеству эпох обучения,
|
||||
- ошибке MSE_stop, приемлемой для останова обучения,
|
||||
- ошибке реконструкции обучающей выборки (порогу обнаружения
|
||||
аномалий),
|
||||
- характеристикам качества обучения EDCA одноклассового
|
||||
классификатора
|
||||
|
||||
для качественного обнаружения аномалий в данных.
|
||||
|
||||
1) Данные для обучения должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение
|
||||
2) Архитектура автокодировщика должна постепенно сужатся к бутылочному горлышку,а затем постепенно возвращатся к исходным выходным размерам, кол-во скрытых слоев 3-5
|
||||
3) В рамках данного набора данных оптимальное кол-во эпох 3000 с patience 300 эпох
|
||||
4) Оптимальная ошибка MSE-stop в районе 0.01, желательно не меньше для предотвращения переобучения
|
||||
5) Значение порога в районе 0.45
|
||||
6) Значение Excess не больше 0.75, значение Deficit равное 0, значение Coating равное 1, значение Approx не меньше 0.58
|
||||
|
||||
## Задание 2
|
||||
|
||||
### 1) Изучить описание своего набора реальных данных, что он из себя представляет
|
||||
|
||||
Бригада 6 => набор данных 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))
|
||||
```
|
||||
|
||||
```output
|
||||
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, early_stopping_delta = 0.001)
|
||||
print("Время на обучение: ", time() - start)
|
||||
```
|
||||
|
||||
|
||||
```output
|
||||
|
||||
Время на обучение: 1232.8548789024353
|
||||
```
|
||||
|
||||
### 5) Зафиксировать ошибку MSE, на которой обучение завершилось. Построить график ошибки реконструкции обучающей выборки. Зафиксировать порог ошибки реконструкции – порог обнаружения аномалий.
|
||||
|
||||
Скрытых слоев 7, нейроны: 46->26->14->10->14->26->48
|
||||
|
||||
Ошибка MSE_AE3_v1 = 0.0137
|
||||
|
||||
```python
|
||||
lib.ire_plot('training', IRE3_v1, IREth3_v1, 'AE3_v1')
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
print("Время на обучение: ", time() - start)
|
||||
```
|
||||
|
||||
```output
|
||||
|
||||
Время на обучение: 1298.1322848796844
|
||||
```
|
||||
|
||||
Скрытых слоев 11, нейроны: 48->36->28->22->16->12->16->22->28->36->48
|
||||
|
||||
Ошибка MSE_AE3_v1 = 0.0077
|
||||
|
||||
```python
|
||||
# Построение графика ошибки реконструкции
|
||||
lib.ire_plot('training', IRE3_v2, IREth3_v2, 'AE3_v2')
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 7) Изучить и загрузить тестовую выборку Cardio.txt.
|
||||
|
||||
```python
|
||||
#загрузка тестовой выборки
|
||||
test = np.loadtxt('cardio_test.txt', dtype=float)
|
||||
print('\n test:\n', test)
|
||||
print('test.shape:', np.shape(test))
|
||||
```
|
||||
|
||||
```output
|
||||
|
||||
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')
|
||||
```
|
||||
|
||||

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

|
||||
|
||||
```python
|
||||
# тестирование АE1
|
||||
lib.anomaly_detection_ae(predicted_labels3_v1, IRE3_v1, IREth3_v1)
|
||||
```
|
||||
|
||||
```output
|
||||
|
||||
i Labels IRE IREth
|
||||
0 [1.] 0.62 1.82
|
||||
1 [1.] 0.81 1.82
|
||||
2 [1.] 0.68 1.82
|
||||
3 [1.] 0.68 1.82
|
||||
4 [1.] 1.14 1.82
|
||||
5 [1.] 0.64 1.82
|
||||
6 [1.] 0.84 1.82
|
||||
7 [1.] 0.87 1.82
|
||||
8 [1.] 0.51 1.82
|
||||
9 [1.] 0.46 1.82
|
||||
10 [1.] 0.5 1.82
|
||||
11 [1.] 0.67 1.82
|
||||
12 [1.] 0.74 1.82
|
||||
13 [1.] 0.9 1.82
|
||||
14 [1.] 0.66 1.82
|
||||
15 [1.] 1.33 1.82
|
||||
16 [1.] 0.66 1.82
|
||||
17 [1.] 0.5 1.82
|
||||
18 [1.] 0.64 1.82
|
||||
19 [1.] 0.5 1.82
|
||||
20 [1.] 0.4 1.82
|
||||
21 [1.] 0.49 1.82
|
||||
22 [1.] 0.43 1.82
|
||||
23 [1.] 0.61 1.82
|
||||
24 [1.] 0.43 1.82
|
||||
25 [1.] 0.98 1.82
|
||||
26 [1.] 0.49 1.82
|
||||
27 [1.] 0.92 1.82
|
||||
28 [1.] 0.91 1.82
|
||||
29 [0.] 0.41 1.82
|
||||
30 [1.] 0.55 1.82
|
||||
31 [1.] 0.55 1.82
|
||||
32 [1.] 0.58 1.82
|
||||
33 [1.] 0.39 1.82
|
||||
34 [1.] 0.73 1.82
|
||||
35 [1.] 0.4 1.82
|
||||
36 [1.] 0.22 1.82
|
||||
37 [1.] 0.62 1.82
|
||||
38 [0.] 0.36 1.82
|
||||
39 [0.] 0.31 1.82
|
||||
40 [0.] 0.38 1.82
|
||||
41 [0.] 0.5 1.82
|
||||
42 [1.] 0.84 1.82
|
||||
43 [1.] 0.38 1.82
|
||||
44 [1.] 1.03 1.82
|
||||
45 [1.] 0.3 1.82
|
||||
46 [1.] 0.3 1.82
|
||||
47 [1.] 0.8 1.82
|
||||
48 [0.] 0.67 1.82
|
||||
49 [1.] 0.6 1.82
|
||||
50 [1.] 0.59 1.82
|
||||
51 [1.] 0.66 1.82
|
||||
52 [1.] 0.71 1.82
|
||||
53 [1.] 0.48 1.82
|
||||
54 [0.] 0.25 1.82
|
||||
55 [1.] 0.95 1.82
|
||||
56 [1.] 0.33 1.82
|
||||
57 [1.] 0.6 1.82
|
||||
58 [1.] 0.6 1.82
|
||||
59 [1.] 0.71 1.82
|
||||
60 [1.] 0.39 1.82
|
||||
61 [0.] 0.33 1.82
|
||||
62 [0.] 0.57 1.82
|
||||
63 [0.] 0.93 1.82
|
||||
64 [0.] 0.78 1.82
|
||||
65 [0.] 0.4 1.82
|
||||
66 [1.] 0.44 1.82
|
||||
67 [1.] 0.71 1.82
|
||||
68 [1.] 0.57 1.82
|
||||
69 [1.] 0.32 1.82
|
||||
70 [1.] 0.27 1.82
|
||||
71 [1.] 0.47 1.82
|
||||
72 [1.] 0.62 1.82
|
||||
73 [1.] 0.46 1.82
|
||||
74 [1.] 0.61 1.82
|
||||
75 [1.] 1.2 1.82
|
||||
76 [1.] 0.38 1.82
|
||||
77 [1.] 1.46 1.82
|
||||
78 [1.] 0.58 1.82
|
||||
79 [1.] 0.92 1.82
|
||||
80 [1.] 0.51 1.82
|
||||
81 [1.] 0.9 1.82
|
||||
82 [1.] 0.99 1.82
|
||||
83 [1.] 0.56 1.82
|
||||
84 [1.] 0.55 1.82
|
||||
85 [1.] 0.58 1.82
|
||||
86 [1.] 0.76 1.82
|
||||
87 [1.] 0.65 1.82
|
||||
88 [1.] 0.34 1.82
|
||||
89 [1.] 0.98 1.82
|
||||
90 [1.] 0.52 1.82
|
||||
91 [1.] 0.22 1.82
|
||||
92 [1.] 0.57 1.82
|
||||
93 [1.] 0.46 1.82
|
||||
94 [1.] 0.29 1.82
|
||||
95 [1.] 0.37 1.82
|
||||
96 [1.] 0.38 1.82
|
||||
97 [1.] 0.51 1.82
|
||||
98 [1.] 0.54 1.82
|
||||
99 [1.] 0.61 1.82
|
||||
100 [1.] 0.47 1.82
|
||||
101 [1.] 0.57 1.82
|
||||
102 [1.] 0.48 1.82
|
||||
103 [1.] 0.46 1.82
|
||||
104 [1.] 0.45 1.82
|
||||
105 [1.] 0.43 1.82
|
||||
106 [1.] 0.19 1.82
|
||||
107 [1.] 0.24 1.82
|
||||
108 [1.] 0.71 1.82
|
||||
Обнаружено 97.0 аномалий
|
||||
```
|
||||
|
||||
Для AE3_v1 точность составляет 92%
|
||||
|
||||
```python
|
||||
# тестирование АE2
|
||||
lib.anomaly_detection_ae(predicted_labels3_v2, IRE3_v2, IREth3_v2)
|
||||
```
|
||||
|
||||
```output
|
||||
|
||||
i Labels IRE IREth
|
||||
0 [1.] 0.37 1.15
|
||||
1 [1.] 0.43 1.15
|
||||
2 [1.] 0.36 1.15
|
||||
3 [1.] 0.57 1.15
|
||||
4 [1.] 1.03 1.15
|
||||
5 [1.] 0.37 1.15
|
||||
6 [1.] 0.56 1.15
|
||||
7 [1.] 0.6 1.15
|
||||
8 [1.] 0.5 1.15
|
||||
9 [1.] 0.5 1.15
|
||||
10 [1.] 0.28 1.15
|
||||
11 [1.] 0.57 1.15
|
||||
12 [1.] 0.69 1.15
|
||||
13 [1.] 0.54 1.15
|
||||
14 [1.] 0.89 1.15
|
||||
15 [1.] 0.48 1.15
|
||||
16 [1.] 0.4 1.15
|
||||
17 [1.] 0.48 1.15
|
||||
18 [1.] 0.37 1.15
|
||||
19 [1.] 0.18 1.15
|
||||
20 [1.] 0.48 1.15
|
||||
21 [1.] 0.31 1.15
|
||||
22 [1.] 0.39 1.15
|
||||
23 [1.] 0.52 1.15
|
||||
24 [1.] 0.35 1.15
|
||||
25 [1.] 0.62 1.15
|
||||
26 [1.] 0.28 1.15
|
||||
27 [1.] 0.44 1.15
|
||||
28 [1.] 0.53 1.15
|
||||
29 [0.] 0.38 1.15
|
||||
30 [1.] 0.24 1.15
|
||||
31 [1.] 0.6 1.15
|
||||
32 [1.] 0.25 1.15
|
||||
33 [1.] 0.18 1.15
|
||||
34 [1.] 0.47 1.15
|
||||
35 [1.] 0.25 1.15
|
||||
36 [1.] 0.13 1.15
|
||||
37 [1.] 0.38 1.15
|
||||
38 [0.] 0.21 1.15
|
||||
39 [0.] 0.21 1.15
|
||||
40 [0.] 0.28 1.15
|
||||
41 [1.] 0.51 1.15
|
||||
42 [1.] 0.67 1.15
|
||||
43 [1.] 0.2 1.15
|
||||
44 [1.] 0.67 1.15
|
||||
45 [1.] 0.31 1.15
|
||||
46 [1.] 0.31 1.15
|
||||
47 [1.] 0.25 1.15
|
||||
48 [1.] 0.25 1.15
|
||||
49 [1.] 0.29 1.15
|
||||
50 [1.] 0.28 1.15
|
||||
51 [1.] 0.31 1.15
|
||||
52 [1.] 0.41 1.15
|
||||
53 [1.] 0.35 1.15
|
||||
54 [0.] 0.19 1.15
|
||||
55 [1.] 0.43 1.15
|
||||
56 [1.] 0.25 1.15
|
||||
57 [1.] 0.52 1.15
|
||||
58 [1.] 0.61 1.15
|
||||
59 [1.] 0.49 1.15
|
||||
60 [1.] 0.39 1.15
|
||||
61 [0.] 0.31 1.15
|
||||
62 [0.] 0.42 1.15
|
||||
63 [0.] 0.47 1.15
|
||||
64 [0.] 0.57 1.15
|
||||
65 [0.] 0.21 1.15
|
||||
66 [1.] 0.37 1.15
|
||||
67 [1.] 0.58 1.15
|
||||
68 [1.] 0.19 1.15
|
||||
69 [1.] 0.34 1.15
|
||||
70 [1.] 0.18 1.15
|
||||
71 [1.] 0.26 1.15
|
||||
72 [1.] 0.3 1.15
|
||||
73 [1.] 0.3 1.15
|
||||
74 [1.] 0.51 1.15
|
||||
75 [1.] 0.51 1.15
|
||||
76 [1.] 0.22 1.15
|
||||
77 [1.] 1.05 1.15
|
||||
78 [1.] 0.36 1.15
|
||||
79 [1.] 0.81 1.15
|
||||
80 [1.] 0.38 1.15
|
||||
81 [1.] 0.56 1.15
|
||||
82 [1.] 0.55 1.15
|
||||
83 [1.] 0.3 1.15
|
||||
84 [1.] 0.44 1.15
|
||||
85 [1.] 0.37 1.15
|
||||
86 [1.] 0.43 1.15
|
||||
87 [1.] 0.39 1.15
|
||||
88 [1.] 0.27 1.15
|
||||
89 [1.] 0.74 1.15
|
||||
90 [1.] 0.44 1.15
|
||||
91 [1.] 0.2 1.15
|
||||
92 [1.] 0.45 1.15
|
||||
93 [1.] 0.24 1.15
|
||||
94 [1.] 0.25 1.15
|
||||
95 [1.] 0.41 1.15
|
||||
96 [1.] 0.43 1.15
|
||||
97 [1.] 0.35 1.15
|
||||
98 [1.] 0.41 1.15
|
||||
99 [1.] 0.42 1.15
|
||||
100 [1.] 0.5 1.15
|
||||
101 [1.] 0.42 1.15
|
||||
102 [1.] 0.47 1.15
|
||||
103 [1.] 0.49 1.15
|
||||
104 [1.] 0.29 1.15
|
||||
105 [1.] 0.14 1.15
|
||||
106 [1.] 0.16 1.15
|
||||
107 [1.] 0.13 1.15
|
||||
108 [1.] 0.73 1.15
|
||||
Обнаружено 99.0 аномалий
|
||||
```
|
||||
|
||||
Для AE3_v2 точность составляет 92%
|
||||
|
||||
### 9) Если результаты обнаружения аномалий не удовлетворительные (обнаружено менее 70% аномалий), то подобрать подходящие параметры автокодировщика и повторить шаги (4) – (9)
|
||||
|
||||
Результаты обнаружения аномалий удовлетворены.
|
||||
|
||||
### 10) Параметры наилучшего автокодировщика и результаты обнаружения аномалий занести в таблицу:
|
||||
Табл. 2 Результаты задания №2
|
||||
|
||||
| Dataset name | Количество<br>скрытых слоев | Количество<br>нейронов в скрытых слоях | Количество<br>эпох обучения | Ошибка<br>MSE_stop | Порог ошибки<br>реконструкции | % обнаруженных<br>аномалий |
|
||||
|:-------------|:-----------------------------|:----------------------------------------|:-----------------------------|:-------------------|:-------------------------------|:---------------------------|
|
||||
| Cardio | 11 | 48, 36, 28, 22, 16, 10, 16, 22, 28, 36, 48 | 100000 | 0.0077 | 1 | 99% |
|
||||
|
||||
### 11) Сделать выводы о требованиях к:
|
||||
- данным для обучения,
|
||||
- архитектуре автокодировщика,
|
||||
- количеству эпох обучения,
|
||||
- ошибке MSE_stop, приемлемой для останова обучения,
|
||||
- ошибке реконструкции обучающей выборки (порогу обнаружения
|
||||
аномалий)
|
||||
|
||||
для качественного обнаружения аномалий в случае, когда размерность
|
||||
пространства признаков высока.
|
||||
|
||||
1) Данные для обучения должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение
|
||||
2) Архитектура автокодировщика должна постепенно сужатся к бутылочному горлышку,а затем постепенно возвращатся к исходным выходным размерам, кол-во скрытых слоев 7-11.
|
||||
3) В рамках данного набора данных оптимальное кол-во эпох 100000 с patience 4000 эпох
|
||||
4) Оптимальная ошибка MSE-stop в районе 0.001, желательно не меньше для предотвращения переобучения
|
||||
5) Значение порога 1 - идеальное
|
||||
9
labworks/LW3/README.md
Обычный файл
@@ -0,0 +1,9 @@
|
||||
## Лабораторныа работа №3
|
||||
|
||||
## Распознавание изображений
|
||||
|
||||
* [Задание](IS_Lab03_2023.pdf)
|
||||
|
||||
* [Методические указания](IS_Lab03_Metod_2023.pdf)
|
||||
|
||||
* <a href="https://youtube.com/playlist?list=PLZDCDMGmelH-pHt-Ij0nImVrOmj8DYKbB" target="_blank">Плейлист с видео о сверточных сетях</a>
|
||||
Двоичные данные
labworks/LW3/images/1.png
|
До Ширина: | Высота: | Размер: 6.9 KiB |
Двоичные данные
labworks/LW3/images/2.png
|
До Ширина: | Высота: | Размер: 6.6 KiB |
Двоичные данные
labworks/LW3/images/3.png
|
До Ширина: | Высота: | Размер: 32 KiB |
Двоичные данные
labworks/LW3/images/4.png
|
До Ширина: | Высота: | Размер: 122 KiB |
Двоичные данные
labworks/LW3/images/5.png
|
До Ширина: | Высота: | Размер: 12 KiB |
Двоичные данные
labworks/LW3/images/6.png
|
До Ширина: | Высота: | Размер: 12 KiB |
Двоичные данные
labworks/LW3/images/7.png
|
До Ширина: | Высота: | Размер: 69 KiB |
Двоичные данные
labworks/LW3/images/8.png
|
До Ширина: | Высота: | Размер: 6.3 KiB |
Двоичные данные
labworks/LW3/images/9.png
|
До Ширина: | Высота: | Размер: 7.6 KiB |
@@ -1,717 +0,0 @@
|
||||
{
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": [],
|
||||
"gpuType": "T4"
|
||||
},
|
||||
"kernelspec": {
|
||||
"name": "python3",
|
||||
"display_name": "Python 3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
},
|
||||
"accelerator": "GPU"
|
||||
},
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Задание 1"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "oZs0KGcz01BY"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "gz18QPRz03Ec"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# импорт модулей\n",
|
||||
"import os\n",
|
||||
"os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab3')\n",
|
||||
"\n",
|
||||
"from tensorflow import keras\n",
|
||||
"from tensorflow.keras import layers\n",
|
||||
"from tensorflow.keras.models import Sequential\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import numpy as np\n",
|
||||
"from sklearn.metrics import classification_report, confusion_matrix\n",
|
||||
"from sklearn.metrics import ConfusionMatrixDisplay"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "mr9IszuQ1ANG"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 2) Загрузили набор данных MNIST, содержащий размеченные изображения рукописных цифр. "
|
||||
],
|
||||
"metadata": {
|
||||
"id": "FFRtE0TN1AiA"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# загрузка датасета\n",
|
||||
"from keras.datasets import mnist\n",
|
||||
"(X_train, y_train), (X_test, y_test) = mnist.load_data()"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "Ixw5Sp0_1A-w"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 3) Разбили набор данных на обучающие и тестовые данные в соотношении 60 000:10 000 элементов. Параметр random_state выбрали равным (4k – 1)=23, где k=6 –номер бригады. Вывели размерности полученных обучающих и тестовых массивов данных."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "aCo_lUXl1BPV"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# создание своего разбиения датасета\n",
|
||||
"from sklearn.model_selection import train_test_split\n",
|
||||
"\n",
|
||||
"# объединяем в один набор\n",
|
||||
"X = np.concatenate((X_train, X_test))\n",
|
||||
"y = np.concatenate((y_train, y_test))\n",
|
||||
"\n",
|
||||
"# разбиваем по вариантам\n",
|
||||
"X_train, X_test, y_train, y_test = train_test_split(X, y,\n",
|
||||
" test_size = 10000,\n",
|
||||
" train_size = 60000,\n",
|
||||
" random_state = 23)\n",
|
||||
"# вывод размерностей\n",
|
||||
"print('Shape of X train:', X_train.shape)\n",
|
||||
"print('Shape of y train:', y_train.shape)\n",
|
||||
"print('Shape of X test:', X_test.shape)\n",
|
||||
"print('Shape of y test:', y_test.shape)"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "BrSjcpEe1BeV"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 4) Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения сверточной нейронной сети. Входные данные принимают значения от 0 до 1, метки цифр закодированы по принципу «one-hot encoding». Вывели размерности предобработанных обучающих и тестовых массивов данных."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "4hclnNaD1BuB"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# Зададим параметры данных и модели\n",
|
||||
"num_classes = 10\n",
|
||||
"input_shape = (28, 28, 1)\n",
|
||||
"\n",
|
||||
"# Приведение входных данных к диапазону [0, 1]\n",
|
||||
"X_train = X_train / 255\n",
|
||||
"X_test = X_test / 255\n",
|
||||
"\n",
|
||||
"# Расширяем размерность входных данных, чтобы каждое изображение имело\n",
|
||||
"# размерность (высота, ширина, количество каналов)\n",
|
||||
"\n",
|
||||
"X_train = np.expand_dims(X_train, -1)\n",
|
||||
"X_test = np.expand_dims(X_test, -1)\n",
|
||||
"print('Shape of transformed X train:', X_train.shape)\n",
|
||||
"print('Shape of transformed X test:', X_test.shape)\n",
|
||||
"\n",
|
||||
"# переведем метки в one-hot\n",
|
||||
"y_train = keras.utils.to_categorical(y_train, num_classes)\n",
|
||||
"y_test = keras.utils.to_categorical(y_test, num_classes)\n",
|
||||
"print('Shape of transformed y train:', y_train.shape)\n",
|
||||
"print('Shape of transformed y test:', y_test.shape)"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "xJH87ISq1B9h"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 5) Реализовали модель сверточной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "7x99O8ig1CLh"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# создаем модель\n",
|
||||
"model = Sequential()\n",
|
||||
"model.add(layers.Conv2D(32, kernel_size=(3, 3), activation=\"relu\", input_shape=input_shape))\n",
|
||||
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
|
||||
"model.add(layers.Conv2D(64, kernel_size=(3, 3), activation=\"relu\"))\n",
|
||||
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
|
||||
"model.add(layers.Dropout(0.5))\n",
|
||||
"model.add(layers.Flatten())\n",
|
||||
"model.add(layers.Dense(num_classes, activation=\"softmax\"))\n",
|
||||
"\n",
|
||||
"model.summary()"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "Un561zSH1Cmv"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# компилируем и обучаем модель\n",
|
||||
"batch_size = 512\n",
|
||||
"epochs = 15\n",
|
||||
"model.compile(loss=\"categorical_crossentropy\", optimizer=\"adam\", metrics=[\"accuracy\"])\n",
|
||||
"model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "q_h8PxkN9m0v"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 6) Оценили качество обучения на тестовых данных. Вывели значение функции ошибки и значение метрики качества классификации на тестовых данных."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "HL2_LVga1C3l"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# Оценка качества работы модели на тестовых данных\n",
|
||||
"scores = model.evaluate(X_test, y_test)\n",
|
||||
"print('Loss on test data:', scores[0])\n",
|
||||
"print('Accuracy on test data:', scores[1])"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "81Cgq8dn9uL6"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 7) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "KzrVY1SR1DZh"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# вывод двух тестовых изображений и результатов распознавания\n",
|
||||
"\n",
|
||||
"for n in [11,43]:\n",
|
||||
" result = model.predict(X_test[n:n+1])\n",
|
||||
" print('NN output:', result)\n",
|
||||
"\n",
|
||||
" plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))\n",
|
||||
" plt.show()\n",
|
||||
" print('Real mark: ', np.argmax(y_test[n]))\n",
|
||||
" print('NN answer: ', np.argmax(result))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "dbfkWjDI1Dp7"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 8) Вывели отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "YgiVGr5_1D3u"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# истинные метки классов\n",
|
||||
"true_labels = np.argmax(y_test, axis=1)\n",
|
||||
"# предсказанные метки классов\n",
|
||||
"predicted_labels = np.argmax(model.predict(X_test), axis=1)\n",
|
||||
"\n",
|
||||
"# отчет о качестве классификации\n",
|
||||
"print(classification_report(true_labels, predicted_labels))\n",
|
||||
"# вычисление матрицы ошибок\n",
|
||||
"conf_matrix = confusion_matrix(true_labels, predicted_labels)\n",
|
||||
"# отрисовка матрицы ошибок в виде \"тепловой карты\"\n",
|
||||
"display = ConfusionMatrixDisplay(confusion_matrix=conf_matrix)\n",
|
||||
"display.plot()\n",
|
||||
"plt.show()"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "7MqcG_wl1EHI"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 9) Загрузили, предобработали и подали на вход обученной нейронной сети собственное изображение, созданное при выполнении лабораторной работы №1. Вывели изображение и результат распознавания."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "amaspXGW1EVy"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# загрузка собственного изображения\n",
|
||||
"from PIL import Image\n",
|
||||
"\n",
|
||||
"for name_image in ['190 (2).png', '690 (1).png']:\n",
|
||||
" file_data = Image.open(name_image)\n",
|
||||
" file_data = file_data.convert('L') # перевод в градации серого\n",
|
||||
" test_img = np.array(file_data)\n",
|
||||
"\n",
|
||||
" # вывод собственного изображения\n",
|
||||
" plt.imshow(test_img, cmap=plt.get_cmap('gray'))\n",
|
||||
" plt.show()\n",
|
||||
"\n",
|
||||
" # предобработка\n",
|
||||
" test_img = test_img / 255\n",
|
||||
" test_img = np.reshape(test_img, (1,28,28,1))\n",
|
||||
"\n",
|
||||
" # распознавание\n",
|
||||
" result = model.predict(test_img)\n",
|
||||
" print('I think it\\'s', np.argmax(result))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "ktWEeqWd1EyF"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 10) Загрузили с диска модель, сохраненную при выполнении лабораторной работы №1. Вывели информацию об архитектуре модели. Повторили для этой модели п. 6."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "mgrihPd61E8w"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"model_lr1 = keras.models.load_model(\"best_model.keras\")\n",
|
||||
"\n",
|
||||
"model_lr1.summary()"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "DblXqn3l1FL2"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# развернем каждое изображение 28*28 в вектор 784\n",
|
||||
"X_train, X_test, y_train, y_test = train_test_split(X, y,\n",
|
||||
" test_size = 10000,\n",
|
||||
" train_size = 60000,\n",
|
||||
" random_state = 23)\n",
|
||||
"num_pixels = X_train.shape[1] * X_train.shape[2]\n",
|
||||
"X_train = X_train.reshape(X_train.shape[0], num_pixels) / 255\n",
|
||||
"X_test = X_test.reshape(X_test.shape[0], num_pixels) / 255\n",
|
||||
"print('Shape of transformed X train:', X_train.shape)\n",
|
||||
"print('Shape of transformed X train:', X_test.shape)\n",
|
||||
"\n",
|
||||
"# переведем метки в one-hot\n",
|
||||
"y_train = keras.utils.to_categorical(y_train, num_classes)\n",
|
||||
"y_test = keras.utils.to_categorical(y_test, num_classes)\n",
|
||||
"print('Shape of transformed y train:', y_train.shape)\n",
|
||||
"print('Shape of transformed y test:', y_test.shape)"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "0ki8fhJrEyEt"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# Оценка качества работы модели на тестовых данных\n",
|
||||
"scores = model_lr1.evaluate(X_test, y_test)\n",
|
||||
"print('Loss on test data:', scores[0])\n",
|
||||
"print('Accuracy on test data:', scores[1])"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "0Yj0fzLNE12k"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 11) Сравнили обученную модель сверточной сети и наилучшую модель полносвязной сети из лабораторной работы №1 по следующим показателям:\n",
|
||||
"### - количество настраиваемых параметров в сети\n",
|
||||
"### - количество эпох обучения\n",
|
||||
"### - качество классификации тестовой выборки.\n",
|
||||
"### Сделали выводы по результатам применения сверточной нейронной сети для распознавания изображений. "
|
||||
],
|
||||
"metadata": {
|
||||
"id": "MsM3ew3d1FYq"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"Таблица1:"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "xxFO4CXbIG88"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |\n",
|
||||
"|----------|-------------------------------------|---------------------------|-----------------------------------------|\n",
|
||||
"| Сверточная | 34 826 | 15 | accuracy:0.987 ; loss:0.037 |\n",
|
||||
"| Полносвязная | 79512 | 50 | accuracy:0.946 ; loss:0.185 |\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "xvoivjuNFlEf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"По результатам применения сверточной НС, а также по результатам таблицы 1 делаем выводы, что сверточная НС намного лучше справляется с задачами распознования изображений, чем полносвязная - имеет меньше настраиваемых параметров, быстрее обучается, имеет лучшие показатели качества."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "YctF8h_sIB-P"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Задание 2"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "wCLHZPGB1F1y"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### В новом блокноте выполнили п. 2–8 задания 1, изменив набор данных MNIST на CIFAR-10, содержащий размеченные цветные изображения объектов, разделенные на 10 классов. \n",
|
||||
"### При этом:\n",
|
||||
"### - в п. 3 разбиение данных на обучающие и тестовые произвели в соотношении 50 000:10 000\n",
|
||||
"### - после разбиения данных (между п. 3 и 4) вывели 25 изображений из обучающей выборки с подписями классов\n",
|
||||
"### - в п. 7 одно из тестовых изображений должно распознаваться корректно, а другое – ошибочно. "
|
||||
],
|
||||
"metadata": {
|
||||
"id": "DUOYls124TT8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 1) Загрузили набор данных CIFAR-10, содержащий цветные изображения размеченные на 10 классов: самолет, автомобиль, птица, кошка, олень, собака, лягушка, лошадь, корабль, грузовик."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "XDStuSpEJa8o"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# загрузка датасета\n",
|
||||
"from keras.datasets import cifar10\n",
|
||||
"\n",
|
||||
"(X_train, y_train), (X_test, y_test) = cifar10.load_data()"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "y0qK7eKL4Tjy"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 2) Разбили набор данных на обучающие и тестовые данные в соотношении 50 000:10 000 элементов. Параметр random_state выбрали равным (4k – 1)=23, где k=6 –номер бригады. Вывели размерности полученных обучающих и тестовых массивов данных."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "wTHiBy-ZJ5oh"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# создание своего разбиения датасета\n",
|
||||
"\n",
|
||||
"# объединяем в один набор\n",
|
||||
"X = np.concatenate((X_train, X_test))\n",
|
||||
"y = np.concatenate((y_train, y_test))\n",
|
||||
"\n",
|
||||
"# разбиваем по вариантам\n",
|
||||
"X_train, X_test, y_train, y_test = train_test_split(X, y,\n",
|
||||
" test_size = 10000,\n",
|
||||
" train_size = 50000,\n",
|
||||
" random_state = 23)\n",
|
||||
"# вывод размерностей\n",
|
||||
"print('Shape of X train:', X_train.shape)\n",
|
||||
"print('Shape of y train:', y_train.shape)\n",
|
||||
"print('Shape of X test:', X_test.shape)\n",
|
||||
"print('Shape of y test:', y_test.shape)"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "DlnFbQogKD2v"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Вывели 25 изображений из обучающей выборки с подписью классов."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "pj3bMaz1KZ3a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',\n",
|
||||
" 'dog', 'frog', 'horse', 'ship', 'truck']\n",
|
||||
"\n",
|
||||
"plt.figure(figsize=(10,10))\n",
|
||||
"for i in range(25):\n",
|
||||
" plt.subplot(5,5,i+1)\n",
|
||||
" plt.xticks([])\n",
|
||||
" plt.yticks([])\n",
|
||||
" plt.grid(False)\n",
|
||||
" plt.imshow(X_train[i])\n",
|
||||
" plt.xlabel(class_names[y_train[i][0]])\n",
|
||||
"plt.show()"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "TW8D67KEKhVE"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 3) Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения сверточной нейронной сети. Входные данные принимают значения от 0 до 1, метки цифр закодированы по принципу «one-hot encoding». Вывели размерности предобработанных обучающих и тестовых массивов данных."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "d3TPr2w1KQTK"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# Зададим параметры данных и модели\n",
|
||||
"num_classes = 10\n",
|
||||
"input_shape = (32, 32, 3)\n",
|
||||
"\n",
|
||||
"# Приведение входных данных к диапазону [0, 1]\n",
|
||||
"X_train = X_train / 255\n",
|
||||
"X_test = X_test / 255\n",
|
||||
"\n",
|
||||
"print('Shape of transformed X train:', X_train.shape)\n",
|
||||
"print('Shape of transformed X test:', X_test.shape)\n",
|
||||
"\n",
|
||||
"# переведем метки в one-hot\n",
|
||||
"y_train = keras.utils.to_categorical(y_train, num_classes)\n",
|
||||
"y_test = keras.utils.to_categorical(y_test, num_classes)\n",
|
||||
"print('Shape of transformed y train:', y_train.shape)\n",
|
||||
"print('Shape of transformed y test:', y_test.shape)"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "iFDpxEauLZ8j"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 4) Реализовали модель сверточной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "ydNITXptLeGT"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# создаем модель\n",
|
||||
"model = Sequential()\n",
|
||||
"model.add(layers.Conv2D(32, kernel_size=(3, 3), activation=\"relu\", input_shape=input_shape))\n",
|
||||
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
|
||||
"model.add(layers.Conv2D(64, kernel_size=(3, 3), activation=\"relu\"))\n",
|
||||
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
|
||||
"model.add(layers.Conv2D(128, kernel_size=(3, 3), activation=\"relu\"))\n",
|
||||
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
|
||||
"model.add(layers.Flatten())\n",
|
||||
"model.add(layers.Dense(128, activation='relu'))\n",
|
||||
"model.add(layers.Dropout(0.5))\n",
|
||||
"model.add(layers.Dense(num_classes, activation=\"softmax\"))\n",
|
||||
"model.summary()"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "YhAD5CllLlv7"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# компилируем и обучаем модель\n",
|
||||
"batch_size = 64\n",
|
||||
"epochs = 50\n",
|
||||
"model.compile(loss=\"categorical_crossentropy\", optimizer=\"adam\", metrics=[\"accuracy\"])\n",
|
||||
"model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "3otvqMjjOdq5"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 5) Оценили качество обучения на тестовых данных. Вывели значение функции ошибки и значение метрики качества классификации на тестовых данных."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "Vv1kUHWTLl9B"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# Оценка качества работы модели на тестовых данных\n",
|
||||
"scores = model.evaluate(X_test, y_test)\n",
|
||||
"print('Loss on test data:', scores[0])\n",
|
||||
"print('Accuracy on test data:', scores[1])"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "SaDxydiyLmRX"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 6) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "OdgEiyUGLmhP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# вывод двух тестовых изображений и результатов распознавания\n",
|
||||
"\n",
|
||||
"for n in [3,16]:\n",
|
||||
" result = model.predict(X_test[n:n+1])\n",
|
||||
" print('NN output:', result)\n",
|
||||
"\n",
|
||||
" plt.imshow(X_test[n].reshape(32,32,3), cmap=plt.get_cmap('gray'))\n",
|
||||
" plt.show()\n",
|
||||
" print('Real mark: ', np.argmax(y_test[n]))\n",
|
||||
" print('NN answer: ', np.argmax(result))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "t3yGj1MlLm9H"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 7) Вывели отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "3h6VGDRrLnNC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# истинные метки классов\n",
|
||||
"true_labels = np.argmax(y_test, axis=1)\n",
|
||||
"# предсказанные метки классов\n",
|
||||
"predicted_labels = np.argmax(model.predict(X_test), axis=1)\n",
|
||||
"\n",
|
||||
"# отчет о качестве классификации\n",
|
||||
"print(classification_report(true_labels, predicted_labels, target_names=class_names))\n",
|
||||
"# вычисление матрицы ошибок\n",
|
||||
"conf_matrix = confusion_matrix(true_labels, predicted_labels)\n",
|
||||
"# отрисовка матрицы ошибок в виде \"тепловой карты\"\n",
|
||||
"fig, ax = plt.subplots(figsize=(6, 6))\n",
|
||||
"disp = ConfusionMatrixDisplay(confusion_matrix=conf_matrix,display_labels=class_names)\n",
|
||||
"disp.plot(ax=ax, xticks_rotation=45) # поворот подписей по X и приятная палитра\n",
|
||||
"plt.tight_layout() # чтобы всё влезло\n",
|
||||
"plt.show()"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "od56oyyzM0nw"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"По результатам классификации датасета CIFAR-10 сверточной моделью делаем вывод, что она удовлетворительно справилась с задачей. Полученные метрики оценки качества имеют показатели в районе 0.71."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "RF4xK1cxamBc"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,530 +0,0 @@
|
||||
# Отчёт по лабораторной работе №3
|
||||
|
||||
**Касимов Азамат, Немыкин Никита — А-01-22**
|
||||
|
||||
---
|
||||
## Задание 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)=23, где k=6 –номер бригады. Вывели размерности полученных обучающих и тестовых массивов данных.
|
||||
|
||||
```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()
|
||||
```
|
||||
**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 ━━━━━━━━━━━━━━━━━━━━ 3s 9ms/step - accuracy: 0.9891 - loss: 0.0327
|
||||
Loss on test data: 0.03766785189509392
|
||||
Accuracy on test data: 0.9879000186920166
|
||||
```
|
||||
|
||||
### 7) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания.
|
||||
|
||||
```python
|
||||
# вывод двух тестовых изображений и результатов распознавания
|
||||
|
||||
for n in [11,43]:
|
||||
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 ━━━━━━━━━━━━━━━━━━━━ 2s 5ms/step
|
||||
precision recall f1-score support
|
||||
|
||||
0 1.00 0.99 0.99 997
|
||||
1 1.00 0.99 1.00 1164
|
||||
2 0.99 0.98 0.98 1030
|
||||
3 1.00 0.98 0.99 1031
|
||||
4 0.99 0.99 0.99 967
|
||||
5 0.97 0.99 0.98 860
|
||||
6 0.99 0.99 0.99 977
|
||||
7 0.99 0.99 0.99 1072
|
||||
8 0.98 0.98 0.98 939
|
||||
9 0.99 0.98 0.99 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 ['190 (2).png', '690 (1).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 1
|
||||
```
|
||||

|
||||
```
|
||||
I think it's 6
|
||||
```
|
||||
|
||||
### 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_1 (Dense) | (None, 100) | 78,500 |
|
||||
| dense_2 (Dense) | (None, 10) | 1,010 |
|
||||
Total params: 79,512 (310.60 KB)
|
||||
Trainable params: 79,510 (310.59 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 = 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 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.9490 - loss: 0.1739
|
||||
Loss on test data: 0.18475718796253204
|
||||
Accuracy on test data: 0.9458000063896179
|
||||
```
|
||||
|
||||
### 11) Сравнили обученную модель сверточной сети и наилучшую модель полносвязной сети из лабораторной работы №1 по следующим показателям:
|
||||
### - количество настраиваемых параметров в сети
|
||||
### - количество эпох обучения
|
||||
### - качество классификации тестовой выборки.
|
||||
### Сделали выводы по результатам применения сверточной нейронной сети для распознавания изображений.
|
||||
|
||||
Таблица1:
|
||||
|
||||
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|
||||
|----------|-------------------------------------|---------------------------|-----------------------------------------|
|
||||
| Сверточная | 34 826 | 15 | accuracy:0.987 ; loss:0.037 |
|
||||
| Полносвязная | 79512 | 50 | accuracy:0.946 ; loss:0.185 |
|
||||
|
||||
|
||||
##### По результатам применения сверточной НС, а также по результатам таблицы 1 делаем выводы, что сверточная НС намного лучше справляется с задачами распознования изображений, чем полносвязная - имеет меньше настраиваемых параметров, быстрее обучается, имеет лучшие показатели качества.
|
||||
|
||||
## Задание 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 = 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)
|
||||
```
|
||||
|
||||
### Вывели 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()
|
||||
```
|
||||

|
||||
|
||||
### 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()
|
||||
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.Conv2D(128, kernel_size=(3, 3), activation="relu"))
|
||||
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
|
||||
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_1"
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
│ conv2d_2 (Conv2D) │ (None, 30, 30, 32) │ 896 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ max_pooling2d_2 (MaxPooling2D) │ (None, 15, 15, 32) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ conv2d_3 (Conv2D) │ (None, 13, 13, 64) │ 18,496 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ max_pooling2d_3 (MaxPooling2D) │ (None, 6, 6, 64) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ conv2d_4 (Conv2D) │ (None, 4, 4, 128) │ 73,856 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ max_pooling2d_4 (MaxPooling2D) │ (None, 2, 2, 128) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ flatten_1 (Flatten) │ (None, 512) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense_1 (Dense) │ (None, 128) │ 65,664 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dropout_1 (Dropout) │ (None, 128) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense_2 (Dense) │ (None, 10) │ 1,290 │
|
||||
└─────────────────────────────────┴────────────────────────┴───────────────┘
|
||||
Total params: 160,202 (625.79 KB)
|
||||
Trainable params: 160,202 (625.79 KB)
|
||||
Non-trainable params: 0 (0.00 B)
|
||||
|
||||
```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 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step - accuracy: 0.7087 - loss: 1.3107
|
||||
Loss on test data: 1.2974315881729126
|
||||
Accuracy on test data: 0.7123000025749207
|
||||
```
|
||||
|
||||
### 6) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания.
|
||||
|
||||
```python
|
||||
# вывод двух тестовых изображений и результатов распознавания
|
||||
|
||||
for n in [3,16]:
|
||||
result = model.predict(X_test[n:n+1])
|
||||
print('NN output:', result)
|
||||
|
||||
plt.imshow(X_test[n].reshape(32,32,3), cmap=plt.get_cmap('gray'))
|
||||
plt.show()
|
||||
print('Real mark: ', np.argmax(y_test[n]))
|
||||
print('NN answer: ', np.argmax(result))
|
||||
```
|
||||

|
||||
```
|
||||
Real mark: 0
|
||||
NN answer: 0
|
||||
```
|
||||

|
||||
```
|
||||
Real mark: 7
|
||||
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 ━━━━━━━━━━━━━━━━━━━━ 1s 2ms/step
|
||||
precision recall f1-score support
|
||||
|
||||
airplane 0.69 0.76 0.72 986
|
||||
automobile 0.85 0.80 0.82 971
|
||||
bird 0.66 0.60 0.63 1043
|
||||
cat 0.54 0.55 0.55 1037
|
||||
deer 0.66 0.67 0.67 969
|
||||
dog 0.63 0.64 0.63 979
|
||||
frog 0.78 0.78 0.78 1025
|
||||
horse 0.74 0.73 0.74 948
|
||||
ship 0.79 0.82 0.80 1003
|
||||
truck 0.80 0.78 0.79 1039
|
||||
|
||||
accuracy 0.71 10000
|
||||
macro avg 0.71 0.71 0.71 10000
|
||||
weighted avg 0.71 0.71 0.71 10000
|
||||
```
|
||||

|
||||
|
||||
### По результатам классификации датасета CIFAR-10 сверточной моделью делаем вывод, что она удовлетворительно справилась с задачей. Полученные метрики оценки качества имеют показатели в районе 0.71.
|
||||
7
labworks/LW4/README.md
Обычный файл
@@ -0,0 +1,7 @@
|
||||
## Лабораторныа работа №4
|
||||
|
||||
## Распознавание последовательностей
|
||||
|
||||
* [Задание](IS_Lab04_2023.pdf)
|
||||
|
||||
* [Методические указания](IS_Lab04_Metod_2023.pdf)
|
||||
Двоичные данные
labworks/LW4/images/1.png
|
До Ширина: | Высота: | Размер: 21 KiB |
@@ -1,461 +0,0 @@
|
||||
{
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": [],
|
||||
"gpuType": "T4"
|
||||
},
|
||||
"kernelspec": {
|
||||
"name": "python3",
|
||||
"display_name": "Python 3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
},
|
||||
"accelerator": "GPU"
|
||||
},
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули. Настроили блокнот для работы с аппаратным ускорителем GPU."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "gz18QPRz03Ec"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"from google.colab import drive\n",
|
||||
"drive.mount('/content/drive')"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "kn5Tz1FjvRgl"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# импорт модулей\n",
|
||||
"import os\n",
|
||||
"os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab4')\n",
|
||||
"\n",
|
||||
"from tensorflow import keras\n",
|
||||
"from tensorflow.keras import layers\n",
|
||||
"from tensorflow.keras.models import Sequential\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import numpy as np\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "mr9IszuQ1ANG"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"import tensorflow as tf\n",
|
||||
"device_name = tf.test.gpu_device_name()\n",
|
||||
"if device_name != '/device:GPU:0':\n",
|
||||
" raise SystemError('GPU device not found')\n",
|
||||
"print('Found GPU at: {}'.format(device_name))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "o63-lKG_RuNc"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 2) Загрузили набор данных IMDb, содержащий оцифрованные отзывы на фильмы, размеченные на два класса: позитивные и негативные. При загрузке набора данных параметр seed выбрали равным значению (4k – 1)=23, где k=6 – номер бригады. Вывели размеры полученных обучающих и тестовых массивов данных."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "FFRtE0TN1AiA"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# загрузка датасета\n",
|
||||
"from keras.datasets import imdb\n",
|
||||
"\n",
|
||||
"vocabulary_size = 5000\n",
|
||||
"index_from = 3\n",
|
||||
"\n",
|
||||
"(X_train, y_train), (X_test, y_test) = imdb.load_data(\n",
|
||||
" path=\"imdb.npz\",\n",
|
||||
" num_words=vocabulary_size,\n",
|
||||
" skip_top=0,\n",
|
||||
" maxlen=None,\n",
|
||||
" seed=23,\n",
|
||||
" start_char=1,\n",
|
||||
" oov_char=2,\n",
|
||||
" index_from=index_from\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"# вывод размерностей\n",
|
||||
"print('Shape of X train:', X_train.shape)\n",
|
||||
"print('Shape of y train:', y_train.shape)\n",
|
||||
"print('Shape of X test:', X_test.shape)\n",
|
||||
"print('Shape of y test:', y_test.shape)"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "Ixw5Sp0_1A-w"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 3) Вывели один отзыв из обучающего множества в виде списка индексов слов. Преобразовали список индексов в текст и вывели отзыв в виде текста. Вывели длину отзыва. Вывели метку класса данного отзыва и название класса (1 – Positive, 0 – Negative)."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "aCo_lUXl1BPV"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# создание словаря для перевода индексов в слова\n",
|
||||
"# заргузка словаря \"слово:индекс\"\n",
|
||||
"word_to_id = imdb.get_word_index()\n",
|
||||
"# уточнение словаря\n",
|
||||
"word_to_id = {key:(value + index_from) for key,value in word_to_id.items()}\n",
|
||||
"word_to_id[\"<PAD>\"] = 0\n",
|
||||
"word_to_id[\"<START>\"] = 1\n",
|
||||
"word_to_id[\"<UNK>\"] = 2\n",
|
||||
"word_to_id[\"<UNUSED>\"] = 3\n",
|
||||
"# создание обратного словаря \"индекс:слово\"\n",
|
||||
"id_to_word = {value:key for key,value in word_to_id.items()}"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "9W3RklPcZyH0"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"print(X_train[23])\n",
|
||||
"print('len:',len(X_train[23]))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "Nu-Bs1jnaYhB"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"review_as_text = ' '.join(id_to_word[id] for id in X_train[23])\n",
|
||||
"print(review_as_text)\n",
|
||||
"print('len:',len(review_as_text))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "JhTwTurtZ6Sp"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 4) Вывели максимальную и минимальную длину отзыва в обучающем множестве."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "4hclnNaD1BuB"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"print('MAX Len: ',len(max(X_train, key=len)))\n",
|
||||
"print('MIN Len: ',len(min(X_train, key=len)))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "xJH87ISq1B9h"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 5) Провели предобработку данных. Выбрали единую длину, к которой будут приведены все отзывы. Короткие отзывы дополнили спецсимволами, а длинные обрезали до выбранной длины."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "7x99O8ig1CLh"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# предобработка данных\n",
|
||||
"from tensorflow.keras.utils import pad_sequences\n",
|
||||
"max_words = 500\n",
|
||||
"X_train = pad_sequences(X_train, maxlen=max_words, value=0, padding='pre', truncating='post')\n",
|
||||
"X_test = pad_sequences(X_test, maxlen=max_words, value=0, padding='pre', truncating='post')"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "lrF-B2aScR4t"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 6) Повторили пункт 4."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "HL2_LVga1C3l"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"print('MAX Len: ',len(max(X_train, key=len)))\n",
|
||||
"print('MIN Len: ',len(min(X_train, key=len)))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "81Cgq8dn9uL6"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 7) Повторили пункт 3. Сделали вывод о том, как отзыв преобразовался после предобработки."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "KzrVY1SR1DZh"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"print(X_train[23])\n",
|
||||
"print('len:',len(X_train[23]))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "vudlgqoCbjU1"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"review_as_text = ' '.join(id_to_word[id] for id in X_train[23])\n",
|
||||
"print(review_as_text)\n",
|
||||
"print('len:',len(review_as_text))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "dbfkWjDI1Dp7"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"#### После обработки в начало отзыва добавилось необходимое количество токенов <PAD>, чтобы отзыв был длинной в 500 индексов."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "mJNRXo5TdPAE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 8) Вывели предобработанные массивы обучающих и тестовых данных и их размерности."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "YgiVGr5_1D3u"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# вывод данных\n",
|
||||
"print('X train: \\n',X_train)\n",
|
||||
"print('X train: \\n',X_test)\n",
|
||||
"\n",
|
||||
"# вывод размерностей\n",
|
||||
"print('Shape of X train:', X_train.shape)\n",
|
||||
"print('Shape of X test:', X_test.shape)"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "7MqcG_wl1EHI"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 9) Реализовали модель рекуррентной нейронной сети, состоящей из слоев Embedding, LSTM, Dropout, Dense, и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети. Добились качества обучения по метрике accuracy не менее 0.8."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "amaspXGW1EVy"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"embed_dim = 32\n",
|
||||
"lstm_units = 64\n",
|
||||
"\n",
|
||||
"model = Sequential()\n",
|
||||
"model.add(layers.Embedding(input_dim=vocabulary_size, output_dim=embed_dim, input_length=max_words, input_shape=(max_words,)))\n",
|
||||
"model.add(layers.LSTM(lstm_units))\n",
|
||||
"model.add(layers.Dropout(0.5))\n",
|
||||
"model.add(layers.Dense(1, activation='sigmoid'))\n",
|
||||
"\n",
|
||||
"model.summary()"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "ktWEeqWd1EyF"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# компилируем и обучаем модель\n",
|
||||
"batch_size = 64\n",
|
||||
"epochs = 3\n",
|
||||
"model.compile(loss=\"binary_crossentropy\", optimizer=\"adam\", metrics=[\"accuracy\"])\n",
|
||||
"model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.2)"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "CuPqKpX0kQfP"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"test_loss, test_acc = model.evaluate(X_test, y_test)\n",
|
||||
"print(f\"\\nTest accuracy: {test_acc}\")"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "hJIWinxymQjb"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 10) Оценили качество обучения на тестовых данных:\n",
|
||||
"### - вывели значение метрики качества классификации на тестовых данных\n",
|
||||
"### - вывели отчет о качестве классификации тестовой выборки \n",
|
||||
"### - построили ROC-кривую по результату обработки тестовой выборки и вычислили площадь под ROC-кривой (AUC ROC)"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "mgrihPd61E8w"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"#значение метрики качества классификации на тестовых данных\n",
|
||||
"print(f\"\\nTest accuracy: {test_acc}\")"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "Rya5ABT8msha"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"#отчет о качестве классификации тестовой выборки\n",
|
||||
"y_score = model.predict(X_test)\n",
|
||||
"y_pred = [1 if y_score[i,0]>=0.5 else 0 for i in range(len(y_score))]\n",
|
||||
"\n",
|
||||
"from sklearn.metrics import classification_report\n",
|
||||
"print(classification_report(y_test, y_pred, labels = [0, 1], target_names=['Negative', 'Positive']))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "2kHjcmnCmv0Y"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"#построение ROC-кривой и AUC ROC\n",
|
||||
"from sklearn.metrics import roc_curve, auc\n",
|
||||
"\n",
|
||||
"fpr, tpr, thresholds = roc_curve(y_test, y_score)\n",
|
||||
"plt.plot(fpr, tpr)\n",
|
||||
"plt.grid()\n",
|
||||
"plt.xlabel('False Positive Rate')\n",
|
||||
"plt.ylabel('True Positive Rate')\n",
|
||||
"plt.title('ROC')\n",
|
||||
"plt.show()\n",
|
||||
"print('AUC ROC:', auc(fpr, tpr))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "Kp4AQRbcmwAx"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### 11) Сделали выводы по результатам применения рекуррентной нейронной сети для решения задачи определения тональности текста. "
|
||||
],
|
||||
"metadata": {
|
||||
"id": "MsM3ew3d1FYq"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"Таблица1:"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "xxFO4CXbIG88"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |\n",
|
||||
"|----------|-------------------------------------|---------------------------|-----------------------------------------|\n",
|
||||
"| Рекуррентная | 184 897 | 3 | accuracy:0.8389 ; loss:0.3970 ; AUC ROC:0.9009 |\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "xvoivjuNFlEf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"#### По результатам применения рекуррентной нейронной сети можно сделать вывод, что модель хорошо справилась с задачей определения тональности текста. Показатель accuracy = 0.8389, выше порога 0.8. Значение AUC ROC = 0.9009 (> 0.9) говорит о высокой способности модели различать два класса (положительные и отрицательные отзывы)."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "YctF8h_sIB-P"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,333 +0,0 @@
|
||||
# Отчёт по лабораторной работе №4
|
||||
|
||||
**Касимов Азамат, Немыкин Никита — А-01-22**
|
||||
|
||||
---
|
||||
## Задание 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)=23, где k=6 – номер бригады. Вывели размеры полученных обучающих и тестовых массивов данных.
|
||||
|
||||
```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[21])
|
||||
print('len:',len(X_train[21]))
|
||||
```
|
||||
```
|
||||
[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[26])
|
||||
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()
|
||||
```
|
||||
|
||||
**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 ━━━━━━━━━━━━━━━━━━━━ 12s 23ms/step - accuracy: 0.6705 - loss: 0.5794 - val_accuracy: 0.6740 - val_loss: 1.3409
|
||||
Epoch 2/3
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 6s 19ms/step - accuracy: 0.6394 - loss: 0.8250 - val_accuracy: 0.7424 - val_loss: 0.5590
|
||||
Epoch 3/3
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 7s 22ms/step - accuracy: 0.7780 - loss: 0.4830 - val_accuracy: 0.8268 - val_loss: 0.4142
|
||||
<keras.src.callbacks.history.History at 0x784aa347c710>
|
||||
```
|
||||
```python
|
||||
test_loss, test_acc = model.evaluate(X_test, y_test)
|
||||
print(f"\nTest accuracy: {test_acc}")
|
||||
```
|
||||
```
|
||||
782/782 ━━━━━━━━━━━━━━━━━━━━ 7s 8ms/step - accuracy: 0.8389 - loss: 0.3970
|
||||
|
||||
Test accuracy: 0.8352800011634827
|
||||
```
|
||||
|
||||
### 10) Оценили качество обучения на тестовых данных:
|
||||
### - вывели значение метрики качества классификации на тестовых данных
|
||||
### - вывели отчет о качестве классификации тестовой выборки
|
||||
### - построили ROC-кривую по результату обработки тестовой выборки и вычислили площадь под ROC-кривой (AUC ROC)
|
||||
|
||||
```python
|
||||
#значение метрики качества классификации на тестовых данных
|
||||
print(f"\nTest accuracy: {test_acc}")
|
||||
```
|
||||
```
|
||||
Test accuracy: 0.8352800011634827
|
||||
```
|
||||
|
||||
```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.86 0.80 0.83 12500
|
||||
Positive 0.81 0.87 0.84 12500
|
||||
|
||||
accuracy 0.84 25000
|
||||
macro avg 0.84 0.84 0.84 25000
|
||||
weighted avg 0.84 0.84 0.84 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.9009091648
|
||||
```
|
||||
|
||||
### 11) Сделали выводы по результатам применения рекуррентной нейронной сети для решения задачи определения тональности текста.
|
||||
|
||||
Таблица1:
|
||||
|
||||
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|
||||
|----------|-------------------------------------|---------------------------|-----------------------------------------|
|
||||
| Рекуррентная | 184 897 | 3 | accuracy:0.8389 ; loss:0.3970 ; AUC ROC:0.9009 |
|
||||
|
||||
|
||||
#### По результатам применения рекуррентной нейронной сети можно сделать вывод, что модель хорошо справилась с задачей определения тональности текста. Показатель accuracy = 0.8389 превышает требуемый порог 0.8.
|
||||
#### Значение AUC ROC = 0.9009 (> 0.9) - высокая способность модели различать два класса (положительные и отрицательные отзывы).
|
||||