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

...

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

Автор SHA1 Сообщение Дата
AnikeevAnA 4839130152 Изменил(а) на 'labworks/LW4/report.md'
3 недель назад
AnikeevAnA 435251dda9 Изменил(а) на 'labworks/LW4/report.md'
3 недель назад
AnikeevAnA 1f4530ed08 Изменил(а) на 'labworks/LW4/report.md'
3 недель назад
AnikeevAnA 585d4cefb7 Изменил(а) на 'labworks/LW4/report.md'
3 недель назад
AnikeevAnA b773704a64 Изменил(а) на 'labworks/LW4/report.md'
3 недель назад
AnikeevAnA e5e51c84da Изменил(а) на 'labworks/LW4/report.md'
3 недель назад
AnikeevAnA ae913af3e6 Изменил(а) на 'labworks/LW4/report.md'
3 недель назад
AnikeevAnA 3b78efe6d6 Изменил(а) на 'labworks/LW4/report.md'
3 недель назад
AnikeevAnA 5daa3e1220 Загрузил(а) файлы в 'labworks/LW4'
3 недель назад
AnikeevAnA 6726629d06 Изменил(а) на 'labworks/LW4/report.md'
3 недель назад
AnikeevAnA 58d047d9e6 Изменил(а) на 'labworks/LW4/report.md'
3 недель назад
AnikeevAnA a2286b1ddf Изменил(а) на 'labworks/LW4/report.md'
3 недель назад
AnikeevAnA f447f0b776 Изменил(а) на 'labworks/LW4/report.md'
3 недель назад
AnikeevAnA 86af704063 Создал(а) 'labworks/LW4/report.md'
3 недель назад
AnikeevAnA ca98677d2b Загрузил(а) файлы в 'labworks/LW3'
1 месяц назад
AnikeevAnA ac746690cb Изменил(а) на 'labworks/LW3/report.md'
1 месяц назад
AnikeevAnA 3b3cf60fd1 Изменил(а) на 'labworks/LW3/report.md'
1 месяц назад
AnikeevAnA a261e3043d Загрузил(а) файлы в 'labworks/LW3'
1 месяц назад
AnikeevAnA 48ed334bf6 Загрузил(а) файлы в 'labworks/LW3'
1 месяц назад
AnikeevAnA b605313e2d Изменил(а) на 'labworks/LW3/report.md'
1 месяц назад
AnikeevAnA 23650241b1 Изменил(а) на 'labworks/LW3/report.md'
1 месяц назад
AnikeevAnA 872fc21ca2 Изменил(а) на 'labworks/LW3/LW3.md'
1 месяц назад
AnikeevAnA 877c4e4335 Создал(а) 'labworks/LW3/LW3.md'
1 месяц назад
AnikeevAnA 47b46c5b35 Изменил(а) на 'labworks/LW2/LW2_variant2.md'
2 месяцев назад
AnikeevAnA 75fdcfc8a4 Изменил(а) на 'labworks/LW2/LW2_variant2.md'
2 месяцев назад
AnikeevAnA 497c8debd0 Изменил(а) на 'labworks/LW2/LW2_variant2.md'
2 месяцев назад
AnikeevAnA f0d43204ce Изменил(а) на 'labworks/LW2/LW2_variant2.md'
2 месяцев назад
AnikeevAnA 3d59ae06ee Загрузил(а) файлы в 'labworks/LW2'
2 месяцев назад
AnikeevAnA 83e8438a7f Загрузил(а) файлы в 'labworks/LW2'
2 месяцев назад
AnikeevAnA e5a6973187 Изменил(а) на 'labworks/LW2/LW2_variant2.md'
2 месяцев назад
AnikeevAnA caf5544694 Изменил(а) на 'labworks/LW2/LW2_variant2.md'
2 месяцев назад
AnikeevAnA 3b3165fdbd Изменил(а) на 'labworks/LW2/LW2_variant2.md'
2 месяцев назад
AnikeevAnA ac6cb3167a Загрузил(а) файлы в 'labworks/LW2'
2 месяцев назад
AnikeevAnA eadb521950 Загрузил(а) файлы в 'labworks/LW2'
2 месяцев назад
AnikeevAnA d1b22d7890 Загрузил(а) файлы в 'labworks/LW2'
2 месяцев назад
AnikeevAnA 72f29dd5c2 Изменил(а) на 'labworks/LW2/LW2_variant2.md'
2 месяцев назад
AnikeevAnA 31fddb9d60 Изменил(а) на 'labworks/LW2/LW2_variant2.md'
2 месяцев назад
AnikeevAnA 9f1f1721dc Создал(а) 'labworks/LW2/LW2_variant2.md'
2 месяцев назад
AnikeevAnA 7a02d2e76e Изменил(а) на 'labworks/LW1/report.md'
3 месяцев назад
AnikeevAnA 4fea393dad Изменил(а) на 'labworks/LW1/report.md'
3 месяцев назад
AnikeevAnA ecb5efc171 Загрузил(а) файлы в 'labworks/LW1'
3 месяцев назад
AnikeevAnA 2b3c06b794 Удалить 'labworks/LW1/report.md'
3 месяцев назад
AnikeevAnA 53235c77a0 Изменил(а) на 'labworks/LW1/report.md'
3 месяцев назад
AnikeevAnA 8f4c2cc964 Загрузил(а) файлы в 'labworks/LW1'
3 месяцев назад
AnikeevAnA 63c923cc08 Загрузил(а) файлы в 'labworks/LW1'
3 месяцев назад
AnikeevAnA 709c748ef1 Загрузил(а) файлы в 'labworks/LW1'
3 месяцев назад
AnikeevAnA b29da1b2eb Загрузил(а) файлы в 'labworks/LW1'
3 месяцев назад
AnikeevAnA ac71aa9055 Изменил(а) на 'labworks/LW1/report.md'
3 месяцев назад
AnikeevAnA af9da40582 Создал(а) 'labworks/LW1/report.md'
3 месяцев назад

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

