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

...

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

Автор SHA1 Сообщение Дата
DanRie 0afecdbc43 fix: fix Lab4
3 недель назад
DanRie 16441c99ef fix: fix report
3 недель назад
DanRie 9c1d9f27ca LR4 done
3 недель назад
DanRie c7a9f84efe LR3 done
1 месяц назад
DanRie a8217ec15e fix: fix images LR2
2 месяцев назад
DanRie 2b771f3f16 Выполнена ЛР2
2 месяцев назад
DanRie 0cefa2a80b fix: Исправление текста в report.md в lab1
3 месяцев назад
DanRie 8ad9cbda10 fix: Исправление выводов картинок в report.md в lab1
3 месяцев назад
DanRie 96e8cf5799 Добавлен отчет по lab1
3 месяцев назад

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

Двоичные данные
labworks/LW1/model_1h100_2h50.keras

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

@ -0,0 +1,586 @@
# Отчёт по лабораторной работе №1
**Кнзев Станислав, Жихарев Данила — А-02-22**
---
## 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули.
```python
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks')
current_directory = os.getcwd()
print("Текущая директория:", current_directory)
```
**Текущая директория:** `/content/drive/MyDrive/Colab Notebooks`
```python
# импорт модулей
from tensorflow import keras
import matplotlib.pyplot as plt
import numpy as np
import sklearn
```
---
## 2) Загрузили набор данных MNIST, содержащий размеченные изображения рукописных цифр.
```python
# загрузка датасета
from keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()
```
---
## 3) Разбили набор данных на обучающие и тестовые данные в соотношении 60 000:10 000 элементов.
При разбиении параметр `random_state` выбрали равным (4k – 1), где k - номер бригады, k = 6 ⇒ `random_state = 23`.
```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) Вывели первые 4 элемента обучающих данных (изображения и метки цифр).
```python
# вывод изображения
for i in range(4):
plt.imshow(X_train[i], cmap=plt.get_cmap('gray'))
plt.show()
# вывод метки для этого изображения
print(y_train[i])
```
![первый элемент](images/picture1.png)
```
6
```
![второй элемент](images/picture2.png)
```
4
```
![третий элемент](images/picture3.png)
```
4
```
![четвертый элемент](images/picture4.png)
```
3
```
---
## 5) Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения нейронной сети. Входные данные должны принимать значения от 0 до 1, метки цифр должны быть закодированы по принципу «one-hot encoding». Вывели размерности предобработанных обучающих и тестовых массивов данных.
```python
# развернем каждое изображение 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)
```
```python
# переведем метки в 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) Реализовали модель однослойной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети. Вывели график функции ошибки на обучающих и валидационных данных по эпохам.
**Параметры:**
- количество скрытых слоёв: 0
- функция активации выходного слоя: `softmax`
- функция ошибки: `categorical_crossentropy`
- алгоритм обучения: `sgd`
- метрика качества: `accuracy`
- количество эпох: 50
- доля валидационных данных от обучающих: 0.1
```python
from keras.models import Sequential
from keras.layers import Dense
# создаем модель
model_1output = Sequential()
model_1output.add(Dense(units=num_classes, input_dim=num_pixels, activation='softmax'))
# компилируем модель
model_1output.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
# вывод информации об архитектуре модели
print(model_1output.summary())
```
![архитектура модели](images/picture5.png)
```python
# Обучаем модель
H_1output = model_1output.fit(X_train, y_train, validation_split=0.1, epochs=50)
```
```python
# вывод графика ошибки по эпохам
plt.plot(H.history['loss'])
plt.plot(H.history['val_loss'])
plt.grid()
plt.xlabel('Epochs')
plt.ylabel('loss')
plt.legend(['train_loss', 'val_loss'])
plt.title('Loss by epochs')
plt.show()
```
![график обучения](images/picture6.png)
---
## 7) Применили обученную модель к тестовым данным. Вывели значение функции ошибки и значение метрики качества классификации на тестовых данных.
```python
# Оценка качества работы модели на тестовых данных
scores = model_1output.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
```
Loss on test data: 0.28093650937080383
Accuracy on test data: 0.921500027179718
```
---
## 8) Добавили в модель один скрытый и провели обучение и тестирование (повторить п. 6–7) при 100, 300, 500 нейронах в скрытом слое. По метрике качества классификации на тестовых данных выбрали наилучшее количество нейронов в скрытом слое. В качестве функции активации нейронов в скрытом слое использовали функцию `sigmoid`.
### При 100 нейронах в скрытом слое:
```python
# создаем модель
model_1h100 = Sequential()
model_1h100.add(Dense(units=100, input_dim=num_pixels, activation='sigmoid'))
model_1h100.add(Dense(units=num_classes, activation='softmax'))
# компилируем модель
model_1h100.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
# вывод информации об архитектуре модели
print(model_1h100.summary())
```
![архитектура модели](images/picture7.png)
```python
# Обучаем модель
H_1h100 = model_1h100.fit(X_train, y_train, validation_split=0.1, epochs=50)
```
```python
# вывод графика ошибки по эпохам
plt.plot(H_1h100.history['loss'])
plt.plot(H_1h100.history['val_loss'])
plt.grid()
plt.xlabel('Epochs')
plt.ylabel('loss')
plt.legend(['train_loss', 'val_loss'])
plt.title('Loss by epochs')
plt.show()
```
![график обучения](images/picture8.png)
```python
# Оценка качества работы модели на тестовых данных
scores = model_1h100.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
```
Loss on test data: 0.20816442370414734
Accuracy on test data: 0.9397000074386597
```
### При 300 нейронах в скрытом слое:
```python
# создаем модель
model_1h300 = Sequential()
model_1h300.add(Dense(units=300, input_dim=num_pixels, activation='sigmoid'))
model_1h300.add(Dense(units=num_classes, activation='softmax'))
# компилируем модель
model_1h300.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
# вывод информации об архитектуре модели
print(model_1h300.summary())
```
![архитектура модели](images/picture9.png)
```python
# Обучаем модель
H_1h300 = model_1h300.fit(X_train, y_train, validation_split=0.1, epochs=50)
```
```python
# вывод графика ошибки по эпохам
plt.plot(H_1h300.history['loss'])
plt.plot(H_1h300.history['val_loss'])
plt.grid()
plt.xlabel('Epochs')
plt.ylabel('loss')
plt.legend(['train_loss', 'val_loss'])
plt.title('Loss by epochs')
plt.show()
```
![график обучения](images/picture10.png)
```python
# Оценка качества работы модели на тестовых данных
scores = model_1h300.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
```
Loss on test data: 0.2359277904033661
Accuracy on test data: 0.9320999979972839
```
### При 500 нейронах в скрытом слое:
```python
# создаем модель
model_1h500 = Sequential()
model_1h500.add(Dense(units=500, input_dim=num_pixels, activation='sigmoid'))
model_1h500.add(Dense(units=num_classes, activation='softmax'))
# компилируем модель
model_1h500.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
# вывод информации об архитектуре модели
print(model_1h500.summary())
```
![архитектура модели](images/picture11.png)
```python
# Обучаем модель
H_1h500 = model_1h500.fit(X_train, y_train, validation_split=0.1, epochs=50)
```
```python
# вывод графика ошибки по эпохам
plt.plot(H_1h500.history['loss'])
plt.plot(H_1h500.history['val_loss'])
plt.grid()
plt.xlabel('Epochs')
plt.ylabel('loss')
plt.legend(['train_loss', 'val_loss'])
plt.title('Loss by epochs')
plt.show()
```
![график обучения](images/picture12.png)
```python
# Оценка качества работы модели на тестовых данных
scores = model_1h500.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
```
Loss on test data: 0.25467056035995483
Accuracy on test data: 0.9280999898910522
```
**Лучшая метрика получилась равной 0.9437 при архитектуре со 100 нейронами в скрытом слое, поэтому в дальнейшем используем ее.**
---
## 9) Добавили в наилучшую архитектуру, определенную в п. 8, второй скрытый слой и провели обучение и тестирование при 50 и 100 нейронах во втором скрытом слое. В качестве функции активации нейронов в скрытом слое использовали функцию `sigmoid`.
### При 50 нейронах во втором скрытом слое:
```python
# создаем модель
model_1h100_2h50 = Sequential()
model_1h100_2h50.add(Dense(units=100, input_dim=num_pixels, activation='sigmoid'))
model_1h100_2h50.add(Dense(units=50, activation='sigmoid'))
model_1h100_2h50.add(Dense(units=num_classes, activation='softmax'))
# компилируем модель
model_1h100_2h50.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
# вывод информации об архитектуре модели
print(model_1h100_2h50.summary())
```
![архитектура модели](images/picture13.png)
```python
# Обучаем модель
H_1h100_2h50 = model_1h100_2h50.fit(X_train, y_train, validation_split=0.1, epochs=50)
```
```python
# вывод графика ошибки по эпохам
plt.plot(H_1h100_2h50.history['loss'])
plt.plot(H_1h100_2h50.history['val_loss'])
plt.grid()
plt.xlabel('Epochs')
plt.ylabel('loss')
plt.legend(['train_loss', 'val_loss'])
plt.title('Loss by epochs')
plt.show()
```
![график обучения](images/picture14.png)
```python
# Оценка качества работы модели на тестовых данных
scores = model_1h100_2h50.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
```
Loss on test data: 0.19274231791496277
Accuracy on test data: 0.9430000185966492
```
### При 100 нейронах во втором скрытом слое:
```python
# создаем модель
model_1h100_2h100 = Sequential()
model_1h100_2h100.add(Dense(units=100, input_dim=num_pixels, activation='sigmoid'))
model_1h100_2h100.add(Dense(units=100, activation='sigmoid'))
model_1h100_2h100.add(Dense(units=num_classes, activation='softmax'))
# компилируем модель
model_1h100_2h100.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
# вывод информации об архитектуре модели
print(model_1h100_2h100.summary())
```
![архитектура модели](images/picture15.png)
```python
# Обучаем модель
H_1h100_2h100 = model_1h100_2h100.fit(X_train, y_train, validation_split=0.1, epochs=50)
```
```python
# вывод графика ошибки по эпохам
plt.plot(H_1h100_2h100.history['loss'])
plt.plot(H_1h100_2h100.history['val_loss'])
plt.grid()
plt.xlabel('Epochs')
plt.ylabel('loss')
plt.legend(['train_loss', 'val_loss'])
plt.title('Loss by epochs')
plt.show()
```
![график обучения](images/picture16.png)
```python
# Оценка качества работы модели на тестовых данных
scores = model_1h100_2h100.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
```
Loss on test data: 0.21183738112449646
Accuracy on test data: 0.9372000098228455
```
---
## 10) Результаты исследования архитектуры нейронной сети занесли в таблицу:
![график обучения](images/table2.png)
### По результатам исследования сделали выводы и выбрали наилучшую архитектуру нейронной сети с точки зрения качества классификации.
**Из таблицы следует, что лучшей архитектурой является НС с двумя скрытыми слоями по 100 и 50 нейронов соответственно, затем идет НС с одним скрытым слоем и 100 нейронами. При увеличении количества нейронов в скрытых слоях значение метрики качества падает. Такая тенденция возникает из-за простоты датасета MNIST, при усложнении архитектуры НС начинает переобучаться, а оценка качества на тестовых данных падает.**
---
## 11) Сохранили наилучшую нейронную сеть на диск.
```python
# сохранение модели на диск
model_1h100_2h50.save('/content/drive/MyDrive/Colab Notebooks/laba1/model_1h100_2h50.keras')
```
---
## 12) Для нейронной сети наилучшей архитектуры вывели два тестовых изображения, истинные метки и результат распознавания изображений.
```python
#Результаты для двух тестовых изображений
for n in [3,26]:
result = model_1h100_2h50.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)))
```
![результат 1](images/picture17.png)
![результат 2](images/picture18.png)
---
## 13) Создали собственные изображения рукописных цифр, подобное представленным в наборе MNIST. Цифру выбрали как остаток от деления на 10 числа своего дня рождения (26 ноября → 26 mod 10 = 6, 3 июля → 3 mod 10 = 3). Сохранили изображения. Загрузили, предобработали и подали на вход обученной нейронной сети собственные изображения. Вывели изображения и результаты распознавания.
```python
# загрузка собственного изображения
from PIL import Image
file1_data = Image.open('/content/drive/MyDrive/Colab Notebooks/laba1/цифра 3.png')
file1_data = file1_data.convert('L') # перевод в градации серого
test1_img = np.array(file1_data)
plt.imshow(test1_img, cmap=plt.get_cmap('gray'))
plt.show()
from PIL import Image
file2_data = Image.open('/content/drive/MyDrive/Colab Notebooks/laba1/цифра 6.png')
file2_data = file2_data.convert('L') # перевод в градации серого
test2_img = np.array(file2_data)
# вывод собственного изображения
plt.imshow(test1_img, cmap=plt.get_cmap('gray'))
plt.imshow(test2_img, cmap=plt.get_cmap('gray'))
plt.show()
```
![собственные изображения](images/picture19.png)
```python
# предобработка
test1_img = test1_img / 255
test1_img = test1_img.reshape(1, num_pixels)
test2_img = test2_img / 255
test2_img = test2_img.reshape(1, num_pixels)
# распознавание
result1 = model_1h100_2h50.predict(test1_img)
print('Я думаю это ', np.argmax(result1))
result2 = model_1h100_2h50.predict(test2_img)
print('Я думаю это ', np.argmax(result2))
```
```
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step
Я думаю это 3
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step
Я думаю это 6
```
---
## 14) Создать копию собственного изображения, отличающуюся от оригинала поворотом на 90 градусов в любую сторону. Сохранили изображения. Загрузили, предобработали и подали на вход обученной нейронной сети измененные изображения. Вывели изображения и результаты распознавания. Сделали выводы по результатам эксперимента.
```python
# загрузка собственного изображения
from PIL import Image
file3_data = Image.open('/content/drive/MyDrive/Colab Notebooks/laba1/цифра 3 перевернутая.png')
file3_data = file3_data.convert('L') # перевод в градации серого
test3_img = np.array(file3_data)
plt.imshow(test3_img, cmap=plt.get_cmap('gray'))
plt.show()
from PIL import Image
file4_data = Image.open('/content/drive/MyDrive/Colab Notebooks/laba1/цифра 6 перевернутая.png')
file4_data = file4_data.convert('L') # перевод в градации серого
test4_img = np.array(file4_data)
# вывод собственного изображения
plt.imshow(test3_img, cmap=plt.get_cmap('gray'))
plt.imshow(test4_img, cmap=plt.get_cmap('gray'))
plt.show()
```
![собственные изображения перевернутые](images/picture20.png)
```python
# предобработка
test3_img = test3_img / 255
test3_img = test3_img.reshape(1, num_pixels)
test4_img = test4_img / 255
test4_img = test4_img.reshape(1, num_pixels)
# распознавание
result3 = model_1h100_2h50.predict(test3_img)
print('Я думаю это ', np.argmax(result3))
result4 = model_1h100_2h50.predict(test4_img)
print('Я думаю это ', np.argmax(result4))
```
```
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step
Я думаю это 5
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step
Я думаю это 4
```
**При повороте рисунков цифр НС не смогла их правильно распознать. Так получилось потому что НС не обучалась на перевернутых изображениях**
---

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

