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

..

3 Коммитов

Автор SHA1 Сообщение Дата
Lipisin
964549a094 Открыта ЛР4 2025-11-26 14:24:27 +03:00
b344e76a21 Открыта ЛР3 2025-10-31 12:03:15 +03:00
Lipisin
047d249b1f Изменения в библиотекте для ЛР2:
- Добавлен callback для частичного отображения эпох
- Добавлены kwargs для частичного отображения эпох и ранней остановки по дельте и значению метрики
- Для EarlyStoppingCallback добавлена зависимость от verbose_show
2025-10-18 17:24:22 +03:00
67 изменённых файлов: 73 добавлений и 9976 удалений

Просмотреть файл

@@ -1,27 +1,14 @@
# Интеллектуальные системы # Интеллектуальные системы
## <a href="https://docs.google.com/spreadsheets/d/1E1vXKs7ZLeZcsPQiLG2JUh6mjsG6mXnmtFT58aCQul0/edit?usp=sharing">Журнал</a> ## <a href="https://docs.google.com/spreadsheets/d/1E1vXKs7ZLeZcsPQiLG2JUh6mjsG6mXnmtFT58aCQul0/edit?usp=sharing">Журнал</a>
## Лабораторные работы ## Лабораторные работы
1. [Архитектура и обучение глубоких нейронных сетей](labworks/LW1) 1. [Архитектура и обучение глубоких нейронных сетей](labworks/LW1)
2. [Обнаружение аномалий](labworks/LW2) 2. [Обнаружение аномалий](labworks/LW2)
3. [Распознавание изображений](labworks/LW3)
4. [Распознавание последовательностей](labworks/LW4)
<!--
### Лабораторная работа №3
* [Задание](labworks/LW3/IS_Lab03_2023.pdf)
* [Методические указания](labworks/LW3/IS_Lab03_Metod_2023.pdf)
* <a href="https://youtube.com/playlist?list=PLZDCDMGmelH-pHt-Ij0nImVrOmj8DYKbB" target="_blank">Плейлист с видео о сверточных сетях (крутая визуализация)</a>
### Лабораторная работа №4
* [Задание](labworks/LW4/IS_Lab04_2023.pdf)
* [Методические указания](labworks/LW4/IS_Lab04_Metod_2023.pdf)
-->
## Архив материалов курса ## Архив материалов курса
В 2021–2022 годах материалы выкладывались <a href="https://uii.bitbucket.io/study/courses/#:~:text=Интеллектуальные%20системы%20(глубокие%20нейронные%20сети)" target="_blank">на этой странице</a>. В 2021–2022 годах материалы выкладывались <a href="https://uii.bitbucket.io/study/courses/#:~:text=Интеллектуальные%20системы%20(глубокие%20нейронные%20сети)" target="_blank">на этой странице</a>.

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

Просмотреть файл

@@ -1,4 +1,11 @@
## Лабораторныа работа №1
## Архитектура и обучение глубоких нейронных сетей
* [Задание](IS_Lab01_2023.pdf) * [Задание](IS_Lab01_2023.pdf)
* [Методические указания](IS_Lab01_Metod_2023.pdf) * [Методические указания](IS_Lab01_Metod_2023.pdf)
* <a href="https://youtube.com/playlist?list=PLfdZ2TeaMzfzlpZ60rbaYU_epH5XPNbWU" target="_blank"><s>Какие нейроны, что вообще происходит?</s> Рекомендуется к просмотру для понимания (4 видео)</a> * <a href="https://youtube.com/playlist?list=PLfdZ2TeaMzfzlpZ60rbaYU_epH5XPNbWU" target="_blank"><s>Какие нейроны, что вообще происходит?</s> Рекомендуется к просмотру для понимания (4 видео)</a>
* <a href="https://www.youtube.com/watch?v=FwFduRA_L6Q" target="_blank">Почувствуйте себя пионером нейронных сетей в области распознавания образов</a> * <a href="https://www.youtube.com/watch?v=FwFduRA_L6Q" target="_blank">Почувствуйте себя пионером нейронных сетей в области распознавания образов</a>

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

Просмотреть файл

@@ -1,610 +0,0 @@
# Отчет по лабораторной работе №1
Касимов Азамат, Немыкин Никита, А-01-22
## 1. В среде GoogleColab создали блокнот(notebook.ipynb).
```
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks')
```
* импорт модулей
```
from tensorflow import keras
import matplotlib.pyplot as plt
import numpy as np
import sklearn
```
## 2. Загрузка датасета MNIST
```
from keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()
```
## 3. Разбиение набора данных на обучающие и тестовые
```
from sklearn.model_selection import train_test_split
```
* объединяем в один набор
```
X = np.concatenate((X_train, X_test))
y = np.concatenate((y_train, y_test))
```
* разбиваем по вариантам
```
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size = 10000,train_size = 60000, random_state = 27)
```
* Вывод размерностей
```
print('Shape of X train:', X_train.shape)
print('Shape of y train:', y_train.shape)
```
> Shape of X train: (60000, 28, 28)
> Shape of y train: (60000,)
## 4. Вывод элементов обучающих данных
* Создаем subplot для 4 изображений
```
fig, axes = plt.subplots(1, 4, figsize=(10, 3))
for i in range(4):
axes[i].imshow(X_train[i], cmap=plt.get_cmap('gray'))
axes[i].set_title(f'Label: {y_train[i]}')
# Добавляем метку как заголовок
plt.show()
```
![отображение элементов](1.png)
## 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)
```
![график функции ошибки](2.png)
## 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)
```
![график функции ошибки](3.png)
```
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)
```
![график функции ошибки](4.png)
```
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)
```
![график функции ошибки](5.png)
```
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)
```
![график функции ошибки](6.png)
```
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)
```
![график функции ошибки](7.png)
```
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]]
![alt text](8.png)
>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]]
![alt text](9.png)
>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()
```
![6 изображение](10.png)
* предобработка
```
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()
```
![1 изображение](11.png)
```
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()
```
![alt text](690.png)
```
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()
```
![alt text](190.png)
```
test_290_img = test_290_img / 255
test_290_img = test_290_img.reshape(1, num_pixels)
result_290 = model.predict(test_290_img)
print('I think it\'s', np.argmax(result_290))
```
> I think it's 4
При повороте изображений сеть не распознала цифры правильно. Так как она не обучалась на повернутых изображениях.

Просмотреть файл

@@ -1,4 +1,11 @@
## Лабораторныа работа №2
## Обнаружение аномалий
* [Задание](IS_Lab02_2023.pdf) * [Задание](IS_Lab02_2023.pdf)
* [Методические указания](IS_Lab02_Metod_2023.pdf) * [Методические указания](IS_Lab02_Metod_2023.pdf)
* [Наборы данных](data) * [Наборы данных](data)
* [Библиотека для автокодировщиков](lab02_lib.py) * [Библиотека для автокодировщиков](lab02_lib.py)

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

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

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

