Сравнить коммиты
4 Коммитов
| Автор | SHA1 | Дата |
|---|---|---|
|
|
964549a094 | 2 месяцев назад |
|
|
b344e76a21 | 3 месяцев назад |
|
|
047d249b1f | 4 месяцев назад |
|
|
339fe963d0 | 4 месяцев назад |
|
До Ширина: | Высота: | Размер: 233 B |
|
До Ширина: | Высота: | Размер: 156 B |
|
До Ширина: | Высота: | Размер: 292 B |
|
До Ширина: | Высота: | Размер: 235 B |
@ -1,4 +1,11 @@
|
||||
* [Задание](IS_Lab01_2023.pdf)
|
||||
## Лабораторныа работа №1
|
||||
|
||||
## Архитектура и обучение глубоких нейронных сетей
|
||||
|
||||
* [Задание](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>
|
||||
|
До Ширина: | Высота: | Размер: 7.0 KiB |
|
До Ширина: | Высота: | Размер: 7.1 KiB |
|
До Ширина: | Высота: | Размер: 10 KiB |
|
До Ширина: | Высота: | Размер: 33 KiB |
|
До Ширина: | Высота: | Размер: 33 KiB |
|
До Ширина: | Высота: | Размер: 33 KiB |
|
До Ширина: | Высота: | Размер: 32 KiB |
|
До Ширина: | Высота: | Размер: 36 KiB |
|
До Ширина: | Высота: | Размер: 36 KiB |
@ -1,608 +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 = 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()
|
||||
```
|
||||
|
||||

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

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

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

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

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

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

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

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

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

|
||||
|
||||
* предобработка
|
||||
```
|
||||
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()
|
||||
```
|
||||
|
||||

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

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

|
||||
|
||||
```
|
||||
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
|
||||
|
||||
При повороте изображений сеть не распознала цифры правильно. Так как она не обучалась на повернутых изображениях.
|
||||
@ -0,0 +1,11 @@
|
||||
## Лабораторныа работа №2
|
||||
|
||||
## Обнаружение аномалий
|
||||
|
||||
* [Задание](IS_Lab02_2023.pdf)
|
||||
|
||||
* [Методические указания](IS_Lab02_Metod_2023.pdf)
|
||||
|
||||
* [Наборы данных](data)
|
||||
|
||||
* [Библиотека для автокодировщиков](lab02_lib.py)
|
||||
|
До Ширина: | Высота: | Размер: 36 KiB |
|
До Ширина: | Высота: | Размер: 42 KiB |
|
До Ширина: | Высота: | Размер: 21 KiB |
|
До Ширина: | Высота: | Размер: 42 KiB |
|
До Ширина: | Высота: | Размер: 66 KiB |
|
До Ширина: | Высота: | Размер: 66 KiB |
|
До Ширина: | Высота: | Размер: 108 KiB |
|
До Ширина: | Высота: | Размер: 31 KiB |
|
До Ширина: | Высота: | Размер: 90 KiB |
|
До Ширина: | Высота: | Размер: 103 KiB |
|
До Ширина: | Высота: | Размер: 30 KiB |
|
До Ширина: | Высота: | Размер: 63 KiB |
|
До Ширина: | Высота: | Размер: 74 KiB |
|
До Ширина: | Высота: | Размер: 20 KiB |
|
До Ширина: | Высота: | Размер: 85 KiB |
|
До Ширина: | Высота: | Размер: 75 KiB |
@ -1,324 +0,0 @@
|
||||
# Отчет по лабораторной работе №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)
|
||||
```
|
||||

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

|
||||
Порог ошибки реконструкции:
|
||||
```
|
||||
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')
|
||||
```
|
||||

|
||||
Порог ошибки реконструкции:
|
||||
```
|
||||
IREth2
|
||||
np.float64(0.47)
|
||||
```
|
||||
|
||||
## 7. Характеристики качества обучения
|
||||
``` py
|
||||
# построение областей покрытия и границ классов
|
||||
# расчет характеристик качества обучения
|
||||
numb_square = 20
|
||||
xx, yy, Z1 = lib.square_calc(numb_square, data, ae1_trained, IREth1, '1', True)
|
||||
```
|
||||

|
||||
amount: 21
|
||||
amount_ae: 294
|
||||

|
||||

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

|
||||
amount: 21
|
||||
amount_ae: 39
|
||||

|
||||

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

|
||||
|
||||
* Вывод: при увеличении количества скрытых слоев - показатели качества улучшаются. Таким образом, для качественного обнаружения аномалий стоит использовать автокодировщик 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')
|
||||
```
|
||||
Аномалий не обнаружено
|
||||

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

|
||||
|
||||
## 11. Построение областей аппроксимации и точек тестового набора
|
||||
``` py
|
||||
lib.plot2in1_anomaly(data, xx, yy, Z1, Z2, test_data)
|
||||
```
|
||||

|
||||
|
||||
## 12. Результаты исследования
|
||||
|
||||
Табл. 1 Результаты задания №1.
|
||||

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

|
||||
Порог ошибки реконструкции:
|
||||
```
|
||||
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 аномалий
|
||||
```
|
||||

|
||||
|
||||
## 10. Результаты обнаружения аномалий
|
||||
|
||||
Обнаружено более 70% аномалий, результаты удовлетворены.
|
||||
|
||||
## 10. Результаты исследования
|
||||
|
||||
Табл. 2 Результаты задания №2.
|
||||

|
||||
|
||||
## 11. Выводы о требованиях
|
||||
|
||||
для качественного обнаружения аномалий в случае, когда размерность пространства признаков высока.
|
||||
|
||||
* Данные для обучения: должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение
|
||||
* Архитектура автокодировщика: многомерный автокодировщик должен иметь достаточно большое количество внутренних слоев (в данном датасете не менее 7) и нейронов в них. Размеры определяются размерностью исходных данных.
|
||||
* Количество эпох обучения: в рамках данного набора данных оптимальное кол-во эпох 100000 с patience 5000 эпох
|
||||
* Ошибка MSE-stop: оптимальная ошибка MSE-stop 0.001
|
||||
* Ошибка реконструкции: значение ошибки реконструкции должно как можно меньше
|
||||
|
До Ширина: | Высота: | Размер: 61 KiB |
|
До Ширина: | Высота: | Размер: 16 KiB |
|
До Ширина: | Высота: | Размер: 118 KiB |
|
До Ширина: | Высота: | Размер: 51 KiB |
|
До Ширина: | Высота: | Размер: 12 KiB |
|
До Ширина: | Высота: | Размер: 12 KiB |
|
До Ширина: | Высота: | Размер: 62 KiB |
@ -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>
|
||||
|
До Ширина: | Высота: | Размер: 25 KiB |
|
До Ширина: | Высота: | Размер: 28 KiB |
|
До Ширина: | Высота: | Размер: 6.5 KiB |
|
До Ширина: | Высота: | Размер: 7.2 KiB |
|
До Ширина: | Высота: | Размер: 32 KiB |
|
До Ширина: | Высота: | Размер: 6.4 KiB |
|
До Ширина: | Высота: | Размер: 6.7 KiB |
@ -1,506 +0,0 @@
|
||||
# Отчёт по лабораторной работе №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()
|
||||
```
|
||||

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

|
||||
```
|
||||
Real mark: 1
|
||||
NN answer: 1
|
||||
```
|
||||

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

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

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

|
||||
```
|
||||
I think it's 2
|
||||
```
|
||||
|
||||
## 10) Загрузили с диска модель, сохраненную при выполнении лабораторной работы №1. Вывели информацию об архитектуре модели. Повторили для этой модели п. 6.
|
||||
|
||||
```python
|
||||
model_lr1 = keras.models.load_model("best_model.keras")
|
||||
|
||||
model_lr1.summary()
|
||||
```
|
||||

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

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

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

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

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

|
||||
|
||||
## Вывод
|
||||
По результатам классификации датасета CIFAR-10 созданной сверточной моделью можно сделать вывод, что она довольно неплохо справилась с задачей. Полученные метрики оценки качества имеют показатели в районе 0.85.
|
||||
|
До Ширина: | Высота: | Размер: 21 KiB |
|
До Ширина: | Высота: | Размер: 20 KiB |
@ -0,0 +1,7 @@
|
||||
## Лабораторныа работа №4
|
||||
|
||||
## Распознавание последовательностей
|
||||
|
||||
* [Задание](IS_Lab04_2023.pdf)
|
||||
|
||||
* [Методические указания](IS_Lab04_Metod_2023.pdf)
|
||||
@ -1,325 +0,0 @@
|
||||
# Отчёт по лабораторной работе №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()
|
||||
```
|
||||

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

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