После

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

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

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

После

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

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

После

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

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

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

После

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

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

@ -0,0 +1,6 @@
5.528552372507079760e+00 5.559228990189748920e+00
5.648388730839360328e+00 5.694735265167601135e+00
6.034000861003956828e+00 6.014071576183726897e+00
6.514146742942168800e+00 6.578190189984116643e+00
6.639221608726088597e+00 6.634545308633034288e+00

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

Ширина:  |  Высота:  |  Размер: 55 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.001)
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)
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=0.0001, patience = patience,
verbose=1, mode='auto',
min_delta=early_stopping_delta, patience = patience,
verbose=verbose, mode='min',
baseline=None,
restore_best_weights=False)
restore_best_weights=True)
history_callback = tensorflow.keras.callbacks.History()
verbose = 1 if verbose_show else 0
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)
@ -538,4 +565,4 @@ def ire_plot(title, IRE_test, IREth, ae_name):
plt.gcf().savefig('out/IRE_' + title + ae_name + '.png')
plt.show()
return
return

@ -0,0 +1,871 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "1c1905f6-acba-4dba-aba9-4d2fe59298df",
"metadata": {
"id": "1c1905f6-acba-4dba-aba9-4d2fe59298df"
},
"source": [
"## Задание 1"
]
},
{
"cell_type": "markdown",
"id": "61f467d3-d1c1-481a-8560-f259a22e0824",
"metadata": {
"id": "61f467d3-d1c1-481a-8560-f259a22e0824"
},
"source": [
"### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "58e787ca-562f-458d-8c62-e86b6fb1580a",
"metadata": {
"id": "58e787ca-562f-458d-8c62-e86b6fb1580a"
},
"outputs": [],
"source": [
"# импорт модулей\n",
"import os\n",
"os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab2')\n",
"\n",
"import numpy as np\n",
"import lab02_lib as lib"
]
},
{
"cell_type": "markdown",
"id": "5bbb8290-8806-4184-b33b-f1b0680bf563",
"metadata": {
"id": "5bbb8290-8806-4184-b33b-f1b0680bf563"
},
"source": [
"### 2) Сгенерировали индивидуальный набор двумерных данных в пространстве признаков с координатами центра (6, 6), где 6 – номер бригады. Вывели полученные данные на рисунок и в консоль."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "29603d03-8478-4341-b7ad-bb608ad88890",
"metadata": {
"id": "29603d03-8478-4341-b7ad-bb608ad88890"
},
"outputs": [],
"source": [
"# генерация датасета\n",
"data = lib.datagen(6, 6, 1000, 2)\n",
"\n",
"# вывод данных и размерности\n",
"print('Исходные данные:')\n",
"print(data)\n",
"print('Размерность данных:')\n",
"print(data.shape)"
]
},
{
"cell_type": "markdown",
"id": "00ba79e5-d8f9-4c40-a065-e8fd21a68e21",
"metadata": {
"id": "00ba79e5-d8f9-4c40-a065-e8fd21a68e21"
},
"source": [
"### 3) Создали и обучили автокодировщик AE1 простой архитектуры, выбрав небольшое количество эпох обучения. Зафиксировали в таблице вида табл.1 количество скрытых слоёв и нейронов в них"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bc736f50-204b-4b1d-8c1c-0dd34fb1f02b",
"metadata": {
"id": "bc736f50-204b-4b1d-8c1c-0dd34fb1f02b"
},
"outputs": [],
"source": [
"# обучение AE1\n",
"patience = 300\n",
"ae1_trained, IRE1, IREth1 = lib.create_fit_save_ae(data,'out/AE1.h5','out/AE1_ire_th.txt',\n",
"1000, True, patience)"
]
},
{
"cell_type": "markdown",
"id": "ae9e6816-d300-455a-a4ee-77e4911e02f5",
"metadata": {
"id": "ae9e6816-d300-455a-a4ee-77e4911e02f5"
},
"source": [
"### 4) Зафиксировали ошибку MSE, на которой обучение завершилось. Построили график ошибки реконструкции обучающей выборки. Зафиксировали порог ошибки реконструкции – порог обнаружения аномалий."
]
},
{
"cell_type": "markdown",
"source": [
"Ошибка MSE_AE1 = 19.5568"
],
"metadata": {
"id": "Np8zquNSgtO9"
},
"id": "Np8zquNSgtO9"
},
{
"cell_type": "code",
"execution_count": null,
"id": "fb7eeae8-f478-4295-b6de-b5790b7861f2",
"metadata": {
"id": "fb7eeae8-f478-4295-b6de-b5790b7861f2"
},
"outputs": [],
"source": [
"# Построение графика ошибки реконструкции\n",
"lib.ire_plot('training', IRE1, IREth1, 'AE1')"
]
},
{
"cell_type": "markdown",
"id": "92fb420f-907e-4417-ab34-6d12308bed0b",
"metadata": {
"id": "92fb420f-907e-4417-ab34-6d12308bed0b"
},
"source": [
"### 5) Создали и обучили второй автокодировщик AE2 с усложненной архитектурой, задав большее количество эпох обучения"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bb9f83e2-fecf-4118-8376-a712726d12d5",
"metadata": {
"id": "bb9f83e2-fecf-4118-8376-a712726d12d5"
},
"outputs": [],
"source": [
"# обучение AE2\n",
"ae2_trained, IRE2, IREth2 = lib.create_fit_save_ae(data,'out/AE2.h5','out/AE2_ire_th.txt',\n",
"3000, True, patience)"
]
},
{
"cell_type": "markdown",
"id": "03194c1b-c03e-42a5-93e5-f4d007ddb7c7",
"metadata": {
"id": "03194c1b-c03e-42a5-93e5-f4d007ddb7c7"
},
"source": [
"### 6) Зафиксировали ошибку MSE, на которой обучение завершилось. Построили график ошибки реконструкции обучающей выборки. Зафиксировали второй порог ошибки реконструкции – порог обнаружения аномалий."
]
},
{
"cell_type": "markdown",
"source": [
"Ошибка MSE_AE2 = 0.0108"
],
"metadata": {
"id": "6TBPoMskhCQp"
},
"id": "6TBPoMskhCQp"
},
{
"cell_type": "code",
"execution_count": null,
"id": "47cf147a-f97b-41d3-9d7c-b799da0115fe",
"metadata": {
"id": "47cf147a-f97b-41d3-9d7c-b799da0115fe"
},
"outputs": [],
"source": [
"# Построение графика ошибки реконструкции\n",
"lib.ire_plot('training', IRE2, IREth2, 'AE2')"
]
},
{
"cell_type": "markdown",
"id": "fd14d331-aad6-4b98-9926-5ab6a055beb0",
"metadata": {
"id": "fd14d331-aad6-4b98-9926-5ab6a055beb0"
},
"source": [
"### 7) Рассчитали характеристики качества обучения EDCA для AE1 и AE2. Визуализировали и сравнили области пространства признаков, распознаваемые автокодировщиками AE1 и AE2. Сделали вывод о пригодности AE1 и AE2 для качественного обнаружения аномалий.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "58fd0b46-1064-4f2f-b04f-88307bf938d2",
"metadata": {
"id": "58fd0b46-1064-4f2f-b04f-88307bf938d2"
},
"outputs": [],
"source": [
"# построение областей покрытия и границ классов\n",
"# расчет характеристик качества обучения\n",
"numb_square = 20\n",
"xx, yy, Z1 = lib.square_calc(numb_square, data, ae1_trained, IREth1, '1', True)"
]
},
{
"cell_type": "code",
"source": [
"# построение областей покрытия и границ классов\n",
"# расчет характеристик качества обучения\n",
"numb_square = 20\n",
"xx, yy, Z2 = lib.square_calc(numb_square, data, ae2_trained, IREth2, '2', True)"
],
"metadata": {
"id": "ZG72thVfYMOy"
},
"id": "ZG72thVfYMOy",
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# сравнение характеристик качества обучения и областей аппроксимации\n",
"lib.plot2in1(data, xx, yy, Z1, Z2)"
],
"metadata": {
"id": "RJWYYYHQbUIN"
},
"id": "RJWYYYHQbUIN",
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"id": "d766b8f0-3ba7-4a73-94a0-7858eb2f5515",
"metadata": {
"id": "d766b8f0-3ba7-4a73-94a0-7858eb2f5515"
},
"source": [
"### 8) Если автокодировщик AE2 недостаточно точно аппроксимирует область обучающих данных, то подобрать подходящие параметры автокодировщика и повторить шаги (6) – (8)."
]
},
{
"cell_type": "markdown",
"source": [
"Полученные показатели EDCA для автокодировщика AE2 нас устраивают."
],
"metadata": {
"id": "XbnbvTima5dv"
},
"id": "XbnbvTima5dv"
},
{
"cell_type": "markdown",
"id": "cfa38b82-4c8e-4437-9c25-581d7fea0f2c",
"metadata": {
"id": "cfa38b82-4c8e-4437-9c25-581d7fea0f2c"
},
"source": [
"### 9) Изучили сохраненный набор данных и пространство признаков. Создали тестовую выборку, состоящую, как минимум, из 4ёх элементов, не входящих в обучающую выборку. Элементы должны быть такими, чтобы AE1 распознавал их как норму, а AE2 детектировал как аномалии."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d618382f-f65a-4c17-b0d0-3d2d0c4bc50e",
"metadata": {
"id": "d618382f-f65a-4c17-b0d0-3d2d0c4bc50e"
},
"outputs": [],
"source": [
"# загрузка тестового набора\n",
"data_test = np.loadtxt('data_test.txt', dtype=float)\n",
"print(data_test)"
]
},
{
"cell_type": "markdown",
"source": [
"### 10) Применили обученные автокодировщики AE1 и AE2 к тестовым данным и вывели значения ошибки реконструкции для каждого элемента тестовой выборки относительно порога на график и в консоль."
],
"metadata": {
"id": "3Ce8wSVMdjBj"
},
"id": "3Ce8wSVMdjBj"
},
{
"cell_type": "code",
"source": [
"# тестирование АE1\n",
"predicted_labels1, ire1 = lib.predict_ae(ae1_trained, data_test, IREth1)"
],
"metadata": {
"id": "Hq8A0LyMcKXk"
},
"id": "Hq8A0LyMcKXk",
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# тестирование АE1\n",
"lib.anomaly_detection_ae(predicted_labels1, ire1, IREth1)\n",
"lib.ire_plot('test', ire1, IREth1, 'AE1')"
],
"metadata": {
"id": "Z_v2X4HvcQD5"
},
"id": "Z_v2X4HvcQD5",
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# тестирование АE2\n",
"predicted_labels2, ire2 = lib.predict_ae(ae2_trained, data_test, IREth2)"
],
"metadata": {
"id": "fT75bpEnc7a2"
},
"id": "fT75bpEnc7a2",
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# тестирование АE2\n",
"lib.anomaly_detection_ae(predicted_labels2, ire2, IREth2)\n",
"lib.ire_plot('test', ire2, IREth2, 'AE2')"
],
"metadata": {
"id": "EpGtgYZVdAen"
},
"id": "EpGtgYZVdAen",
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"id": "7acf3a7f-4dd8-44df-b201-509aa4caa7f0",
"metadata": {
"id": "7acf3a7f-4dd8-44df-b201-509aa4caa7f0"
},
"source": [
"### 11) Визуализировали элементы обучающей и тестовой выборки в областях пространства признаков, распознаваемых автокодировщиками AE1 и AE2."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a2fbf3a9-5e11-49d0-a0db-f77f3edeb7b7",
"metadata": {
"id": "a2fbf3a9-5e11-49d0-a0db-f77f3edeb7b7"
},
"outputs": [],
"source": [
"# построение областей аппроксимации и точек тестового набора\n",
"lib.plot2in1_anomaly(data, xx, yy, Z1, Z2, data_test)"
]
},
{
"cell_type": "markdown",
"id": "bd63edf4-3452-41db-8080-d8a2ff4f09a4",
"metadata": {
"id": "bd63edf4-3452-41db-8080-d8a2ff4f09a4"
},
"source": [
"### 12) Результаты исследования занесли в таблицу:\n",
"Табл. 1 Результаты задания №1"
]
},
{
"cell_type": "markdown",
"source": [
"| | Количество<br>скрытых слоев | Количество<br>нейронов в скрытых слоях | Количество<br>эпох обучения | Ошибка<br>MSE_stop | Порог ошибки<br>реконструкции | Значение показателя<br>Excess | Значение показателя<br>Approx | Количество обнаруженных<br>аномалий |\n",
"|-----:|------------------------------|----------------------------------------|-----------------------------|--------------------|-------------------------------|-------------------------------|--------------------------------|-------------------------------------|\n",
"| AE1 | 1 | 1 | 1000 | 19.5568 | 6.53 | 12.67 | 0.073 | 0 |\n",
"| AE2 | 5 | 3,2,1,2,3 | 3000 | 0.0108 | 0.4 | 0.33 | 0.750 | 4 |\n"
],
"metadata": {
"id": "df2BIryKfkpk"
},
"id": "df2BIryKfkpk"
},
{
"cell_type": "markdown",
"id": "b8e54861-e2c2-4755-a2d8-5d4b6cace481",
"metadata": {
"id": "b8e54861-e2c2-4755-a2d8-5d4b6cace481"
},
"source": [
"### 13) Сделали выводы о требованиях к:\n",
"- данным для обучения,\n",
"- архитектуре автокодировщика,\n",
"- количеству эпох обучения,\n",
"- ошибке MSE_stop, приемлемой для останова обучения,\n",
"- ошибке реконструкции обучающей выборки (порогу обнаружения\n",
"аномалий),\n",
"- характеристикам качества обучения EDCA одноклассового\n",
"классификатора\n",
"\n",
"для качественного обнаружения аномалий в данных."
]
},
{
"cell_type": "markdown",
"source": [
"1) Данные для обучения должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение\n",
"2) Архитектура автокодировщика должна постепенно сужатся к бутылочному горлышку,а затем постепенно возвращатся к исходным выходным размерам, кол-во скрытых слоев 3-5\n",
"3) В рамках данного набора данных оптимальное кол-во эпох 3000 с patience 300 эпох\n",
"4) Оптимальная ошибка MSE-stop в районе 0.01, желательно не меньше для предотвращения переобучения\n",
"5) Значение порога в районе 0.4\n",
"6) Значение Excess не больше 0.5, значение Deficit равное 0, значение Coating равное 1, значение Approx не меньше 0.7"
],
"metadata": {
"id": "1s5_ye8vkleI"
},
"id": "1s5_ye8vkleI"
},
{
"cell_type": "markdown",
"source": [
"## Задание 2"
],
"metadata": {
"id": "rqdVflKXo6Bo"
},
"id": "rqdVflKXo6Bo"
},
{
"cell_type": "markdown",
"source": [
"### 1) Изучить описание своего набора реальных данных, что он из себя представляет"
],
"metadata": {
"id": "rSvJtTReo928"
},
"id": "rSvJtTReo928"
},
{
"cell_type": "markdown",
"source": [
"Бригада 6 => набор данных Cardio. Это реальный набор данных, который состоит из измерений частоты сердечных сокращений плода и\n",
"сокращений матки на кардиотокограммах, классифицированных экспертами\n",
"акушерами. Исходный набор данных предназначен для классификации. В нем\n",
"представлено 3 класса: «норма», «подозрение» и «патология». Для обнаружения\n",
"аномалий класс «норма» принимается за норму, класс «патология» принимается за\n",
"аномалии, а класс «подозрение» был отброшен.\n",
"\n",
"| Количество<br>признаков | Количество<br>примеров | Количество<br>нормальных примеров | Количество<br>аномальных примеров |\n",
"|-------------------------:|-----------------------:|----------------------------------:|-----------------------------------:|\n",
"| 21 | 1764 | 1655 | 109 |\n"
],
"metadata": {
"id": "gf-0gJ7jqTdk"
},
"id": "gf-0gJ7jqTdk"
},
{
"cell_type": "markdown",
"source": [
"### 2) Загрузить многомерную обучающую выборку реальных данных Cardio.txt."
],
"metadata": {
"id": "N2Egw1pho-F_"
},
"id": "N2Egw1pho-F_"
},
{
"cell_type": "code",
"source": [
"# загрузка обчуающей выборки\n",
"train = np.loadtxt('data/cardio_train.txt', dtype=float)"
],
"metadata": {
"id": "G8QTxAFapASY"
},
"id": "G8QTxAFapASY",
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 3) Вывести полученные данные и их размерность в консоли."
],
"metadata": {
"id": "zj2WXPNco-Tz"
},
"id": "zj2WXPNco-Tz"
},
{
"cell_type": "code",
"source": [
"print('train:\\n', train)\n",
"print('train.shape:', np.shape(train))"
],
"metadata": {
"id": "W6hTlfk6pAo9"
},
"id": "W6hTlfk6pAo9",
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 4) Создать и обучить автокодировщик с подходящей для данных архитектурой. Выбрать необходимое количество эпох обучения."
],
"metadata": {
"id": "0T11A0x4o-gr"
},
"id": "0T11A0x4o-gr"
},
{
"cell_type": "code",
"source": [
"# **kwargs\n",
"# verbose_every_n_epochs - отображать прогресс каждые N эпох (по умолчанию - 1000)\n",
"# early_stopping_delta - дельта для ранней остановки (по умолчанию - 0.01)\n",
"# early_stopping_value = значение для ранней остановки (по умолчанию - 0.0001)\n",
"\n",
"from time import time\n",
"\n",
"patience = 4000\n",
"start = time()\n",
"ae3_v1_trained, IRE3_v1, IREth3_v1 = lib.create_fit_save_ae(train,'out/AE3_V1.h5','out/AE3_v1_ire_th.txt',\n",
"100000, False, patience, early_stopping_delta = 0.001)\n",
"print(\"Время на обучение: \", time() - start)"
],
"metadata": {
"id": "rPwtBtdRPztp"
},
"id": "rPwtBtdRPztp",
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 5) Зафиксировать ошибку MSE, на которой обучение завершилось. Построить график ошибки реконструкции обучающей выборки. Зафиксировать порог ошибки реконструкции – порог обнаружения аномалий."
],
"metadata": {
"id": "8ALjaY8lo-sa"
},
"id": "8ALjaY8lo-sa"
},
{
"cell_type": "markdown",
"source": [
"Скрытых слоев 7, нейроны: 46->26->14->10->14->26->48\n",
"\n",
"Ошибка MSE_AE3_v1 = 0.0126"
],
"metadata": {
"id": "b4sk_fhYY6Qb"
},
"id": "b4sk_fhYY6Qb"
},
{
"cell_type": "code",
"source": [
"# Построение графика ошибки реконструкции\n",
"lib.ire_plot('training', IRE3_v1, IREth3_v1, 'AE3_v1')"
],
"metadata": {
"id": "a4sR3SSDpBPU"
},
"id": "a4sR3SSDpBPU",
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 6) Сделать вывод о пригодности обученного автокодировщика для качественного обнаружения аномалий. Если порог ошибки реконструкции слишком велик, то подобрать подходящие параметры автокодировщика и повторить шаги (4) – (6)."
],
"metadata": {
"id": "DGBM9xNFo-4k"
},
"id": "DGBM9xNFo-4k"
},
{
"cell_type": "code",
"source": [
"# **kwargs\n",
"# verbose_every_n_epochs - отображать прогресс каждые N эпох (по умолчанию - 1000)\n",
"# early_stopping_delta - дельта для ранней остановки (по умолчанию - 0.01)\n",
"# early_stopping_value = значение для ранней остановки (по умолчанию - 0.0001)\n",
"\n",
"from time import time\n",
"\n",
"patience = 4000\n",
"start = time()\n",
"ae3_v2_trained, IRE3_v2, IREth3_v2 = lib.create_fit_save_ae(train,'out/AE3_V2.h5','out/AE3_v2_ire_th.txt',\n",
"100000, False, patience, early_stopping_delta = 0.001)\n",
"print(\"Время на обучение: \", time() - start)"
],
"metadata": {
"id": "ZvM1VbKEgalO"
},
"id": "ZvM1VbKEgalO",
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"Скрытых слоев 7, нейроны: 48->36->28->22->16->12->16->22->28->36->48\n",
"\n",
"Ошибка MSE_AE3_v1 = 0.0098"
],
"metadata": {
"id": "9BrPUb_8fX5R"
},
"id": "9BrPUb_8fX5R"
},
{
"cell_type": "code",
"source": [
"# Построение графика ошибки реконструкции\n",
"lib.ire_plot('training', IRE3_v2, IREth3_v2, 'AE3_v2')"
],
"metadata": {
"id": "kh1eMtvpf6F-"
},
"id": "kh1eMtvpf6F-",
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 7) Изучить и загрузить тестовую выборку Cardio.txt."
],
"metadata": {
"id": "vJvW1mOtpgFO"
},
"id": "vJvW1mOtpgFO"
},
{
"cell_type": "code",
"source": [
"#загрузка тестовой выборки\n",
"test = np.loadtxt('data/cardio_test.txt', dtype=float)\n",
"print('\\n test:\\n', test)\n",
"print('test.shape:', np.shape(test))"
],
"metadata": {
"id": "GrXQ5YymtD2u"
},
"id": "GrXQ5YymtD2u",
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 8) Подать тестовую выборку на вход обученного автокодировщика для обнаружения аномалий. Вывести график ошибки реконструкции элементов тестовой выборки относительно порога."
],
"metadata": {
"id": "6iqO4Yxbpgob"
},
"id": "6iqO4Yxbpgob"
},
{
"cell_type": "code",
"source": [
"# тестирование АE3\n",
"predicted_labels3_v1, ire3_v1 = lib.predict_ae(ae3_v1_trained, test, IREth3_v1)"
],
"metadata": {
"id": "Vxj1fTAikDuU"
},
"id": "Vxj1fTAikDuU",
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# Построение графика ошибки реконструкции\n",
"lib.ire_plot('test', ire3_v1, IREth3_v1, 'AE3_v1')"
],
"metadata": {
"id": "21DdnIKYtmtM"
},
"id": "21DdnIKYtmtM",
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# тестирование АE3\n",
"predicted_labels3_v2, ire3_v2 = lib.predict_ae(ae3_v2_trained, test, IREth3_v2)"
],
"metadata": {
"id": "Ql1JMAM6sf7Z"
},
"id": "Ql1JMAM6sf7Z",
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# Построение графика ошибки реконструкции\n",
"lib.ire_plot('test', ire3_v2, IREth3_v2, 'AE3_v2')"
],
"metadata": {
"id": "jczBRWjTt35R"
},
"id": "jczBRWjTt35R",
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# тестирование АE2\n",
"lib.anomaly_detection_ae(predicted_labels3_v1, IRE3_v1, IREth3_v1)"
],
"metadata": {
"id": "2kF1XknIpg48"
},
"id": "2kF1XknIpg48",
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"Для AE3_v1 точность составляет 88%"
],
"metadata": {
"id": "LXHt7-gxuJIy"
},
"id": "LXHt7-gxuJIy"
},
{
"cell_type": "code",
"source": [
"# тестирование АE2\n",
"lib.anomaly_detection_ae(predicted_labels3_v2, IRE3_v2, IREth3_v2)"
],
"metadata": {
"id": "5ow1D88nsrir"
},
"id": "5ow1D88nsrir",
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"Для AE3_v2 точность составляет 92%"
],
"metadata": {
"id": "LDsC5WyeuRHS"
},
"id": "LDsC5WyeuRHS"
},
{
"cell_type": "markdown",
"source": [
"### 9) Если результаты обнаружения аномалий не удовлетворительные (обнаружено менее 70% аномалий), то подобрать подходящие параметры автокодировщика и повторить шаги (4) – (9)."
],
"metadata": {
"id": "fPPbYwnQpqS3"
},
"id": "fPPbYwnQpqS3"
},
{
"cell_type": "markdown",
"source": [
"Результаты обнаружения аномалий удовлетворены."
],
"metadata": {
"id": "IVmw2aeduXml"
},
"id": "IVmw2aeduXml"
},
{
"cell_type": "markdown",
"source": [
"### 10) Параметры наилучшего автокодировщика и результаты обнаружения аномалий занести в таблицу:\n",
"Табл. 2 Результаты задания №2"
],
"metadata": {
"id": "u3cAX_IgpvWU"
},
"id": "u3cAX_IgpvWU"
},
{
"cell_type": "markdown",
"source": [
"| Dataset name | Количество<br>скрытых слоев | Количество<br>нейронов в скрытых слоях | Количество<br>эпох обучения | Ошибка<br>MSE_stop | Порог ошибки<br>реконструкции | % обнаруженных<br>аномалий |\n",
"|:-------------|:-----------------------------|:----------------------------------------|:-----------------------------|:-------------------|:-------------------------------|:---------------------------|\n",
"| Cardio | 11 | 48, 36, 28, 22, 16, 10, 16, 22, 28, 36, 48 | 100000 | 0.0098 | 1.6 | 92% |\n"
],
"metadata": {
"id": "tryfJdjTvgU8"
},
"id": "tryfJdjTvgU8"
},
{
"cell_type": "markdown",
"source": [
"### 11) Сделать выводы о требованиях к:\n",
"- данным для обучения,\n",
"- архитектуре автокодировщика, \n",
"- количеству эпох обучения,\n",
"- ошибке MSE_stop, приемлемой для останова обучения,\n",
"- ошибке реконструкции обучающей выборки (порогу обнаружения\n",
"аномалий)\n",
"\n",
"для качественного обнаружения аномалий в случае, когда размерность\n",
"пространства признаков высока."
],
"metadata": {
"id": "eE7IYyGJp0Vv"
},
"id": "eE7IYyGJp0Vv"
},
{
"cell_type": "markdown",
"source": [
"1) Данные для обучения должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение\n",
"2) Архитектура автокодировщика должна постепенно сужатся к бутылочному горлышку,а затем постепенно возвращатся к исходным выходным размерам, кол-во скрытых слоев 7-11.\n",
"3) В рамках данного набора данных оптимальное кол-во эпох 100000 с patience 4000 эпох\n",
"4) Оптимальная ошибка MSE-stop в районе 0.001, желательно не меньше для предотвращения переобучения\n",
"5) Значение порога не больше 1.6"
],
"metadata": {
"id": "67p7AeSWwVXE"
},
"id": "67p7AeSWwVXE"
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

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

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

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

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

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

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

Двоичные данные
labworks/LW2/out/IRE_trainingAE1.png

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

После

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

Двоичные данные
labworks/LW2/out/IRE_trainingAE2.png

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

После

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

Двоичные данные
labworks/LW2/out/train_set.png

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

После

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

@ -0,0 +1,417 @@
# Отчёт по лабораторной работе №2
**Кнзев Станислав, Жихарев Данила — А-02-22**
---
## Задание 1
### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули.
```python
# импорт модулей
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab2')
import numpy as np
import lab02_lib as lib
```
### 2) Сгенерировали индивидуальный набор двумерных данных в пространстве признаков с координатами центра (6, 6), где 6 – номер бригады. Вывели полученные данные на рисунок и в консоль.
```python
# генерация датасета
data = lib.datagen(6, 6, 1000, 2)
# вывод данных и размерности
print('Исходные данные:')
print(data)
print('Размерность данных:')
print(data.shape)
```
![Training set](images/picture1_1.png)
```
Исходные данные:
[[5.8619435 5.99297106]
[6.12066008 5.98527609]
[5.98643623 5.9813867 ]
...
[5.80640873 6.16429542]
[6.01437944 6.13645626]
[6.00333385 5.99329265]]
Размерность данных:
(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 = 19.5568
```python
# Построение графика ошибки реконструкции
lib.ire_plot('training', IRE1, IREth1, 'AE1')
```
![IRE for training set. AE1](images/picture1_2.png)
### 5) Создали и обучили второй автокодировщик AE2 с усложненной архитектурой, задав большее количество эпох обучения
```python
# обучение AE2
ae2_trained, IRE2, IREth2 = lib.create_fit_save_ae(data,'out/AE2.h5','out/AE2_ire_th.txt',
3000, True, patience)
```
### 6) Зафиксировали ошибку MSE, на которой обучение завершилось. Построили график ошибки реконструкции обучающей выборки. Зафиксировали второй порог ошибки реконструкции – порог обнаружения аномалий.
Ошибка MSE_AE2 = 0.0108
```python
# Построение графика ошибки реконструкции
lib.ire_plot('training', IRE2, IREth2, 'AE2')
```
![IRE for training set. AE1](images/picture1_3.png)
### 7) Рассчитали характеристики качества обучения EDCA для AE1 и AE2. Визуализировали и сравнили области пространства признаков, распознаваемые автокодировщиками AE1 и AE2. Сделали вывод о пригодности AE1 и AE2 для качественного обнаружения аномалий.
```python
# построение областей покрытия и границ классов
# расчет характеристик качества обучения
numb_square = 20
xx, yy, Z1 = lib.square_calc(numb_square, data, ae1_trained, IREth1, '1', True)
```
![Autoencoder AE1. Training set. Class boundary](images/picture1_4.png)
```
amount: 21
amount_ae: 287
```
![Площади множеств Xt и Xd AE1](images/picture1_5.png)
![EDCA AE1](images/picture1_6.png)
```
Оценка качества AE1
IDEAL = 0. Excess: 12.666666666666666
IDEAL = 0. Deficit: 0.0
IDEAL = 1. Coating: 1.0
summa: 1.0
IDEAL = 1. Extrapolation precision (Approx): 0.07317073170731707
```
```python
# построение областей покрытия и границ классов
# расчет характеристик качества обучения
numb_square = 20
xx, yy, Z2 = lib.square_calc(numb_square, data, ae2_trained, IREth2, '2', True)
```
![Autoencoder AE2. Training set. Class boundary](images/picture1_7.png)
```
amount: 21
amount_ae: 28
```
![Площади множеств Xt и Xd AE1](images/picture1_8.png)
![EDCA AE1](images/picture1_9.png)
```
Оценка качества AE2
IDEAL = 0. Excess: 0.3333333333333333
IDEAL = 0. Deficit: 0.0
IDEAL = 1. Coating: 1.0
summa: 1.0
IDEAL = 1. Extrapolation precision (Approx): 0.75
```
```python
# сравнение характеристик качества обучения и областей аппроксимации
lib.plot2in1(data, xx, yy, Z1, Z2)
```
![Сравнение обучения AE1 и AE2](images/picture1_10.png)
### 8) Если автокодировщик AE2 недостаточно точно аппроксимирует область обучающих данных, то подобрать подходящие параметры автокодировщика и повторить шаги (6) – (8).
Полученные показатели EDCA для автокодировщика AE2 нас устраивают.
### 9) Изучили сохраненный набор данных и пространство признаков. Создали тестовую выборку, состоящую, как минимум, из 4ёх элементов, не входящих в обучающую выборку. Элементы должны быть такими, чтобы AE1 распознавал их как норму, а AE2 детектировал как аномалии.
```python
# загрузка тестового набора
data_test = np.loadtxt('data_test.txt', dtype=float)
print(data_test)
```
```
[[4.52855237 4.55922899]
[4.64838873 4.69473527]
[4.41414674 4.47819019]
[4.43922161 4.43454531]]
```
### 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')
```
```
Аномалий не обнаружено
```
![IRE fir test set. AE1](images/picture1_11.png)
```python
# тестирование АE2
predicted_labels2, ire2 = lib.predict_ae(ae2_trained, data_test, IREth2)
```
```python
# тестирование АE2
lib.anomaly_detection_ae(predicted_labels2, ire2, IREth2)
lib.ire_plot('test', ire2, IREth2, 'AE2')
```
```
i Labels IRE IREth
0 [1.] [2.02] 0.4
1 [1.] [1.84] 0.4
2 [1.] [2.16] 0.4
3 [1.] [2.17] 0.4
Обнаружено 4.0 аномалий
```
![IRE fir test set. AE2](images/picture1_12.png)
### 11) Визуализировали элементы обучающей и тестовой выборки в областях пространства признаков, распознаваемых автокодировщиками AE1 и AE2.
```python
# построение областей аппроксимации и точек тестового набора
lib.plot2in1_anomaly(data, xx, yy, Z1, Z2, data_test)
```
![Сравнение теста AE1 и AE2](images/picture1_13.png)
### 12) Результаты исследования занесли в таблицу:
Табл. 1 Результаты задания №1
| | Количество<br>скрытых слоев | Количество<br>нейронов в скрытых слоях | Количество<br>эпох обучения | Ошибка<br>MSE_stop | Порог ошибки<br>реконструкции | Значение показателя<br>Excess | Значение показателя<br>Approx | Количество обнаруженных<br>аномалий |
|-----:|------------------------------|----------------------------------------|-----------------------------|--------------------|-------------------------------|-------------------------------|--------------------------------|-------------------------------------|
| AE1 | 1 | 1 | 1000 | 19.5568 | 6.53 | 12.67 | 0.073 | 0 |
| AE2 | 5 | 3,2,1,2,3 | 3000 | 0.0108 | 0.4 | 0.33 | 0.750 | 4 |
### 13) Сделали выводы о требованиях к:
- данным для обучения,
- архитектуре автокодировщика,
- количеству эпох обучения,
- ошибке MSE_stop, приемлемой для останова обучения,
- ошибке реконструкции обучающей выборки (порогу обнаружения
аномалий),
- характеристикам качества обучения EDCA одноклассового
классификатора
для качественного обнаружения аномалий в данных.
1) Данные для обучения должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение
2) Архитектура автокодировщика должна постепенно сужатся к бутылочному горлышку,а затем постепенно возвращатся к исходным выходным размерам, кол-во скрытых слоев 3-5
3) В рамках данного набора данных оптимальное кол-во эпох 3000 с patience 300 эпох
4) Оптимальная ошибка MSE-stop в районе 0.01, желательно не меньше для предотвращения переобучения
5) Значение порога в районе 0.4
6) Значение Excess не больше 0.5, значение Deficit равное 0, значение Coating равное 1, значение Approx не меньше 0.7
## Задание 2
### 1) Изучить описание своего набора реальных данных, что он из себя представляет
Бригада 6 => набор данных Cardio. Это реальный набор данных, который состоит из измерений частоты сердечных сокращений плода и
сокращений матки на кардиотокограммах, классифицированных экспертами
акушерами. Исходный набор данных предназначен для классификации. В нем
представлено 3 класса: «норма», «подозрение» и «патология». Для обнаружения
аномалий класс «норма» принимается за норму, класс «патология» принимается за
аномалии, а класс «подозрение» был отброшен.
| Количество<br>признаков | Количество<br>примеров | Количество<br>нормальных примеров | Количество<br>аномальных примеров |
|-------------------------:|-----------------------:|----------------------------------:|-----------------------------------:|
| 21 | 1764 | 1655 | 109 |
### 2) Загрузить многомерную обучающую выборку реальных данных Cardio.txt.
```python
# загрузка обчуающей выборки
train = np.loadtxt('data/cardio_train.txt', dtype=float)
```
### 3) Вывести полученные данные и их размерность в консоли.
```python
print('train:\n', train)
print('train.shape:', np.shape(train))
```
```
train:
[[ 0.00491231 0.69319077 -0.20364049 ... 0.23149795 -0.28978574
-0.49329397]
[ 0.11072935 -0.07990259 -0.20364049 ... 0.09356344 -0.25638541
-0.49329397]
[ 0.21654639 -0.27244466 -0.20364049 ... 0.02459619 -0.25638541
1.1400175 ]
...
[ 0.85144861 -0.91998844 -0.20364049 ... 0.57633422 -0.65718941
1.1400175 ]
[ 0.85144861 -0.91998844 -0.20364049 ... 0.57633422 -0.62378908
-0.49329397]
[ 1.0630827 -0.51148142 -0.16958144 ... 0.57633422 -0.65718941
-0.49329397]]
train.shape: (1654, 21)
```
### 4) Создать и обучить автокодировщик с подходящей для данных архитектурой. Выбрать необходимое количество эпох обучения.
```python
# **kwargs
# verbose_every_n_epochs - отображать прогресс каждые N эпох (по умолчанию - 1000)
# early_stopping_delta - дельта для ранней остановки (по умолчанию - 0.01)
# early_stopping_value = значение для ранней остановки (по умолчанию - 0.0001)
from time import time
patience = 4000
start = time()
ae3_v1_trained, IRE3_v1, IREth3_v1 = lib.create_fit_save_ae(train,'out/AE3_V1.h5','out/AE3_v1_ire_th.txt',
100000, False, patience, early_stopping_delta = 0.001)
print("Время на обучение: ", time() - start)
```
### 5) Зафиксировать ошибку MSE, на которой обучение завершилось. Построить график ошибки реконструкции обучающей выборки. Зафиксировать порог ошибки реконструкции – порог обнаружения аномалий.
Скрытых слоев 7, нейроны: 46->26->14->10->14->26->48
Ошибка MSE_AE3_v1 = 0.0126
```python
# Построение графика ошибки реконструкции
lib.ire_plot('training', IRE3_v1, IREth3_v1, 'AE3_v1')
```
![IRE for training set. AE3_v1](images/picture2_1.png)
### 6) Сделать вывод о пригодности обученного автокодировщика для качественного обнаружения аномалий. Если порог ошибки реконструкции слишком велик, то подобрать подходящие параметры автокодировщика и повторить шаги (4) – (6).
```python
# **kwargs
# verbose_every_n_epochs - отображать прогресс каждые N эпох (по умолчанию - 1000)
# early_stopping_delta - дельта для ранней остановки (по умолчанию - 0.01)
# early_stopping_value = значение для ранней остановки (по умолчанию - 0.0001)
from time import time
patience = 4000
start = time()
ae3_v2_trained, IRE3_v2, IREth3_v2 = lib.create_fit_save_ae(train,'out/AE3_V2.h5','out/AE3_v2_ire_th.txt',
100000, False, patience, early_stopping_delta = 0.001)
print("Время на обучение: ", time() - start)
```
Скрытых слоев 7, нейроны: 48->36->28->22->16->12->16->22->28->36->48
Ошибка MSE_AE3_v1 = 0.0098
```python
# Построение графика ошибки реконструкции
lib.ire_plot('training', IRE3_v2, IREth3_v2, 'AE3_v2')
```
![IRE for training set. AE3_v2](images/picture2_2.png)
### 7) Изучить и загрузить тестовую выборку Cardio.txt.
```python
#загрузка тестовой выборки
test = np.loadtxt('data/cardio_test.txt', dtype=float)
print('\n test:\n', test)
print('test.shape:', np.shape(test))
```
```
test:
[[ 0.21654639 -0.65465178 -0.20364049 ... -2.0444214 4.987467
-0.49329397]
[ 0.21654639 -0.5653379 -0.20364049 ... -2.1133887 6.490482
-0.49329397]
[-0.3125388 -0.91998844 6.9653692 ... -1.1478471 3.9186563
-0.49329397]
...
[-0.41835583 -0.91998844 -0.16463485 ... -1.4926834 0.24461959
-0.49329397]
[-0.41835583 -0.91998844 -0.15093411 ... -1.4237162 0.14441859
-0.49329397]
[-0.41835583 -0.91998844 -0.20364049 ... -1.2857816 3.5846529
-0.49329397]]
test.shape: (109, 21)
```
### 8) Подать тестовую выборку на вход обученного автокодировщика для обнаружения аномалий. Вывести график ошибки реконструкции элементов тестовой выборки относительно порога.
```python
# тестирование АE3
predicted_labels3_v1, ire3_v1 = lib.predict_ae(ae3_v1_trained, test, IREth3_v1)
```
```python
# Построение графика ошибки реконструкции
lib.ire_plot('test', ire3_v1, IREth3_v1, 'AE3_v1')
```
![IRE for test set. AE3_v1](images/picture2_3.png)
```python
# тестирование АE3
predicted_labels3_v2, ire3_v2 = lib.predict_ae(ae3_v2_trained, test, IREth3_v2)
```
```python
# Построение графика ошибки реконструкции
lib.ire_plot('test', ire3_v2, IREth3_v2, 'AE3_v2')
```
![IRE for test set. AE3_v2](images/picture2_4.png)
```python
# тестирование АE2
lib.anomaly_detection_ae(predicted_labels3_v1, IRE3_v1, IREth3_v1)
```
Для AE3_v1 точность составляет 88%
```python
# тестирование АE2
lib.anomaly_detection_ae(predicted_labels3_v2, IRE3_v2, IREth3_v2)
```
Для 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.0098 | 1.6 | 92% |
### 11) Сделать выводы о требованиях к:
- данным для обучения,
- архитектуре автокодировщика,
- количеству эпох обучения,
- ошибке MSE_stop, приемлемой для останова обучения,
- ошибке реконструкции обучающей выборки (порогу обнаружения
аномалий)
для качественного обнаружения аномалий в случае, когда размерность
пространства признаков высока.
1) Данные для обучения должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение
2) Архитектура автокодировщика должна постепенно сужатся к бутылочному горлышку,а затем постепенно возвращатся к исходным выходным размерам, кол-во скрытых слоев 7-11.
3) В рамках данного набора данных оптимальное кол-во эпох 100000 с patience 4000 эпох
4) Оптимальная ошибка MSE-stop в районе 0.001, желательно не меньше для предотвращения переобучения
5) Значение порога не больше 1.6

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