До

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

Просмотреть файл

@@ -29,12 +29,14 @@ from pandas import DataFrame
from sklearn.metrics import precision_score, recall_score, f1_score, confusion_matrix from sklearn.metrics import precision_score, recall_score, f1_score, confusion_matrix
from tensorflow.keras.models import Sequential from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation from tensorflow.keras.layers import Dense, Activation
from tensorflow.keras.callbacks import Callback
visual = True visual = True
verbose_show = False verbose_show = False
# generate 2d classification dataset # generate 2d classification dataset
def datagen(x_c, y_c, n_samples, n_features): def datagen(x_c, y_c, n_samples, n_features):
@@ -91,8 +93,27 @@ class EarlyStoppingOnValue(tensorflow.keras.callbacks.Callback):
) )
return monitor_value return monitor_value
class VerboseEveryNEpochs(Callback):
def __init__(self, every_n_epochs=1000, verbose=1):
super().__init__()
self.every_n_epochs = every_n_epochs
self.verbose = verbose
def on_epoch_end(self, epoch, logs=None):
if (epoch + 1) % self.every_n_epochs == 0:
if self.verbose:
print(f"\nEpoch {epoch + 1}/{self.params['epochs']}")
if logs:
log_str = ", ".join([f"{k}: {v:.4f}" for k, v in logs.items()])
print(f" - {log_str}")
#создание и обучение модели автокодировщика #создание и обучение модели автокодировщика
def create_fit_save_ae(cl_train, ae_file, irefile, epohs, verbose_show, patience): def create_fit_save_ae(cl_train, ae_file, irefile, epohs, verbose_show, patience, **kwargs):
verbose_every_n_epochs = kwargs.get('verbose_every_n_epochs', 1000)
early_stopping_delta = kwargs.get('early_stopping_delta', 0.01)
early_stopping_value = kwargs.get('early_stopping_value', 0.0001)
size = cl_train.shape[1] size = cl_train.shape[1]
#ans = '2' #ans = '2'
@@ -140,22 +161,28 @@ def create_fit_save_ae(cl_train, ae_file, irefile, epohs, verbose_show, patience
optimizer = tensorflow.keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False) optimizer = tensorflow.keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False)
ae.compile(loss='mean_squared_error', optimizer=optimizer) ae.compile(loss='mean_squared_error', optimizer=optimizer)
error_stop = 0.0001
epo = epohs epo = epohs
early_stopping_callback_on_error = EarlyStoppingOnValue(monitor='loss', baseline=error_stop)
early_stopping_callback_on_improving = tensorflow.keras.callbacks.EarlyStopping(monitor='loss',
min_delta=0.0001, patience = patience,
verbose=1, mode='auto',
baseline=None,
restore_best_weights=False)
history_callback = tensorflow.keras.callbacks.History()
verbose = 1 if verbose_show else 0 verbose = 1 if verbose_show else 0
early_stopping_callback_on_error = EarlyStoppingOnValue(monitor='loss', baseline=early_stopping_value)
early_stopping_callback_on_improving = tensorflow.keras.callbacks.EarlyStopping(monitor='loss',
min_delta=early_stopping_delta, patience = patience,
verbose=verbose, mode='min',
baseline=None,
restore_best_weights=True)
history_callback = tensorflow.keras.callbacks.History()
history_object = ae.fit(cl_train, cl_train, history_object = ae.fit(cl_train, cl_train,
batch_size=cl_train.shape[0], batch_size=cl_train.shape[0],
epochs=epo, epochs=epo,
callbacks=[early_stopping_callback_on_error, history_callback, callbacks=[
early_stopping_callback_on_improving], early_stopping_callback_on_error,
history_callback,
early_stopping_callback_on_improving,
VerboseEveryNEpochs(every_n_epochs=verbose_every_n_epochs),
],
verbose=verbose) verbose=verbose)
ae_trainned = ae ae_trainned = ae
ae_pred = ae_trainned.predict(cl_train) ae_pred = ae_trainned.predict(cl_train)

Просмотреть файл