@ -0,0 +1,576 @@
# Отчет по лабораторной работе №1
Аникеев Андрей, Чагин Сергей, А-02-22
## 1. В среде Google Colab создание нового блокнота.
```
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks')
```
1.1 Импорт необходимых модулей.
```
from tensorflow import keras
import matplotlib.pyplot as plt
import numpy as np
import sklearn
```
## 2. Загрузка датасета.
```
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
```
* 3.1 Объединение в один набор.
```
X = np.concatenate((X_train, X_test))
y = np.concatenate((y_train, y_test))
```
* 3.2 Разбиение по вариантам. (5 бригада -> k=4*5-1)
```
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size = 10000,train_size = 60000, random_state = 19)
```
* 3.3 Вывод размерностей.
```
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. Вывод обучающих данных.
* 4.1 Выведем первые четыре элемента обучающих данных.
```
plt.figure(figsize=(10, 3))
for i in range(4):
plt.subplot(1, 4, i + 1)
plt.imshow(X_train[i], cmap='gray')
plt.title(f'Label: {y_train[i]}')
plt.axis('off')
plt.tight_layout()
plt.show()
```
![отображение элементов](1.png)
## 5. Предобработка данных.
* 5.1 Развернем каждое изображение в вектор.
```
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)
* 5.2 Переведем метки в 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 = Sequential()
model.add(Dense(units=num_classes, activation='softmax'))
```
* 6.2. Компилируем модель.
```
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
print(model.summary())
```
>Model: "sequential_6"
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
>│ dense_18 (Dense) │ ? │ 0 (unbuilt) │
>└─────────────────────────────────┴────────────────────────┴───────────────┘
>Total params: 0 (0.00 B)
>Trainable params: 0 (0.00 B)
>Non-trainable params: 0 (0.00 B)
* 6.3 Обучаем модель.
```
H = model.fit(X_train, y_train, validation_split=0.1, epochs=50)
```
* 6.4 Выводим график функции ошибки
```
plt.plot(H.history['loss'])
plt.plot(H.history['val_loss'])
plt.grid()
plt.xlabel('Epochs')
plt.ylabel('loss')
plt.legend(['train_loss', 'val_loss'])
plt.title('Loss by epochs')
plt.show()
```
![график функции ошибки](2.png)
## 7. Применение модели к тестовым данным.
```
scores = model.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
>accuracy: 0.9213 - loss: 0.2825
>Loss on test data: 0.28365787863731384
>Accuracy on test data: 0.9225000143051147
## 8. Добавление одного скрытого слоя.
* 8.1 При 100 нейронах в скрытом слое.
```
model100 = Sequential()
model100.add(Dense(units=100,input_dim=num_pixels, activation='sigmoid'))
model100.add(Dense(units=num_classes, activation='softmax'))
model100.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy']
print(model100.summary())
```
>Model: "sequential_10"
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
>│ dense_19 (Dense) │ (None, 100) │ 78,500 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_20 (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)
* 8.2 Обучение модели.
```
H = model100.fit(X_train, y_train, validation_split=0.1, epochs=50)
```
* 8.3 График функции ошибки.
```
plt.plot(H.history['loss'])
plt.plot(H.history['val_loss'])
plt.grid()
plt.xlabel('Epochs')
plt.ylabel('loss')
plt.legend(['train_loss', 'val_loss'])
plt.title('Loss by epochs')
plt.show()
```
![график функции ошибки](3.png)
```
scores = model100.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
>accuracy: 0.9465 - loss: 0.1946
>Loss on test data: 0.19745595753192902
>Accuracy on test data: 0.9442999958992004
* 8.4 При 300 нейронах в скрытом слое.
```
model300 = Sequential()
model300.add(Dense(units=300,input_dim=num_pixels, activation='sigmoid'))
model300.add(Dense(units=num_classes, activation='softmax'))
model300.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
print(model300.summary())
```
>Model: "sequential_14"
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
>│ dense_27 (Dense) │ (None, 300) │ 235,500 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_28 (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)
* 8.5 Обучение модели.
```
H = model300.fit(X_train, y_train, validation_split=0.1, epochs=50)
```
* 8.6 Вывод графиков функции ошибки.
```
plt.plot(H.history['loss'])
plt.plot(H.history['val_loss'])
plt.grid()
plt.xlabel('Epochs')
plt.ylabel('loss')
plt.legend(['train_loss', 'val_loss'])
plt.title('Loss by epochs')
plt.show()
```
![график функции ошибки](4.png)
```
scores = model300.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
>accuracy: 0.9361 - loss: 0.2237
>Loss on test data: 0.22660093009471893
>Accuracy on test data: 0.9348000288009644
* 8.7 При 500 нейронах в скрытом слое.
```
model500 = Sequential()
model500.add(Dense(units=500,input_dim=num_pixels, activation='sigmoid'))
model500.add(Dense(units=num_classes, activation='softmax'))
model500.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
print(model500.summary())
```
>Model: "sequential_16"
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
>│ dense_31 (Dense) │ (None, 500) │ 392,500 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_32 (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)
* 8.8 Обучение модели.
```
H = model500.fit(X_train, y_train, validation_split=0.1, epochs=50)
```
* 8.9 Вывод графиков функции ошибки.
```
plt.plot(H.history['loss'])
plt.plot(H.history['val_loss'])
plt.grid()
plt.xlabel('Epochs')
plt.ylabel('loss')
plt.legend(['train_loss', 'val_loss'])
plt.title('Loss by epochs')
plt.show()
```
![график функции ошибки](5.png)
```
scores = model500.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
>accuracy: 0.9306 - loss: 0.2398
>Loss on test data: 0.24357788264751434
>Accuracy on test data: 0.9304999709129333
Как мы видим, лучшая метрика получилась при архитектуре со 100 нейронами в скрытом слое:
Ошибка на тестовых данных: 0.19745595753192902
Точность тестовых данных: 0.9442999958992004
## 9. Добавление второго скрытого слоя.
* 9.1 При 50 нейронах во втором скрытом слое.
```
model10050 = Sequential()
model10050.add(Dense(units=100,input_dim=num_pixels, activation='sigmoid'))
model10050.add(Dense(units=50,activation='sigmoid'))
model10050.add(Dense(units=num_classes, activation='softmax'))
model10050.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
print(model10050.summary())
```
>Model: "sequential_17"
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
>│ dense_33 (Dense) │ (None, 100) │ 78,500 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_34 (Dense) │ (None, 50) │ 5,050 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_35 (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)
* 9.2 Обучаем модель.
```
H = model10050.fit(X_train, y_train, validation_split=0.1, epochs=50)
```
* 9.3 Выводим график функции ошибки.
```
plt.plot(H.history['loss'])
plt.plot(H.history['val_loss'])
plt.grid()
plt.xlabel('Epochs')
plt.ylabel('loss')
plt.legend(['train_loss', 'val_loss'])
plt.title('Loss by epochs')
plt.show()
```
![график функции ошибки](6.png)
```
scores = model10050.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
>accuracy: 0.9439 - loss: 0.1962
>Loss on test data: 0.1993969976902008
>Accuracy on test data: 0.9438999891281128
* 9.4 При 100 нейронах во втором скрытом слое.
```
model100100 = Sequential()
model100100.add(Dense(units=100,input_dim=num_pixels, activation='sigmoid'))
model100100.add(Dense(units=100,activation='sigmoid'))
model100100.add(Dense(units=num_classes, activation='softmax'))
model100100.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
print(model100100.summary())
```
>Model: "sequential_18"
>┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
>┃ Layer (type) ┃ Output Shape ┃ Param # ┃
>┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
>│ dense_36 (Dense) │ (None, 100) │ 78,500 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_37 (Dense) │ (None, 100) │ 10,100 │
>├─────────────────────────────────┼────────────────────────┼───────────────┤
>│ dense_38 (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)
* 9.5 Обучаем модель.
```
H = model100100.fit(X_train, y_train, validation_split=0.1, epochs=50)
```
* 9.6 Выводим график функции ошибки.
```
plt.plot(H.history['loss'])
plt.plot(H.history['val_loss'])
plt.grid()
plt.xlabel('Epochs')
plt.ylabel('loss')
plt.legend(['train_loss', 'val_loss'])
plt.title('Loss by epochs')
plt.show()
```
![график функции ошибки](7.png)
```
scores = model100100.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])
```
>accuracy: 0.9449 - loss: 0.1931
>Loss on test data: 0.19571688771247864
>Accuracy on test data: 0.9435999989509583
## 10. Результаты исследования архитектур нейронной сети.
| Количество скрытых слоев | Количество нейронов в первом скрытом слое | Количество нейронов во втором скрытом слое | Значение метрики качества классификации |
|--------------------------|-------------------------------------------|--------------------------------------------|------------------------------------------|
| 0 | - | - | 0.9225000143051147 |
| 1 | 100 | - | 0.9442999958992004 |
| 1 | 300 | - | 0.9348000288009644 |
| 1 | 500 | - | 0.9304999709129333 |
| 2 | 100 | 50 | 0.9438999891281128 |
| 2 | 100 | 100 | 0.9435999989509583 |
Анализ результатов показал, что наивысшую точность (около 94.5%) демонстрируют модели со сравнительно простой архитектурой: однослойная сеть со 100 нейронами и двухслойная конфигурация (100 и 50 нейронов). Усложнение модели за счет увеличения количества слоев или нейронов не привело к улучшению качества, а в некоторых случаях даже вызвало его снижение. Это свидетельствует о том, что для относительно простого набора данных MNIST более сложные архитектуры склонны к переобучению, в то время как простые модели лучше обобщают закономерности.
## 11. Сохранение наилучшей модели на диск.
```
model100.save('/content/drive/MyDrive/Colab Notebooks/best_model/model100.keras')
```
* 11.1 Загрузка лучшей модели с диска.
```
from keras.models import load_model
model = load_model('/content/drive/MyDrive/Colab Notebooks/best_model/model100.keras')
```
## 12. Вывод тестовых изображений и результатов распознаваний.
```
n = 111
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: [[1.1728607e-03 5.4896927e-06 3.3185919e-05 2.6362878e-04 4.8558863e-06
>9.9795568e-01 1.9454242e-07 1.6833146e-05 4.9621973e-04 5.1067746e-05]]
![alt text](8.png)
>Real mark: 5
>NN answer: 5
```
n = 222
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: [[1.02687673e-05 2.02151591e-06 2.86183599e-03 8.74871985e-05
>1.51387369e-02 6.32769879e-05 3.97122385e-05 4.11829986e-02 1.06158564e-04 9.40507472e-01]]
![alt text](9.png)
>Real mark: 9
>NN answer: 9
## 13. Тестирование на собственных изображениях.
* 13.1 Загрузка 1 собственного изображения.
```
from PIL import Image
file_data = Image.open('test.png')
file_data = file_data.convert('L') # перевод в градации серого
test_img = np.array(file_data)
```
* 13.2 Вывод собственного изображения.
```
plt.imshow(test_img, cmap=plt.get_cmap('gray'))
plt.show()
```
![1 изображение](10.png)
* 13.3 Предобработка.
```
test_img = test_img / 255
test_img = test_img.reshape(1, num_pixels)
```
* 13.4 Распознавание.
```
result = model.predict(test_img)
print('I think it\'s ', np.argmax(result))
```
>I think it's 5
* 13.5 Тест 2 изображения.
```
from PIL import Image
file2_data = Image.open('test_2.png')
file2_data = file2_data.convert('L') # перевод в градации серого
test2_img = np.array(file2_data)
```
```
plt.imshow(test2_img, cmap=plt.get_cmap('gray'))
plt.show()
```
![2 изображение](11.png)
```
test2_img = test2_img / 255
test2_img = test2_img.reshape(1, num_pixels)
```
```
result_2 = model.predict(test2_img)
print('I think it\'s ', np.argmax(result_2))
```
>I think it's 2
Сеть корректно распознала цифры на изображениях.
## 14. Тестирование на повернутых изображениях.
```
from PIL import Image
file90_data = Image.open('test90.png')
file90_data = file90_data.convert('L') # перевод в градации серого
test90_img = np.array(file90_data)
plt.imshow(test90_img, cmap=plt.get_cmap('gray'))
plt.show()
```
![alt text](12.png)
```
test90_img = test90_img / 255
test90_img = test90_img.reshape(1, num_pixels)
result_3 = model.predict(test90_img)
print('I think it\'s ', np.argmax(result_3))
```
>I think it's 7
```
from PIL import Image
file902_data = Image.open('test90_2.png')
file902_data = file902_data.convert('L') # перевод в градации серого
test902_img = np.array(file902_data)
plt.imshow(test902_img, cmap=plt.get_cmap('gray'))
plt.show()
```
![alt text](13.png)
```
test902_img = test902_img / 255
test902_img = test902_img.reshape(1, num_pixels)
result_4 = model.predict(test902_img)
print('I think it\'s ', np.argmax(result_4))
```
>I think it's 7
Сеть не распознала цифры на изображениях корректно.

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

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

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