@ -0,0 +1,739 @@
{
"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 [3,26]:\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 ['цифра 3.png', 'цифра 6.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(\"model_1h100_2h50.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.990 ; loss:0.029 |\n",
"| Полносвязная | 84 062 | 50 | accuracy:0.942 ; loss:0.198 |\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",
"\n",
"# Блок 1\n",
"model.add(layers.Conv2D(32, (3, 3), padding=\"same\",\n",
" activation=\"relu\", input_shape=input_shape))\n",
"model.add(layers.BatchNormalization())\n",
"model.add(layers.Conv2D(32, (3, 3), padding=\"same\", activation=\"relu\"))\n",
"model.add(layers.BatchNormalization())\n",
"model.add(layers.MaxPooling2D((2, 2)))\n",
"model.add(layers.Dropout(0.25))\n",
"\n",
"# Блок 2\n",
"model.add(layers.Conv2D(64, (3, 3), padding=\"same\", activation=\"relu\"))\n",
"model.add(layers.BatchNormalization())\n",
"model.add(layers.Conv2D(64, (3, 3), padding=\"same\", activation=\"relu\"))\n",
"model.add(layers.BatchNormalization())\n",
"model.add(layers.MaxPooling2D((2, 2)))\n",
"model.add(layers.Dropout(0.25))\n",
"\n",
"# Блок 3\n",
"model.add(layers.Conv2D(128, (3, 3), padding=\"same\", activation=\"relu\"))\n",
"model.add(layers.BatchNormalization())\n",
"model.add(layers.Conv2D(128, (3, 3), padding=\"same\", activation=\"relu\"))\n",
"model.add(layers.BatchNormalization())\n",
"model.add(layers.MaxPooling2D((2, 2)))\n",
"model.add(layers.Dropout(0.4))\n",
"\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",
"\n",
"\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,15]:\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.85."
],
"metadata": {
"id": "RF4xK1cxamBc"
}
}
]
}

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