@@ -1,688 +0,0 @@
# Отчёт по лабораторной работе №2
**Касимов Азамат, Немыкин Никита — А-01-22**
---
## Задание 1
### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули.
```python
# импорт модулей
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab2')
```
```python
import lab02_lib as lib
```
### 2) Сгенерировали индивидуальный набор двумерных данных в пространстве признаков с координатами центра (6, 6), где 6 – номер бригады. Вывели полученные данные на рисунок и в консоль.
```python
# генерация датасета
data = lib.datagen(6, 6, 1000, 2)
# вывод данных и размерности
print('Исходные данные:')
print(data)
print('Размерность данных:')
print(data.shape)
```
![o](images/1.png)
```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')
```
![o](images/2.png)
### 5) Создали и обучили второй автокодировщик AE2 с усложненной архитектурой, задав большее количество эпох обучения
```python
# обучение AE2
ae2_trained, IRE2, IREth2 = lib.create_fit_save_ae(data,'out/AE2.h5','out/AE2_ire_th.txt',
3000, True, patience)
```
### 6) Зафиксировали ошибку MSE, на которой обучение завершилось. Построили график ошибки реконструкции обучающей выборки. Зафиксировали второй порог ошибки реконструкции – порог обнаружения аномалий.
Ошибка MSE_AE2 = 0.0112
```python
# Построение графика ошибки реконструкции
lib.ire_plot('training', IRE2, IREth2, 'AE2')
```
![o](images/3.png)
### 7) Рассчитали характеристики качества обучения EDCA для AE1 и AE2. Визуализировали и сравнили области пространства признаков, распознаваемые автокодировщиками AE1 и AE2. Сделали вывод о пригодности AE1 и AE2 для качественного обнаружения аномалий.
```python
# построение областей покрытия и границ классов
# расчет характеристик качества обучения
numb_square = 20
xx, yy, Z1 = lib.square_calc(numb_square, data, ae1_trained, IREth1, '1', True)
```
![o](images/4.png)
```output
amount: 21
amount_ae: 301
```
![o](images/5.png)
![o](images/6.png)
```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)
```
![o](images/7.png)
```output
amount: 21
amount_ae: 36
```
![o](images/8.png)
![o](images/9.png)
```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)
```
![o](images/10.png)
### 8) Если автокодировщик AE2 недостаточно точно аппроксимирует область обучающих данных, то подобрать подходящие параметры автокодировщика и повторить шаги (6) – (8).
Полученные показатели EDCA для автокодировщика AE2 нас устраивают.
### 9) Изучили сохраненный набор данных и пространство признаков. Создали тестовую выборку, состоящую, как минимум, из 4ёх элементов, не входящих в обучающую выборку. Элементы должны быть такими, чтобы AE1 распознавал их как норму, а AE2 детектировал как аномалии.
```python
# загрузка тестового набора
data_test = np.loadtxt('data_test.txt', dtype=float)
print(data_test)
```
```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
Аномалий не обнаружено
```
![o](images/11.png)
```python
# тестирование АE2
predicted_labels2, ire2 = lib.predict_ae(ae2_trained, data_test, IREth2)
```
```python
# тестирование АE2
lib.anomaly_detection_ae(predicted_labels2, ire2, IREth2)
lib.ire_plot('test', ire2, IREth2, 'AE2')
```
```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 аномалий
```
![o](images/12.png)
### 11) Визуализировали элементы обучающей и тестовой выборки в областях пространства признаков, распознаваемых автокодировщиками AE1 и AE2.
```python
lib.plot2in1_anomaly(data, xx, yy, Z1, Z2, data_test)
```
![o](images/13.png)
### 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')
```
![o](images/14.png)
### 6) Сделать вывод о пригодности обученного автокодировщика для качественного обнаружения аномалий. Если порог ошибки реконструкции слишком велик, то подобрать подходящие параметры автокодировщика и повторить шаги (4) – (6).
```python
# **kwargs
# verbose_every_n_epochs - отображать прогресс каждые N эпох (по умолчанию - 1000)
# early_stopping_delta - дельта для ранней остановки (по умолчанию - 0.01)
# early_stopping_value = значение для ранней остановки (по умолчанию - 0.0001)
from time import time
patience = 4000
start = time()
ae3_v2_trained, IRE3_v2, IREth3_v2 = lib.create_fit_save_ae(train,'out/AE3_V2.h5','out/AE3_v2_ire_th.txt',
100000, False, patience, early_stopping_delta = 0.001)
print("Время на обучение: ", time() - start)
```
```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')
```
![o](images/15.png)
### 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')
```
![o](images/16.png)
```python
# тестирование АE3
predicted_labels3_v2, ire3_v2 = lib.predict_ae(ae3_v2_trained, test, IREth3_v2)
```
```python
# Построение графика ошибки реконструкции
lib.ire_plot('test', ire3_v2, IREth3_v2, 'AE3_v2')
```
![o](images/17.png)
```python
# тестирование АE1
lib.anomaly_detection_ae(predicted_labels3_v1, IRE3_v1, IREth3_v1)
```
```output
i Labels IRE IREth
0 [1.] 0.62 1.82
1 [1.] 0.81 1.82
2 [1.] 0.68 1.82
3 [1.] 0.68 1.82
4 [1.] 1.14 1.82
5 [1.] 0.64 1.82
6 [1.] 0.84 1.82
7 [1.] 0.87 1.82
8 [1.] 0.51 1.82
9 [1.] 0.46 1.82
10 [1.] 0.5 1.82
11 [1.] 0.67 1.82
12 [1.] 0.74 1.82
13 [1.] 0.9 1.82
14 [1.] 0.66 1.82
15 [1.] 1.33 1.82
16 [1.] 0.66 1.82
17 [1.] 0.5 1.82
18 [1.] 0.64 1.82
19 [1.] 0.5 1.82
20 [1.] 0.4 1.82
21 [1.] 0.49 1.82
22 [1.] 0.43 1.82
23 [1.] 0.61 1.82
24 [1.] 0.43 1.82
25 [1.] 0.98 1.82
26 [1.] 0.49 1.82
27 [1.] 0.92 1.82
28 [1.] 0.91 1.82
29 [0.] 0.41 1.82
30 [1.] 0.55 1.82
31 [1.] 0.55 1.82
32 [1.] 0.58 1.82
33 [1.] 0.39 1.82
34 [1.] 0.73 1.82
35 [1.] 0.4 1.82
36 [1.] 0.22 1.82
37 [1.] 0.62 1.82
38 [0.] 0.36 1.82
39 [0.] 0.31 1.82
40 [0.] 0.38 1.82
41 [0.] 0.5 1.82
42 [1.] 0.84 1.82
43 [1.] 0.38 1.82
44 [1.] 1.03 1.82
45 [1.] 0.3 1.82
46 [1.] 0.3 1.82
47 [1.] 0.8 1.82
48 [0.] 0.67 1.82
49 [1.] 0.6 1.82
50 [1.] 0.59 1.82
51 [1.] 0.66 1.82
52 [1.] 0.71 1.82
53 [1.] 0.48 1.82
54 [0.] 0.25 1.82
55 [1.] 0.95 1.82
56 [1.] 0.33 1.82
57 [1.] 0.6 1.82
58 [1.] 0.6 1.82
59 [1.] 0.71 1.82
60 [1.] 0.39 1.82
61 [0.] 0.33 1.82
62 [0.] 0.57 1.82
63 [0.] 0.93 1.82
64 [0.] 0.78 1.82
65 [0.] 0.4 1.82
66 [1.] 0.44 1.82
67 [1.] 0.71 1.82
68 [1.] 0.57 1.82
69 [1.] 0.32 1.82
70 [1.] 0.27 1.82
71 [1.] 0.47 1.82
72 [1.] 0.62 1.82
73 [1.] 0.46 1.82
74 [1.] 0.61 1.82
75 [1.] 1.2 1.82
76 [1.] 0.38 1.82
77 [1.] 1.46 1.82
78 [1.] 0.58 1.82
79 [1.] 0.92 1.82
80 [1.] 0.51 1.82
81 [1.] 0.9 1.82
82 [1.] 0.99 1.82
83 [1.] 0.56 1.82
84 [1.] 0.55 1.82
85 [1.] 0.58 1.82
86 [1.] 0.76 1.82
87 [1.] 0.65 1.82
88 [1.] 0.34 1.82
89 [1.] 0.98 1.82
90 [1.] 0.52 1.82
91 [1.] 0.22 1.82
92 [1.] 0.57 1.82
93 [1.] 0.46 1.82
94 [1.] 0.29 1.82
95 [1.] 0.37 1.82
96 [1.] 0.38 1.82
97 [1.] 0.51 1.82
98 [1.] 0.54 1.82
99 [1.] 0.61 1.82
100 [1.] 0.47 1.82
101 [1.] 0.57 1.82
102 [1.] 0.48 1.82
103 [1.] 0.46 1.82
104 [1.] 0.45 1.82
105 [1.] 0.43 1.82
106 [1.] 0.19 1.82
107 [1.] 0.24 1.82
108 [1.] 0.71 1.82
Обнаружено 97.0 аномалий
```
Для AE3_v1 точность составляет 92%
```python
# тестирование АE2
lib.anomaly_detection_ae(predicted_labels3_v2, IRE3_v2, IREth3_v2)
```
```output
i Labels IRE IREth
0 [1.] 0.37 1.15
1 [1.] 0.43 1.15
2 [1.] 0.36 1.15
3 [1.] 0.57 1.15
4 [1.] 1.03 1.15
5 [1.] 0.37 1.15
6 [1.] 0.56 1.15
7 [1.] 0.6 1.15
8 [1.] 0.5 1.15
9 [1.] 0.5 1.15
10 [1.] 0.28 1.15
11 [1.] 0.57 1.15
12 [1.] 0.69 1.15
13 [1.] 0.54 1.15
14 [1.] 0.89 1.15
15 [1.] 0.48 1.15
16 [1.] 0.4 1.15
17 [1.] 0.48 1.15
18 [1.] 0.37 1.15
19 [1.] 0.18 1.15
20 [1.] 0.48 1.15
21 [1.] 0.31 1.15
22 [1.] 0.39 1.15
23 [1.] 0.52 1.15
24 [1.] 0.35 1.15
25 [1.] 0.62 1.15
26 [1.] 0.28 1.15
27 [1.] 0.44 1.15
28 [1.] 0.53 1.15
29 [0.] 0.38 1.15
30 [1.] 0.24 1.15
31 [1.] 0.6 1.15
32 [1.] 0.25 1.15
33 [1.] 0.18 1.15
34 [1.] 0.47 1.15
35 [1.] 0.25 1.15
36 [1.] 0.13 1.15
37 [1.] 0.38 1.15
38 [0.] 0.21 1.15
39 [0.] 0.21 1.15
40 [0.] 0.28 1.15
41 [1.] 0.51 1.15
42 [1.] 0.67 1.15
43 [1.] 0.2 1.15
44 [1.] 0.67 1.15
45 [1.] 0.31 1.15
46 [1.] 0.31 1.15
47 [1.] 0.25 1.15
48 [1.] 0.25 1.15
49 [1.] 0.29 1.15
50 [1.] 0.28 1.15
51 [1.] 0.31 1.15
52 [1.] 0.41 1.15
53 [1.] 0.35 1.15
54 [0.] 0.19 1.15
55 [1.] 0.43 1.15
56 [1.] 0.25 1.15
57 [1.] 0.52 1.15
58 [1.] 0.61 1.15
59 [1.] 0.49 1.15
60 [1.] 0.39 1.15
61 [0.] 0.31 1.15
62 [0.] 0.42 1.15
63 [0.] 0.47 1.15
64 [0.] 0.57 1.15
65 [0.] 0.21 1.15
66 [1.] 0.37 1.15
67 [1.] 0.58 1.15
68 [1.] 0.19 1.15
69 [1.] 0.34 1.15
70 [1.] 0.18 1.15
71 [1.] 0.26 1.15
72 [1.] 0.3 1.15
73 [1.] 0.3 1.15
74 [1.] 0.51 1.15
75 [1.] 0.51 1.15
76 [1.] 0.22 1.15
77 [1.] 1.05 1.15
78 [1.] 0.36 1.15
79 [1.] 0.81 1.15
80 [1.] 0.38 1.15
81 [1.] 0.56 1.15
82 [1.] 0.55 1.15
83 [1.] 0.3 1.15
84 [1.] 0.44 1.15
85 [1.] 0.37 1.15
86 [1.] 0.43 1.15
87 [1.] 0.39 1.15
88 [1.] 0.27 1.15
89 [1.] 0.74 1.15
90 [1.] 0.44 1.15
91 [1.] 0.2 1.15
92 [1.] 0.45 1.15
93 [1.] 0.24 1.15
94 [1.] 0.25 1.15
95 [1.] 0.41 1.15
96 [1.] 0.43 1.15
97 [1.] 0.35 1.15
98 [1.] 0.41 1.15
99 [1.] 0.42 1.15
100 [1.] 0.5 1.15
101 [1.] 0.42 1.15
102 [1.] 0.47 1.15
103 [1.] 0.49 1.15
104 [1.] 0.29 1.15
105 [1.] 0.14 1.15
106 [1.] 0.16 1.15
107 [1.] 0.13 1.15
108 [1.] 0.73 1.15
Обнаружено 99.0 аномалий
```
Для AE3_v2 точность составляет 92%
### 9) Если результаты обнаружения аномалий не удовлетворительные (обнаружено менее 70% аномалий), то подобрать подходящие параметры автокодировщика и повторить шаги (4) – (9)
Результаты обнаружения аномалий удовлетворены.
### 10) Параметры наилучшего автокодировщика и результаты обнаружения аномалий занести в таблицу:
Табл. 2 Результаты задания №2
| Dataset name | Количество<br>скрытых слоев | Количество<br>нейронов в скрытых слоях | Количество<br>эпох обучения | Ошибка<br>MSE_stop | Порог ошибки<br>реконструкции | % обнаруженных<br>аномалий |
|:-------------|:-----------------------------|:----------------------------------------|:-----------------------------|:-------------------|:-------------------------------|:---------------------------|
| Cardio | 11 | 48, 36, 28, 22, 16, 10, 16, 22, 28, 36, 48 | 100000 | 0.0077 | 1 | 99% |
### 11) Сделать выводы о требованиях к:
- данным для обучения,
- архитектуре автокодировщика,
- количеству эпох обучения,
- ошибке MSE_stop, приемлемой для останова обучения,
- ошибке реконструкции обучающей выборки (порогу обнаружения
аномалий)
для качественного обнаружения аномалий в случае, когда размерность
пространства признаков высока.
1) Данные для обучения должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение
2) Архитектура автокодировщика должна постепенно сужатся к бутылочному горлышку,а затем постепенно возвращатся к исходным выходным размерам, кол-во скрытых слоев 7-11.
3) В рамках данного набора данных оптимальное кол-во эпох 100000 с patience 4000 эпох
4) Оптимальная ошибка MSE-stop в районе 0.001, желательно не меньше для предотвращения переобучения
5) Значение порога 1 - идеальное