После

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

@ -0,0 +1,447 @@
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"gpuType": "T4"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"source": [
"1 пункт"
],
"metadata": {
"id": "S59WEX1lbXWW"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "lhabo1q_VXgc"
},
"outputs": [],
"source": [
"import os\n",
"os.chdir('/content/drive/MyDrive/Colab Notebooks/IS_LR3')"
]
},
{
"cell_type": "code",
"source": [
"# импорт модулей\n",
"from tensorflow import keras\n",
"from tensorflow.keras import layers\n",
"from tensorflow.keras.models import Sequential\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"from sklearn.metrics import classification_report, confusion_matrix\n",
"from sklearn.metrics import ConfusionMatrixDisplay"
],
"metadata": {
"id": "ZYpnLJOCaSFR"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"2 пункт\n"
],
"metadata": {
"id": "QTplfsEEbWtr"
}
},
{
"cell_type": "code",
"source": [
"# загрузка датасета\n",
"from keras.datasets import mnist\n",
"(X_train, y_train), (X_test, y_test) = mnist.load_data()"
],
"metadata": {
"id": "FmAqO707aR_5"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"3 пункт\n"
],
"metadata": {
"id": "VR6XttyDbpGS"
}
},
{
"cell_type": "code",
"source": [
"# создание своего разбиения датасета\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"# объединяем в один набор\n",
"X = np.concatenate((X_train, X_test))\n",
"y = np.concatenate((y_train, y_test))\n",
"\n",
"# разбиваем по вариантам\n",
"X_train, X_test, y_train, y_test = train_test_split(X, y,\n",
" test_size = 10000,\n",
" train_size = 60000,\n",
" random_state = 19)"
],
"metadata": {
"id": "idfAHcp9aR32"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# вывод размерностей\n",
"print('Shape of X train:', X_train.shape)\n",
"print('Shape of y train:', y_train.shape)\n",
"\n",
"print('Shape of X test:', X_test.shape)\n",
"print('Shape of y test:', y_test.shape)"
],
"metadata": {
"id": "ZcpI4-Mfb8_M"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"4 пункт"
],
"metadata": {
"id": "MsUxxLu4dXsF"
}
},
{
"cell_type": "code",
"source": [
"# Зададим параметры данных и модели\n",
"num_classes = 10\n",
"input_shape = (28, 28, 1)\n",
"\n",
"# Приведение входных данных к диапазону [0, 1]\n",
"X_train = X_train / 255\n",
"X_test = X_test / 255\n",
"\n",
"# Расширяем размерность входных данных, чтобы каждое изображение имело\n",
"# размерность (высота, ширина, количество каналов)\n",
"\n",
"\n",
"X_train = np.expand_dims(X_train, -1)\n",
"X_test = np.expand_dims(X_test, -1)\n",
"print('Shape of transformed X train:', X_train.shape)\n",
"print('Shape of transformed X test:', X_test.shape)\n",
"\n",
"# переведем метки в one-hot\n",
"y_train = keras.utils.to_categorical(y_train, num_classes)\n",
"y_test = keras.utils.to_categorical(y_test, num_classes)\n",
"print('Shape of transformed y train:', y_train.shape)\n",
"print('Shape of transformed y test:', y_test.shape)"
],
"metadata": {
"id": "xIB0CdYqdWPv"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"5 пункт"
],
"metadata": {
"id": "1HQjX5z6dp3h"
}
},
{
"cell_type": "code",
"source": [
"# создаем модель\n",
"model = Sequential()\n",
"model.add(layers.Conv2D(32, kernel_size=(3, 3), activation=\"relu\", input_shape=input_shape))\n",
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(layers.Conv2D(64, kernel_size=(3, 3), activation=\"relu\"))\n",
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(layers.Dropout(0.5))\n",
"model.add(layers.Flatten())\n",
"model.add(layers.Dense(num_classes, activation=\"softmax\"))\n",
"\n",
"model.summary()\n",
"\n"
],
"metadata": {
"id": "owMPTAvseQFB"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"batch_size = 512\n",
"epochs = 15\n",
"model.compile(loss=\"categorical_crossentropy\", optimizer=\"adam\", metrics=[\"accuracy\"])\n",
"model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)"
],
"metadata": {
"id": "thNo1LXUepwN"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"6 пункт"
],
"metadata": {
"id": "8Vvr7f3ng2EI"
}
},
{
"cell_type": "code",
"source": [
"# Оценка качества работы модели на тестовых данных\n",
"scores = model.evaluate(X_test, y_test)\n",
"print('Loss on test data:', scores[0])\n",
"print('Accuracy on test data:', scores[1])"
],
"metadata": {
"id": "JUg1WDEngza0"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"7 пункт"
],
"metadata": {
"id": "EYoMHxN_hPlv"
}
},
{
"cell_type": "code",
"source": [
"# вывод первого тестового изображения и результата распознавания\n",
"n = 222\n",
"result = model.predict(X_test[n:n+1])\n",
"print('NN output:', result)\n",
"plt.show()\n",
"plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))\n",
"print('Real mark: ', np.argmax(y_test[n]))\n",
"print('NN answer: ', np.argmax(result))"
],
"metadata": {
"id": "ozvxCjFFhF0i"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# вывод второго тестового изображения и результата распознавания\n",
"n = 111\n",
"result = model.predict(X_test[n:n+1])\n",
"print('NN output:', result)\n",
"plt.show()\n",
"plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))\n",
"print('Real mark: ', np.argmax(y_test[n]))\n",
"print('NN answer: ', np.argmax(result))"
],
"metadata": {
"id": "XrQQWslhjhxA"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"8 пункт"
],
"metadata": {
"id": "njvWDE6whDUz"
}
},
{
"cell_type": "code",
"source": [
"# истинные метки классов\n",
"true_labels = np.argmax(y_test, axis=1)\n",
"# предсказанные метки классов\n",
"predicted_labels = np.argmax(model.predict(X_test), axis=1)\n",
"\n",
"# отчет о качестве классификации\n",
"print(classification_report(true_labels, predicted_labels))\n",
"# вычисление матрицы ошибок\n",
"conf_matrix = confusion_matrix(true_labels, predicted_labels)\n",
"# отрисовка матрицы ошибок в виде \"тепловой карты\"\n",
"display = ConfusionMatrixDisplay(confusion_matrix=conf_matrix)\n",
"display.plot()\n",
"plt.show()"
],
"metadata": {
"id": "HuPTHd_YkZ-V"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"9 пункт\n"
],
"metadata": {
"id": "uNi4E7gPl8rd"
}
},
{
"cell_type": "code",
"source": [
"# загрузка собственного изображения 1\n",
"from PIL import Image\n",
"file_data = Image.open('test.png')\n",
"file_data = file_data.convert('L') # перевод в градации серого\n",
"test_img = np.array(file_data)\n",
"\n",
"# вывод собственного изображения\n",
"plt.imshow(test_img, cmap=plt.get_cmap('gray'))\n",
"plt.show()\n",
"\n",
"# предобработка\n",
"test_img = test_img / 255\n",
"test_img = np.reshape(test_img, (1,28,28,1))\n",
"\n",
"# распознавание\n",
"result = model.predict(test_img)\n",
"print('I think it\\'s ', np.argmax(result))"
],
"metadata": {
"id": "cQUHadWyl_d4"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# загрузка собственного изображения 2\n",
"from PIL import Image\n",
"file_data = Image.open('test_2.png')\n",
"file_data = file_data.convert('L') # перевод в градации серого\n",
"test_img = np.array(file_data)\n",
"\n",
"# вывод собственного изображения\n",
"plt.imshow(test_img, cmap=plt.get_cmap('gray'))\n",
"plt.show()\n",
"\n",
"# предобработка\n",
"test_img = test_img / 255\n",
"test_img = np.reshape(test_img, (1,28,28,1))\n",
"\n",
"# распознавание\n",
"result = model.predict(test_img)\n",
"print('I think it\\'s ', np.argmax(result))"
],
"metadata": {
"id": "D-LsJFTpmsCL"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"10 пункт"
],
"metadata": {
"id": "B7dQZmiTnFjk"
}
},
{
"cell_type": "code",
"source": [
"# путь к сохранённой модели из ЛР1\n",
"model_fc = keras.models.load_model('/content/drive/MyDrive/Colab Notebooks/best_model/model100.keras')\n",
"\n",
"# архитектура модели\n",
"model_fc.summary()\n",
"\n"
],
"metadata": {
"id": "JAFvXfzHnEyf"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# подготовка тестовых данных для полносвязной модели\n",
"X_test_fc = X_test.reshape(X_test.shape[0], 28*28) # (10000, 784)\n",
"y_test_fc = y_test # если в ЛР3 ты уже перевёл метки в one-hot\n",
"\n",
"# оценка качества, как в п. 6\n",
"scores = model_fc.evaluate(X_test_fc, y_test_fc, verbose=0)\n",
"print('Loss on test data (FC model):', scores[0])\n",
"print('Accuracy on test data (FC model):', scores[1])"
],
"metadata": {
"id": "iSMKJsCznIKM"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"11 пункт"
],
"metadata": {
"id": "YE0Ne5Y5pUaZ"
}
},
{
"cell_type": "code",
"source": [],
"metadata": {
"id": "c22hf9CjpT6Z"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [],
"metadata": {
"id": "S4SaPgPbnIAp"
},
"execution_count": null,
"outputs": []
}
]
}

@ -0,0 +1,346 @@
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"gpuType": "T4"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"source": [
"1 пункт"
],
"metadata": {
"id": "n2S-d-dy1com"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "EfImqmoI0eWN"
},
"outputs": [],
"source": [
"import os\n",
"os.chdir('/content/drive/MyDrive/Colab Notebooks/IS_LR3')"
]
},
{
"cell_type": "code",
"source": [
"# импорт модулей\n",
"from tensorflow import keras\n",
"from tensorflow.keras import layers\n",
"from tensorflow.keras.models import Sequential\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"from sklearn.metrics import classification_report, confusion_matrix\n",
"from sklearn.metrics import ConfusionMatrixDisplay"
],
"metadata": {
"id": "VBMRl6Iw1eqz"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"2 пункт"
],
"metadata": {
"id": "LnvGg6FZ1mDT"
}
},
{
"cell_type": "code",
"source": [
"# загрузка датасета\n",
"from keras.datasets import cifar10\n",
"\n",
"(X_train, y_train), (X_test, y_test) = cifar10.load_data()"
],
"metadata": {
"id": "90-GJpwO1k0u"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"3 пункт"
],
"metadata": {
"id": "ArL8T5q32POX"
}
},
{
"cell_type": "code",
"source": [
"# создание своего разбиения датасета\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"# объединяем в один набор\n",
"X = np.concatenate((X_train, X_test))\n",
"y = np.concatenate((y_train, y_test))\n",
"\n",
"# разбиваем по вариантам\n",
"X_train, X_test, y_train, y_test = train_test_split(X, y,\n",
" test_size = 10000,\n",
" train_size = 50000,\n",
" random_state = 19)"
],
"metadata": {
"id": "I9pe41Ni1kvJ"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# вывод размерностей\n",
"print('Shape of X train:', X_train.shape)\n",
"print('Shape of y train:', y_train.shape)\n",
"\n",
"print('Shape of X test:', X_test.shape)\n",
"print('Shape of y test:', y_test.shape)"
],
"metadata": {
"id": "m-KhW4L93B9o"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# вывод 25 изображений из обучающей выборки с подписями классов\n",
"class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',\n",
" 'dog', 'frog', 'horse', 'ship', 'truck']\n",
"\n",
"plt.figure(figsize=(10,10))\n",
"for i in range(25):\n",
" plt.subplot(5,5,i+1)\n",
" plt.xticks([])\n",
" plt.yticks([])\n",
" plt.grid(False)\n",
" plt.imshow(X_train[i])\n",
" plt.xlabel(class_names[y_train[i][0]])\n",
"plt.show()"
],
"metadata": {
"id": "p6RhtysM3Fol"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"4 пункт"
],
"metadata": {
"id": "ZtUEifrW31w4"
}
},
{
"cell_type": "code",
"source": [
"# Зададим параметры данных и модели\n",
"num_classes = 10\n",
"input_shape = (32, 32, 3)\n",
"\n",
"# Приведение входных данных к диапазону [0, 1]\n",
"X_train = X_train / 255\n",
"X_test = X_test / 255\n",
"\n",
"# Расширяем размерность входных данных, чтобы каждое изображение имело\n",
"# размерность (высота, ширина, количество каналов)\n",
"\n",
"\n",
"print('Shape of transformed X train:', X_train.shape)\n",
"print('Shape of transformed X test:', X_test.shape)\n",
"\n",
"# переведем метки в one-hot\n",
"y_train = keras.utils.to_categorical(y_train, num_classes)\n",
"y_test = keras.utils.to_categorical(y_test, num_classes)\n",
"print('Shape of transformed y train:', y_train.shape)\n",
"print('Shape of transformed y test:', y_test.shape)"
],
"metadata": {
"id": "_1EvYA5C31oT"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"5 пункт"
],
"metadata": {
"id": "HiZ1igLn4ZvE"
}
},
{
"cell_type": "code",
"source": [
"# создаем модель\n",
"model = Sequential()\n",
"model.add(layers.Conv2D(32, kernel_size=(3, 3), activation=\"relu\", input_shape=input_shape))\n",
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(layers.Conv2D(64, kernel_size=(3, 3), activation=\"relu\"))\n",
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(layers.Conv2D(128, kernel_size=(3, 3), activation=\"relu\"))\n",
"model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(layers.Flatten())\n",
"model.add(layers.Dense(128, activation='relu'))\n",
"model.add(layers.Dropout(0.5))\n",
"model.add(layers.Dense(num_classes, activation=\"softmax\"))\n",
"\n",
"model.summary()\n"
],
"metadata": {
"id": "szeMGpaW31it"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"batch_size = 512\n",
"epochs = 15\n",
"model.compile(loss=\"categorical_crossentropy\", optimizer=\"adam\", metrics=[\"accuracy\"])\n",
"model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)"
],
"metadata": {
"id": "CMUVJn2v3bx_"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"6 пункт"
],
"metadata": {
"id": "CTohcQAy7JGG"
}
},
{
"cell_type": "code",
"source": [
"# Оценка качества работы модели на тестовых данных\n",
"scores = model.evaluate(X_test, y_test)\n",
"print('Loss on test data:', scores[0])\n",
"print('Accuracy on test data:', scores[1])"
],
"metadata": {
"id": "ag1rP16A4oJC"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"7 пункт"
],
"metadata": {
"id": "lWZIle5r96tj"
}
},
{
"cell_type": "code",
"source": [
"# ПРАВИЛЬНО распознанное изображение\n",
"n = 0\n",
"result = model.predict(X_test[n:n+1])\n",
"print('NN output:', result)\n",
"\n",
"plt.imshow(X_test[n])\n",
"plt.show()\n",
"\n",
"print('Real class: ', np.argmax(y_test[n]), '->', class_names[np.argmax(y_test[n])])\n",
"print('NN answer:', np.argmax(result), '->', class_names[np.argmax(result)])"
],
"metadata": {
"id": "b8gAO65m9yZG"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# НЕВЕРНО распознанное изображение\n",
"n = 9\n",
"result = model.predict(X_test[n:n+1])\n",
"print('NN output:', result)\n",
"\n",
"plt.imshow(X_test[n])\n",
"plt.show()\n",
"\n",
"print('Real class: ', np.argmax(y_test[n]), '->', class_names[np.argmax(y_test[n])])\n",
"print('NN answer:', np.argmax(result), '->', class_names[np.argmax(result)])"
],
"metadata": {
"id": "gZiOC9Ke-BCz"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"8 пункт"
],
"metadata": {
"id": "MaamG6bP_xsp"
}
},
{
"cell_type": "code",
"source": [
"# истинные метки классов\n",
"true_labels = np.argmax(y_test, axis=1)\n",
"\n",
"# предсказанные метки классов\n",
"predicted_labels = np.argmax(model.predict(X_test), axis=1)\n",
"\n",
"# отчет о качестве классификации\n",
"print(classification_report(true_labels, predicted_labels, target_names=class_names))\n",
"\n",
"# вычисление матрицы ошибок\n",
"conf_matrix = confusion_matrix(true_labels, predicted_labels)\n",
"\n",
"# отрисовка матрицы ошибок в виде \"тепловой карты\"\n",
"display = ConfusionMatrixDisplay(confusion_matrix=conf_matrix,\n",
" display_labels=class_names)\n",
"display.plot(xticks_rotation=45)\n",
"plt.show()\n"
],
"metadata": {
"id": "Ix27-pKH_yG-"
},
"execution_count": null,
"outputs": []
}
]
}

@ -0,0 +1,619 @@
# Лабораторная работа №3: Распознавание изображений
**Аникеев А.А; Чагин С.А. — А-02-22**
## Номер бригады - 5
### Цель работы
Получить практические навыки создания, обучения и применения сверточных нейронных сетей для распознавания изображений. Познакомиться с
классическими показателями качества классификации.
### Определение варианта
- Номер бригады: k = 5
- random_state = (4k - 1) = 19
### Подготовка среды
```python
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks/IS_LR3')
```
---
## ЗАДАНИЕ 1
### Пункт №1. Импорт необходимых для работы библиотек и модулей.
```python
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. Разбиение набора данных на обучающие и тестовые данные.
```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 = 19)
# вывод размерностей
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. Проведене предобработки данных.
```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()
```
**Результат выполнения:**
| Layer (type) | Output Shape | Param # |
|-----------------------|-------------------|---------|
| conv2d (Conv2D) | (None, 26, 26, 32) | 320 |
| max_pooling2d (MaxPooling2D) | (None, 13, 13, 32) | 0 |
| conv2d_1 (Conv2D) | (None, 11, 11, 64) | 18,496 |
| max_pooling2d_1 (MaxPooling2D) | (None, 5, 5, 64) | 0 |
| dropout (Dropout) | (None, 5, 5, 64) | 0 |
| flatten (Flatten) | (None, 1600) | 0 |
| dense (Dense) | (None, 10) | 16,010 |
**Model: "sequential"**
**Total params:** 34,826 (136.04 KB)
**Trainable params:** 34,826 (136.04 KB)
**Non-trainable params:** 0 (0.00 B)
```
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.9885 - loss: 0.0418
Loss on test data: 0.04163474589586258
Accuracy on test data: 0.988099992275238
```
### Пункт №7. Выведение изображения, истинных меток и результатов распознавания.
```python
# вывод первого тестового изображения и результата распознавания
n = 222
result = model.predict(X_test[n:n+1])
print('NN output:', result)
plt.show()
plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))
print('Real mark: ', np.argmax(y_test[n]))
print('NN answer: ', np.argmax(result))
```
![Результаты](1.png)
**Результат выполнения:**
```
NN output: [[4.3116913e-08 3.3146053e-13 2.1031238e-07 4.8524967e-06 4.2155320e-06 1.1801652e-05 3.3284198e-11 2.9875573e-05 2.4400490e-06 9.9994659e-01]]
Real mark: 9
NN answer: 9
```
```python
# вывод второго тестового изображения и результата распознавания
n = 111
result = model.predict(X_test[n:n+1])
print('NN output:', result)
plt.show()
plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))
print('Real mark: ', np.argmax(y_test[n]))
print('NN answer: ', np.argmax(result))
```
![Результаты](2.png)
**Результат выполнения:**
```
NN output: [[1.5492931e-13 8.0427107e-16 6.5475694e-14 3.2799780e-06 1.5800725e-14 9.9999642e-01 1.6747580e-12 1.4161887e-15 1.3768246e-07 1.1293472e-07]]
Real mark: 5
NN answer: 5
```
### Пункт №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()
```
![Результаты](3.png)
**Результат выполнения:**
```
precision recall f1-score support
0 0.99 1.00 0.99 969
1 0.99 0.99 0.99 1155
2 0.98 0.99 0.98 969
3 0.99 0.99 0.99 1032
4 0.99 0.99 0.99 1016
5 0.98 0.99 0.99 898
6 0.99 0.99 0.99 990
7 0.99 0.99 0.99 1038
8 0.98 0.99 0.98 913
9 0.99 0.97 0.98 1020
accuracy 0.99 10000
macro avg 0.99 0.99 0.99 10000
weighted avg 0.99 0.99 0.99 10000
```
### Пункт №9. Подача на вход обученной нейронной сети собственного изображения.
```python
# загрузка собственного изображения 1
from PIL import Image
file_data = Image.open('test.png')
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))
```
![Результаты](4.png)
**Результат выполнения:**
```
I think it's 5
```
```python
# загрузка собственного изображения 2
from PIL import Image
file_data = Image.open('test_2.png')
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))
```
![Результаты](5.png)
**Результат выполнения:**
```
I think it's 2
```
### Пункт №10. Загрузка с диска модели, сохраненной при выполнении лабораторной работы №1.
```python
# путь к сохранённой модели из ЛР1
model_fc = keras.models.load_model('/content/drive/MyDrive/Colab Notebooks/best_model/model100.keras')
# архитектура модели
model_fc.summary()
```
**Результат выполнения:**
| Layer (type) | Output Shape | Param # |
|--------------------|-------------------|---------|
| dense_19 (Dense) | (None, 100) | 78,500 |
| dense_20 (Dense) | (None, 10) | 1,010 |
**Model: "sequential_10"**
**Total params:** 79,512 (310.60 KB)
**Trainable params:** 79,510 (310.59 KB)
**Non-trainable params:** 0 (0.00 B)
**Optimizer params:** 2 (12.00 B)
```python
# подготовка тестовых данных для полносвязной модели
X_test_fc = X_test.reshape(X_test.shape[0], 28*28) # (10000, 784)
y_test_fc = y_test # если в ЛР3 ты уже перевёл метки в one-hot
# оценка качества, как в п. 6
scores = model_fc.evaluate(X_test_fc, y_test_fc, verbose=0)
print('Loss on test data (FC model):', scores[0])
print('Accuracy on test data (FC model):', scores[1])
```
**Результат выполнения:**
```
Loss on test data (FC model): 0.19745591282844543
Accuracy on test data (FC model): 0.9442999958992004
```
### Пункт №11. Сравнение обученной модели сверточной сети и наилучшей модели полносвязной сети из лабораторной работы №1.
**Сравнение моделей:**
```
Количество настраиваемых параметров в сети:
Сверточная сеть: 34 826 параметров.
Полносвязная сеть: 79 512 параметров.
При том что число параметров сверточной сети меньше в 2 раза, она показывает более высокие результаты. Это связано с более эффективным использовании весов за счёт свёрток и фильтров.
Количество эпох обучения:
Сверточная сеть обучалась 15 эпох.
Полносвязная сеть обучалась 100 эпох.
Cверточная модель достигает лучшего результата при меньшем количестве эпох, то есть сходится быстрее и обучается эффективнее.
Качество классификации тестовой выборки:
Сверточная сеть: Accuracy ≈ 0.988, loss ≈ 0.042.
Полносвязная сеть: Accuracy ≈ 0.944, loss ≈ 0.197.
Сверточная нейросеть точнее на 4,5 процента, при этом её ошибка почти в 5 раз меньше.
Вывод:
Использование сверточной нейронной сети для распознавания изображений даёт ощутимо лучший результат по сравнению с полносвязной моделью. Сверточная нейронная сеть требует меньше параметров, быстрее обучается и точнее распознаёт изображения, поскольку учитывает их структуру и выделяет важные визуальные особенности.
```
## ЗАДАНИЕ 2
### Пункт №1. Импорт необходимых для работы библиотек и модулей.
```python
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. Загрузка набора данных CIFAR-10.
```python
from keras.datasets import cifar10
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
```
### Пункт №3. Разбиение набора данных на обучающие и тестовые данные.
```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 = 50000,
random_state = 19)
# вывод размерностей
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)
```
```python
# вывод 25 изображений из обучающей выборки с подписями классов
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()
```
![Результаты](6.png)
### Пункт №4. Проведене предобработки данных.
```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)
```
### Пункт №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.Conv2D(128, kernel_size=(3, 3), activation="relu"))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(num_classes, activation="softmax"))
model.summary()
```
**Результат выполнения:**
| Layer (type) | Output Shape | Param # |
|-----------------------|-------------------|---------|
| conv2d_2 (Conv2D) | (None, 30, 30, 32) | 896 |
| max_pooling2d_2 (MaxPooling2D) | (None, 15, 15, 32) | 0 |
| conv2d_3 (Conv2D) | (None, 13, 13, 64) | 18,496 |
| max_pooling2d_3 (MaxPooling2D) | (None, 6, 6, 64) | 0 |
| conv2d_4 (Conv2D) | (None, 4, 4, 128) | 73,856 |
| max_pooling2d_4 (MaxPooling2D) | (None, 2, 2, 128) | 0 |
| flatten_1 (Flatten) | (None, 512) | 0 |
| dense_1 (Dense) | (None, 128) | 65,664 |
| dropout_1 (Dropout) | (None, 128) | 0 |
| dense_2 (Dense) | (None, 10) | 1,290 |
**Model: "sequential_1"**
**Total params:** 160,202 (625.79 KB)
**Trainable params:** 160,202 (625.79 KB)
**Non-trainable params:** 0 (0.00 B)
```
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.6676 - loss: 0.9584
Loss on test data: 0.9374598860740662
Accuracy on test data: 0.6726999878883362
```
### Пункт №7. Выведение изображения, истинных меток и результатов распознавания.
```python
# правильно распознанное изображение
n = 0
result = model.predict(X_test[n:n+1])
print('NN output:', result)
plt.imshow(X_test[n])
plt.show()
print('Real class: ', np.argmax(y_test[n]), '->', class_names[np.argmax(y_test[n])])
print('NN answer:', np.argmax(result), '->', class_names[np.argmax(result)])
```
![Результаты](7.png)
**Результат выполнения:**
```
NN output: [[1.2349103e-03 8.2268691e-01 1.0979634e-03 2.3796519e-03 1.2556769e-02 6.0236914e-04 1.7611842e-03 1.2650734e-03 3.5482903e-03 1.5286703e-01]]
Real class: 1 -> automobile
NN answer: 1 -> automobile
```
```python
# неверно распознанное изображение
n = 9
result = model.predict(X_test[n:n+1])
print('NN output:', result)
plt.imshow(X_test[n])
plt.show()
print('Real class: ', np.argmax(y_test[n]), '->', class_names[np.argmax(y_test[n])])
print('NN answer:', np.argmax(result), '->', class_names[np.argmax(result)])
```
![Результаты](8.png)
**Результат выполнения:**
```
NN output: [[0.00157286 0.2169207 0.03160945 0.03033627 0.00178993 0.06459528 0.0421534 0.00500837 0.00139859 0.60461515]]
Real class: 1 -> automobile
NN answer: 9 -> truck
```
### Пункт №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, target_names=class_names))
# вычисление матрицы ошибок
conf_matrix = confusion_matrix(true_labels, predicted_labels)
# отрисовка матрицы ошибок в виде "тепловой карты"
display = ConfusionMatrixDisplay(confusion_matrix=conf_matrix,
display_labels=class_names)
display.plot(xticks_rotation=45)
plt.show()
```
![Результаты](9.png)
**Результат выполнения:**
```
precision recall f1-score support
airplane 0.64 0.76 0.70 1015
automobile 0.74 0.85 0.79 1015
bird 0.55 0.58 0.56 1008
cat 0.52 0.42 0.46 966
deer 0.65 0.61 0.63 1026
dog 0.56 0.62 0.58 985
frog 0.75 0.74 0.74 946
horse 0.75 0.71 0.73 1007
ship 0.78 0.77 0.78 1012
truck 0.80 0.68 0.74 1020
accuracy 0.67 10000
macro avg 0.67 0.67 0.67 10000
weighted avg 0.67 0.67 0.67 10000
```

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

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

