Сравнить коммиты
6 Коммитов
main
...
a58df6deff
| Автор | SHA1 | Дата | |
|---|---|---|---|
| a58df6deff | |||
| a8c99d44de | |||
| 0a4883e6ff | |||
| cbf321ddd1 | |||
| 054cb58fe2 | |||
| 48d7dbe714 |
Двоичные данные
labworks/LW1/1.png
Обычный файл
|
После Ширина: | Высота: | Размер: 22 KiB |
Двоичные данные
labworks/LW1/10.png
Обычный файл
|
После Ширина: | Высота: | Размер: 7.6 KiB |
Двоичные данные
labworks/LW1/11.png
Обычный файл
|
После Ширина: | Высота: | Размер: 6.3 KiB |
Двоичные данные
labworks/LW1/190.png
Обычный файл
|
После Ширина: | Высота: | Размер: 6.3 KiB |
Двоичные данные
labworks/LW1/2.png
Обычный файл
|
После Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
labworks/LW1/3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
labworks/LW1/4.png
Обычный файл
|
После Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
labworks/LW1/5.png
Обычный файл
|
После Ширина: | Высота: | Размер: 27 KiB |
Двоичные данные
labworks/LW1/6.png
Обычный файл
|
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
labworks/LW1/690.png
Обычный файл
|
После Ширина: | Высота: | Размер: 7.6 KiB |
Двоичные данные
labworks/LW1/7.png
Обычный файл
|
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
labworks/LW1/8.png
Обычный файл
|
После Ширина: | Высота: | Размер: 8.0 KiB |
Двоичные данные
labworks/LW1/9.png
Обычный файл
|
После Ширина: | Высота: | Размер: 7.0 KiB |
2897
labworks/LW1/LR_1.ipynb
Обычный файл
2897
labworks/LW1/LR_1full.ipynb
Обычный файл
Двоичные данные
labworks/LW1/images/1.png
Обычный файл
|
После Ширина: | Высота: | Размер: 22 KiB |
Двоичные данные
labworks/LW1/images/10.png
Обычный файл
|
После Ширина: | Высота: | Размер: 7.6 KiB |
Двоичные данные
labworks/LW1/images/11.png
Обычный файл
|
После Ширина: | Высота: | Размер: 6.3 KiB |
Двоичные данные
labworks/LW1/images/190 (2).png
Обычный файл
|
После Ширина: | Высота: | Размер: 208 B |
Двоичные данные
labworks/LW1/images/190.png
Обычный файл
|
После Ширина: | Высота: | Размер: 6.3 KiB |
Двоичные данные
labworks/LW1/images/2.png
Обычный файл
|
После Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
labworks/LW1/images/3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
labworks/LW1/images/4.png
Обычный файл
|
После Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
labworks/LW1/images/5.png
Обычный файл
|
После Ширина: | Высота: | Размер: 27 KiB |
Двоичные данные
labworks/LW1/images/6.png
Обычный файл
|
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
labworks/LW1/images/690 (1).png
Обычный файл
|
После Ширина: | Высота: | Размер: 333 B |
Двоичные данные
labworks/LW1/images/690.png
Обычный файл
|
После Ширина: | Высота: | Размер: 7.6 KiB |
Двоичные данные
labworks/LW1/images/7.png
Обычный файл
|
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
labworks/LW1/images/8.png
Обычный файл
|
После Ширина: | Высота: | Размер: 8.0 KiB |
Двоичные данные
labworks/LW1/images/9.png
Обычный файл
|
После Ширина: | Высота: | Размер: 7.0 KiB |
610
labworks/LW1/report.md
Обычный файл
@@ -0,0 +1,610 @@
|
|||||||
|
# Отчет по лабораторной работе №1
|
||||||
|
Касимов Азамат, Немыкин Никита, А-01-22
|
||||||
|
|
||||||
|
## 1. В среде GoogleColab создали блокнот(notebook.ipynb).
|
||||||
|
```
|
||||||
|
import os
|
||||||
|
os.chdir('/content/drive/MyDrive/Colab Notebooks')
|
||||||
|
```
|
||||||
|
|
||||||
|
* импорт модулей
|
||||||
|
```
|
||||||
|
from tensorflow import keras
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
import sklearn
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Загрузка датасета MNIST
|
||||||
|
```
|
||||||
|
from keras.datasets import mnist
|
||||||
|
(X_train, y_train), (X_test, y_test) = mnist.load_data()
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Разбиение набора данных на обучающие и тестовые
|
||||||
|
```
|
||||||
|
from sklearn.model_selection import train_test_split
|
||||||
|
```
|
||||||
|
* объединяем в один набор
|
||||||
|
```
|
||||||
|
X = np.concatenate((X_train, X_test))
|
||||||
|
y = np.concatenate((y_train, y_test))
|
||||||
|
```
|
||||||
|
* разбиваем по вариантам
|
||||||
|
```
|
||||||
|
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size = 10000,train_size = 60000, random_state = 27)
|
||||||
|
```
|
||||||
|
|
||||||
|
* Вывод размерностей
|
||||||
|
```
|
||||||
|
print('Shape of X train:', X_train.shape)
|
||||||
|
print('Shape of y train:', y_train.shape)
|
||||||
|
```
|
||||||
|
|
||||||
|
> Shape of X train: (60000, 28, 28)
|
||||||
|
> Shape of y train: (60000,)
|
||||||
|
|
||||||
|
## 4. Вывод элементов обучающих данных
|
||||||
|
* Создаем subplot для 4 изображений
|
||||||
|
```
|
||||||
|
fig, axes = plt.subplots(1, 4, figsize=(10, 3))
|
||||||
|
|
||||||
|
for i in range(4):
|
||||||
|
axes[i].imshow(X_train[i], cmap=plt.get_cmap('gray'))
|
||||||
|
axes[i].set_title(f'Label: {y_train[i]}')
|
||||||
|
|
||||||
|
# Добавляем метку как заголовок
|
||||||
|
|
||||||
|
plt.show()
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 5. Предобработка данных
|
||||||
|
* развернем каждое изображение 28*28 в вектор 784
|
||||||
|
```
|
||||||
|
num_pixels = X_train.shape[1] * X_train.shape[2]
|
||||||
|
X_train = X_train.reshape(X_train.shape[0], num_pixels) / 255
|
||||||
|
X_test = X_test.reshape(X_test.shape[0], num_pixels) / 255
|
||||||
|
print('Shape of transformed X train:', X_train.shape)
|
||||||
|
```
|
||||||
|
|
||||||
|
> Shape of transformed X train: (60000, 784)
|
||||||
|
|
||||||
|
* переведем метки в one-hot
|
||||||
|
```
|
||||||
|
from keras.utils import to_categorical
|
||||||
|
y_train = to_categorical(y_train)
|
||||||
|
y_test = to_categorical(y_test)
|
||||||
|
print('Shape of transformed y train:', y_train.shape)
|
||||||
|
num_classes = y_train.shape[1]
|
||||||
|
```
|
||||||
|
|
||||||
|
> Shape of transformed y train: (60000, 10)
|
||||||
|
|
||||||
|
## 6. Реализация и обучение однослойной нейронной сети
|
||||||
|
```
|
||||||
|
from keras.models import Sequential
|
||||||
|
from keras.layers import Dense
|
||||||
|
```
|
||||||
|
|
||||||
|
* 6.1. создаем модель - объявляем ее объектом класса Sequential
|
||||||
|
```
|
||||||
|
model_1 = Sequential()
|
||||||
|
model_1.add(Dense(units=num_classes,input_dim=num_pixels, activation='softmax'))
|
||||||
|
```
|
||||||
|
* 6.2. компилируем модель
|
||||||
|
```
|
||||||
|
model_1.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
||||||
|
|
||||||
|
print("Архитектура нейронной сети:")
|
||||||
|
model_1.summary()
|
||||||
|
```
|
||||||
|
|
||||||
|
> Архитектура нейронной сети:
|
||||||
|
> Model: "sequential"
|
||||||
|
> ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||||
|
> ┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||||
|
> ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||||
|
> │ dense (Dense) │ (None, 10) │ 7,850 │
|
||||||
|
> └─────────────────────────────────┴────────────────────────┴───────────────┘
|
||||||
|
> Total params: 7,850 (30.66 KB)
|
||||||
|
> Trainable params: 7,850 (30.66 KB)
|
||||||
|
> Non-trainable params: 0 (0.00 B) '
|
||||||
|
|
||||||
|
* Обучаем модель
|
||||||
|
```
|
||||||
|
history = model_1.fit(
|
||||||
|
X_train, y_train,
|
||||||
|
validation_split=0.1,
|
||||||
|
epochs=50
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
* Выводим график функции ошибки
|
||||||
|
```
|
||||||
|
plt.figure(figsize=(12, 5))
|
||||||
|
|
||||||
|
plt.subplot(1, 2, 1)
|
||||||
|
plt.plot(history.history['loss'], label='Обучающая ошибка')
|
||||||
|
plt.plot(history.history['val_loss'], label='Валидационная ошибка')
|
||||||
|
plt.title('Функция ошибки по эпохам')
|
||||||
|
plt.xlabel('Эпохи')
|
||||||
|
plt.ylabel('Categorical Crossentropy')
|
||||||
|
plt.legend()
|
||||||
|
plt.grid(True)
|
||||||
|
```
|
||||||
|
|
||||||
|

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

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

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

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

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

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

|
||||||
|
>Real mark: 7
|
||||||
|
>NN answer: 7
|
||||||
|
|
||||||
|
```
|
||||||
|
n = 810
|
||||||
|
result = model_2l_100.predict(X_test[n:n+1])
|
||||||
|
print('NN output:', result)
|
||||||
|
|
||||||
|
plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))
|
||||||
|
plt.show()
|
||||||
|
print('Real mark: ', str(np.argmax(y_test[n])))
|
||||||
|
print('NN answer: ', str(np.argmax(result)))
|
||||||
|
```
|
||||||
|
|
||||||
|
> NN output: [[8.1927046e-06 9.8501807e-01 4.7102575e-03 1.5754283e-03 5.3024664e-06
|
||||||
|
> 2.3075400e-03 6.3471968e-04 7.6599965e-05 5.5682263e-03 9.5791329e-05]]
|
||||||
|

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

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

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

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

|
||||||
|
|
||||||
|
```
|
||||||
|
test_290_img = test_290_img / 255
|
||||||
|
test_290_img = test_290_img.reshape(1, num_pixels)
|
||||||
|
|
||||||
|
result_290 = model.predict(test_290_img)
|
||||||
|
print('I think it\'s', np.argmax(result_290))
|
||||||
|
```
|
||||||
|
|
||||||
|
> I think it's 4
|
||||||
|
|
||||||
|
При повороте изображений сеть не распознала цифры правильно. Так как она не обучалась на повернутых изображениях.
|
||||||
Двоичные данные
labworks/LW2/images/1.png
Обычный файл
|
После Ширина: | Высота: | Размер: 41 KiB |
Двоичные данные
labworks/LW2/images/10.png
Обычный файл
|
После Ширина: | Высота: | Размер: 21 KiB |
Двоичные данные
labworks/LW2/images/11.png
Обычный файл
|
После Ширина: | Высота: | Размер: 27 KiB |
Двоичные данные
labworks/LW2/images/12.png
Обычный файл
|
После Ширина: | Высота: | Размер: 34 KiB |
Двоичные данные
labworks/LW2/images/13.png
Обычный файл
|
После Ширина: | Высота: | Размер: 22 KiB |
Двоичные данные
labworks/LW2/images/14.png
Обычный файл
|
После Ширина: | Высота: | Размер: 92 KiB |
Двоичные данные
labworks/LW2/images/15.png
Обычный файл
|
После Ширина: | Высота: | Размер: 100 KiB |
Двоичные данные
labworks/LW2/images/16.png
Обычный файл
|
После Ширина: | Высота: | Размер: 56 KiB |
Двоичные данные
labworks/LW2/images/17.png
Обычный файл
|
После Ширина: | Высота: | Размер: 52 KiB |
Двоичные данные
labworks/LW2/images/2.png
Обычный файл
|
После Ширина: | Высота: | Размер: 50 KiB |
Двоичные данные
labworks/LW2/images/3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 109 KiB |
Двоичные данные
labworks/LW2/images/4.png
Обычный файл
|
После Ширина: | Высота: | Размер: 33 KiB |
Двоичные данные
labworks/LW2/images/5.png
Обычный файл
|
После Ширина: | Высота: | Размер: 88 KiB |
Двоичные данные
labworks/LW2/images/6.png
Обычный файл
|
После Ширина: | Высота: | Размер: 102 KiB |
Двоичные данные
labworks/LW2/images/7.png
Обычный файл
|
После Ширина: | Высота: | Размер: 30 KiB |
Двоичные данные
labworks/LW2/images/8.png
Обычный файл
|
После Ширина: | Высота: | Размер: 62 KiB |
Двоичные данные
labworks/LW2/images/9.png
Обычный файл
|
После Ширина: | Высота: | Размер: 74 KiB |
688
labworks/LW2/report.md
Обычный файл
@@ -0,0 +1,688 @@
|
|||||||
|
# Отчёт по лабораторной работе №2
|
||||||
|
|
||||||
|
**Касимов Азамат, Немыкин Никита — А-01-22**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Задание 1
|
||||||
|
|
||||||
|
### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# импорт модулей
|
||||||
|
import os
|
||||||
|
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab2')
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
import lab02_lib as lib
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2) Сгенерировали индивидуальный набор двумерных данных в пространстве признаков с координатами центра (6, 6), где 6 – номер бригады. Вывели полученные данные на рисунок и в консоль.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# генерация датасета
|
||||||
|
data = lib.datagen(6, 6, 1000, 2)
|
||||||
|
|
||||||
|
# вывод данных и размерности
|
||||||
|
print('Исходные данные:')
|
||||||
|
print(data)
|
||||||
|
print('Размерность данных:')
|
||||||
|
print(data.shape)
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```output
|
||||||
|
Исходные данные:
|
||||||
|
[[5.85155463 5.90866047]
|
||||||
|
[5.89835027 5.87217268]
|
||||||
|
[5.95502834 6.13788939]
|
||||||
|
...
|
||||||
|
[5.97194799 6.15187645]
|
||||||
|
[6.24367408 6.18137502]
|
||||||
|
[6.04890409 6.24554664]]
|
||||||
|
Размерность данных:
|
||||||
|
(1000, 2)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3) Создали и обучили автокодировщик AE1 простой архитектуры, выбрав небольшое количество эпох обучения. Зафиксировали в таблице вида табл.1 количество скрытых слоёв и нейронов в них
|
||||||
|
|
||||||
|
```python
|
||||||
|
# обучение AE1
|
||||||
|
patience = 300
|
||||||
|
ae1_trained, IRE1, IREth1 = lib.create_fit_save_ae(data,'out/AE1.h5','out/AE1_ire_th.txt',
|
||||||
|
1000, True, patience)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
4) Зафиксировали ошибку MSE, на которой обучение завершилось. Построили график ошибки реконструкции обучающей выборки. Зафиксировали порог ошибки реконструкции – порог обнаружения аномалий.
|
||||||
|
|
||||||
|
Ошибка MSE_AE1 = 16.0985
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Построение графика ошибки реконструкции
|
||||||
|
lib.ire_plot('training', IRE1, IREth1, 'AE1')
|
||||||
|
```
|
||||||
|
|
||||||
|

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

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

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

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

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

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

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

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

|
||||||
|
|
||||||
|
### 8) Если автокодировщик AE2 недостаточно точно аппроксимирует область обучающих данных, то подобрать подходящие параметры автокодировщика и повторить шаги (6) – (8).
|
||||||
|
|
||||||
|
Полученные показатели EDCA для автокодировщика AE2 нас устраивают.
|
||||||
|
|
||||||
|
### 9) Изучили сохраненный набор данных и пространство признаков. Создали тестовую выборку, состоящую, как минимум, из 4ёх элементов, не входящих в обучающую выборку. Элементы должны быть такими, чтобы AE1 распознавал их как норму, а AE2 детектировал как аномалии.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# загрузка тестового набора
|
||||||
|
data_test = np.loadtxt('data_test.txt', dtype=float)
|
||||||
|
print(data_test)
|
||||||
|
```
|
||||||
|
|
||||||
|
```output
|
||||||
|
[[4.85155463 4.90866047]
|
||||||
|
[4.89835027 4.87217268]
|
||||||
|
[4.95502834 4.13788939]
|
||||||
|
[4.9958611 4.8697867 ]]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10) Применили обученные автокодировщики AE1 и AE2 к тестовым данным и вывели значения ошибки реконструкции для каждого элемента тестовой выборки относительно порога на график и в консоль.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# тестирование АE1
|
||||||
|
predicted_labels1, ire1 = lib.predict_ae(ae1_trained, data_test, IREth1)
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
# тестирование АE1
|
||||||
|
lib.anomaly_detection_ae(predicted_labels1, ire1, IREth1)
|
||||||
|
lib.ire_plot('test', ire1, IREth1, 'AE1')
|
||||||
|
```
|
||||||
|
|
||||||
|
```output
|
||||||
|
Аномалий не обнаружено
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```python
|
||||||
|
# тестирование АE2
|
||||||
|
predicted_labels2, ire2 = lib.predict_ae(ae2_trained, data_test, IREth2)
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
# тестирование АE2
|
||||||
|
lib.anomaly_detection_ae(predicted_labels2, ire2, IREth2)
|
||||||
|
lib.ire_plot('test', ire2, IREth2, 'AE2')
|
||||||
|
```
|
||||||
|
|
||||||
|
```output
|
||||||
|
|
||||||
|
i Labels IRE IREth
|
||||||
|
0 [1.] [1.48] 0.44
|
||||||
|
1 [1.] [1.47] 0.44
|
||||||
|
2 [1.] [2.04] 0.44
|
||||||
|
3 [1.] [1.41] 0.44
|
||||||
|
Обнаружено 4.0 аномалий
|
||||||
|
```
|
||||||
|
|
||||||
|

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

|
||||||
|
|
||||||
|
### 12) Результаты исследования занесли в таблицу:
|
||||||
|
Табл. 1 Результаты задания №1
|
||||||
|
|
||||||
|
| | Количество<br>скрытых слоев | Количество<br>нейронов в скрытых слоях | Количество<br>эпох обучения | Ошибка<br>MSE_stop | Порог ошибки<br>реконструкции | Значение показателя<br>Excess | Значение показателя<br>Approx | Количество обнаруженных<br>аномалий |
|
||||||
|
|-----:|------------------------------|----------------------------------------|-----------------------------|--------------------|-------------------------------|-------------------------------|--------------------------------|-------------------------------------|
|
||||||
|
| AE1 | 1 | 1 | 1000 | 16.0985 | 6 | 13.333333333333334 | 0.06976744186046512 | 0 |
|
||||||
|
| AE2 | 5 | 3,2,1,2,3 | 3000 | 0.0112 | 0.44 | 0.7142857142857143 | 0.5833333333333335 | 4 |
|
||||||
|
|
||||||
|
### 13) Сделали выводы о требованиях к:
|
||||||
|
- данным для обучения,
|
||||||
|
- архитектуре автокодировщика,
|
||||||
|
- количеству эпох обучения,
|
||||||
|
- ошибке MSE_stop, приемлемой для останова обучения,
|
||||||
|
- ошибке реконструкции обучающей выборки (порогу обнаружения
|
||||||
|
аномалий),
|
||||||
|
- характеристикам качества обучения EDCA одноклассового
|
||||||
|
классификатора
|
||||||
|
|
||||||
|
для качественного обнаружения аномалий в данных.
|
||||||
|
|
||||||
|
1) Данные для обучения должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение
|
||||||
|
2) Архитектура автокодировщика должна постепенно сужатся к бутылочному горлышку,а затем постепенно возвращатся к исходным выходным размерам, кол-во скрытых слоев 3-5
|
||||||
|
3) В рамках данного набора данных оптимальное кол-во эпох 3000 с patience 300 эпох
|
||||||
|
4) Оптимальная ошибка MSE-stop в районе 0.01, желательно не меньше для предотвращения переобучения
|
||||||
|
5) Значение порога в районе 0.45
|
||||||
|
6) Значение Excess не больше 0.75, значение Deficit равное 0, значение Coating равное 1, значение Approx не меньше 0.58
|
||||||
|
|
||||||
|
## Задание 2
|
||||||
|
|
||||||
|
### 1) Изучить описание своего набора реальных данных, что он из себя представляет
|
||||||
|
|
||||||
|
Бригада 6 => набор данных Cardio. Это реальный набор данных, который состоит из измерений частоты сердечных сокращений плода и
|
||||||
|
сокращений матки на кардиотокограммах, классифицированных экспертами
|
||||||
|
акушерами. Исходный набор данных предназначен для классификации. В нем
|
||||||
|
представлено 3 класса: «норма», «подозрение» и «патология». Для обнаружения
|
||||||
|
аномалий класс «норма» принимается за норму, класс «патология» принимается за
|
||||||
|
аномалии, а класс «подозрение» был отброшен.
|
||||||
|
|
||||||
|
| Количество<br>признаков | Количество<br>примеров | Количество<br>нормальных примеров | Количество<br>аномальных примеров |
|
||||||
|
|-------------------------:|-----------------------:|----------------------------------:|-----------------------------------:|
|
||||||
|
| 21 | 1764 | 1655 | 109 |
|
||||||
|
|
||||||
|
### 2) Загрузить многомерную обучающую выборку реальных данных Cardio.txt.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# загрузка обчуающей выборки
|
||||||
|
train = np.loadtxt('cardio_train.txt', dtype=float)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3) Вывести полученные данные и их размерность в консоли.
|
||||||
|
|
||||||
|
```python
|
||||||
|
print('train:\n', train)
|
||||||
|
print('train.shape:', np.shape(train))
|
||||||
|
```
|
||||||
|
|
||||||
|
```output
|
||||||
|
train:
|
||||||
|
[[ 0.00491231 0.69319077 -0.20364049 ... 0.23149795 -0.28978574
|
||||||
|
-0.49329397]
|
||||||
|
[ 0.11072935 -0.07990259 -0.20364049 ... 0.09356344 -0.25638541
|
||||||
|
-0.49329397]
|
||||||
|
[ 0.21654639 -0.27244466 -0.20364049 ... 0.02459619 -0.25638541
|
||||||
|
1.1400175 ]
|
||||||
|
...
|
||||||
|
[ 0.85144861 -0.91998844 -0.20364049 ... 0.57633422 -0.65718941
|
||||||
|
1.1400175 ]
|
||||||
|
[ 0.85144861 -0.91998844 -0.20364049 ... 0.57633422 -0.62378908
|
||||||
|
-0.49329397]
|
||||||
|
[ 1.0630827 -0.51148142 -0.16958144 ... 0.57633422 -0.65718941
|
||||||
|
-0.49329397]]
|
||||||
|
train.shape: (1654, 21)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4) Создать и обучить автокодировщик с подходящей для данных архитектурой. Выбрать необходимое количество эпох обучения.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# **kwargs
|
||||||
|
# verbose_every_n_epochs - отображать прогресс каждые N эпох (по умолчанию - 1000)
|
||||||
|
# early_stopping_delta - дельта для ранней остановки (по умолчанию - 0.01)
|
||||||
|
# early_stopping_value = значение для ранней остановки (по умолчанию - 0.0001)
|
||||||
|
|
||||||
|
from time import time
|
||||||
|
|
||||||
|
patience = 4000
|
||||||
|
start = time()
|
||||||
|
ae3_v1_trained, IRE3_v1, IREth3_v1 = lib.create_fit_save_ae(train,'out/AE3_V1.h5','out/AE3_v1_ire_th.txt',
|
||||||
|
100000, False, patience, early_stopping_delta = 0.001)
|
||||||
|
print("Время на обучение: ", time() - start)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```output
|
||||||
|
|
||||||
|
Время на обучение: 1232.8548789024353
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5) Зафиксировать ошибку MSE, на которой обучение завершилось. Построить график ошибки реконструкции обучающей выборки. Зафиксировать порог ошибки реконструкции – порог обнаружения аномалий.
|
||||||
|
|
||||||
|
Скрытых слоев 7, нейроны: 46->26->14->10->14->26->48
|
||||||
|
|
||||||
|
Ошибка MSE_AE3_v1 = 0.0137
|
||||||
|
|
||||||
|
```python
|
||||||
|
lib.ire_plot('training', IRE3_v1, IREth3_v1, 'AE3_v1')
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 6) Сделать вывод о пригодности обученного автокодировщика для качественного обнаружения аномалий. Если порог ошибки реконструкции слишком велик, то подобрать подходящие параметры автокодировщика и повторить шаги (4) – (6).
|
||||||
|
|
||||||
|
```python
|
||||||
|
# **kwargs
|
||||||
|
# verbose_every_n_epochs - отображать прогресс каждые N эпох (по умолчанию - 1000)
|
||||||
|
# early_stopping_delta - дельта для ранней остановки (по умолчанию - 0.01)
|
||||||
|
# early_stopping_value = значение для ранней остановки (по умолчанию - 0.0001)
|
||||||
|
|
||||||
|
from time import time
|
||||||
|
|
||||||
|
patience = 4000
|
||||||
|
start = time()
|
||||||
|
ae3_v2_trained, IRE3_v2, IREth3_v2 = lib.create_fit_save_ae(train,'out/AE3_V2.h5','out/AE3_v2_ire_th.txt',
|
||||||
|
100000, False, patience, early_stopping_delta = 0.001)
|
||||||
|
print("Время на обучение: ", time() - start)
|
||||||
|
```
|
||||||
|
|
||||||
|
```output
|
||||||
|
|
||||||
|
Время на обучение: 1298.1322848796844
|
||||||
|
```
|
||||||
|
|
||||||
|
Скрытых слоев 11, нейроны: 48->36->28->22->16->12->16->22->28->36->48
|
||||||
|
|
||||||
|
Ошибка MSE_AE3_v1 = 0.0077
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Построение графика ошибки реконструкции
|
||||||
|
lib.ire_plot('training', IRE3_v2, IREth3_v2, 'AE3_v2')
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 7) Изучить и загрузить тестовую выборку Cardio.txt.
|
||||||
|
|
||||||
|
```python
|
||||||
|
#загрузка тестовой выборки
|
||||||
|
test = np.loadtxt('cardio_test.txt', dtype=float)
|
||||||
|
print('\n test:\n', test)
|
||||||
|
print('test.shape:', np.shape(test))
|
||||||
|
```
|
||||||
|
|
||||||
|
```output
|
||||||
|
|
||||||
|
test:
|
||||||
|
[[ 0.21654639 -0.65465178 -0.20364049 ... -2.0444214 4.987467
|
||||||
|
-0.49329397]
|
||||||
|
[ 0.21654639 -0.5653379 -0.20364049 ... -2.1133887 6.490482
|
||||||
|
-0.49329397]
|
||||||
|
[-0.3125388 -0.91998844 6.9653692 ... -1.1478471 3.9186563
|
||||||
|
-0.49329397]
|
||||||
|
...
|
||||||
|
[-0.41835583 -0.91998844 -0.16463485 ... -1.4926834 0.24461959
|
||||||
|
-0.49329397]
|
||||||
|
[-0.41835583 -0.91998844 -0.15093411 ... -1.4237162 0.14441859
|
||||||
|
-0.49329397]
|
||||||
|
[-0.41835583 -0.91998844 -0.20364049 ... -1.2857816 3.5846529
|
||||||
|
-0.49329397]]
|
||||||
|
test.shape: (109, 21)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8) Подать тестовую выборку на вход обученного автокодировщика для обнаружения аномалий. Вывести график ошибки реконструкции элементов тестовой выборки относительно порога.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# тестирование АE3
|
||||||
|
predicted_labels3_v1, ire3_v1 = lib.predict_ae(ae3_v1_trained, test, IREth3_v1)
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Построение графика ошибки реконструкции
|
||||||
|
lib.ire_plot('test', ire3_v1, IREth3_v1, 'AE3_v1')
|
||||||
|
```
|
||||||
|
|
||||||
|

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

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

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