9
labworks/LW3/README.md Обычный файл
Просмотреть файл

@@ -0,0 +1,9 @@
## Лабораторныа работа №3
## Распознавание изображений
* [Задание](IS_Lab03_2023.pdf)
* [Методические указания](IS_Lab03_Metod_2023.pdf)
* <a href="https://youtube.com/playlist?list=PLZDCDMGmelH-pHt-Ij0nImVrOmj8DYKbB" target="_blank">Плейлист с видео о сверточных сетях</a>

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

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

До

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

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

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

До

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

Двоичные данные
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/690 (1).png

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

До

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

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

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

До

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

Просмотреть файл

@@ -1,717 +0,0 @@
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"gpuType": "T4"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"source": [
"## Задание 1"
],
"metadata": {
"id": "oZs0KGcz01BY"
}
},
{
"cell_type": "markdown",
"source": [
"### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули."
],
"metadata": {
"id": "gz18QPRz03Ec"
}
},
{
"cell_type": "code",
"source": [
"# импорт модулей\n",
"import os\n",
"os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab3')\n",
"\n",
"from tensorflow import keras\n",
"from tensorflow.keras import layers\n",
"from tensorflow.keras.models import Sequential\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"from sklearn.metrics import classification_report, confusion_matrix\n",
"from sklearn.metrics import ConfusionMatrixDisplay"
],
"metadata": {
"id": "mr9IszuQ1ANG"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 2) Загрузили набор данных MNIST, содержащий размеченные изображения рукописных цифр. "
],
"metadata": {
"id": "FFRtE0TN1AiA"
}
},
{
"cell_type": "code",
"source": [
"# загрузка датасета\n",
"from keras.datasets import mnist\n",
"(X_train, y_train), (X_test, y_test) = mnist.load_data()"
],
"metadata": {
"id": "Ixw5Sp0_1A-w"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 3) Разбили набор данных на обучающие и тестовые данные в соотношении 60 000:10 000 элементов. Параметр random_state выбрали равным (4k – 1)=23, где k=6 –номер бригады. Вывели размерности полученных обучающих и тестовых массивов данных."
],
"metadata": {
"id": "aCo_lUXl1BPV"
}
},
{
"cell_type": "code",
"source": [
"# создание своего разбиения датасета\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"# объединяем в один набор\n",
"X = np.concatenate((X_train, X_test))\n",
"y = np.concatenate((y_train, y_test))\n",
"\n",
"# разбиваем по вариантам\n",
"X_train, X_test, y_train, y_test = train_test_split(X, y,\n",
" test_size = 10000,\n",
" train_size = 60000,\n",
" random_state = 23)\n",
"# вывод размерностей\n",
"print('Shape of X train:', X_train.shape)\n",
"print('Shape of y train:', y_train.shape)\n",
"print('Shape of X test:', X_test.shape)\n",
"print('Shape of y test:', y_test.shape)"
],
"metadata": {
"id": "BrSjcpEe1BeV"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 4) Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения сверточной нейронной сети. Входные данные принимают значения от 0 до 1, метки цифр закодированы по принципу «one-hot encoding». Вывели размерности предобработанных обучающих и тестовых массивов данных."
],
"metadata": {
"id": "4hclnNaD1BuB"
}
},
{
"cell_type": "code",
"source": [
"# Зададим параметры данных и модели\n",
"num_classes = 10\n",
"input_shape = (28, 28, 1)\n",
"\n",
"# Приведение входных данных к диапазону [0, 1]\n",
"X_train = X_train / 255\n",
"X_test = X_test / 255\n",
"\n",
"# Расширяем размерность входных данных, чтобы каждое изображение имело\n",
"# размерность (высота, ширина, количество каналов)\n",
"\n",
"X_train = np.expand_dims(X_train, -1)\n",
"X_test = np.expand_dims(X_test, -1)\n",
"print('Shape of transformed X train:', X_train.shape)\n",
"print('Shape of transformed X test:', X_test.shape)\n",
"\n",
"# переведем метки в one-hot\n",
"y_train = keras.utils.to_categorical(y_train, num_classes)\n",
"y_test = keras.utils.to_categorical(y_test, num_classes)\n",
"print('Shape of transformed y train:', y_train.shape)\n",
"print('Shape of transformed y test:', y_test.shape)"
],
"metadata": {
"id": "xJH87ISq1B9h"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 5) Реализовали модель сверточной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети."
],
"metadata": {
"id": "7x99O8ig1CLh"
}
},
{
"cell_type": "code",
"source": [
"# создаем модель\n",
"model = Sequential()\n",
"model.add(layers.Conv2D(32, kernel_size=(3, 3), activation=\"relu\", input_shape=input_shape))\n",
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(layers.Conv2D(64, kernel_size=(3, 3), activation=\"relu\"))\n",
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(layers.Dropout(0.5))\n",
"model.add(layers.Flatten())\n",
"model.add(layers.Dense(num_classes, activation=\"softmax\"))\n",
"\n",
"model.summary()"
],
"metadata": {
"id": "Un561zSH1Cmv"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# компилируем и обучаем модель\n",
"batch_size = 512\n",
"epochs = 15\n",
"model.compile(loss=\"categorical_crossentropy\", optimizer=\"adam\", metrics=[\"accuracy\"])\n",
"model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)"
],
"metadata": {
"id": "q_h8PxkN9m0v"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 6) Оценили качество обучения на тестовых данных. Вывели значение функции ошибки и значение метрики качества классификации на тестовых данных."
],
"metadata": {
"id": "HL2_LVga1C3l"
}
},
{
"cell_type": "code",
"source": [
"# Оценка качества работы модели на тестовых данных\n",
"scores = model.evaluate(X_test, y_test)\n",
"print('Loss on test data:', scores[0])\n",
"print('Accuracy on test data:', scores[1])"
],
"metadata": {
"id": "81Cgq8dn9uL6"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 7) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания."
],
"metadata": {
"id": "KzrVY1SR1DZh"
}
},
{
"cell_type": "code",
"source": [
"# вывод двух тестовых изображений и результатов распознавания\n",
"\n",
"for n in [11,43]:\n",
" result = model.predict(X_test[n:n+1])\n",
" print('NN output:', result)\n",
"\n",
" plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))\n",
" plt.show()\n",
" print('Real mark: ', np.argmax(y_test[n]))\n",
" print('NN answer: ', np.argmax(result))"
],
"metadata": {
"id": "dbfkWjDI1Dp7"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 8) Вывели отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки."
],
"metadata": {
"id": "YgiVGr5_1D3u"
}
},
{
"cell_type": "code",
"source": [
"# истинные метки классов\n",
"true_labels = np.argmax(y_test, axis=1)\n",
"# предсказанные метки классов\n",
"predicted_labels = np.argmax(model.predict(X_test), axis=1)\n",
"\n",
"# отчет о качестве классификации\n",
"print(classification_report(true_labels, predicted_labels))\n",
"# вычисление матрицы ошибок\n",
"conf_matrix = confusion_matrix(true_labels, predicted_labels)\n",
"# отрисовка матрицы ошибок в виде \"тепловой карты\"\n",
"display = ConfusionMatrixDisplay(confusion_matrix=conf_matrix)\n",
"display.plot()\n",
"plt.show()"
],
"metadata": {
"id": "7MqcG_wl1EHI"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 9) Загрузили, предобработали и подали на вход обученной нейронной сети собственное изображение, созданное при выполнении лабораторной работы №1. Вывели изображение и результат распознавания."
],
"metadata": {
"id": "amaspXGW1EVy"
}
},
{
"cell_type": "code",
"source": [
"# загрузка собственного изображения\n",
"from PIL import Image\n",
"\n",
"for name_image in ['190 (2).png', '690 (1).png']:\n",
" file_data = Image.open(name_image)\n",
" file_data = file_data.convert('L') # перевод в градации серого\n",
" test_img = np.array(file_data)\n",
"\n",
" # вывод собственного изображения\n",
" plt.imshow(test_img, cmap=plt.get_cmap('gray'))\n",
" plt.show()\n",
"\n",
" # предобработка\n",
" test_img = test_img / 255\n",
" test_img = np.reshape(test_img, (1,28,28,1))\n",
"\n",
" # распознавание\n",
" result = model.predict(test_img)\n",
" print('I think it\\'s', np.argmax(result))"
],
"metadata": {
"id": "ktWEeqWd1EyF"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 10) Загрузили с диска модель, сохраненную при выполнении лабораторной работы №1. Вывели информацию об архитектуре модели. Повторили для этой модели п. 6."
],
"metadata": {
"id": "mgrihPd61E8w"
}
},
{
"cell_type": "code",
"source": [
"model_lr1 = keras.models.load_model(\"best_model.keras\")\n",
"\n",
"model_lr1.summary()"
],
"metadata": {
"id": "DblXqn3l1FL2"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# развернем каждое изображение 28*28 в вектор 784\n",
"X_train, X_test, y_train, y_test = train_test_split(X, y,\n",
" test_size = 10000,\n",
" train_size = 60000,\n",
" random_state = 23)\n",
"num_pixels = X_train.shape[1] * X_train.shape[2]\n",
"X_train = X_train.reshape(X_train.shape[0], num_pixels) / 255\n",
"X_test = X_test.reshape(X_test.shape[0], num_pixels) / 255\n",
"print('Shape of transformed X train:', X_train.shape)\n",
"print('Shape of transformed X train:', X_test.shape)\n",
"\n",
"# переведем метки в one-hot\n",
"y_train = keras.utils.to_categorical(y_train, num_classes)\n",
"y_test = keras.utils.to_categorical(y_test, num_classes)\n",
"print('Shape of transformed y train:', y_train.shape)\n",
"print('Shape of transformed y test:', y_test.shape)"
],
"metadata": {
"id": "0ki8fhJrEyEt"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# Оценка качества работы модели на тестовых данных\n",
"scores = model_lr1.evaluate(X_test, y_test)\n",
"print('Loss on test data:', scores[0])\n",
"print('Accuracy on test data:', scores[1])"
],
"metadata": {
"id": "0Yj0fzLNE12k"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 11) Сравнили обученную модель сверточной сети и наилучшую модель полносвязной сети из лабораторной работы №1 по следующим показателям:\n",
"### - количество настраиваемых параметров в сети\n",
"### - количество эпох обучения\n",
"### - качество классификации тестовой выборки.\n",
"### Сделали выводы по результатам применения сверточной нейронной сети для распознавания изображений. "
],
"metadata": {
"id": "MsM3ew3d1FYq"
}
},
{
"cell_type": "markdown",
"source": [
"Таблица1:"
],
"metadata": {
"id": "xxFO4CXbIG88"
}
},
{
"cell_type": "markdown",
"source": [
"| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |\n",
"|----------|-------------------------------------|---------------------------|-----------------------------------------|\n",
"| Сверточная | 34 826 | 15 | accuracy:0.987 ; loss:0.037 |\n",
"| Полносвязная | 79512 | 50 | accuracy:0.946 ; loss:0.185 |\n"
],
"metadata": {
"id": "xvoivjuNFlEf"
}
},
{
"cell_type": "markdown",
"source": [
"По результатам применения сверточной НС, а также по результатам таблицы 1 делаем выводы, что сверточная НС намного лучше справляется с задачами распознования изображений, чем полносвязная - имеет меньше настраиваемых параметров, быстрее обучается, имеет лучшие показатели качества."
],
"metadata": {
"id": "YctF8h_sIB-P"
}
},
{
"cell_type": "markdown",
"source": [
"## Задание 2"
],
"metadata": {
"id": "wCLHZPGB1F1y"
}
},
{
"cell_type": "markdown",
"source": [
"### В новом блокноте выполнили п. 2–8 задания 1, изменив набор данных MNIST на CIFAR-10, содержащий размеченные цветные изображения объектов, разделенные на 10 классов. \n",
"### При этом:\n",
"### - в п. 3 разбиение данных на обучающие и тестовые произвели в соотношении 50 000:10 000\n",
"### - после разбиения данных (между п. 3 и 4) вывели 25 изображений из обучающей выборки с подписями классов\n",
"### - в п. 7 одно из тестовых изображений должно распознаваться корректно, а другое – ошибочно. "
],
"metadata": {
"id": "DUOYls124TT8"
}
},
{
"cell_type": "markdown",
"source": [
"### 1) Загрузили набор данных CIFAR-10, содержащий цветные изображения размеченные на 10 классов: самолет, автомобиль, птица, кошка, олень, собака, лягушка, лошадь, корабль, грузовик."
],
"metadata": {
"id": "XDStuSpEJa8o"
}
},
{
"cell_type": "code",
"source": [
"# загрузка датасета\n",
"from keras.datasets import cifar10\n",
"\n",
"(X_train, y_train), (X_test, y_test) = cifar10.load_data()"
],
"metadata": {
"id": "y0qK7eKL4Tjy"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 2) Разбили набор данных на обучающие и тестовые данные в соотношении 50 000:10 000 элементов. Параметр random_state выбрали равным (4k – 1)=23, где k=6 –номер бригады. Вывели размерности полученных обучающих и тестовых массивов данных."
],
"metadata": {
"id": "wTHiBy-ZJ5oh"
}
},
{
"cell_type": "code",
"source": [
"# создание своего разбиения датасета\n",
"\n",
"# объединяем в один набор\n",
"X = np.concatenate((X_train, X_test))\n",
"y = np.concatenate((y_train, y_test))\n",
"\n",
"# разбиваем по вариантам\n",
"X_train, X_test, y_train, y_test = train_test_split(X, y,\n",
" test_size = 10000,\n",
" train_size = 50000,\n",
" random_state = 23)\n",
"# вывод размерностей\n",
"print('Shape of X train:', X_train.shape)\n",
"print('Shape of y train:', y_train.shape)\n",
"print('Shape of X test:', X_test.shape)\n",
"print('Shape of y test:', y_test.shape)"
],
"metadata": {
"id": "DlnFbQogKD2v"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### Вывели 25 изображений из обучающей выборки с подписью классов."
],
"metadata": {
"id": "pj3bMaz1KZ3a"
}
},
{
"cell_type": "code",
"source": [
"class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',\n",
" 'dog', 'frog', 'horse', 'ship', 'truck']\n",
"\n",
"plt.figure(figsize=(10,10))\n",
"for i in range(25):\n",
" plt.subplot(5,5,i+1)\n",
" plt.xticks([])\n",
" plt.yticks([])\n",
" plt.grid(False)\n",
" plt.imshow(X_train[i])\n",
" plt.xlabel(class_names[y_train[i][0]])\n",
"plt.show()"
],
"metadata": {
"id": "TW8D67KEKhVE"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 3) Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения сверточной нейронной сети. Входные данные принимают значения от 0 до 1, метки цифр закодированы по принципу «one-hot encoding». Вывели размерности предобработанных обучающих и тестовых массивов данных."
],
"metadata": {
"id": "d3TPr2w1KQTK"
}
},
{
"cell_type": "code",
"source": [
"# Зададим параметры данных и модели\n",
"num_classes = 10\n",
"input_shape = (32, 32, 3)\n",
"\n",
"# Приведение входных данных к диапазону [0, 1]\n",
"X_train = X_train / 255\n",
"X_test = X_test / 255\n",
"\n",
"print('Shape of transformed X train:', X_train.shape)\n",
"print('Shape of transformed X test:', X_test.shape)\n",
"\n",
"# переведем метки в one-hot\n",
"y_train = keras.utils.to_categorical(y_train, num_classes)\n",
"y_test = keras.utils.to_categorical(y_test, num_classes)\n",
"print('Shape of transformed y train:', y_train.shape)\n",
"print('Shape of transformed y test:', y_test.shape)"
],
"metadata": {
"id": "iFDpxEauLZ8j"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 4) Реализовали модель сверточной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети."
],
"metadata": {
"id": "ydNITXptLeGT"
}
},
{
"cell_type": "code",
"source": [
"# создаем модель\n",
"model = Sequential()\n",
"model.add(layers.Conv2D(32, kernel_size=(3, 3), activation=\"relu\", input_shape=input_shape))\n",
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(layers.Conv2D(64, kernel_size=(3, 3), activation=\"relu\"))\n",
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(layers.Conv2D(128, kernel_size=(3, 3), activation=\"relu\"))\n",
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(layers.Flatten())\n",
"model.add(layers.Dense(128, activation='relu'))\n",
"model.add(layers.Dropout(0.5))\n",
"model.add(layers.Dense(num_classes, activation=\"softmax\"))\n",
"model.summary()"
],
"metadata": {
"id": "YhAD5CllLlv7"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# компилируем и обучаем модель\n",
"batch_size = 64\n",
"epochs = 50\n",
"model.compile(loss=\"categorical_crossentropy\", optimizer=\"adam\", metrics=[\"accuracy\"])\n",
"model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)"
],
"metadata": {
"id": "3otvqMjjOdq5"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 5) Оценили качество обучения на тестовых данных. Вывели значение функции ошибки и значение метрики качества классификации на тестовых данных."
],
"metadata": {
"id": "Vv1kUHWTLl9B"
}
},
{
"cell_type": "code",
"source": [
"# Оценка качества работы модели на тестовых данных\n",
"scores = model.evaluate(X_test, y_test)\n",
"print('Loss on test data:', scores[0])\n",
"print('Accuracy on test data:', scores[1])"
],
"metadata": {
"id": "SaDxydiyLmRX"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 6) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания."
],
"metadata": {
"id": "OdgEiyUGLmhP"
}
},
{
"cell_type": "code",
"source": [
"# вывод двух тестовых изображений и результатов распознавания\n",
"\n",
"for n in [3,16]:\n",
" result = model.predict(X_test[n:n+1])\n",
" print('NN output:', result)\n",
"\n",
" plt.imshow(X_test[n].reshape(32,32,3), cmap=plt.get_cmap('gray'))\n",
" plt.show()\n",
" print('Real mark: ', np.argmax(y_test[n]))\n",
" print('NN answer: ', np.argmax(result))"
],
"metadata": {
"id": "t3yGj1MlLm9H"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 7) Вывели отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки."
],
"metadata": {
"id": "3h6VGDRrLnNC"
}
},
{
"cell_type": "code",
"source": [
"# истинные метки классов\n",
"true_labels = np.argmax(y_test, axis=1)\n",
"# предсказанные метки классов\n",
"predicted_labels = np.argmax(model.predict(X_test), axis=1)\n",
"\n",
"# отчет о качестве классификации\n",
"print(classification_report(true_labels, predicted_labels, target_names=class_names))\n",
"# вычисление матрицы ошибок\n",
"conf_matrix = confusion_matrix(true_labels, predicted_labels)\n",
"# отрисовка матрицы ошибок в виде \"тепловой карты\"\n",
"fig, ax = plt.subplots(figsize=(6, 6))\n",
"disp = ConfusionMatrixDisplay(confusion_matrix=conf_matrix,display_labels=class_names)\n",
"disp.plot(ax=ax, xticks_rotation=45) # поворот подписей по X и приятная палитра\n",
"plt.tight_layout() # чтобы всё влезло\n",
"plt.show()"
],
"metadata": {
"id": "od56oyyzM0nw"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"По результатам классификации датасета CIFAR-10 сверточной моделью делаем вывод, что она удовлетворительно справилась с задачей. Полученные метрики оценки качества имеют показатели в районе 0.71."
],
"metadata": {
"id": "RF4xK1cxamBc"
}
}
]
}

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

