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

..

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

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

@ -0,0 +1,608 @@
# Отчет по лабораторной работе №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 = 15)
```
* Вывод размерностей
```
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()
```
![отображение элементов](p_4.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_8"
> ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
> ┃ Layer (type) ┃ Output Shape ┃ Param # ┃
> ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
> │ dense_19 (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)
```
![график функции ошибки](p_6.png)
## 7. Применение модели к тестовым данным
```
scores=model_1.evaluate(X_test,y_test)
print('Lossontestdata:',scores[0]) #значение функции ошибки
print('Accuracyontestdata:',scores[1]) #значение метрики качества классификации
```
> - accuracy: 0.9316 - loss: 0.2666
>Lossontestdata: 0.2741525173187256
>Accuracyontestdata: 0.928600013256073
## 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_20 (Dense) │ (None, 100) │ 78,500 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_21 (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)
```
![график функции ошибки](p_8_100.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.9482 - loss: 0.1875
>Lossontestdata: 0.19283892214298248
>Accuracyontestdata: 0.9462000131607056 '
* при 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_10"
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
>│ dense_22 (Dense) │ (None, 300) │ 235,500 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_23 (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)
```
![график функции ошибки](p_8_300.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.9437 - loss: 0.2113
>Lossontestdata: 0.2168053537607193
>Accuracyontestdata: 0.9412000179290771
* при 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_11"
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
>│ dense_24 (Dense) │ (None, 500) │ 392,500 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_25 (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)
```
![график функции ошибки](p_8_500.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.9396 - loss: 0.2295
>Lossontestdata: 0.23596525192260742
>Accuracyontestdata: 0.9369999766349792
Как мы видим, лучшая метрика получилась равной 0.9465000033378601 при архитектуре со 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_12"
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
>│ dense_26 (Dense) │ (None, 100) │ 78,500 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_27 (Dense) │ (None, 50) │ 5,050 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_28 (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)
```
![график функции ошибки](p_9_50.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.9459 - loss: 0.1914
>Lossontestdata: 0.1960301399230957
>Accuracyontestdata: 0.9444000124931335
* при 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_13"
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
>│ dense_29 (Dense) │ (None, 100) │ 78,500 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_30 (Dense) │ (None, 100) │ 10,100 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_31 (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)
```
![график функции ошибки](p_9_100.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.9488 - loss: 0.1810
>Lossontestdata: 0.18787769973278046
>Accuracyontestdata: 0.9467999935150146
Количество Количество нейронов в Количество нейронов во Значение метрики
скрытых слоев первом скрытом слое втором скрытом слое качества классификации
0 - - 0.913100004196167
1 100 - 0.9462000131607056
1 300 - 0.9412000179290771
1 500 - 0.9369999766349792
2 100 50 0.9444000124931335
2 100 100 0.9467999935150146
Из таблицы видно, что лучше всего справились с задачей НС с одним скрытым слоем и 100 нейронами и НС с двумя скрытыми слоями по 100 нейронов.
Метрика точности достигла почти 95% при достаточно простой архитектуре сетей, это может быть связано с тем, что датасет MNIST имеет только 60,000 обучающих примеров - недостаточно для более сложных архитектур. Также при усложнении архитектуры сети появляется риск переобучения. В нашей задаче мы видим, что при увеличении числа нейронов в скрытых слоях метрика падает.Простая модель лучше обобщает на подобных учебных датасетах, более сложные же архитектуры стоит использовать на более сложных датасетах, например ImageNet.
## 11. Сохранение наилучшей модели на диск
```
model_2l_100.save(filepath='best_model.keras')
```
## 12. Вывод тестовых изображений и результатов распознаваний
```
n = 333
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: ', str(np.argmax(y_test[n])))
print('NN answer: ', str(np.argmax(result)))
```
> NN output: [[3.0055828e-02 1.7918642e-06 1.0183058e-05 1.3000262e-04 2.2273003e-05
> 9.6671683e-01 3.1997326e-05 6.5717955e-05 2.9293287e-03 3.6015103e-05]]
![alt text](p_11.png)
>Real mark: 5
>NN answer: 5
```
n = 555
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: ', str(np.argmax(y_test[n])))
print('NN answer: ', str(np.argmax(result)))
```
> NN output: [[9.8050815e-01 5.7898621e-08 9.2301030e-05 8.2087971e-04 5.6250155e-06
> 1.8371470e-02 9.3076023e-06 1.4318567e-04 2.3332947e-05 2.5768295e-05]]
![alt text](p_11_2.png)
>Real mark: 0
>NN answer: 0 '
## 12. Тестирование на собственных изображениях
* загрузка 1 собственного изображения
```
from PIL import Image
file_1_data = Image.open('1.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()
```
![1 изображение](1.png)
* предобработка
```
test_1_img = test_1_img / 255
test_1_img = test_1_img.reshape(1, num_pixels)
```
* распознавание
```
result_1 = model.predict(test_1_img)
print('I think it\'s', np.argmax(result_1))
```
> I think it's 1
* тест 2 изображения
```
file_2_data = Image.open('2.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()
```
![2 изображение](2.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 2
Сеть не ошиблась и корректно распознала обе цифры на изображениях
## 14. Тестирование на собственных повернутых изображениях
```
file_1_90_data = Image.open('1_90.png')
file_1_90_data = file_1_90_data.convert('L') #перевод в градации серого
test_1_90_img = np.array(file_1_90_data)
plt.imshow(test_1_90_img, cmap=plt.get_cmap('gray'))
plt.show()
```
![alt text](1_90.png)
```
test_1_90_img = test_1_90_img / 255
test_1_90_img = test_1_90_img.reshape(1, num_pixels)
result_1_90 = model.predict(test_1_90_img)
print('I think it\'s', np.argmax(result_1_90))
```
> I think it's 4
```
file_2_90_data = Image.open('2_90.png')
file_2_90_data = file_2_90_data.convert('L') #перевод в градации серого
test_2_90_img = np.array(file_2_90_data)
plt.imshow(test_2_90_img, cmap=plt.get_cmap('gray'))
plt.show()
```
![alt text](2_90.png)
```
test_2_90_img = test_2_90_img / 255
test_2_90_img = test_2_90_img.reshape(1, num_pixels)
result_2_90 = model.predict(test_2_90_img)
print('I think it\'s', np.argmax(result_2_90))
```
> I think it's 5
При повороте изображений сеть не распознала цифры правильно. Так как она не обучалась на повернутых изображениях.

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

@ -0,0 +1,324 @@
# Отчет по лабораторной работе №2
Артюшина Валерия, Хохлов Кирилл, А-01-22
## Подготовка к работе
Номер бригады k = 4
N = 4 mod 3 = 1
Набор данных Letter
# Задание 1
## 1. В среде GoogleColab создали блокнот(is_lab2.ipynb).
``` py
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab2')
```
* импорт модулей
``` py
import numpy as np
import lab02_lib as lib
```
## 2. Генерация набора двумерных данных
``` py
data = lib.datagen(4, 4, 1000, 2)
# вывод данных и размерности
print('Исходные данные:')
print(data)
print('Размерность данных:')
print(data.shape)
```
![alt text](ex1_p2.png)
```
Исходные данные:
[[3.89754058 4.00467196]
[4.00996996 4.00696404]
[4.13181175 4.19264161]
...
[3.90249897 3.8890494 ]
[3.98817291 4.05824572]
[3.95966561 3.94263676]]
Размерность данных:
(1000, 2)
```
## 3. Создание и обучение автокодировщика AE1
``` py
patience = 100
ae1_trained, IRE1, IREth1 = lib.create_fit_save_ae(data,'out/AE1.h5','out/AE1_ire_th.txt',
500, True, patience)
```
> Параметры архитектуры
```
Задать архитектуру автокодировщиков или использовать архитектуру по умолчанию? (1/2): 1
Задайте количество скрытых слоёв (нечетное число) : 3
Задайте архитектуру скрытых слоёв автокодировщика, например, в виде 3 1 3 : 3 1 3
```
## 4. Результаты обучения
Ошибка MSE, на которой обучение завершилось:
```
mse_stop_ae1 = 3.0205
```
``` py
# Построение графика ошибки реконструкции
lib.ire_plot('training', IRE1, IREth1, 'AE1')
```
![alt text](ex1_p4.png)
Порог ошибки реконструкции:
```
IREth1
np.float64(2.8)
```
## 5. Создание и обучение автокодировщика AE2
``` py
ae2_trained, IRE2, IREth2 = lib.create_fit_save_ae(data,'out/AE2.h5','out/AE2_ire_th.txt',
2000, True, patience)
lib.ire_plot('training', IRE2, IREth2, 'AE2')
```
## 6. Результаты обучения
Ошибка MSE, на которой обучение завершилось:
```
mse_stop_ae2 = 0.0121
```
``` py
# Построение графика ошибки реконструкции
lib.ire_plot('training', IRE2, IREth2, 'AE2')
```
![alt text](ex1_p6.png)
Порог ошибки реконструкции:
```
IREth2
np.float64(0.47)
```
## 7. Характеристики качества обучения
``` py
# построение областей покрытия и границ классов
# расчет характеристик качества обучения
numb_square = 20
xx, yy, Z1 = lib.square_calc(numb_square, data, ae1_trained, IREth1, '1', True)
```
![alt text](ex1_p7_1.png)
amount: 21
amount_ae: 294
![alt text](ex1_p7_2.png)
![alt text](ex1_p7_3.png)
Оценка качества AE1
```
IDEAL = 0. Excess: 13.0
IDEAL = 0. Deficit: 0.0
IDEAL = 1. Coating: 1.0
summa: 1.0
IDEAL = 1. Extrapolation precision (Approx): 0.07142857142857144
```
``` py
# построение областей покрытия и границ классов
# расчет характеристик качества обучения
numb_square = 20
xx, yy, Z2 = lib.square_calc(numb_square, data, ae2_trained, IREth2, '2', True)
```
![alt text](ex1_p7_4.png)
amount: 21
amount_ae: 39
![alt text](ex1_p7_5.png)
![alt text](ex1_p7_6.png)
Оценка качества AE2
```
IDEAL = 0. Excess: 0.8571428571428571
IDEAL = 0. Deficit: 0.0
IDEAL = 1. Coating: 1.0
summa: 1.0
IDEAL = 1. Extrapolation precision (Approx): 0.5384615384615385
```
``` py
# сравнение характеристик качества обучения и областей аппроксимации
lib.plot2in1(data, xx, yy, Z1, Z2)
```
![alt text](ex1_p7_7.png)
* Вывод: при увеличении количества скрытых слоев - показатели качества улучшаются. Таким образом, для качественного обнаружения аномалий стоит использовать автокодировщик AE2.
## 9. Создание тестовой выборки
``` py
test_data = np.array([[3.5, 4.2], [3.2, 4], [4.1, 3], [3.5,3.5], [3, 4], [3.5, 4.5]])
```
```
test_data
array([[3.5, 4.2],
[3.2, 4. ],
[4.1, 3. ],
[3.5, 3.5],
[3. , 4. ],
[3.5, 4.5]])
```
## 10. Применение автокодировщиков к тестовым данным
``` py
# тестирование AE1
predicted_labels1, ire1 = lib.predict_ae(ae1_trained, test_data, IREth1)
lib.anomaly_detection_ae(predicted_labels1, ire1, IREth1)
lib.ire_plot('test', ire1, IREth1, 'AE1')
```
Аномалий не обнаружено
![alt text](ex1_p10_1.png)
``` py
# тестирование AE2
predicted_labels2, ire2 = lib.predict_ae(ae2_trained, test_data, IREth2)
lib.anomaly_detection_ae(predicted_labels2, ire2, IREth2)
lib.ire_plot('test', ire2, IREth2, 'AE2')
```
i Labels IRE IREth
0 [1.] [0.5] 0.47
1 [1.] [0.73] 0.47
2 [1.] [0.94] 0.47
3 [1.] [0.6] 0.47
4 [1.] [0.93] 0.47
5 [1.] [0.71] 0.47
Обнаружено 6.0 аномалий
![alt text](ex1_p10_2.png)
## 11. Построение областей аппроксимации и точек тестового набора
``` py
lib.plot2in1_anomaly(data, xx, yy, Z1, Z2, test_data)
```
![alt text](ex1_p11.png)
## 12. Результаты исследования
Табл. 1 Результаты задания №1.
![alt text](tab1.png)
## 13. Выводы о требованиях
Для успешного обучения автокодировщика для задачи одноклассовой классификации должны быть соблюдены следующие требования:
* Данные для обучения: данные должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение. Данные должны соответствовать одному классу и в пространстве признаков образовывать сплошной кластер
* Архитектура автокодировщика: автокодировщик должен содержать более одного внутреннего слоя. Архитектура автокодировщика имеет форму «бабочки»
* Количество эпох обучения: количество эпох обучения должно быть порядка тысяч. В рамках данного набора данных оптимально использовать 3000 с patience 300 эпох
* Ошибка MSE_stop: оптимальная ошибка для остановки обучения составляет 0,01 (для предотвращения переобучения)
* Ошибка реконструкции: должна быть минимальной
* Характеристики качества обучения EDCA: Excess не больше 0.5, Deficit = 0, Coating = 1, Approx не меньше 0.7
# Задание 2
## 1. Набор данных Letter
Набор предназначен для распознавания черно-белых пиксельных прямоугольников как одну из 26 заглавных букв английского алфавита, где буквы алфавита представлены в 16 измерениях. (32 признака, 1600 примеров - 1500 нормальных, 100 аномальных)
## 2. Загрузка многомерной обучающей выборки
``` py
train = np.loadtxt('letter_train.txt', dtype=float)
```
## 3. Вывод данных и размерности
``` py
print('Исходные данные:')
print(train)
print('Размерность данных:')
print(train.shape)
```
```
Исходные данные:
[[ 6. 10. 5. ... 10. 2. 7.]
[ 0. 6. 0. ... 8. 1. 7.]
[ 4. 7. 5. ... 8. 2. 8.]
...
[ 7. 10. 10. ... 8. 5. 6.]
[ 7. 7. 10. ... 6. 0. 8.]
[ 3. 4. 5. ... 9. 5. 5.]]
Размерность данных:
(1500, 32)
```
## 4. Создание и обучение автокодировщика AE3 (100000 эпох)
``` py
patience= 20000
ae3_trained, IRE3, IREth3= lib.create_fit_save_ae(train,'out/AE3.h5','out/AE3_ire_th.txt', 100000, False, patience, early_stopping_delta = 0.001)
```
> Параметры архитектуры
```
Задайте количество скрытых слоёв (нечетное число) : 9
Задайте архитектуру скрытых слоёв автокодировщика, например, в виде 3 1 3 : 64 48 32 24 16 24 32 48 64
```
## 5. Результаты обучения
Ошибка MSE, на которой обучение завершилось:
```
mse_stop_ae3 = 0.1056
```
``` py
# Построение графика ошибки реконструкции
lib.ire_plot('training', IRE3, IREth3, 'AE3')
```
![alt text](ex2_p5.png)
Порог ошибки реконструкции:
```
IREth3
np.float64(3.64)
```
## 6. Вывод о пригодности автокодировщика
Нейронная сеть обучена оптимально и порог обнаружения аномалий адекватно описывает границу области генеральной совокупности исследуемых данных.
## 7. Загрузка тестовой выборки
``` py
test = np.loadtxt('letter_test.txt', dtype=float)
# вывод данных и размерности
print('Исходные данные:')
print(test)
print('Размерность данных:')
print(test.shape)
```
```
Исходные данные:
[[ 8. 11. 8. ... 7. 4. 9.]
[ 4. 5. 4. ... 13. 8. 8.]
[ 3. 3. 5. ... 8. 3. 8.]
...
[ 4. 9. 4. ... 8. 3. 8.]
[ 6. 10. 6. ... 9. 8. 8.]
[ 3. 1. 3. ... 9. 1. 7.]]
Размерность данных:
(100, 32)
```
## 8. Применение автокодировщика к тестовым данным
``` py
#тестирование АE3
predicted_labels3, ire3 = lib.predict_ae(ae3_trained, test, IREth3)
#вывод результатов классификации
lib.anomaly_detection_ae(predicted_labels3, ire3, IREth3)
# Построение графика ошибки реконструкции
lib.ire_plot('test', ire3, IREth3, 'AE3')
```
```
Обнаружено 98.0 аномалий
```
![alt text](ex2_p8.png)
## 10. Результаты обнаружения аномалий
Обнаружено более 70% аномалий, результаты удовлетворены.
## 10. Результаты исследования
Табл. 2 Результаты задания №2.
![alt text](tab2.png)
## 11. Выводы о требованиях
для качественного обнаружения аномалий в случае, когда размерность пространства признаков высока.
* Данные для обучения: должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение
* Архитектура автокодировщика: многомерный автокодировщик должен иметь достаточно большое количество внутренних слоев (в данном датасете не менее 7) и нейронов в них. Размеры определяются размерностью исходных данных.
* Количество эпох обучения: в рамках данного набора данных оптимальное кол-во эпох 100000 с patience 5000 эпох
* Ошибка MSE-stop: оптимальная ошибка MSE-stop 0.001
* Ошибка реконструкции: значение ошибки реконструкции должно как можно меньше

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

@ -1,9 +0,0 @@
## Лабораторныа работа №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/p10.png

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

@ -0,0 +1,506 @@
# Отчёт по лабораторной работе №3
Артюшина Валерия, Хохлов Кирилл, А-01-22
# Задание 1
## 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули.
```python
# импорт модулей
import os
os.mkdir('/content/drive/MyDrive/Colab Notebooks/is_lab3')
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) = 15, где k = 4 – номер бригады. Вывели размерности полученных обучающих и тестовых массивов данных.
```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 = 15)
# вывод размерностей
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()
```
![alt text](p5.png)
```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])
```
```
accuracy: 0.9895
loss: 0.0345
Loss on test data: 0.035905033349990845
Accuracy on test data: 0.988099992275238
```
## 7) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания.
```python
# вывод двух тестовых изображений и результатов распознавания
for n in [15, 16]:
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))
```
![alt text](p7_1.png)
```
Real mark: 1
NN answer: 1
```
![alt text](p7_2.png)
```
Real mark: 0
NN answer: 0
```
## 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()
```
```
precision recall f1-score support
0 0.99 0.99 0.99 994
1 0.99 0.99 0.99 1194
2 0.98 0.99 0.98 975
3 0.99 0.99 0.99 1031
4 0.98 0.99 0.99 967
5 0.99 0.99 0.99 937
6 0.99 0.99 0.99 964
7 0.99 0.99 0.99 998
8 0.98 0.98 0.98 965
9 0.99 0.98 0.98 975
accuracy 0.99 10000
macro avg 0.99 0.99 0.99 10000
weighted avg 0.99 0.99 0.99 10000
```
![alt text](p8.png)
## 9) Загрузили, предобработали и подали на вход обученной нейронной сети собственное изображение, созданное при выполнении лабораторной работы №1. Вывели изображение и результат распознавания.
```python
# загрузка собственного изображения
from PIL import Image
for name_image in ['1.png', '2.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))
```
![alt text](p9_1.png)
```
I think it's 1
```
![alt text](p9_2.png)
```
I think it's 2
```
## 10) Загрузили с диска модель, сохраненную при выполнении лабораторной работы №1. Вывели информацию об архитектуре модели. Повторили для этой модели п. 6.
```python
model_lr1 = keras.models.load_model("best_model.keras")
model_lr1.summary()
```
![alt text](p10.png)
```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])
```
```
accuracy: 0.9474
loss: 0.1746
Loss on test data: 0.18537543714046478
Accuracy on test data: 0.9453999996185303
```
## 11) Сравнили обученную модель сверточной сети и наилучшую модель полносвязной сети из лабораторной работы №1 по следующим показателям:
## - количество настраиваемых параметров в сети
## - количество эпох обучения
## - качество классификации тестовой выборки.
## Сделали выводы по результатам применения сверточной нейронной сети для распознавания изображений.
Таблица 1:
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|----------|-------------------------------------|---------------------------|-----------------------------------------|
| Сверточная | 34 826 | 15 | accuracy:0.988 ; loss:0.036 |
| Полносвязная | 79,512 | 50 | accuracy:0.9454 ; 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)=15, где k=4 –номер бригады. Вывели размерности полученных обучающих и тестовых массивов данных.
```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 = 15)
# вывод размерностей
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()
```
![alt text](2_p2.png)
## 3) Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения сверточной нейронной сети. Входные данные принимают значения от 0 до 1, метки цифр закодированы по принципу «one-hot encoding». Вывели размерности предобработанных обучающих и тестовых массивов данных.
```python
# Зададим параметры данных и модели
num_classes = 10
input_shape = (32, 32, 3)
# Приведение входных данных к диапазону [0, 1]
X_train = X_train / 255
X_test = X_test / 255
print('Shape of transformed X train:', X_train.shape)
print('Shape of transformed X test:', X_test.shape)
# переведем метки в one-hot
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print('Shape of transformed y train:', y_train.shape)
print('Shape of transformed y test:', y_test.shape)
```
```
Shape of transformed X train: (50000, 32, 32, 3)
Shape of transformed X test: (10000, 32, 32, 3)
Shape of transformed y train: (50000, 10)
Shape of transformed y test: (10000, 10)
```
## 4) Реализовали модель сверточной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети.
```python
# создаем модель
model = Sequential()
# Блок 1
model.add(layers.Conv2D(32, (3, 3), padding="same",
activation="relu", input_shape=input_shape))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(32, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.25))
# Блок 2
model.add(layers.Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.25))
# Блок 3
model.add(layers.Conv2D(128, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(128, (3, 3), padding="same", activation="relu"))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.4))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(num_classes, activation="softmax"))
model.summary()
```
![alt text](2_p4.png)
```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])
```
```
accuracy: 0.8587
loss: 0.5093
Loss on test data: 0.5083962678909302
Accuracy on test data: 0.857200026512146
```
## 6) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания.
```python
# вывод двух тестовых изображений и результатов распознавания
for n in [2,3]:
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))
```
![alt text](2_p6_1.png)
```
Real mark: 8
NN answer: 2
```
![alt text](2_p6_2.png)
```
Real mark: 4
NN answer: 4
```
## 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()
```
```
precision recall f1-score support
airplane 0.90 0.83 0.86 1015
automobile 0.94 0.94 0.94 933
bird 0.85 0.79 0.82 1010
cat 0.78 0.67 0.72 1025
deer 0.79 0.89 0.84 998
dog 0.77 0.82 0.79 1006
frog 0.83 0.94 0.88 1010
horse 0.94 0.84 0.89 1005
ship 0.90 0.93 0.91 1001
truck 0.89 0.94 0.92 997
accuracy 0.86 10000
macro avg 0.86 0.86 0.86 10000
weighted avg 0.86 0.86 0.86 10000
```
![alt text](2_p7.png)
## Вывод
По результатам классификации датасета CIFAR-10 созданной сверточной моделью можно сделать вывод, что она довольно неплохо справилась с задачей. Полученные метрики оценки качества имеют показатели в районе 0.85.

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

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

