Сравнить коммиты
9 Коммитов
| Автор | SHA1 | Дата |
|---|---|---|
|
|
0afecdbc43 | 3 недель назад |
|
|
16441c99ef | 3 недель назад |
|
|
9c1d9f27ca | 3 недель назад |
|
|
c7a9f84efe | 1 месяц назад |
|
|
a8217ec15e | 2 месяцев назад |
|
|
2b771f3f16 | 2 месяцев назад |
|
|
0cefa2a80b | 3 месяцев назад |
|
|
8ad9cbda10 | 3 месяцев назад |
|
|
96e8cf5799 | 3 месяцев назад |
|
После Ширина: | Высота: | Размер: 13 KiB |
|
После Ширина: | Высота: | Размер: 25 KiB |
|
После Ширина: | Высота: | Размер: 19 KiB |
|
После Ширина: | Высота: | Размер: 24 KiB |
|
После Ширина: | Высота: | Размер: 22 KiB |
|
После Ширина: | Высота: | Размер: 29 KiB |
|
После Ширина: | Высота: | Размер: 22 KiB |
|
После Ширина: | Высота: | Размер: 28 KiB |
|
После Ширина: | Высота: | Размер: 26 KiB |
|
После Ширина: | Высота: | Размер: 25 KiB |
|
После Ширина: | Высота: | Размер: 19 KiB |
|
После Ширина: | Высота: | Размер: 13 KiB |
|
После Ширина: | Высота: | Размер: 19 KiB |
|
После Ширина: | Высота: | Размер: 12 KiB |
|
После Ширина: | Высота: | Размер: 13 KiB |
|
После Ширина: | Высота: | Размер: 17 KiB |
|
После Ширина: | Высота: | Размер: 28 KiB |
|
После Ширина: | Высота: | Размер: 19 KiB |
|
После Ширина: | Высота: | Размер: 25 KiB |
|
После Ширина: | Высота: | Размер: 20 KiB |
|
После Ширина: | Высота: | Размер: 20 KiB |
|
После Ширина: | Высота: | Размер: 26 KiB |
@ -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])
|
||||
```
|
||||
|
||||
|
||||

|
||||
|
||||
```
|
||||
6
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
4
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
4
|
||||
```
|
||||
|
||||

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

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

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

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

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

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

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

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

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

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

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

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

|
||||
|
||||
```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) Результаты исследования архитектуры нейронной сети занесли в таблицу:
|
||||
|
||||

|
||||
|
||||
|
||||
### По результатам исследования сделали выводы и выбрали наилучшую архитектуру нейронной сети с точки зрения качества классификации.
|
||||
|
||||
**Из таблицы следует, что лучшей архитектурой является НС с двумя скрытыми слоями по 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)))
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||

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

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

|
||||
|
||||
```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 |
|
После Ширина: | Высота: | Размер: 1.2 KiB |
|
После Ширина: | Высота: | Размер: 1.2 KiB |
|
После Ширина: | Высота: | Размер: 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
|
||||
|
||||
|
После Ширина: | Высота: | Размер: 42 KiB |
|
После Ширина: | Высота: | Размер: 22 KiB |
|
После Ширина: | Высота: | Размер: 24 KiB |
|
После Ширина: | Высота: | Размер: 29 KiB |
|
После Ширина: | Высота: | Размер: 22 KiB |
|
После Ширина: | Высота: | Размер: 48 KiB |
|
После Ширина: | Высота: | Размер: 107 KiB |
|
После Ширина: | Высота: | Размер: 32 KiB |
|
После Ширина: | Высота: | Размер: 84 KiB |
|
После Ширина: | Высота: | Размер: 96 KiB |
|
После Ширина: | Высота: | Размер: 30 KiB |
|
После Ширина: | Высота: | Размер: 61 KiB |
|
После Ширина: | Высота: | Размер: 73 KiB |
|
После Ширина: | Высота: | Размер: 94 KiB |
|
После Ширина: | Высота: | Размер: 87 KiB |
|
После Ширина: | Высота: | Размер: 52 KiB |
|
После Ширина: | Высота: | Размер: 55 KiB |
@ -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
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
5.95
|
||||
@ -0,0 +1 @@
|
||||
0.45
|
||||
|
После Ширина: | Высота: | Размер: 52 KiB |
|
После Ширина: | Высота: | Размер: 100 KiB |
|
После Ширина: | Высота: | Размер: 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)
|
||||
```
|
||||