|
||||||
|
```
|
||||||
|
Real mark: 9
|
||||||
|
NN answer: 9
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8) Вывели отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# истинные метки классов
|
||||||
|
true_labels = np.argmax(y_test, axis=1)
|
||||||
|
# предсказанные метки классов
|
||||||
|
predicted_labels = np.argmax(model.predict(X_test), axis=1)
|
||||||
|
|
||||||
|
# отчет о качестве классификации
|
||||||
|
print(classification_report(true_labels, predicted_labels))
|
||||||
|
# вычисление матрицы ошибок
|
||||||
|
conf_matrix = confusion_matrix(true_labels, predicted_labels)
|
||||||
|
# отрисовка матрицы ошибок в виде "тепловой карты"
|
||||||
|
display = ConfusionMatrixDisplay(confusion_matrix=conf_matrix)
|
||||||
|
display.plot()
|
||||||
|
plt.show()
|
||||||
|
```
|
||||||
|
```
|
||||||
|
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 5ms/step
|
||||||
|
precision recall f1-score support
|
||||||
|
|
||||||
|
0 1.00 0.99 0.99 997
|
||||||
|
1 1.00 0.99 1.00 1164
|
||||||
|
2 0.99 0.98 0.98 1030
|
||||||
|
3 1.00 0.98 0.99 1031
|
||||||
|
4 0.99 0.99 0.99 967
|
||||||
|
5 0.97 0.99 0.98 860
|
||||||
|
6 0.99 0.99 0.99 977
|
||||||
|
7 0.99 0.99 0.99 1072
|
||||||
|
8 0.98 0.98 0.98 939
|
||||||
|
9 0.99 0.98 0.99 963
|
||||||
|
|
||||||
|
accuracy 0.99 10000
|
||||||
|
macro avg 0.99 0.99 0.99 10000
|
||||||
|
weighted avg 0.99 0.99 0.99 10000
|
||||||
|
```
|
||||||
|

