Сравнить коммиты
49 Коммитов
|
После Ширина: | Высота: | Размер: 7.9 KiB |
|
После Ширина: | Высота: | Размер: 6.5 KiB |
|
После Ширина: | Высота: | Размер: 6.3 KiB |
|
После Ширина: | Высота: | Размер: 6.3 KiB |
|
После Ширина: | Высота: | Размер: 6.3 KiB |
|
После Ширина: | Высота: | Размер: 25 KiB |
|
После Ширина: | Высота: | Размер: 25 KiB |
|
После Ширина: | Высота: | Размер: 25 KiB |
|
После Ширина: | Высота: | Размер: 24 KiB |
|
После Ширина: | Высота: | Размер: 29 KiB |
|
После Ширина: | Высота: | Размер: 29 KiB |
|
После Ширина: | Высота: | Размер: 7.0 KiB |
|
После Ширина: | Высота: | Размер: 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()
|
||||
```
|
||||
|
||||

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

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

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

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

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

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

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

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

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

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

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

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

|
||||
|
||||
```
|
||||
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
|
||||
|
||||
Сеть не распознала цифры на изображениях корректно.
|
||||
|
После Ширина: | Высота: | Размер: 41 KiB |
|
После Ширина: | Высота: | Размер: 17 KiB |
|
После Ширина: | Высота: | Размер: 31 KiB |
|
После Ширина: | Высота: | Размер: 29 KiB |
|
После Ширина: | Высота: | Размер: 17 KiB |
|
После Ширина: | Высота: | Размер: 48 KiB |
|
После Ширина: | Высота: | Размер: 52 KiB |
|
После Ширина: | Высота: | Размер: 95 KiB |
|
После Ширина: | Высота: | Размер: 32 KiB |
|
После Ширина: | Высота: | Размер: 98 KiB |
|
После Ширина: | Высота: | Размер: 82 KiB |
|
После Ширина: | Высота: | Размер: 83 KiB |
|
После Ширина: | Высота: | Размер: 52 KiB |
|
После Ширина: | Высота: | Размер: 61 KiB |
|
После Ширина: | Высота: | Размер: 57 KiB |
|
После Ширина: | Высота: | Размер: 68 KiB |
|
После Ширина: | Высота: | Размер: 16 KiB |
|
После Ширина: | Высота: | Размер: 80 KiB |
|
После Ширина: | Высота: | Размер: 6.8 KiB |
|
После Ширина: | Высота: | Размер: 7.0 KiB |
|
После Ширина: | Высота: | Размер: 32 KiB |
|
После Ширина: | Высота: | Размер: 6.5 KiB |
|
После Ширина: | Высота: | Размер: 6.3 KiB |
|
После Ширина: | Высота: | Размер: 119 KiB |
|
После Ширина: | Высота: | Размер: 12 KiB |
|
После Ширина: | Высота: | Размер: 12 KiB |
|
После Ширина: | Высота: | Размер: 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))
|
||||
```
|
||||
|
||||

|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
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))
|
||||
```
|
||||
|
||||

|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
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))
|
||||
```
|
||||
|
||||

|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
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))
|
||||
```
|
||||
|
||||

|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Пункт №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)])
|
||||
```
|
||||
|
||||

|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
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)])
|
||||
```
|
||||
|
||||

|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
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
|
||||
```
|
||||
|
После Ширина: | Высота: | Размер: 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))
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
|
||||

|
||||
|
||||
Area under ROC is 0.9304564479999999
|
||||
|
||||
### Пункт №11. Выводы по результатам применения рекуррентной нейронной сети.
|
||||
|
||||
**Выводы по лабораторной работе:**
|
||||
|
||||
```
|
||||
В ходе выполнения лабораторной работы была построена и обучена рекуррентная нейронная сеть на основе слоя LSTM для решения задачи определения тональности текстов из датасета IMDb. После предварительной обработки данных (приведение длины отзывов к фиксированному размеру и преобразование слов в числовые индексы) модель успешно обучилась классифицировать отзывы на положительные и отрицательные.
|
||||
|
||||
По итогам эксперимента качество модели на тестовой выборке составило accuracy ≈ 0.86, что означает, что сеть правильно классифицировала около 86% отзывов. Анализ отчёта о качестве классификации (precision, recall, f1-score) показал, что модель обеспечивает близкие значения метрик для обоих классов.
|
||||
|
||||
ROC-кривая модели проходит значительно выше диагонали случайного классификатора, а значение AUC ROC ≈ 0.93 указывает на высокую способность модели различать положительные и отрицательные отзывы.
|
||||
|
||||
Таким образом, использование рекуррентной нейронной сети, основанной на LSTM, оказалось эффективным для анализа тональности текста. Модель успешно улавливает зависимости в последовательностях слов и демонстрирует высокое качество классификации. Данная архитектура подходит для практических задач анализа текста, таких как фильтрация отзывов, определение эмоциональной окраски сообщений или анализ пользовательских комментариев.
|
||||
```
|
||||