После

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

@ -0,0 +1,412 @@
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"gpuType": "T4"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"source": [
"1 пункт"
],
"metadata": {
"id": "6tuecB2YaGZd"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "EexxrLenVcsK"
},
"outputs": [],
"source": [
"import os\n",
"os.chdir('/content/drive/MyDrive/Colab Notebooks/IS_LR4')"
]
},
{
"cell_type": "code",
"source": [
"import tensorflow as tf\n",
"device_name = tf.test.gpu_device_name()\n",
"if device_name != '/device:GPU:0':\n",
" raise SystemError('GPU device not found')\n",
"print('Found GPU at: {}'.format(device_name))"
],
"metadata": {
"id": "JZQBWhlnZ3Kz"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"2 пункт"
],
"metadata": {
"id": "BMVDcB8saN1d"
}
},
{
"cell_type": "code",
"source": [
"# загрузка датасета\n",
"from keras.datasets import imdb\n",
"vocabulary_size = 5000\n",
"index_from = 3\n",
"(X_train, y_train), (X_test, y_test) = imdb.load_data(path=\"imdb.npz\",\n",
"num_words=vocabulary_size,\n",
"skip_top=0,\n",
"maxlen=None,\n",
"seed=19,\n",
"start_char=1,\n",
"oov_char=2,\n",
"index_from=index_from\n",
")"
],
"metadata": {
"id": "dVZOh4OjaNfT"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"print(\"Размер обучающего множества X_train:\", X_train.shape)\n",
"print(\"Размер обучающих меток y_train:\", y_train.shape)\n",
"print(\"Размер тестового множества X_test:\", X_test.shape)\n",
"print(\"Размер тестовых меток y_test:\", y_test.shape)"
],
"metadata": {
"id": "ONS-UYoqb7VM"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"3 пункт"
],
"metadata": {
"id": "vrPoEAUFcZ6P"
}
},
{
"cell_type": "code",
"source": [
"# создание словаря для перевода индексов в слова\n",
"# заргузка словаря \"слово:индекс\"\n",
"word_to_id = imdb.get_word_index()\n",
"# уточнение словаря\n",
"word_to_id = {key:(value + index_from) for key,value in word_to_id.items()}\n",
"word_to_id[\"<PAD>\"] = 0\n",
"word_to_id[\"<START>\"] = 1\n",
"word_to_id[\"<UNK>\"] = 2\n",
"word_to_id[\"<UNUSED>\"] = 3\n",
"# создание обратного словаря \"индекс:слово\"\n",
"id_to_word = {value:key for key,value in word_to_id.items()}"
],
"metadata": {
"id": "ldO9EDteccDO"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"idx = 19\n",
"review_indices = X_train[idx]\n",
"print(\"Отзыв в виде индексов:\\n\", review_indices)\n",
"\n",
"review_text = \" \".join(id_to_word.get(i, \"?\") for i in review_indices)\n",
"print(\"\\nОтзыв в виде текста:\\n\", review_text)\n",
"\n",
"print(\"\\nДлина отзыва (количество индексов):\", len(review_indices))\n",
"\n",
"label = y_train[idx]\n",
"class_name = \"Positive\" if label == 1 else \"Negative\"\n",
"print(\"Метка класса:\", label, \"| Класс:\", class_name)\n"
],
"metadata": {
"id": "dgLjpdWVcaT1"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"4 пункт"
],
"metadata": {
"id": "sJRCzgSXdyaX"
}
},
{
"cell_type": "code",
"source": [
"print(\"Максимальная длина отзыва:\", len(max(X_train, key=len)))\n",
"print(\"Минимальная длина отзыва:\", len(min(X_train, key=len)))"
],
"metadata": {
"id": "NKuA8LSfd4nq"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"5 пункт"
],
"metadata": {
"id": "xRZqJEnkensA"
}
},
{
"cell_type": "code",
"source": [
"# предобработка данных\n",
"from tensorflow.keras.utils import pad_sequences\n",
"max_words = 500\n",
"X_train = pad_sequences(X_train, maxlen=max_words, value=0, padding='pre', truncating='post')\n",
"X_test = pad_sequences(X_test, maxlen=max_words, value=0, padding='pre', truncating='post')\n",
"\n"
],
"metadata": {
"id": "FcSsuqWGeqDE"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"6 пункт"
],
"metadata": {
"id": "Mrh00gk2gHaS"
}
},
{
"cell_type": "code",
"source": [
"print(\"Максимальная длина отзыва после предобработки:\", len(max(X_train, key=len)))\n",
"print(\"Минимальная длина отзыва после предобработки:\", len(min(X_train, key=len)))"
],
"metadata": {
"id": "woU0e9UMeqQi"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"7 пункт\n"
],
"metadata": {
"id": "jvOmAItEgJsq"
}
},
{
"cell_type": "code",
"source": [
"idx = 19\n",
"review_indices = X_train[idx]\n",
"print(\"Отзыв в виде индексов:\\n\", review_indices)\n",
"\n",
"review_text = \" \".join(id_to_word.get(i, \"?\") for i in review_indices)\n",
"print(\"\\nОтзыв в виде текста:\\n\", review_text)\n",
"\n",
"print(\"\\nДлина отзыва (количество индексов):\", len(review_indices))\n",
"\n",
"label = y_train[idx]\n",
"class_name = \"Positive\" if label == 1 else \"Negative\"\n",
"print(\"Метка класса:\", label, \"| Класс:\", class_name)"
],
"metadata": {
"id": "LGoRw4AHgJ9s"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"8 пункт"
],
"metadata": {
"id": "5CAdHfC_hVfo"
}
},
{
"cell_type": "code",
"source": [
"\n",
"print(\"Предобработанное обучающее множество X_train (первые 5 примеров):\")\n",
"print(X_train[:5])\n",
"\n",
"print(\"\\nПредобработанное тестовое множество X_test (первые 5 примеров):\")\n",
"print(X_test[:5])\n",
"\n",
"\n",
"print(\"Размер обучающего множества X_train:\", X_train.shape)\n",
"print(\"Размер обучающих меток y_train:\", y_train.shape)\n",
"print(\"Размер тестового множества X_test:\", X_test.shape)\n",
"print(\"Размер тестовых меток y_test:\", y_test.shape)"
],
"metadata": {
"id": "OAsrX4WdhYAx"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"9 пункт"
],
"metadata": {
"id": "GTQnxs9AjEaz"
}
},
{
"cell_type": "code",
"source": [
"from tensorflow.keras.models import Sequential\n",
"from tensorflow.keras.layers import Embedding, LSTM, Dropout, Dense\n",
"\n",
"\n",
"model = Sequential()\n",
"model.add(Embedding(input_dim=vocabulary_size, output_dim=32, input_length=max_words))\n",
"model.add(LSTM(64))\n",
"model.add(Dropout(0.5))\n",
"model.add(Dense(1, activation='sigmoid'))\n",
"\n",
"\n",
"model.compile(\n",
" optimizer='adam',\n",
" loss='binary_crossentropy',\n",
" metrics=['accuracy']\n",
")\n",
"\n",
"model.build(input_shape=(None, max_words))\n",
"model.summary()"
],
"metadata": {
"id": "R_-5hCfGjibD"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# Обучение модели\n",
"history = model.fit(\n",
" X_train,\n",
" y_train,\n",
" epochs=5,\n",
" batch_size=64,\n",
" validation_split=0.2,\n",
" verbose=1\n",
")"
],
"metadata": {
"id": "JyegJgdBlU4P"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"print(\"\\nКачество обучения по эпохам\")\n",
"for i in range(5):\n",
" train_acc = history.history['accuracy'][i]\n",
" val_acc = history.history['val_accuracy'][i]\n",
" print(f\"Эпоха {i+1}: accuracy = {train_acc:.4f}, val_accuracy = {val_acc:.4f}\")"
],
"metadata": {
"id": "9etKZpeVmeNj"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"10 пункт"
],
"metadata": {
"id": "sulUG0iDmukX"
}
},
{
"cell_type": "code",
"source": [
"test_loss, test_accuracy = model.evaluate(X_test, y_test, verbose=0)\n",
"\n",
"print(\"Качество классификации на тестовой выборке\")\n",
"print(f\"Test accuracy: {test_accuracy:.4f}\")"
],
"metadata": {
"id": "hVdh7SIAnWrx"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"y_score = model.predict(X_test)\n",
"y_pred = [1 if y_score[i,0]>=0.5 else 0 for i in range(len(y_score))]\n",
"from sklearn.metrics import classification_report\n",
"print(classification_report(y_test, y_pred, labels = [0, 1], target_names=['Negative', 'Positive']))"
],
"metadata": {
"id": "-p7pfGE7mwZi"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"from sklearn.metrics import roc_curve, auc\n",
"import matplotlib.pyplot as plt\n",
"fpr, tpr, thresholds = roc_curve(y_test, y_score)\n",
"plt.plot(fpr, tpr)\n",
"plt.grid()\n",
"plt.xlabel('False Positive Rate')\n",
"plt.ylabel('True Positive Rate')\n",
"plt.title('ROC')\n",
"plt.show()\n",
"print('Area under ROC is', auc(fpr, tpr))"
],
"metadata": {
"id": "A_ZMEN_YpmAq"
},
"execution_count": null,
"outputs": []
}
]
}