Просмотреть файл

@@ -1,530 +0,0 @@
# Отчёт по лабораторной работе №3
**Касимов Азамат, Немыкин Никита — А-01-22**
---
## Задание 1
### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули.
```python
# импорт модулей
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab3')
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.metrics import ConfusionMatrixDisplay
```
### 2) Загрузили набор данных MNIST, содержащий размеченные изображения рукописных цифр.
```python
# загрузка датасета
from keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()
```
### 3) Разбили набор данных на обучающие и тестовые данные в соотношении 60 000:10 000 элементов. Параметр random_state выбрали равным (4k – 1)=23, где k=6 –номер бригады. Вывели размерности полученных обучающих и тестовых массивов данных.
```python
# создание своего разбиения датасета
from sklearn.model_selection import train_test_split
# объединяем в один набор
X = np.concatenate((X_train, X_test))
y = np.concatenate((y_train, y_test))
# разбиваем по вариантам
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size = 10000,
train_size = 60000,
random_state = 23)
# вывод размерностей
print('Shape of X train:', X_train.shape)
print('Shape of y train:', y_train.shape)
print('Shape of X test:', X_test.shape)
print('Shape of y test:', y_test.shape)
```
```
Shape of X train: (60000, 28, 28)
Shape of y train: (60000,)
Shape of X test: (10000, 28, 28)
Shape of y test: (10000,)
```
### 4) Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения сверточной нейронной сети. Входные данные принимают значения от 0 до 1, метки цифр закодированы по принципу «one-hot encoding». Вывели размерности предобработанных обучающих и тестовых массивов данных.
```python
# Зададим параметры данных и модели
num_classes = 10
input_shape = (28, 28, 1)
# Приведение входных данных к диапазону [0, 1]
X_train = X_train / 255
X_test = X_test / 255
# Расширяем размерность входных данных, чтобы каждое изображение имело
# размерность (высота, ширина, количество каналов)
X_train = np.expand_dims(X_train, -1)
X_test = np.expand_dims(X_test, -1)
print('Shape of transformed X train:', X_train.shape)
print('Shape of transformed X test:', X_test.shape)
# переведем метки в one-hot
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print('Shape of transformed y train:', y_train.shape)
print('Shape of transformed y test:', y_test.shape)
```
```
Shape of transformed X train: (60000, 28, 28, 1)
Shape of transformed X test: (10000, 28, 28, 1)
Shape of transformed y train: (60000, 10)
Shape of transformed y test: (10000, 10)
```
### 5) Реализовали модель сверточной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети.
```python
# создаем модель
model = Sequential()
model.add(layers.Conv2D(32, kernel_size=(3, 3), activation="relu", input_shape=input_shape))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Conv2D(64, kernel_size=(3, 3), activation="relu"))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Dropout(0.5))
model.add(layers.Flatten())
model.add(layers.Dense(num_classes, activation="softmax"))
model.summary()
```
**Model: "sequential"**
| Layer (type) | Output Shape | Param # |
|--------------------------------|---------------------|--------:|
| conv2d (Conv2D) | (None, 26, 26, 32) | 320 |
| max_pooling2d (MaxPooling2D) | (None, 13, 13, 32) | 0 |
| conv2d_1 (Conv2D) | (None, 11, 11, 64) | 18,496 |
| max_pooling2d_1 (MaxPooling2D) | (None, 5, 5, 64) | 0 |
| dropout (Dropout) | (None, 5, 5, 64) | 0 |
| flatten (Flatten) | (None, 1600) | 0 |
| dense (Dense) | (None, 10) | 16,010 |
**Total params:** 34,826 (136.04 KB)
**Trainable params:** 34,826 (136.04 KB)
**Non-trainable params:** 0 (0.00 B)
```python
# компилируем и обучаем модель
batch_size = 512
epochs = 15
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)
```
### 6) Оценили качество обучения на тестовых данных. Вывели значение функции ошибки и значение метрики качества классификации на тестовых данных.
```python
# Оценка качества работы модели на тестовых данных
scores = model.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
```
313/313 ━━━━━━━━━━━━━━━━━━━━ 3s 9ms/step - accuracy: 0.9891 - loss: 0.0327
Loss on test data: 0.03766785189509392
Accuracy on test data: 0.9879000186920166
```
### 7) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания.
```python
# вывод двух тестовых изображений и результатов распознавания
for n in [11,43]:
result = model.predict(X_test[n:n+1])
print('NN output:', result)
plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))
plt.show()
print('Real mark: ', np.argmax(y_test[n]))
print('NN answer: ', np.argmax(result))
```
![picture](images/1.png)
```
Real mark: 2
NN answer: 2
```
![picture](images/2.png)
```
Real mark: 9
NN answer: 9
```
### 8) Вывели отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки.
```python
# истинные метки классов
true_labels = np.argmax(y_test, axis=1)
# предсказанные метки классов
predicted_labels = np.argmax(model.predict(X_test), axis=1)
# отчет о качестве классификации
print(classification_report(true_labels, predicted_labels))
# вычисление матрицы ошибок
conf_matrix = confusion_matrix(true_labels, predicted_labels)
# отрисовка матрицы ошибок в виде "тепловой карты"
display = ConfusionMatrixDisplay(confusion_matrix=conf_matrix)
display.plot()
plt.show()
```
```
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 5ms/step
precision recall f1-score support
0 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
```
![picture](images/3.png)
### 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))
```
![picture](images/190 (2).png)
```
I think it's 1
```
![picture](images/690 (1).png)
```
I think it's 6
```
### 10) Загрузили с диска модель, сохраненную при выполнении лабораторной работы №1. Вывели информацию об архитектуре модели. Повторили для этой модели п. 6.
```python
model_lr1 = keras.models.load_model("model_1h100_2h50.keras")
model_lr1.summary()
```
**Model: "sequential_10"**
| Layer (type) | Output Shape | Param # |
|------------------|-------------:|--------:|
| dense_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()
```
![picture](images/4.png)
### 3) Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения сверточной нейронной сети. Входные данные принимают значения от 0 до 1, метки цифр закодированы по принципу «one-hot encoding». Вывели размерности предобработанных обучающих и тестовых массивов данных.
```python
# Зададим параметры данных и модели
num_classes = 10
input_shape = (32, 32, 3)
# Приведение входных данных к диапазону [0, 1]
X_train = X_train / 255
X_test = X_test / 255
print('Shape of transformed X train:', X_train.shape)
print('Shape of transformed X test:', X_test.shape)
# переведем метки в one-hot
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print('Shape of transformed y train:', y_train.shape)
print('Shape of transformed y test:', y_test.shape)
```
```
Shape of transformed X train: (50000, 32, 32, 3)
Shape of transformed X test: (10000, 32, 32, 3)
Shape of transformed y train: (50000, 10)
Shape of transformed y test: (10000, 10)
```
### 4) Реализовали модель сверточной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети.
```python
# создаем модель
model = Sequential()
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))
```
![picture](images/5.png)
```
Real mark: 0
NN answer: 0
```
![picture](images/6.png)
```
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
```
![picture](images/7.png)
### По результатам классификации датасета CIFAR-10 сверточной моделью делаем вывод, что она удовлетворительно справилась с задачей. Полученные метрики оценки качества имеют показатели в районе 0.71.

7
labworks/LW4/README.md Обычный файл
Просмотреть файл

@@ -0,0 +1,7 @@
## Лабораторныа работа №4
## Распознавание последовательностей
* [Задание](IS_Lab04_2023.pdf)
* [Методические указания](IS_Lab04_Metod_2023.pdf)