|
||||
```
|
||||
Исходные данные:
|
||||
[[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')
|
||||
```
|
||||

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

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

|
||||
```
|
||||
amount: 21
|
||||
amount_ae: 287
|
||||
```
|
||||

|
||||

|
||||
|
||||
```
|
||||
Оценка качества 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)
|
||||
```
|
||||

|
||||
```
|
||||
amount: 21
|
||||
amount_ae: 28
|
||||
```
|
||||

|
||||

|
||||
|
||||
```
|
||||
Оценка качества 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)
|
||||
```
|
||||

|
||||
|
||||
### 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')
|
||||
```
|
||||
```
|
||||
Аномалий не обнаружено
|
||||
```
|
||||

|
||||
|
||||
```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 аномалий
|
||||
```
|
||||

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

|
||||
|
||||
### 12) Результаты исследования занесли в таблицу:
|
||||
Табл. 1 Результаты задания №1
|
||||
|
||||
| | Количество<br>скрытых слоев | Количество<br>нейронов в скрытых слоях | Количество<br>эпох обучения | Ошибка<br>MSE_stop | Порог ошибки<br>реконструкции | Значение показателя<br>Excess | Значение показателя<br>Approx | Количество обнаруженных<br>аномалий |
|
||||
|-----:|------------------------------|----------------------------------------|-----------------------------|--------------------|-------------------------------|-------------------------------|--------------------------------|-------------------------------------|
|
||||
| AE1 | 1 | 1 | 1000 | 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')
|
||||
```
|
||||

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

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

|
||||
|
||||
```python
|
||||
# тестирование АE3
|
||||
predicted_labels3_v2, ire3_v2 = lib.predict_ae(ae3_v2_trained, test, IREth3_v2)
|
||||
```
|
||||
|
||||
```python
|
||||
# Построение графика ошибки реконструкции
|
||||
lib.ire_plot('test', ire3_v2, IREth3_v2, 'AE3_v2')
|
||||
```
|
||||

|
||||
|
||||
```python
|
||||
# тестирование А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
|
||||
|
После Ширина: | Высота: | Размер: 7.3 KiB |
|
После Ширина: | Высота: | Размер: 7.0 KiB |
|
После Ширина: | Высота: | Размер: 30 KiB |
|
После Ширина: | Высота: | Размер: 7.5 KiB |
|
После Ширина: | Высота: | Размер: 7.4 KiB |
|
После Ширина: | Высота: | Размер: 122 KiB |
|
После Ширина: | Высота: | Размер: 12 KiB |
|
После Ширина: | Высота: | Размер: 11 KiB |
|
После Ширина: | Высота: | Размер: 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))
|
||||
```
|
||||

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

|
||||
```
|
||||
Real mark: 9
|
||||
NN answer: 9
|
||||
```
|
||||
|
||||
### 8) Вывели отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки.
|
||||
|
||||
```python
|
||||
# истинные метки классов
|
||||
true_labels = np.argmax(y_test, axis=1)
|
||||
# предсказанные метки классов
|
||||
predicted_labels = np.argmax(model.predict(X_test), axis=1)
|
||||
|
||||
# отчет о качестве классификации
|
||||
print(classification_report(true_labels, predicted_labels))
|
||||
# вычисление матрицы ошибок
|
||||
conf_matrix = confusion_matrix(true_labels, predicted_labels)
|
||||
# отрисовка матрицы ошибок в виде "тепловой карты"
|
||||
display = ConfusionMatrixDisplay(confusion_matrix=conf_matrix)
|
||||
display.plot()
|
||||
plt.show()
|
||||
```
|
||||
```
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 5ms/step
|
||||
precision recall f1-score support
|
||||
|
||||
0 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
|
||||
```
|
||||

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

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

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

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

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

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

|
||||
|
||||
#### По результатам классификации датасета CIFAR-10 созданной сверточной моделью можно сделать вывод, что она довольно неплохо справилась с задачей. Полученные метрики оценки качества имеют показатели в районе 0.85.
|
||||
|
После Ширина: | Высота: | Размер: 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))
|
||||
```
|
||||

|
||||
```
|
||||
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) говорит о высокой способности модели различать два класса (положительные и отрицательные отзывы).
|
||||