@ -0,0 +1,554 @@
# Отчёт по лабораторной работе №3
**Кнзев Станислав, Жихарев Данила — А-02-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 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step - accuracy: 0.9909 - loss: 0.0257
Loss on test data: 0.02905484288930893
Accuracy on test data: 0.9904999732971191
```
### 7) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания.
```python
# вывод двух тестовых изображений и результатов распознавания
for n in [3,26]:
result = model.predict(X_test[n:n+1])
print('NN output:', result)
plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))
plt.show()
print('Real mark: ', np.argmax(y_test[n]))
print('NN answer: ', np.argmax(result))
```
![picture](images/1.png)
```
Real mark: 2
NN answer: 2
```
![picture](images/2.png)
```
Real mark: 9
NN answer: 9
```
### 8) Вывели отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки.
```python
# истинные метки классов
true_labels = np.argmax(y_test, axis=1)
# предсказанные метки классов
predicted_labels = np.argmax(model.predict(X_test), axis=1)
# отчет о качестве классификации
print(classification_report(true_labels, predicted_labels))
# вычисление матрицы ошибок
conf_matrix = confusion_matrix(true_labels, predicted_labels)
# отрисовка матрицы ошибок в виде "тепловой карты"
display = ConfusionMatrixDisplay(confusion_matrix=conf_matrix)
display.plot()
plt.show()
```
```
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 5ms/step
precision recall f1-score support
0 0.99 0.99 0.99 997
1 1.00 1.00 1.00 1164
2 0.99 0.98 0.99 1030
3 1.00 0.99 0.99 1031
4 0.99 1.00 0.99 967
5 0.98 1.00 0.99 860
6 0.99 1.00 1.00 977
7 0.99 0.99 0.99 1072
8 0.99 0.98 0.99 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
```
![picture](images/3.png)
### 9) Загрузили, предобработали и подали на вход обученной нейронной сети собственное изображение, созданное при выполнении лабораторной работы №1. Вывели изображение и результат распознавания.
```python
# загрузка собственного изображения
from PIL import Image
for name_image in ['цифра 3.png', 'цифра 6.png']:
file_data = Image.open(name_image)
file_data = file_data.convert('L') # перевод в градации серого
test_img = np.array(file_data)
# вывод собственного изображения
plt.imshow(test_img, cmap=plt.get_cmap('gray'))
plt.show()
# предобработка
test_img = test_img / 255
test_img = np.reshape(test_img, (1,28,28,1))
# распознавание
result = model.predict(test_img)
print('I think it\'s', np.argmax(result))
```
![picture](images/4.png)
```
I think it's 3
```
![picture](images/5.png)
```
I think it's 6
```
### 10) Загрузили с диска модель, сохраненную при выполнении лабораторной работы №1. Вывели информацию об архитектуре модели. Повторили для этой модели п. 6.
```python
model_lr1 = keras.models.load_model("model_1h100_2h50.keras")
model_lr1.summary()
```
**Model: "sequential_10"**
| Layer (type) | Output Shape | Param # |
|------------------|-------------:|--------:|
| dense_22 (Dense) | (None, 100) | 78,500 |
| dense_23 (Dense) | (None, 50) | 5,050 |
| dense_24 (Dense) | (None, 10) | 510 |
**Total params:** 84,062 (328.37 KB)
**Trainable params:** 84,060 (328.36 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 ━━━━━━━━━━━━━━━━━━━━ 3s 8ms/step - accuracy: 0.9453 - loss: 0.1872
Loss on test data: 0.19880765676498413
Accuracy on test data: 0.9416000247001648
```
### 11) Сравнили обученную модель сверточной сети и наилучшую модель полносвязной сети из лабораторной работы №1 по следующим показателям:
### - количество настраиваемых параметров в сети
### - количество эпох обучения
### - качество классификации тестовой выборки.
### Сделали выводы по результатам применения сверточной нейронной сети для распознавания изображений.
Таблица1:
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|----------|-------------------------------------|---------------------------|-----------------------------------------|
| Сверточная | 34 826 | 15 | accuracy:0.990 ; loss:0.029 |
| Полносвязная | 84 062 | 50 | accuracy:0.942 ; loss:0.198 |
##### По результатам применения сверточной НС, а также по результатам таблицы 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()
```
![picture](images/6.png)
### 3) Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения сверточной нейронной сети. Входные данные принимают значения от 0 до 1, метки цифр закодированы по принципу «one-hot encoding». Вывели размерности предобработанных обучающих и тестовых массивов данных.
```python
# Зададим параметры данных и модели
num_classes = 10
input_shape = (32, 32, 3)
# Приведение входных данных к диапазону [0, 1]
X_train = X_train / 255
X_test = X_test / 255
print('Shape of transformed X train:', X_train.shape)
print('Shape of transformed X test:', X_test.shape)
# переведем метки в one-hot
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print('Shape of transformed y train:', y_train.shape)
print('Shape of transformed y test:', y_test.shape)
```
```
Shape of transformed X train: (50000, 32, 32, 3)
Shape of transformed X test: (10000, 32, 32, 3)
Shape of transformed y train: (50000, 10)
Shape of transformed y test: (10000, 10)
```
### 4) Реализовали модель сверточной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети.
```python
# создаем модель
model = Sequential()
# Блок 1
model.add(layers.Conv2D(32, (3, 3), padding="same",
activation="relu", input_shape=input_shape))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(32, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.25))
# Блок 2
model.add(layers.Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.25))
# Блок 3
model.add(layers.Conv2D(128, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(128, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.4))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(num_classes, activation="softmax"))
model.summary()
```
**Model: "sequential_9"**
| Layer (type) | Output Shape | Param # |
|--------------------------------------------|-------------------|---------:|
| conv2d_41 (Conv2D) | (None, 32, 32, 32) | 896 |
| batch_normalization_6 (BatchNormalization) | (None, 32, 32, 32) | 128 |
| conv2d_42 (Conv2D) | (None, 32, 32, 32) | 9,248 |
| batch_normalization_7 (BatchNormalization) | (None, 32, 32, 32) | 128 |
| max_pooling2d_26 (MaxPooling2D) | (None, 16, 16, 32) | 0 |
| dropout_24 (Dropout) | (None, 16, 16, 32) | 0 |
| conv2d_43 (Conv2D) | (None, 16, 16, 64) | 18,496 |
| batch_normalization_8 (BatchNormalization) | (None, 16, 16, 64) | 256 |
| conv2d_44 (Conv2D) | (None, 16, 16, 64) | 36,928 |
| batch_normalization_9 (BatchNormalization) | (None, 16, 16, 64) | 256 |
| max_pooling2d_27 (MaxPooling2D) | (None, 8, 8, 64) | 0 |
| dropout_25 (Dropout) | (None, 8, 8, 64) | 0 |
| conv2d_45 (Conv2D) | (None, 8, 8, 128) | 73,856 |
| batch_normalization_10 (BatchNormalization)| (None, 8, 8, 128) | 512 |
| conv2d_46 (Conv2D) | (None, 8, 8, 128) | 147,584 |
| batch_normalization_11 (BatchNormalization)| (None, 8, 8, 128) | 512 |
| max_pooling2d_28 (MaxPooling2D) | (None, 4, 4, 128) | 0 |
| dropout_26 (Dropout) | (None, 4, 4, 128) | 0 |
| flatten_9 (Flatten) | (None, 2048) | 0 |
| dense_17 (Dense) | (None, 128) | 262,272 |
| dropout_27 (Dropout) | (None, 128) | 0 |
| dense_18 (Dense) | (None, 10) | 1,290 |
**Total params:** 552,362 (2.11 MB)
**Trainable params:** 551,466 (2.10 MB)
**Non-trainable params:** 896 (3.50 KB)
```python
# компилируем и обучаем модель
batch_size = 64
epochs = 50
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)
```
### 5) Оценили качество обучения на тестовых данных. Вывели значение функции ошибки и значение метрики качества классификации на тестовых данных.
```python
# Оценка качества работы модели на тестовых данных
scores = model.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
```
313/313 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.8507 - loss: 0.5097
Loss on test data: 0.4886781871318817
Accuracy on test data: 0.8521999716758728
```
### 6) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания.
```python
# вывод двух тестовых изображений и результатов распознавания
for n in [3,15]:
result = model.predict(X_test[n:n+1])
print('NN output:', result)
plt.imshow(X_test[n].reshape(32,32,3), cmap=plt.get_cmap('gray'))
plt.show()
print('Real mark: ', np.argmax(y_test[n]))
print('NN answer: ', np.argmax(result))
```
![picture](images/7.png)
```
Real mark: 0
NN answer: 0
```
![picture](images/8.png)
```
Real mark: 2
NN answer: 6
```
### 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 4ms/step
precision recall f1-score support
airplane 0.86 0.86 0.86 986
automobile 0.97 0.90 0.93 971
bird 0.85 0.76 0.80 1043
cat 0.72 0.74 0.73 1037
deer 0.84 0.84 0.84 969
dog 0.74 0.79 0.77 979
frog 0.88 0.88 0.88 1025
horse 0.86 0.89 0.88 948
ship 0.92 0.93 0.93 1003
truck 0.89 0.93 0.91 1039
accuracy 0.85 10000
macro avg 0.85 0.85 0.85 10000
weighted avg 0.85 0.85 0.85 10000
```
![picture](images/9.png)
#### По результатам классификации датасета CIFAR-10 созданной сверточной моделью можно сделать вывод, что она довольно неплохо справилась с задачей. Полученные метрики оценки качества имеют показатели в районе 0.85.

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

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

После

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

@ -0,0 +1,449 @@
{
"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": [
"# импорт модулей\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=26,\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[26])\n",
"print('len:',len(X_train[26]))"
],
"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[26])\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[26])\n",
"print('len:',len(X_train[26]))"
],
"metadata": {
"id": "vudlgqoCbjU1"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"review_as_text = ' '.join(id_to_word[id] for id in X_train[26])\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.8556 ; loss:0.5214 ; AUC ROC:0.9165 |\n"
],
"metadata": {
"id": "xvoivjuNFlEf"
}
},
{
"cell_type": "markdown",
"source": [
"#### По результатам применения рекуррентной нейронной сети, а также по данным таблицы 1 можно сделать вывод, что модель хорошо справилась с задачей определения тональности текста. Показатель accuracy = 0.8556 превышает требуемый порог 0.8. Значение AUC ROC = 0.9165 (> 0.9) говорит о высокой способности модели различать два класса (положительные и отрицательные отзывы)."
],
"metadata": {
"id": "YctF8h_sIB-P"
}
}
]
}

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

@ -0,0 +1,333 @@
# Отчёт по лабораторной работе №4
**Кнзев Станислав, Жихарев Данила — А-02-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=26,
start_char=1,
oov_char=2,
index_from=index_from
)
# вывод размерностей
print('Shape of X train:', X_train.shape)
print('Shape of y train:', y_train.shape)
print('Shape of X test:', X_test.shape)
print('Shape of y test:', y_test.shape)
```
```
Shape of X train: (25000,)
Shape of y train: (25000,)
Shape of X test: (25000,)
Shape of y test: (25000,)
```
### 3) Вывели один отзыв из обучающего множества в виде списка индексов слов. Преобразовали список индексов в текст и вывели отзыв в виде текста. Вывели длину отзыва. Вывели метку класса данного отзыва и название класса (1 – Positive, 0 – Negative).
```python
# создание словаря для перевода индексов в слова
# заргузка словаря "слово:индекс"
word_to_id = imdb.get_word_index()
# уточнение словаря
word_to_id = {key:(value + index_from) for key,value in word_to_id.items()}
word_to_id["<PAD>"] = 0
word_to_id["<START>"] = 1
word_to_id["<UNK>"] = 2
word_to_id["<UNUSED>"] = 3
# создание обратного словаря "индекс:слово"
id_to_word = {value:key for key,value in word_to_id.items()}
```
```python
print(X_train[26])
print('len:',len(X_train[26]))
```
```
[1, 4, 78, 46, 304, 39, 2, 7, 968, 2, 295, 209, 101, 147, 65, 10, 10, 2643, 2, 497, 8, 30, 6, 147, 284, 5, 996, 174, 10, 10, 11, 4, 130, 4, 2, 4979, 11, 2, 10, 10, 2]
len: 41
```
```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> the bad out takes from <UNK> of fire <UNK> together without any real story br br dean <UNK> tries to be a real actor and fails again br br in the end the <UNK> quit in <UNK> br br <UNK>
len: 193
```
### 4) Вывели максимальную и минимальную длину отзыва в обучающем множестве.
```python
print('MAX Len: ',len(max(X_train, key=len)))
print('MIN Len: ',len(min(X_train, key=len)))
```
```
MAX Len: 2494
MIN Len: 11
```
### 5) Провели предобработку данных. Выбрали единую длину, к которой будут приведены все отзывы. Короткие отзывы дополнили спецсимволами, а длинные обрезали до выбранной длины.
```python
# предобработка данных
from tensorflow.keras.utils import pad_sequences
max_words = 500
X_train = pad_sequences(X_train, maxlen=max_words, value=0, padding='pre', truncating='post')
X_test = pad_sequences(X_test, maxlen=max_words, value=0, padding='pre', truncating='post')
```
### 6) Повторили пункт 4.
```python
print('MAX Len: ',len(max(X_train, key=len)))
print('MIN Len: ',len(min(X_train, key=len)))
```
```
MAX Len: 500
MIN Len: 500
```
### 7) Повторили пункт 3. Сделали вывод о том, как отзыв преобразовался после предобработки.
```python
print(X_train[26])
print('len:',len(X_train[26]))
```
```
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 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 4 78
46 304 39 2 7 968 2 295 209 101 147 65 10 10
2643 2 497 8 30 6 147 284 5 996 174 10 10 11
4 130 4 2 4979 11 2 10 10 2]
len: 500
```
```python
review_as_text = ' '.join(id_to_word[id] for id in X_train[26])
print(review_as_text)
print('len:',len(review_as_text))
```
```
<PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <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> the bad out takes from <UNK> of fire <UNK> together without any real story br br dean <UNK> tries to be a real actor and fails again br br in the end the <UNK> quit in <UNK> br br <UNK>
len: 2947
```
#### После обработки в начало отзыва добавилось необходимое количество токенов <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 ... 1039 7 12]
[ 0 0 0 ... 5 2 1773]
[ 0 0 0 ... 220 175 96]
...
[ 1 3264 153 ... 157 746 14]
[ 0 0 0 ... 3459 55 680]
[ 0 0 0 ... 14 31 56]]
X train:
[[ 0 0 0 ... 241 3366 56]
[ 0 0 0 ... 18 4 755]
[ 0 0 0 ... 149 14 20]
...
[ 0 0 0 ... 2 2152 1835]
[ 0 0 0 ... 3768 3508 3311]
[ 0 0 0 ... 511 8 2725]]
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 ━━━━━━━━━━━━━━━━━━━━ 8s 21ms/step - accuracy: 0.9593 - loss: 0.1184 - val_accuracy: 0.8632 - val_loss: 0.4331
Epoch 2/3
313/313 ━━━━━━━━━━━━━━━━━━━━ 7s 22ms/step - accuracy: 0.9652 - loss: 0.1055 - val_accuracy: 0.8722 - val_loss: 0.5389
Epoch 3/3
313/313 ━━━━━━━━━━━━━━━━━━━━ 6s 20ms/step - accuracy: 0.9741 - loss: 0.0829 - val_accuracy: 0.8648 - val_loss: 0.4959
<keras.src.callbacks.history.History at 0x7e2b23808f50>
```
```python
test_loss, test_acc = model.evaluate(X_test, y_test)
print(f"\nTest accuracy: {test_acc}")
```
```
782/782 ━━━━━━━━━━━━━━━━━━━━ 7s 8ms/step - accuracy: 0.8566 - loss: 0.5214
Test accuracy: 0.8555999994277954
```
### 10) Оценили качество обучения на тестовых данных:
### - вывели значение метрики качества классификации на тестовых данных
### - вывели отчет о качестве классификации тестовой выборки
### - построили ROC-кривую по результату обработки тестовой выборки и вычислили площадь под ROC-кривой (AUC ROC)
```python
#значение метрики качества классификации на тестовых данных
print(f"\nTest accuracy: {test_acc}")
```
```
Test accuracy: 0.8555999994277954
```
```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.85 0.87 0.86 12500
Positive 0.87 0.84 0.85 12500
accuracy 0.86 25000
macro avg 0.86 0.86 0.86 25000
weighted avg 0.86 0.86 0.86 25000
```
```python
#построение ROC-кривой и AUC ROC
from sklearn.metrics import roc_curve, auc
fpr, tpr, thresholds = roc_curve(y_test, y_score)
plt.plot(fpr, tpr)
plt.grid()
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC')
plt.show()
print('AUC ROC:', auc(fpr, tpr))
```
![picture](images/1.png)
```
AUC ROC: 0.9165464031999999
```
### 11) Сделали выводы по результатам применения рекуррентной нейронной сети для решения задачи определения тональности текста.
Таблица1:
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|----------|-------------------------------------|---------------------------|-----------------------------------------|
| Рекуррентная | 184 897 | 3 | accuracy:0.8556 ; loss:0.5214 ; AUC ROC:0.9165 |
#### По результатам применения рекуррентной нейронной сети, а также по данным таблицы 1 можно сделать вывод, что модель хорошо справилась с задачей определения тональности текста. Показатель accuracy = 0.8556 превышает требуемый порог 0.8.
#### Значение AUC ROC = 0.9165 (> 0.9) говорит о высокой способности модели различать два класса (положительные и отрицательные отзывы).
Загрузка…
Отмена
Сохранить