После

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

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

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

После

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

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

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

@ -0,0 +1,325 @@
# Отчёт по лабораторной работе №4
Артюшина Валерия, Хохлов Кирилл, А-01-22
# Задание 1
## 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули. Настроили блокнот для работы с аппаратным ускорителем GPU.
```python
# импорт модулей
import os
os.mkdir('/content/drive/MyDrive/Colab Notebooks/is_lab4')
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab4')
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
import matplotlib.pyplot as plt
import numpy as np
```
```python
import tensorflow as tf
device_name = tf.test.gpu_device_name()
if device_name != '/device:GPU:0':
raise SystemError('GPU device not found')
print('Found GPU at: {}'.format(device_name))
```
```
Found GPU at: /device:GPU:0
```
## 2) Загрузили набор данных IMDb, содержащий оцифрованные отзывы на фильмы, размеченные на два класса: позитивные и негативные. При загрузке набора данных параметр seed выбрали равным значению (4k – 1)=15, где k=4 – номер бригады. Вывели размеры полученных обучающих и тестовых массивов данных.
```python
# загрузка датасета
from keras.datasets import imdb
vocabulary_size = 5000
index_from = 3
(X_train, y_train), (X_test, y_test) = imdb.load_data(
path="imdb.npz",
num_words=vocabulary_size,
skip_top=0,
maxlen=None,
seed=15,
start_char=1,
oov_char=2,
index_from=index_from
)
# вывод размерностей
print('Shape of X train:', X_train.shape)
print('Shape of y train:', y_train.shape)
print('Shape of X test:', X_test.shape)
print('Shape of y test:', y_test.shape)
```
```
Shape of X train: (25000,)
Shape of y train: (25000,)
Shape of X test: (25000,)
Shape of y test: (25000,)
```
## 3) Вывели один отзыв из обучающего множества в виде списка индексов слов. Преобразовали список индексов в текст и вывели отзыв в виде текста. Вывели длину отзыва. Вывели метку класса данного отзыва и название класса (1 – Positive, 0 – Negative).
```python
# создание словаря для перевода индексов в слова
# заргузка словаря "слово:индекс"
word_to_id = imdb.get_word_index()
# уточнение словаря
word_to_id = {key:(value + index_from) for key,value in word_to_id.items()}
word_to_id["<PAD>"] = 0
word_to_id["<START>"] = 1
word_to_id["<UNK>"] = 2
word_to_id["<UNUSED>"] = 3
# создание обратного словаря "индекс:слово"
id_to_word = {value:key for key,value in word_to_id.items()}
```
```python
print(X_train[26])
print('len:',len(X_train[26]))
```
```
[1, 608, 17, 316, 47, 3381, 46, 14, 22, 9, 6, 601, 912, 8, 49, 2461, 14, 9, 88, 12, 16, 6, 2207, 2, 22, 15, 69, 6, 176, 7, 819, 2, 42, 2, 180, 8, 751, 2, 8, 1090, 4, 2, 1745, 675, 21, 4, 22, 47, 111, 85, 1508, 17, 73, 10, 10, 8, 895, 19, 4, 2, 186, 8, 28, 188, 27, 2, 5, 2109, 1849, 56, 4, 2, 11, 14, 22, 26, 2, 5, 92, 40, 3390, 21, 11, 175, 85, 1161, 36, 4486, 40, 2109, 150, 25, 43, 191, 81, 15, 19, 6, 2136, 512, 509, 874, 188, 8, 1231, 8, 4, 2269, 7, 4, 512, 42, 4, 451, 79, 32, 1471, 5, 3222, 34, 2, 2793, 11, 4, 355, 155, 11, 192, 4, 226, 1499, 5, 862, 1353, 114, 9, 142, 15, 47, 460, 77, 224, 18, 2109, 21, 152, 97, 101, 281, 11, 6, 1985, 20, 10, 10, 4129, 4, 1985, 1352, 26, 4, 2, 25, 28, 126, 110, 1814, 11, 4, 1985, 20, 970, 3882, 8, 124, 15, 4, 1985, 1352, 5, 2, 26, 142, 4, 451, 2, 2, 246, 49, 7, 134, 2, 26, 43, 1044, 2968, 10, 10, 50, 26, 6, 378, 7, 1076, 52, 1801, 13, 165, 179, 423, 4, 603, 409, 28, 1046, 2, 2, 2, 5, 10, 10, 1361, 48, 141, 6, 155, 70, 1778, 10, 10, 13, 82, 179, 423, 4, 1347, 18, 2, 4, 2, 2, 50, 26, 38, 111, 189, 102, 15, 2, 23, 105, 2, 2, 21, 11, 14, 420, 36, 86, 2, 6, 55, 2, 5, 1134, 1210, 1985, 2, 5, 140, 4682, 4, 1939, 13, 384, 25, 70, 516, 2, 19, 3390, 3589, 5, 75, 28, 49, 184, 976, 2, 134, 504, 1616, 30, 99, 254, 8, 276, 107, 5, 107, 295, 2, 21, 11, 801, 405, 14, 20, 271, 120, 4, 350, 5, 1608, 49, 85, 55, 2, 5, 1139, 1210, 2, 2872]
len: 323
```
```python
review_as_text = ' '.join(id_to_word[id] for id in X_train[26])
print(review_as_text)
print('len:',len(review_as_text))
```
```
<START> ok as everyone has pointed out this film is a complete dog to some degree this is because it was a gory <UNK> film that had a lot of material <UNK> or <UNK> down to near <UNK> to escape the <UNK> x rating but the film has many other flaws as well br br to begin with the <UNK> seems to have got his <UNK> and vampires mixed up the <UNK> in this film are <UNK> and don't like silver but in every other respect they behave like vampires now you just can't do that with a crappy genre flick you've got to stick to the rules of the genre or the fans get all confused and annoyed by <UNK> disbelief in the wrong thing in fact the whole confusing and poorly presented plot is something that has already been done for vampires but doesn't make any sense in a werewolf movie br br secondly the werewolf costumes are the <UNK> you have ever seen anybody in the werewolf movie business ought to know that the werewolf costumes and <UNK> are something the fans <UNK> <UNK> yet some of these <UNK> are just plain goofy br br there are a couple of slightly good bits i actually quite liked the score others have mentioned <UNK> <UNK> <UNK> and br br spoiler if such a thing can exist br br i also quite liked the plan for <UNK> the <UNK> <UNK> there are so many horror movies that <UNK> on characters <UNK> <UNK> but in this case they first <UNK> a very <UNK> and effective anti werewolf <UNK> and go slaughter the monsters i mean you can kill <UNK> with silver bullets and we have some pretty powerful <UNK> these days shouldn't be too hard to put two and two together <UNK> but in typical style this movie goes over the top and adds some other very <UNK> and amusing anti <UNK> weapons
len: 1682
```
## 4) Вывели максимальную и минимальную длину отзыва в обучающем множестве.
```python
print('MAX Len: ',len(max(X_train, key=len)))
print('MIN Len: ',len(min(X_train, key=len)))
```
```
MAX Len: 2494
MIN Len: 11
```
## 5) Провели предобработку данных. Выбрали единую длину, к которой будут приведены все отзывы. Короткие отзывы дополнили спецсимволами, а длинные обрезали до выбранной длины.
```python
# предобработка данных
from tensorflow.keras.utils import pad_sequences
max_words = 500
X_train = pad_sequences(X_train, maxlen=max_words, value=0, padding='pre', truncating='post')
X_test = pad_sequences(X_test, maxlen=max_words, value=0, padding='pre', truncating='post')
```
## 6) Повторили пункт 4.
```python
print('MAX Len: ',len(max(X_train, key=len)))
print('MIN Len: ',len(min(X_train, key=len)))
```
```
MAX Len: 500
MIN Len: 500
```
## 7) Повторили пункт 3. Сделали вывод о том, как отзыв преобразовался после предобработки.
```python
print(X_train[26])
print('len:',len(X_train[26]))
```
```
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 608 17 316 47
3381 46 14 22 9 6 601 912 8 49 2461 14 9 88
12 16 6 2207 2 22 15 69 6 176 7 819 2 42
2 180 8 751 2 8 1090 4 2 1745 675 21 4 22
47 111 85 1508 17 73 10 10 8 895 19 4 2 186
8 28 188 27 2 5 2109 1849 56 4 2 11 14 22
26 2 5 92 40 3390 21 11 175 85 1161 36 4486 40
2109 150 25 43 191 81 15 19 6 2136 512 509 874 188
8 1231 8 4 2269 7 4 512 42 4 451 79 32 1471
5 3222 34 2 2793 11 4 355 155 11 192 4 226 1499
5 862 1353 114 9 142 15 47 460 77 224 18 2109 21
152 97 101 281 11 6 1985 20 10 10 4129 4 1985 1352
26 4 2 25 28 126 110 1814 11 4 1985 20 970 3882
8 124 15 4 1985 1352 5 2 26 142 4 451 2 2
246 49 7 134 2 26 43 1044 2968 10 10 50 26 6
378 7 1076 52 1801 13 165 179 423 4 603 409 28 1046
2 2 2 5 10 10 1361 48 141 6 155 70 1778 10
10 13 82 179 423 4 1347 18 2 4 2 2 50 26
38 111 189 102 15 2 23 105 2 2 21 11 14 420
36 86 2 6 55 2 5 1134 1210 1985 2 5 140 4682
4 1939 13 384 25 70 516 2 19 3390 3589 5 75 28
49 184 976 2 134 504 1616 30 99 254 8 276 107 5
107 295 2 21 11 801 405 14 20 271 120 4 350 5
1608 49 85 55 2 5 1139 1210 2 2872]
len: 500
```
```python
review_as_text = ' '.join(id_to_word[id] for id in X_train[26])
print(review_as_text)
print('len:',len(review_as_text))
```
```
<PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <START> ok as everyone has pointed out this film is a complete dog to some degree this is because it was a gory <UNK> film that had a lot of material <UNK> or <UNK> down to near <UNK> to escape the <UNK> x rating but the film has many other flaws as well br br to begin with the <UNK> seems to have got his <UNK> and vampires mixed up the <UNK> in this film are <UNK> and don't like silver but in every other respect they behave like vampires now you just can't do that with a crappy genre flick you've got to stick to the rules of the genre or the fans get all confused and annoyed by <UNK> disbelief in the wrong thing in fact the whole confusing and poorly presented plot is something that has already been done for vampires but doesn't make any sense in a werewolf movie br br secondly the werewolf costumes are the <UNK> you have ever seen anybody in the werewolf movie business ought to know that the werewolf costumes and <UNK> are something the fans <UNK> <UNK> yet some of these <UNK> are just plain goofy br br there are a couple of slightly good bits i actually quite liked the score others have mentioned <UNK> <UNK> <UNK> and br br spoiler if such a thing can exist br br i also quite liked the plan for <UNK> the <UNK> <UNK> there are so many horror movies that <UNK> on characters <UNK> <UNK> but in this case they first <UNK> a very <UNK> and effective anti werewolf <UNK> and go slaughter the monsters i mean you can kill <UNK> with silver bullets and we have some pretty powerful <UNK> these days shouldn't be too hard to put two and two together <UNK> but in typical style this movie goes over the top and adds some other very <UNK> and amusing anti <UNK> weapons
len: 2744
```
После обработки в начало отзыва добавилось необходимое количество токенов <PAD>, чтобы отзыв был длинной в 500 индексов.
## 8) Вывели предобработанные массивы обучающих и тестовых данных и их размерности.
```python
# вывод данных
print('X train: \n',X_train)
print('X train: \n',X_test)
# вывод размерностей
print('Shape of X train:', X_train.shape)
print('Shape of X test:', X_test.shape)
```
```
X train:
[[ 0 0 0 ... 4 86 273]
[ 0 0 0 ... 705 9 150]
[ 0 0 0 ... 44 12 32]
...
[ 0 0 0 ... 22 8 377]
[ 0 0 0 ... 4 2554 647]
[ 0 0 0 ... 2 4 2]]
X train:
[[ 0 0 0 ... 106 14 31]
[ 0 0 0 ... 458 168 52]
[ 0 0 0 ... 22 6 31]
...
[ 0 0 0 ... 38 76 128]
[ 0 0 0 ... 73 290 12]
[ 0 0 0 ... 12 38 76]]
Shape of X train: (25000, 500)
Shape of X test: (25000, 500)
```
## 9) Реализовали модель рекуррентной нейронной сети, состоящей из слоев Embedding, LSTM, Dropout, Dense, и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети. Добились качества обучения по метрике accuracy не менее 0.8.
```python
embed_dim = 32
lstm_units = 64
model = Sequential()
model.add(layers.Embedding(input_dim=vocabulary_size, output_dim=embed_dim, input_length=max_words, input_shape=(max_words,)))
model.add(layers.LSTM(lstm_units))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))
model.summary()
```
![alt text](1_p9.png)
```python
# компилируем и обучаем модель
batch_size = 64
epochs = 3
model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"])
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.2)
```
```
Epoch 1/3
313/313 ━━━━━━━━━━━━━━━━━━━━ 12s 23ms/step - accuracy: 0.6328 - loss: 0.6075 - val_accuracy: 0.7826 - val_loss: 0.4588
Epoch 2/3
313/313 ━━━━━━━━━━━━━━━━━━━━ 6s 21ms/step - accuracy: 0.8121 - loss: 0.4143 - val_accuracy: 0.8628 - val_loss: 0.3359
Epoch 3/3
313/313 ━━━━━━━━━━━━━━━━━━━━ 10s 21ms/step - accuracy: 0.8905 - loss: 0.2795 - val_accuracy: 0.8506 - val_loss: 0.3324
<keras.src.callbacks.history.History at 0x7a8b2b9509e0>
```
```python
test_loss, test_acc = model.evaluate(X_test, y_test)
print(f"\nTest accuracy: {test_acc}")
print(f"\nTest loss: {test_loss}")
```
```
accuracy: 0.8544
loss: 0.3396
Test accuracy: 0.8564800024032593
Test loss: 0.33131280541419983
```
## 10) Оценили качество обучения на тестовых данных.
* вывели значение метрики качества классификации на тестовых данных
* вывели отчет о качестве классификации тестовой выборки
* построили ROC-кривую по результату обработки тестовой выборки и вычислили площадь под ROC-кривой (AUC ROC)
```python
#значение метрики качества классификации на тестовых данных
print(f"\nTest accuracy: {test_acc}")
```
```
Test accuracy: 0.8564800024032593
```
```python
#отчет о качестве классификации тестовой выборки
y_score = model.predict(X_test)
y_pred = [1 if y_score[i,0]>=0.5 else 0 for i in range(len(y_score))]
from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred, labels = [0, 1], target_names=['Negative', 'Positive']))
```
```
precision recall f1-score support
Negative 0.83 0.90 0.86 12500
Positive 0.89 0.82 0.85 12500
accuracy 0.86 25000
macro avg 0.86 0.86 0.86 25000
weighted avg 0.86 0.86 0.86 25000
```
```python
#построение ROC-кривой и AUC ROC
from sklearn.metrics import roc_curve, auc
fpr, tpr, thresholds = roc_curve(y_test, y_score)
plt.plot(fpr, tpr)
plt.grid()
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC')
plt.show()
print('AUC ROC:', auc(fpr, tpr))
```
![alt text](1_p10.png)
```
AUC ROC: 0.9356664896
```
## 11) Сделали выводы по результатам применения рекуррентной нейронной сети для решения задачи определения тональности текста.
Таблица1:
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|----------|-------------------------------------|---------------------------|-----------------------------------------|
| Рекуррентная | 184 897 | 3 | accuracy:0.8564 ; loss:0.3313 ; AUC ROC:0.9357 |
## Вывод
По результатам применения рекуррентной нейронной сети можно сделать вывод, что модель остаточно неплохо справилась с задачей определения тональности текста. Показатель accuracy = 0.8564 превышает требуемый порог 0.8. Значение AUC ROC = 0.9357 (> 0.9) говорит о высокой способности модели различать два класса на положительные и отрицательные области.
Загрузка…
Отмена
Сохранить