@ -0,0 +1,378 @@
# Лабораторная работа №4: Распознавание последовательностей
**Аникеев А.А; Чагин С.А. — А-02-22**
## Номер бригады - 5
### Цель работы
Получить практические навыки обработки текстовой информации с помощью рекуррентных искусственных нейронных сетей при решении задачи определения тональности текста.
### Определение варианта
- Номер бригады: k = 5
- random_state = (4k - 1) = 19
### Подготовка среды
```python
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks/IS_LR4')
```
---
### Пункт №1. Настройка блокнота для работы с аппаратным ускорителем GPU.
```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))
```
### Пункт №2. Загрузка набора данных IMDb.
```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=19,
start_char=1,
oov_char=2,
index_from=index_from
)
```
**Результат выполнения:**
```
Размер обучающего множества X_train: (25000,)
Размер обучающих меток y_train: (25000,)
Размер тестового множества X_test: (25000,)
Размер тестовых меток y_test: (25000,)
```
### Пункт №3. Вывод отзывов из обучающего множества в виде списка индексов слов.
```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()}
idx = 19
review_indices = X_train[idx]
print("Отзыв в виде индексов:\n", review_indices)
review_text = " ".join(id_to_word.get(i, "?") for i in review_indices)
print("\nОтзыв в виде текста:\n", review_text)
print("\nДлина отзыва (количество индексов):", len(review_indices))
label = y_train[idx]
class_name = "Positive" if label == 1 else "Negative"
print("Метка класса:", label, "| Класс:", class_name)
```
**Результат выполнения:**
```
Отзыв в виде индексов:
[1, 13, 296, 14, 22, 171, 211, 5, 32, 13, 70, 135, 15, 14, 9, 364, 352, 1916, 5, 15, 12, 127, 24, 28, 233, 8, 81, 19, 6, 147, 479, 2309, 156, 354, 9, 55, 338, 21, 12, 9, 959, 7, 1763, 116, 4361, 259, 37, 296, 14, 22, 150, 242, 104, 7, 2145, 17, 49, 932, 2, 2, 37, 620, 19, 6, 1056, 40, 49, 4618, 2112, 13, 70, 64, 8, 135, 15, 50, 9, 76, 128, 108, 44, 2145, 5, 2321, 11, 148, 153, 5, 15, 2200, 7, 445, 9, 55, 76, 467, 856, 13, 70, 386, 1124, 22, 2, 11, 63, 25, 70, 67, 530, 239, 7, 2, 284, 2, 2, 11, 6, 1686, 7, 2, 2145]
Отзыв в виде текста:
<START> i watched this film few times and all i can say that this is low budget rubbish and that it does not have anything to do with a real history facts actors performances is very poor but it is result of limited acting possibilities anyone who watched this film now probably think of hitler as some crazy <UNK> <UNK> who running with a gun like some chicago gangster i can only to say that there is much better films about hitler and germany in those years and that rise of evil is very much under average i can recommend german film <UNK> in which you can see brilliant performance of <UNK> actor <UNK> <UNK> in a roll of <UNK> hitler
Длина отзыва (количество индексов): 121
Метка класса: 0 | Класс: Negative
```
### Пункт №4. Вывод максимальной и минимальной длины отзыва в обучающем множестве.
```python
print("Максимальная длина отзыва:", len(max(X_train, key=len)))
print("Минимальная длина отзыва:", len(min(X_train, key=len)))
```
**Результат выполнения:**
```
Максимальная длина отзыва: 2494
Минимальная длина отзыва: 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("Максимальная длина отзыва после предобработки:", len(max(X_train, key=len)))
print("Минимальная длина отзыва после предобработки:", len(min(X_train, key=len)))
```
**Результат выполнения:**
```
Максимальная длина отзыва после предобработки: 500
Минимальная длина отзыва после предобработки: 500
```
### Пункт №7. Повторение пункта 3.
```python
idx = 19
review_indices = X_train[idx]
print("Отзыв в виде индексов:\n", review_indices)
review_text = " ".join(id_to_word.get(i, "?") for i in review_indices)
print("\nОтзыв в виде текста:\n", review_text)
print("\nДлина отзыва (количество индексов):", len(review_indices))
label = y_train[idx]
class_name = "Positive" if label == 1 else "Negative"
print("Метка класса:", label, "| Класс:", class_name)
```
**Результат выполнения:**
```
Отзыв в виде индексов:
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 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 13 296 14 22 171 211 5 32 13 70 135 15
14 9 364 352 1916 5 15 12 127 24 28 233 8 81
19 6 147 479 2309 156 354 9 55 338 21 12 9 959
7 1763 116 4361 259 37 296 14 22 150 242 104 7 2145
17 49 932 2 2 37 620 19 6 1056 40 49 4618 2112
13 70 64 8 135 15 50 9 76 128 108 44 2145 5
2321 11 148 153 5 15 2200 7 445 9 55 76 467 856
13 70 386 1124 22 2 11 63 25 70 67 530 239 7
2 284 2 2 11 6 1686 7 2 2145
Отзыв в виде текста:
<PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <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> i watched this film few times and all i can say that this is low budget rubbish and that it does not have anything to do with a real history facts actors performances is very poor but it is result of limited acting possibilities anyone who watched this film now probably think of hitler as some crazy <UNK> <UNK> who running with a gun like some chicago gangster i can only to say that there is much better films about hitler and germany in those years and that rise of evil is very much under average i can recommend german film <UNK> in which you can see brilliant performance of <UNK> actor <UNK> <UNK> in a roll of <UNK> hitler
Длина отзыва (количество индексов): 500
Метка класса: 0 | Класс: Negative
```
**Вывод:**
```
После предобработки длина всех отзывов была приведена к 500 словам. Рассматриваемый отзыв был дополнен нулями (<PAD>) в начале, так как его исходная длина была меньше выбранного максимума. Обрезания текста не произошло. Функция pad_sequences выровняла все отзывы к единой длине.
```
### Пункт №8. Вывод предобработанных массивов обучающих и тестовых данных.
```python
print("Предобработанное обучающее множество X_train (первые 5 примеров):")
print(X_train[:5])
print("\nПредобработанное тестовое множество X_test (первые 5 примеров):")
print(X_test[:5])
print("Размер обучающего множества X_train:", X_train.shape)
print("Размер обучающих меток y_train:", y_train.shape)
print("Размер тестового множества X_test:", X_test.shape)
print("Размер тестовых меток y_test:", y_test.shape)
```
**Результат выполнения:**
```
Предобработанное обучающее множество X_train (первые 5 примеров):
[ 0 0 0 ... 786 7 12]
[ 0 0 0 ... 35 709 790]
[ 0 0 0 ... 11 4 2]
[ 0 0 0 ... 358 4 2]
[ 0 0 0 ... 2 3174 2]
Предобработанное тестовое множество X_test (первые 5 примеров):
[ 0 0 0 ... 67 14 20]
[ 0 0 0 ... 48 24 6]
[ 1 146 6 ... 15 12 16]
[ 0 0 0 ... 141 17 134]
[ 1 12 9 ... 320 7 51]
Размер обучающего множества X_train: (25000, 500)
Размер обучающих меток y_train: (25000,)
Размер тестового множества X_test: (25000, 500)
Размер тестовых меток y_test: (25000,)
```
### Пункт №9. Реализация модели рекуррентной нейронной сети.
```python
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dropout, Dense
vocabulary_size = 5000
embedding_dim = 32
lstm_units = 64
dropout_rate = 0.5
model = Sequential()
model.add(Embedding(
input_dim=vocabulary_size + index_from,
output_dim=embedding_dim,
input_length=max_words
))
model.add(LSTM(lstm_units))
model.add(Dropout(dropout_rate))
model.add(Dense(1, activation='sigmoid'))
model.compile(
loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy']
)
model.build(input_shape=(None, max_words))
model.summary()
# Обучение модели
history = model.fit(
X_train,
y_train,
epochs=5,
batch_size=64,
validation_split=0.2,
verbose=1
)
```
**Результат выполнения:**
| Layer (type) | Output Shape | Param # |
|-----------------------|-------------------|-----------|
| embedding_3 (Embedding) | (None, 500, 32) | 160,096 |
| lstm_3 (LSTM) | (None, 64) | 24,832 |
| dropout_3 (Dropout) | (None, 64) | 0 |
| dense_3 (Dense) | (None, 1) | 65 |
**Total params:** 184,993 (722.63 KB)
**Trainable params:** 184,993 (722.63 KB)
**Non-trainable params:** 0 (0.00 B)
```
Качество обучения по эпохам
Эпоха 1: accuracy = 0.9302, val_accuracy = 0.8686
Эпоха 2: accuracy = 0.9298, val_accuracy = 0.8416
Эпоха 3: accuracy = 0.9351, val_accuracy = 0.8576
Эпоха 4: accuracy = 0.9311, val_accuracy = 0.8678
Эпоха 5: accuracy = 0.9522, val_accuracy = 0.8670
Добились качества обучения по метрике accuracy не менее 0.8.
```
### Пункт №10.1 Оценка качества обучения на тестовых данных.
```python
test_loss, test_accuracy = model.evaluate(X_test, y_test, verbose=0)
print("Качество классификации на тестовой выборке")
print(f"Test accuracy: {test_accuracy:.4f}")
```
**Результат выполнения:**
```
Качество классификации на тестовой выборке
Test accuracy: 0.8607
```
### Пункт №10.2
```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']))
```
**Результат выполнения:**
| Class | Precision | Recall | F1-Score | Support |
|-----------|-----------|--------|----------|---------|
| Negative | 0.84 | 0.89 | 0.86 | 12500 |
| Positive | 0.88 | 0.83 | 0.86 | 12500 |
| Macro Avg | 0.86 | 0.86 | 0.86 | 25000 |
| Weighted Avg | 0.86 | 0.86 | 0.86 | 25000 |
```
accuracy: 0.86 25000
```
### Пункт №10.3
```python
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt
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('Area under ROC is', auc(fpr, tpr))
```
**Результат выполнения:**
![Результаты](1.png)
Area under ROC is 0.9304564479999999
### Пункт №11. Выводы по результатам применения рекуррентной нейронной сети.
**Выводы по лабораторной работе:**
```
В ходе выполнения лабораторной работы была построена и обучена рекуррентная нейронная сеть на основе слоя LSTM для решения задачи определения тональности текстов из датасета IMDb. После предварительной обработки данных (приведение длины отзывов к фиксированному размеру и преобразование слов в числовые индексы) модель успешно обучилась классифицировать отзывы на положительные и отрицательные.
По итогам эксперимента качество модели на тестовой выборке составило accuracy ≈ 0.86, что означает, что сеть правильно классифицировала около 86% отзывов. Анализ отчёта о качестве классификации (precision, recall, f1-score) показал, что модель обеспечивает близкие значения метрик для обоих классов.
ROC-кривая модели проходит значительно выше диагонали случайного классификатора, а значение AUC ROC ≈ 0.93 указывает на высокую способность модели различать положительные и отрицательные отзывы.
Таким образом, использование рекуррентной нейронной сети, основанной на LSTM, оказалось эффективным для анализа тональности текста. Модель успешно улавливает зависимости в последовательностях слов и демонстрирует высокое качество классификации. Данная архитектура подходит для практических задач анализа текста, таких как фильтрация отзывов, определение эмоциональной окраски сообщений или анализ пользовательских комментариев.
```
Загрузка…
Отмена
Сохранить