|
||||||
|
|
||||||
|
### 9) Загрузили, предобработали и подали на вход обученной нейронной сети собственное изображение, созданное при выполнении лабораторной работы №1. Вывели изображение и результат распознавания.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# загрузка собственного изображения
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
for name_image in ['190 (2).png', '690 (1).png']:
|
||||||
|
file_data = Image.open(name_image)
|
||||||
|
file_data = file_data.convert('L') # перевод в градации серого
|
||||||
|
test_img = np.array(file_data)
|
||||||
|
|
||||||
|
# вывод собственного изображения
|
||||||
|
plt.imshow(test_img, cmap=plt.get_cmap('gray'))
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
# предобработка
|
||||||
|
test_img = test_img / 255
|
||||||
|
test_img = np.reshape(test_img, (1,28,28,1))
|
||||||
|
|
||||||
|
# распознавание
|
||||||
|
result = model.predict(test_img)
|
||||||
|
print('I think it\'s', np.argmax(result))
|
||||||
|
```
|
||||||
|

|
||||||
|
```
|
||||||
|
I think it's 1
|
||||||
|
```
|
||||||
|

|
||||||
|
```
|
||||||
|
I think it's 6
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10) Загрузили с диска модель, сохраненную при выполнении лабораторной работы №1. Вывели информацию об архитектуре модели. Повторили для этой модели п. 6.
|
||||||
|
|
||||||
|
```python
|
||||||
|
model_lr1 = keras.models.load_model("model_1h100_2h50.keras")
|
||||||
|
|
||||||
|
model_lr1.summary()
|
||||||
|
```
|
||||||
|
**Model: "sequential_10"**
|
||||||
|
| Layer (type) | Output Shape | Param # |
|
||||||
|
|------------------|-------------:|--------:|
|
||||||
|
| dense_1 (Dense) | (None, 100) | 78,500 |
|
||||||
|
| dense_2 (Dense) | (None, 10) | 1,010 |
|
||||||
|
Total params: 79,512 (310.60 KB)
|
||||||
|
Trainable params: 79,510 (310.59 KB)
|
||||||
|
Non-trainable params: 0 (0.00 B)
|
||||||
|
Optimizer params: 2 (12.00 B)
|
||||||
|
|
||||||
|
|
||||||
|
```python
|
||||||
|
# развернем каждое изображение 28*28 в вектор 784
|
||||||
|
X_train, X_test, y_train, y_test = train_test_split(X, y,
|
||||||
|
test_size = 10000,
|
||||||
|
train_size = 60000,
|
||||||
|
random_state = 23)
|
||||||
|
num_pixels = X_train.shape[1] * X_train.shape[2]
|
||||||
|
X_train = X_train.reshape(X_train.shape[0], num_pixels) / 255
|
||||||
|
X_test = X_test.reshape(X_test.shape[0], num_pixels) / 255
|
||||||
|
print('Shape of transformed X train:', X_train.shape)
|
||||||
|
print('Shape of transformed X train:', X_test.shape)
|
||||||
|
|
||||||
|
# переведем метки в one-hot
|
||||||
|
y_train = keras.utils.to_categorical(y_train, num_classes)
|
||||||
|
y_test = keras.utils.to_categorical(y_test, num_classes)
|
||||||
|
print('Shape of transformed y train:', y_train.shape)
|
||||||
|
print('Shape of transformed y test:', y_test.shape)
|
||||||
|
```
|
||||||
|
```
|
||||||
|
Shape of transformed X train: (60000, 784)
|
||||||
|
Shape of transformed X train: (10000, 784)
|
||||||
|
Shape of transformed y train: (60000, 10)
|
||||||
|
Shape of transformed y test: (10000, 10)
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Оценка качества работы модели на тестовых данных
|
||||||
|
scores = model_lr1.evaluate(X_test, y_test)
|
||||||
|
print('Loss on test data:', scores[0])
|
||||||
|
print('Accuracy on test data:', scores[1])
|
||||||
|
```
|
||||||
|
```
|
||||||
|
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.9490 - loss: 0.1739
|
||||||
|
Loss on test data: 0.18475718796253204
|
||||||
|
Accuracy on test data: 0.9458000063896179
|
||||||
|
```
|
||||||
|
|
||||||
|
### 11) Сравнили обученную модель сверточной сети и наилучшую модель полносвязной сети из лабораторной работы №1 по следующим показателям:
|
||||||
|
### - количество настраиваемых параметров в сети
|
||||||
|
### - количество эпох обучения
|
||||||
|
### - качество классификации тестовой выборки.
|
||||||
|
### Сделали выводы по результатам применения сверточной нейронной сети для распознавания изображений.
|
||||||
|
|
||||||
|
Таблица1:
|
||||||
|
|
||||||
|
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|
||||||
|
|----------|-------------------------------------|---------------------------|-----------------------------------------|
|
||||||
|
| Сверточная | 34 826 | 15 | accuracy:0.987 ; loss:0.037 |
|
||||||
|
| Полносвязная | 79512 | 50 | accuracy:0.946 ; loss:0.185 |
|
||||||
|
|
||||||
|
|
||||||
|
##### По результатам применения сверточной НС, а также по результатам таблицы 1 делаем выводы, что сверточная НС намного лучше справляется с задачами распознования изображений, чем полносвязная - имеет меньше настраиваемых параметров, быстрее обучается, имеет лучшие показатели качества.
|
||||||
|
|
||||||
|
## Задание 2
|
||||||
|
|
||||||
|
### В новом блокноте выполнили п. 2–8 задания 1, изменив набор данных MNIST на CIFAR-10, содержащий размеченные цветные изображения объектов, разделенные на 10 классов.
|
||||||
|
### При этом:
|
||||||
|
### - в п. 3 разбиение данных на обучающие и тестовые произвели в соотношении 50 000:10 000
|
||||||
|
### - после разбиения данных (между п. 3 и 4) вывели 25 изображений из обучающей выборки с подписями классов
|
||||||
|
### - в п. 7 одно из тестовых изображений должно распознаваться корректно, а другое – ошибочно.
|
||||||
|
|
||||||
|
### 1) Загрузили набор данных CIFAR-10, содержащий цветные изображения размеченные на 10 классов: самолет, автомобиль, птица, кошка, олень, собака, лягушка, лошадь, корабль, грузовик.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# загрузка датасета
|
||||||
|
from keras.datasets import cifar10
|
||||||
|
|
||||||
|
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2) Разбили набор данных на обучающие и тестовые данные в соотношении 50 000:10 000 элементов. Параметр random_state выбрали равным (4k – 1)=23, где k=6 –номер бригады. Вывели размерности полученных обучающих и тестовых массивов данных.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# создание своего разбиения датасета
|
||||||
|
|
||||||
|
# объединяем в один набор
|
||||||
|
X = np.concatenate((X_train, X_test))
|
||||||
|
y = np.concatenate((y_train, y_test))
|
||||||
|
|
||||||
|
# разбиваем по вариантам
|
||||||
|
X_train, X_test, y_train, y_test = train_test_split(X, y,
|
||||||
|
test_size = 10000,
|
||||||
|
train_size = 50000,
|
||||||
|
random_state = 23)
|
||||||
|
# вывод размерностей
|
||||||
|
print('Shape of X train:', X_train.shape)
|
||||||
|
print('Shape of y train:', y_train.shape)
|
||||||
|
print('Shape of X test:', X_test.shape)
|
||||||
|
print('Shape of y test:', y_test.shape)
|
||||||
|
```
|
||||||
|
```
|
||||||
|
Shape of X train: (50000, 32, 32, 3)
|
||||||
|
Shape of y train: (50000, 1)
|
||||||
|
Shape of X test: (10000, 32, 32, 3)
|
||||||
|
Shape of y test: (10000, 1)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Вывели 25 изображений из обучающей выборки с подписью классов.
|
||||||
|
|
||||||
|
```python
|
||||||
|
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
|
||||||
|
'dog', 'frog', 'horse', 'ship', 'truck']
|
||||||
|
|
||||||
|
plt.figure(figsize=(10,10))
|
||||||
|
for i in range(25):
|
||||||
|
plt.subplot(5,5,i+1)
|
||||||
|
plt.xticks([])
|
||||||
|
plt.yticks([])
|
||||||
|
plt.grid(False)
|
||||||
|
plt.imshow(X_train[i])
|
||||||
|
plt.xlabel(class_names[y_train[i][0]])
|
||||||
|
plt.show()
|
||||||
|
```
|
||||||
|

|
||||||
|
|
||||||
|
### 3) Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения сверточной нейронной сети. Входные данные принимают значения от 0 до 1, метки цифр закодированы по принципу «one-hot encoding». Вывели размерности предобработанных обучающих и тестовых массивов данных.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Зададим параметры данных и модели
|
||||||
|
num_classes = 10
|
||||||
|
input_shape = (32, 32, 3)
|
||||||
|
|
||||||
|
# Приведение входных данных к диапазону [0, 1]
|
||||||
|
X_train = X_train / 255
|
||||||
|
X_test = X_test / 255
|
||||||
|
|
||||||
|
print('Shape of transformed X train:', X_train.shape)
|
||||||
|
print('Shape of transformed X test:', X_test.shape)
|
||||||
|
|
||||||
|
# переведем метки в one-hot
|
||||||
|
y_train = keras.utils.to_categorical(y_train, num_classes)
|
||||||
|
y_test = keras.utils.to_categorical(y_test, num_classes)
|
||||||
|
print('Shape of transformed y train:', y_train.shape)
|
||||||
|
print('Shape of transformed y test:', y_test.shape)
|
||||||
|
```
|
||||||
|
```
|
||||||
|
Shape of transformed X train: (50000, 32, 32, 3)
|
||||||
|
Shape of transformed X test: (10000, 32, 32, 3)
|
||||||
|
Shape of transformed y train: (50000, 10)
|
||||||
|
Shape of transformed y test: (10000, 10)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4) Реализовали модель сверточной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# создаем модель
|
||||||
|
model = Sequential()
|
||||||
|
model.add(layers.Conv2D(32, kernel_size=(3, 3), activation="relu", input_shape=input_shape))
|
||||||
|
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
|
||||||
|
model.add(layers.Conv2D(64, kernel_size=(3, 3), activation="relu"))
|
||||||
|
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
|
||||||
|
model.add(layers.Conv2D(128, kernel_size=(3, 3), activation="relu"))
|
||||||
|
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
|
||||||
|
model.add(layers.Flatten())
|
||||||
|
model.add(layers.Dense(128, activation='relu'))
|
||||||
|
model.add(layers.Dropout(0.5))
|
||||||
|
model.add(layers.Dense(num_classes, activation="softmax"))
|
||||||
|
model.summary()
|
||||||
|
```
|
||||||
|
Model: "sequential_1"
|
||||||
|
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||||
|
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||||
|
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||||
|
│ conv2d_2 (Conv2D) │ (None, 30, 30, 32) │ 896 │
|
||||||
|
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||||
|
│ max_pooling2d_2 (MaxPooling2D) │ (None, 15, 15, 32) │ 0 │
|
||||||
|
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||||
|
│ conv2d_3 (Conv2D) │ (None, 13, 13, 64) │ 18,496 │
|
||||||
|
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||||
|
│ max_pooling2d_3 (MaxPooling2D) │ (None, 6, 6, 64) │ 0 │
|
||||||
|
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||||
|
│ conv2d_4 (Conv2D) │ (None, 4, 4, 128) │ 73,856 │
|
||||||
|
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||||
|
│ max_pooling2d_4 (MaxPooling2D) │ (None, 2, 2, 128) │ 0 │
|
||||||
|
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||||
|
│ flatten_1 (Flatten) │ (None, 512) │ 0 │
|
||||||
|
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||||
|
│ dense_1 (Dense) │ (None, 128) │ 65,664 │
|
||||||
|
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||||
|
│ dropout_1 (Dropout) │ (None, 128) │ 0 │
|
||||||
|
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||||
|
│ dense_2 (Dense) │ (None, 10) │ 1,290 │
|
||||||
|
└─────────────────────────────────┴────────────────────────┴───────────────┘
|
||||||
|
Total params: 160,202 (625.79 KB)
|
||||||
|
Trainable params: 160,202 (625.79 KB)
|
||||||
|
Non-trainable params: 0 (0.00 B)
|
||||||
|
|
||||||
|
```python
|
||||||
|
# компилируем и обучаем модель
|
||||||
|
batch_size = 64
|
||||||
|
epochs = 50
|
||||||
|
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
|
||||||
|
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5) Оценили качество обучения на тестовых данных. Вывели значение функции ошибки и значение метрики качества классификации на тестовых данных.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Оценка качества работы модели на тестовых данных
|
||||||
|
scores = model.evaluate(X_test, y_test)
|
||||||
|
print('Loss on test data:', scores[0])
|
||||||
|
print('Accuracy on test data:', scores[1])
|
||||||
|
```
|
||||||
|
```
|
||||||
|
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step - accuracy: 0.7087 - loss: 1.3107
|
||||||
|
Loss on test data: 1.2974315881729126
|
||||||
|
Accuracy on test data: 0.7123000025749207
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# вывод двух тестовых изображений и результатов распознавания
|
||||||
|
|
||||||
|
for n in [3,16]:
|
||||||
|
result = model.predict(X_test[n:n+1])
|
||||||
|
print('NN output:', result)
|
||||||
|
|
||||||
|
plt.imshow(X_test[n].reshape(32,32,3), cmap=plt.get_cmap('gray'))
|
||||||
|
plt.show()
|
||||||
|
print('Real mark: ', np.argmax(y_test[n]))
|
||||||
|
print('NN answer: ', np.argmax(result))
|
||||||
|
```
|
||||||
|

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

|
||||||
|
```
|
||||||
|
Real mark: 7
|
||||||
|
NN answer: 2
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7) Вывели отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# истинные метки классов
|
||||||
|
true_labels = np.argmax(y_test, axis=1)
|
||||||
|
# предсказанные метки классов
|
||||||
|
predicted_labels = np.argmax(model.predict(X_test), axis=1)
|
||||||
|
|
||||||
|
# отчет о качестве классификации
|
||||||
|
print(classification_report(true_labels, predicted_labels, target_names=class_names))
|
||||||
|
# вычисление матрицы ошибок
|
||||||
|
conf_matrix = confusion_matrix(true_labels, predicted_labels)
|
||||||
|
# отрисовка матрицы ошибок в виде "тепловой карты"
|
||||||
|
fig, ax = plt.subplots(figsize=(6, 6))
|
||||||
|
disp = ConfusionMatrixDisplay(confusion_matrix=conf_matrix,display_labels=class_names)
|
||||||
|
disp.plot(ax=ax, xticks_rotation=45) # поворот подписей по X и приятная палитра
|
||||||
|
plt.tight_layout() # чтобы всё влезло
|
||||||
|
plt.show()
|
||||||
|
```
|
||||||
|
```
|
||||||
|
313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 2ms/step
|
||||||
|
precision recall f1-score support
|
||||||
|
|
||||||
|
airplane 0.69 0.76 0.72 986
|
||||||
|
automobile 0.85 0.80 0.82 971
|
||||||
|
bird 0.66 0.60 0.63 1043
|
||||||
|
cat 0.54 0.55 0.55 1037
|
||||||
|
deer 0.66 0.67 0.67 969
|
||||||
|
dog 0.63 0.64 0.63 979
|
||||||
|
frog 0.78 0.78 0.78 1025
|
||||||
|
horse 0.74 0.73 0.74 948
|
||||||
|
ship 0.79 0.82 0.80 1003
|
||||||
|
truck 0.80 0.78 0.79 1039
|
||||||
|
|
||||||
|
accuracy 0.71 10000
|
||||||
|
macro avg 0.71 0.71 0.71 10000
|
||||||
|
weighted avg 0.71 0.71 0.71 10000
|
||||||
|
```
|
||||||
|

|
||||||
|
|
||||||
|
### По результатам классификации датасета CIFAR-10 сверточной моделью делаем вывод, что она удовлетворительно справилась с задачей. Полученные метрики оценки качества имеют показатели в районе 0.71.
|
||||||