Сравнить коммиты
18 Коммитов
| Автор | SHA1 | Дата |
|---|---|---|
|
|
71af7a430f | 4 недель назад |
|
|
a7fa56d8c2 | 4 недель назад |
|
|
eeeaa88ded | 4 недель назад |
|
|
55c25f499e | 4 недель назад |
|
|
59588dace0 | 4 недель назад |
|
|
c423e364af | 4 недель назад |
|
|
7ca5ab43f8 | 4 недель назад |
|
|
6e1154bdc8 | 1 месяц назад |
|
|
1b92f2dbf2 | 1 месяц назад |
|
|
0d0beed503 | 1 месяц назад |
|
|
3747146d3c | 1 месяц назад |
|
|
5ad37b5714 | 1 месяц назад |
|
|
7155c4c6fb | 1 месяц назад |
|
|
94ab4931f2 | 2 месяцев назад |
|
|
62a1d8b498 | 2 месяцев назад |
|
|
343ac90b99 | 2 месяцев назад |
|
|
5b1ef923b9 | 2 месяцев назад |
|
|
7585939c57 | 2 месяцев назад |
|
После Ширина: | Высота: | Размер: 3.9 KiB |
|
После Ширина: | Высота: | Размер: 3.9 KiB |
|
После Ширина: | Высота: | Размер: 854 B |
|
После Ширина: | Высота: | Размер: 883 B |
|
После Ширина: | Высота: | Размер: 8.3 KiB |
|
После Ширина: | Высота: | Размер: 9.9 KiB |
|
После Ширина: | Высота: | Размер: 30 KiB |
|
После Ширина: | Высота: | Размер: 33 KiB |
|
После Ширина: | Высота: | Размер: 33 KiB |
|
После Ширина: | Высота: | Размер: 32 KiB |
|
После Ширина: | Высота: | Размер: 30 KiB |
|
После Ширина: | Высота: | Размер: 35 KiB |
|
После Ширина: | Высота: | Размер: 9.6 KiB |
@ -0,0 +1,622 @@
|
||||
# Отчёт по лабораторной работе №1
|
||||
|
||||
**Фонов А.Д., Хнытченков А.М. — А-01-22**
|
||||
|
||||
## 1. В среде Google Colab создан новый блокнот. Импортированы необходимые библиотеки и модули.
|
||||
|
||||
```python
|
||||
from google.colab import drive
|
||||
drive.mount('/content/drive')
|
||||
```
|
||||
|
||||
```python
|
||||
from tensorflow import keras
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import sklearn
|
||||
from keras.datasets import mnist
|
||||
from sklearn.model_selection import train_test_split
|
||||
from tensorflow.keras.utils import to_categorical
|
||||
from keras.models import Sequential
|
||||
from keras.layers import Dense
|
||||
from PIL import Image
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 2. Загрузили набора данных MNIST с изображениями рукописных цифр.
|
||||
|
||||
```python
|
||||
(X_train, y_train), (X_test, y_test) = mnist.load_data()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Разбили данные на обучающую и тестовую выборки 60 000:10 000.
|
||||
|
||||
При объединении исходных выборок и последующем разбиении был использован параметр `random_state = 4*k - 1`, где *k* – номер бригады (k = 3). Такой фиксированный seed обеспечивает воспроизводимость разбиения.
|
||||
|
||||
```python
|
||||
# объединяем исходные обучающие и тестовые данные в один массив
|
||||
X = np.concatenate((X_train, X_test))
|
||||
y = np.concatenate((y_train, y_test))
|
||||
|
||||
# выполняем разбиение на обучающую (60000) и тестовую (10000) выборки
|
||||
X_train, X_test, y_train, y_test = train_test_split(
|
||||
X, y, train_size=60000, test_size=10000, random_state=4*3 - 1
|
||||
)
|
||||
|
||||
# вывод размерностей полученных массивов
|
||||
print('Shape of X train:', X_train.shape)
|
||||
print('Shape of y test:', y_test.shape)
|
||||
```
|
||||
|
||||
```
|
||||
Shape of X train: (60000, 28, 28)
|
||||
Shape of y train: (60000,)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Вывели первые 4 элемента обучающих данных (изображения и метки цифр).
|
||||
|
||||
```python
|
||||
# вывод изображения
|
||||
fig, axes = plt.subplots(1, 4, figsize=(10, 3))
|
||||
for i in range(4):
|
||||
axes[i].imshow(X_train[i], cmap=plt.get_cmap('gray'))
|
||||
axes[i].set_title(y_train[i])
|
||||
axes[i].axis('off')
|
||||
plt.show()
|
||||
```
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 5. Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения нейронной сети. Входные данные должны принимать значения от 0 до 1, метки цифр должны быть закодированы по принципу «one-hot encoding». Вывели размерности предобработанных обучающих и тестовых массивов данных.
|
||||
|
||||
```python
|
||||
# развернем каждое изображение 28*28 в вектор 784
|
||||
num_pixels = X_train.shape[1] * X_train.shape[2]
|
||||
X_train = X_train.reshape(X_train.shape[0], num_pixels) / 255.0
|
||||
X_test = X_test.reshape(X_test.shape[0], num_pixels) / 255.0
|
||||
print('Shape of transformed X train:', X_train.shape)
|
||||
```
|
||||
|
||||
```
|
||||
Shape of transformed X train: (60000, 784)
|
||||
```
|
||||
|
||||
```python
|
||||
# переведем метки в one-hot
|
||||
from tensorflow.keras.utils import to_categorical
|
||||
y_train = to_categorical(y_train)
|
||||
y_test = to_categorical(y_test)
|
||||
```
|
||||
|
||||
```
|
||||
Shapeoftransformedytrain: (60000, 10)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Реализовали и обученили однослойную нейронную сеть.
|
||||
|
||||
**Архитектура и параметры:**
|
||||
- количество скрытых слоёв: 0
|
||||
- функция активации выходного слоя: `softmax`
|
||||
- функция ошибки: `categorical_crossentropy`
|
||||
- алгоритм обучения: `sgd`
|
||||
- метрика качества: `accuracy`
|
||||
- количество эпох: 50
|
||||
- доля валидационных данных от обучающих: 0.1
|
||||
|
||||
```python
|
||||
model = Sequential()
|
||||
model.add(Dense(units=10, input_dim=num_pixels, activation='softmax'))
|
||||
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
||||
model.summary()
|
||||
```
|
||||
|
||||
```
|
||||
Model: "sequential_4"
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
│ dense_5 (Dense) │ (None, 10) │ 7,850 │
|
||||
└─────────────────────────────────┴────────────────────────┴───────────────┘
|
||||
Total params: 7,850 (30.66 KB)
|
||||
Trainable params: 7,850 (30.66 KB)
|
||||
Non-trainable params: 0 (0.00 B)
|
||||
```
|
||||
|
||||
```python
|
||||
#обучение
|
||||
H1 = model.fit(X_train, y_train, batch_size=256, validation_split=0.1, epochs=150)
|
||||
```
|
||||
|
||||
```python
|
||||
# вывод графика ошибки по эпохам
|
||||
plt.plot(H1.history['loss'])
|
||||
plt.plot(H1.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. Применили обученную модель к тестовым данным.
|
||||
|
||||
```python
|
||||
# Оценка качества работы модели на тестовых данных
|
||||
scores = model.evaluate(X_test, y_test)
|
||||
print('Loss on test data:', scores[0])
|
||||
print('Accuracy on test data:', scores[1])
|
||||
```
|
||||
|
||||
```
|
||||
Loss on test data: 0.32417795062065125
|
||||
Accuracy on test data: 0.9110999703407288
|
||||
```
|
||||
|
||||
## 8. Добавили в модель один скрытый слой и провели обучение и тестирование (повторить п. 6–7) при 100, 300, 500 нейронах в скрытом слое. По метрике качества классификации на тестовых данных выбрали наилучшее количество нейронов в скрытом слое. В качестве функции активации нейронов в скрытом слое использовали функцию sigmoid.
|
||||
|
||||
### При 100 нейронах:
|
||||
```python
|
||||
model_100 = Sequential ()
|
||||
model_100.add(Dense(units=100,input_dim=num_pixels, activation='sigmoid'))
|
||||
model_100.add(Dense(units=num_classes, activation='softmax'))
|
||||
model_100.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
||||
print(model_100.summary())
|
||||
```
|
||||
|
||||
```
|
||||
Model: "sequential_5"
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
│ dense_6 (Dense) │ (None, 100) │ 78,500 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense_7 (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)
|
||||
None
|
||||
```
|
||||
|
||||
```python
|
||||
#обучение
|
||||
H_100 = model_100.fit(X_train, y_train, batch_size=256, validation_split=0.1, epochs=150)
|
||||
```
|
||||
|
||||
```python
|
||||
# вывод графика ошибки по эпохам
|
||||
plt.plot(H_100.history['loss'])
|
||||
plt.plot(H_100.history['val_loss'])
|
||||
plt.grid()
|
||||
plt.xlabel('Epochs')
|
||||
plt.ylabel('loss')
|
||||
plt.legend(['train_loss', 'val_loss'])
|
||||
plt.title('Loss by epochs')
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
```python
|
||||
# Оценка качества работы модели на тестовых данных
|
||||
scores = model_100.evaluate(X_test, y_test)
|
||||
print('Loss on test data:', scores[0])
|
||||
print('Accuracy on test data:', scores[1])
|
||||
```
|
||||
|
||||
```
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 2ms/step - accuracy: 0.9184 - loss: 0.2786
|
||||
Loss on test data: 0.2789558172225952
|
||||
Accuracy on test data: 0.9182999730110168
|
||||
```
|
||||
|
||||
### При 300 нейронах:
|
||||
```python
|
||||
model_300 = Sequential ()
|
||||
model_300.add(Dense(units=300,input_dim=num_pixels, activation='sigmoid'))
|
||||
model_300.add(Dense(units=num_classes, activation='softmax'))
|
||||
model_300.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
||||
print(model_300.summary())
|
||||
```
|
||||
|
||||
```
|
||||
Model: "sequential_6"
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
│ dense_8 (Dense) │ (None, 300) │ 235,500 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense_9 (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)
|
||||
None
|
||||
```
|
||||
|
||||
```python
|
||||
H_300 = model_300.fit(X_train, y_train, batch_size=256, validation_split=0.1, epochs=150)
|
||||
```
|
||||
|
||||
```python
|
||||
# вывод графика ошибки по эпохам
|
||||
plt.plot(H_300.history['loss'])
|
||||
plt.plot(H_300.history['val_loss'])
|
||||
plt.grid()
|
||||
plt.xlabel('Epochs')
|
||||
plt.ylabel('loss')
|
||||
plt.legend(['train_loss', 'val_loss'])
|
||||
plt.title('Loss by epochs')
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
```python
|
||||
# Оценка качества работы модели на тестовых данных
|
||||
scores = model_300.evaluate(X_test, y_test)
|
||||
print('Loss on test data:', scores[0])
|
||||
print('Accuracy on test data:', scores[1])
|
||||
```
|
||||
|
||||
```
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - accuracy: 0.9126 - loss: 0.2880
|
||||
Loss on test data: 0.28887832164764404
|
||||
Accuracy on test data: 0.9136999845504761
|
||||
```
|
||||
|
||||
### При 500 нейронах:
|
||||
```python
|
||||
model_500 = Sequential()
|
||||
model_500.add(Dense(units=500, input_dim=num_pixels, activation='sigmoid'))
|
||||
model_500.add(Dense(units=num_classes, activation='softmax'))
|
||||
model_500.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
||||
print(model_500.summary())
|
||||
```
|
||||
|
||||
```
|
||||
Model: "sequential_7"
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
│ dense_10 (Dense) │ (None, 500) │ 392,500 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense_11 (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)
|
||||
None
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
H_500 = model_500.fit(X_train, y_train, batch_size=256, validation_split=0.1, epochs=150)
|
||||
```
|
||||
|
||||
```python
|
||||
# вывод графика ошибки по эпохам
|
||||
plt.plot(H_500.history['loss'])
|
||||
plt.plot(H_500.history['val_loss'])
|
||||
plt.grid()
|
||||
plt.xlabel('Epochs')
|
||||
plt.ylabel('loss')
|
||||
plt.legend(['train_loss', 'val_loss'])
|
||||
plt.title('Loss by epochs')
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
```python
|
||||
# Оценка качества работы модели на тестовых данных
|
||||
scores = model_500.evaluate(X_test, y_test)
|
||||
print('Loss on test data:', scores[0])
|
||||
print('Accuracy on test data:', scores[1])
|
||||
```
|
||||
|
||||
```
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 3ms/step - accuracy: 0.9125 - loss: 0.2925
|
||||
Loss on test data: 0.29266518354415894
|
||||
Accuracy on test data: 0.9136999845504761
|
||||
```
|
||||
|
||||
Мы видим что лучший результат показала модель со 100 нейронами в скрытом слое(Accuracy = 0.9138).
|
||||
|
||||
## 9. Добавили в наилучшую архитектуру, определенную в п. 8, второй скрытый слой и провели обучение и тестирование при 50 и 100 нейронах во втором скрытом слое. В качестве функции активации нейронов в скрытом слое использовали функцию sigmoid.
|
||||
|
||||
### При 50 нейронах в 2-м слое:
|
||||
```python
|
||||
model_100_50 = Sequential()
|
||||
model_100_50.add(Dense(units=100, input_dim=num_pixels, activation='sigmoid'))
|
||||
model_100_50.add(Dense(units=50, activation='sigmoid'))
|
||||
model_100_50.add(Dense(units=num_classes, activation='softmax'))
|
||||
model_100_50.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
||||
print(model_100_50.summary())
|
||||
```
|
||||
|
||||
```
|
||||
Model: "sequential_9"
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
│ dense_14 (Dense) │ (None, 100) │ 78,500 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense_15 (Dense) │ (None, 50) │ 5,050 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense_16 (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)
|
||||
None
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
H_100_50 = model_100_50.fit(X_train, y_train, batch_size=256, validation_split=0.1, epochs=150)
|
||||
```
|
||||
|
||||
```python
|
||||
# вывод графика ошибки по эпохам
|
||||
plt.plot(H_100_50.history['loss'])
|
||||
plt.plot(H_100_50.history['val_loss'])
|
||||
plt.grid()
|
||||
plt.xlabel('Epochs')
|
||||
plt.ylabel('loss')
|
||||
plt.legend(['train_loss', 'val_loss'])
|
||||
plt.title('Loss by epochs')
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
```python
|
||||
# Оценка качества работы модели на тестовых данных
|
||||
scores = model_100_50.evaluate(X_test, y_test)
|
||||
print('Loss on test data:', scores[0])
|
||||
print('Accuracy on test data:', scores[1])
|
||||
```
|
||||
|
||||
```
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 2ms/step - accuracy: 0.9110 - loss: 0.3112
|
||||
Loss on test data: 0.31079161167144775
|
||||
Accuracy on test data: 0.9092000126838684
|
||||
```
|
||||
|
||||
### При 100 нейронах во 2-м слое:\
|
||||
|
||||
```python
|
||||
model_100_100 = Sequential()
|
||||
model_100_100.add(Dense(units=100, input_dim=num_pixels, activation='sigmoid'))
|
||||
model_100_100.add(Dense(units=100, activation='sigmoid'))
|
||||
model_100_100.add(Dense(units=num_classes, activation='softmax'))
|
||||
model_100_100.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
||||
print(model_100_100.summary())
|
||||
```
|
||||
|
||||
```
|
||||
Model: "sequential_10"
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
│ dense_17 (Dense) │ (None, 100) │ 78,500 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense_18 (Dense) │ (None, 100) │ 10,100 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense_19 (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)
|
||||
None
|
||||
```
|
||||
|
||||
```python
|
||||
H_100_100 = model_100_100.fit(X_train, y_train, batch_size=256, validation_split=0.1, epochs=150)
|
||||
```
|
||||
|
||||
```python
|
||||
# вывод графика ошибки по эпохам
|
||||
plt.plot(H_100_100.history['loss'])
|
||||
plt.plot(H_100_100.history['val_loss'])
|
||||
plt.grid()
|
||||
plt.xlabel('Epochs')
|
||||
plt.ylabel('loss')
|
||||
plt.legend(['train_loss', 'val_loss'])
|
||||
plt.title('Loss by epochs')
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
```python
|
||||
# Оценка качества работы модели на тестовых данных
|
||||
scores = model.evaluate(X_test, y_test)
|
||||
print('Loss on test data:', scores[0])
|
||||
print('Accuracy on test data:', scores[1])
|
||||
```
|
||||
|
||||
```
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 2ms/step - accuracy: 0.9144 - loss: 0.2963
|
||||
Loss on test data: 0.29889559745788574
|
||||
Accuracy on test data: 0.9126999974250793
|
||||
```
|
||||
|
||||
## 10. Сравнили качество классификации на тестовых данных всех построенных моделей. Сделали выводы.
|
||||
|
||||
| Кол-во слоёв | Нейронов в 1-м | Нейронов во 2-м | Accuracy |
|
||||
|---------------|----------------|-----------------|-----------|
|
||||
| 0 | – | – | 0.9111 |
|
||||
| 1 | 100 | – | 0.9183 |
|
||||
| 1 | 300 | – | 0.9136 |
|
||||
| 1 | 500 | – | 0.9137 |
|
||||
| 2 | 100 | 50 | 0.9092 |
|
||||
| 2 | 100 | 100 | 0.9127 |
|
||||
|
||||
**Вывод:** наилучшей оказалась архитектура с одним скрытым слоем и 100 нейронами в нём. Увеличение числа нейронов в скрытом слое или добавление второго слоя не улучшило качество классификации, а в некоторых случаях даже ухудшило его. Вероятно, это связано с переобучением модели из-за избыточного количества параметров при относительно небольшом объёме обучающих данных.
|
||||
|
||||
---
|
||||
|
||||
## 11. Сохранили наилучшую модель на диск.
|
||||
|
||||
```python
|
||||
model_100.save("/content/drive/MyDrive/Colab Notebooks/best_model_100.keras")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. Для нейронной сети с наилучшей архитектурой вывели 2 тестовых изображения и истинные метки, а также предсказанные моделью метки.
|
||||
|
||||
```python
|
||||
n = 333
|
||||
result = model_100.predict(X_test[n:n+1])
|
||||
print('NNoutput:',result)
|
||||
plt.imshow(X_test[n].reshape(28,28),cmap=plt.get_cmap('gray'))
|
||||
plt.show()
|
||||
print('Realmark:',str(np.argmax(y_test[n])))
|
||||
print('NNanswer:',str(np.argmax(result)))
|
||||
```
|
||||

|
||||
|
||||
```
|
||||
NNoutput: [[2.8792789e-05 1.1840343e-06 6.8865262e-04 2.9317471e-07 1.0873583e-04
|
||||
3.8107886e-04 9.9874818e-01 3.4978150e-08 4.1428295e-05 1.6908634e-06]]
|
||||
Realmark: 6
|
||||
NNanswer: 6
|
||||
```
|
||||
|
||||
```python
|
||||
n = 234
|
||||
result = model_100.predict(X_test[n:n+1])
|
||||
print('NNoutput:',result)
|
||||
plt.imshow(X_test[n].reshape(28,28),cmap=plt.get_cmap('gray'))
|
||||
plt.show()
|
||||
print('Realmark:',str(np.argmax(y_test[n])))
|
||||
print('NNanswer:',str(np.argmax(result)))
|
||||
```
|
||||

|
||||
|
||||
```
|
||||
NNoutput: [[8.59206193e-05 3.77812080e-06 5.60759217e-04 8.30771052e-04
|
||||
1.28042605e-02 7.39536830e-04 7.70781189e-05 3.77385356e-02
|
||||
7.31113739e-03 9.39848125e-01]]
|
||||
Realmark: 9
|
||||
NNanswer: 9
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 13. Создали собственные изображения рукописных цифр, подобное представленным в наборе MNIST. Цифру выбрали как остаток от деления на 10 числа своего дня рождения (27 апреля → 27 mod 10 = 7, 4 июня → 4 mod 10 = 4). Сохранили изображения. Загрузили, предобработали и подали на вход обученной нейронной сети собственные изображения. Вывели изображения и результаты распознавания.
|
||||
|
||||
### Для 4:
|
||||
|
||||

|
||||
|
||||
```python
|
||||
#вывод собственного изображения
|
||||
plt.imshow(test_img,cmap=plt.get_cmap('gray'))
|
||||
plt.show()
|
||||
#предобработка
|
||||
test_img=test_img/255
|
||||
test_img=test_img.reshape(1,num_pixels)
|
||||
#распознавание
|
||||
result=model_100.predict(test_img)
|
||||
print('I think it\'s',np.argmax(result))
|
||||
```
|
||||
|
||||
```
|
||||
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 27ms/step
|
||||
I think it's 4
|
||||
```
|
||||
|
||||
### Для 7:
|
||||
|
||||

|
||||
|
||||
```python
|
||||
from PIL import Image
|
||||
file_data_7=Image.open('/content/drive/MyDrive/Colab Notebooks/IS_lab_7.png')
|
||||
file_data_7=file_data_7.convert('L')
|
||||
test_img_7=np.array(file_data_7)
|
||||
#вывод собственного изображения
|
||||
plt.imshow(test_img_7,cmap=plt.get_cmap('gray'))
|
||||
plt.show()
|
||||
#предобработка
|
||||
test_img_7=test_img_7/255
|
||||
test_img_7=test_img_7.reshape(1,num_pixels)
|
||||
#распознавание
|
||||
result=model_100.predict(test_img_7)
|
||||
print('I think it\'s',np.argmax(result))
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 41ms/step
|
||||
I think it's 4
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 14. Создать копию собственного изображения, отличающуюся от оригинала поворотом на 90 градусов в любую сторону. Сохранили изображения. Загрузили, предобработали и подали на вход обученной нейронной сети измененные изображения. Вывели изображения и результаты распознавания. Сделали выводы по результатам эксперимента.
|
||||
|
||||
```python
|
||||
from PIL import Image
|
||||
file_data=Image.open('/content/drive/MyDrive/Colab Notebooks/IS_lab_7_90.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=test_img.reshape(1,num_pixels)
|
||||
#распознавание
|
||||
result=model_100.predict(test_img)
|
||||
print('Ithinkit\'s',np.argmax(result))
|
||||
```
|
||||
|
||||

|
||||
|
||||
```python
|
||||
from PIL import Image
|
||||
file_data_4=Image.open('/content/drive/MyDrive/Colab Notebooks/IS_lab_4_90.png')
|
||||
file_data_4=file_data_4.convert('L')
|
||||
test_img_4=np.array(file_data_4)
|
||||
#выводсобственногоизображения
|
||||
plt.imshow(test_img_4,cmap=plt.get_cmap('gray'))
|
||||
plt.show()
|
||||
#предобработка
|
||||
test_img_4=test_img_4/255
|
||||
test_img_4=test_img_4.reshape(1,num_pixels)
|
||||
#распознавание
|
||||
result=model_100.predict(test_img_4)
|
||||
print('Ithinkit\'s',np.argmax(result))
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 39ms/step
|
||||
I think it's 1
|
||||
```
|
||||
|
||||
**Вывод:** модель неустойчива к повороту изображений, так как не обучалась на повернутых данных.
|
||||
|
||||
---
|
||||
|
||||
## Заключение
|
||||
Изучены принципы построения и обучения нейронных сетей в Keras на примере распознавания цифр MNIST. Лучшая точность достигнута простой моделью с одним скрытым слоем из 100 нейронов. При усложнении архитектуры наблюдается переобучение. Сеть корректно классифицирует собственные изображения, но ошибается на повернутых.
|
||||
|
После Ширина: | Высота: | Размер: 20 KiB |
|
После Ширина: | Высота: | Размер: 21 KiB |
|
После Ширина: | Высота: | Размер: 33 KiB |
@ -0,0 +1 @@
|
||||
0.44
|
||||
@ -0,0 +1 @@
|
||||
0.81
|
||||
|
После Ширина: | Высота: | Размер: 55 KiB |
|
После Ширина: | Высота: | Размер: 33 KiB |
|
После Ширина: | Высота: | Размер: 34 KiB |
|
После Ширина: | Высота: | Размер: 98 KiB |
|
После Ширина: | Высота: | Размер: 111 KiB |
|
После Ширина: | Высота: | Размер: 73 KiB |
|
После Ширина: | Высота: | Размер: 86 KiB |
|
После Ширина: | Высота: | Размер: 80 KiB |
|
После Ширина: | Высота: | Размер: 61 KiB |
|
После Ширина: | Высота: | Размер: 34 KiB |
@ -0,0 +1,5 @@
|
||||
------------Оценка качества AE1 С ПОМОЩЬЮ НОВЫХ МЕТРИК------------
|
||||
Approx = 0.1782178217821782
|
||||
Excess = 4.611111111111111
|
||||
Deficit = 0.0
|
||||
Coating = 1.0
|
||||
|
После Ширина: | Высота: | Размер: 44 KiB |
@ -0,0 +1,234 @@
|
||||
# Лабораторная работа №2: Обнаружение аномалий с помощью автокодировщиков
|
||||
|
||||
Выполнили: Фонов А.Д., Хнытченков А.М.
|
||||
Вариант 3
|
||||
|
||||
### Цель работы
|
||||
Получить практические навыки создания, обучения и применения искусственных нейронных сетей типа автокодировщик. Исследовать влияние архитектуры автокодировщика и количества эпох обучения на области в пространстве признаков, распознаваемые автокодировщиком после обучения. Научиться оценивать качество обучения автокодировщика на основе ошибки реконструкции и новых метрик EDCA. Научиться решать актуальную задачу обнаружения аномалий в данных с помощью автокодировщика как одноклассового классификатора.
|
||||
|
||||
|
||||
## ЗАДАНИЕ 1: Работа с двумерными синтетическими данными
|
||||
|
||||
### Импорт библиотек и настройка окружения
|
||||
```python
|
||||
import os
|
||||
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab2')
|
||||
import lab02_lib
|
||||
import numpy as np
|
||||
```
|
||||
|
||||
**Описание:** Импортируются необходимые библиотеки и устанавливаются параметры для варианта 2.
|
||||
|
||||
### Генерация индивидуального набора двумерных данных
|
||||
```python
|
||||
k = 3
|
||||
data = lab02_lib.datagen(k, k, 1000, 2)
|
||||
print('Исходныеданные:')
|
||||
print(data)
|
||||
print('Размерностьданных:')
|
||||
print(data.shape)
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
Исходные данные:
|
||||
k = 3
|
||||
data = lab02_lib.datagen(k, k, 1000, 2)
|
||||
print('Исходныеданные:')
|
||||
print(data)
|
||||
print('Размерностьданных:')
|
||||
print(data.shape)
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Создание и обучение автокодировщика AE1
|
||||
```python
|
||||
epoch = 1000
|
||||
patience = 100
|
||||
ae_trainned, IRE_array, IREth = lab02_lib.create_fit_save_ae(data, 'out/AE_1.h5','out/AE_1_ire_th.txt',
|
||||
epoch, True, patience)
|
||||
|
||||
print(f"IREth: {IREth}")
|
||||
|
||||
|
||||
lab02_lib.ire_plot('training', IRE_array, IREth, 'AE1')
|
||||
```
|
||||
|
||||

|
||||
IREth: 1.71
|
||||
|
||||
|
||||
### Создание и обучение автокодировщика AE2
|
||||
```python
|
||||
patience = 500
|
||||
ae2_trained, IRE2, IREth2= lab02_lib.create_fit_save_ae(data,'out/AE2.h5','out/AE2_ire_th.txt', 3000, True, patience)
|
||||
lab02_lib.ire_plot('training', IRE2, IREth2, 'AE2')
|
||||
print(f"IREth: {IREth2}")
|
||||
```
|
||||
|
||||

|
||||
IREth: 0.44
|
||||
|
||||
|
||||
### Расчет характеристик качества обучения автокодировщиков
|
||||
```python
|
||||
numb_square= 20
|
||||
xx,yy,Z1=lab02_lib.square_calc(numb_square,data, ae_trainned ,IREth,'1',True)
|
||||
```
|
||||
**Результат выполнения:**
|
||||

|
||||
```
|
||||
amount: 18
|
||||
amount_ae: 101
|
||||
|
||||
|
||||
```
|
||||

|
||||

|
||||
```
|
||||
Оценка качества AE1
|
||||
IDEAL = 0. Excess: 4.611111111111111
|
||||
IDEAL = 0. Deficit: 0.0
|
||||
IDEAL = 1. Coating: 1.0
|
||||
summa: 1.0
|
||||
IDEAL = 1. Extrapolation precision (Approx): 0.1782178217821782
|
||||
```
|
||||
|
||||
```python
|
||||
xx,yy,Z2=lab02_lib.square_calc(numb_square,data,ae2_trained,IREth2,'1',True)
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||

|
||||
```
|
||||
amount: 19
|
||||
amount_ae: 40
|
||||
```
|
||||

|
||||

|
||||
```
|
||||
Оценка качества AE2
|
||||
IDEAL = 0. Excess: 1.0
|
||||
IDEAL = 0. Deficit: 0.0
|
||||
IDEAL = 1. Coating: 1.0
|
||||
summa: 1.0
|
||||
IDEAL = 1. Extrapolation precision (Approx): 0.5
|
||||
```
|
||||
```python
|
||||
lab02_lib.plot2in1(data,xx,yy,Z1,Z2)
|
||||
```
|
||||

|
||||
|
||||
### Тестирование автокодировщиков
|
||||
```python
|
||||
data_test= np.loadtxt('data_test.txt', dtype=float)
|
||||
|
||||
lab02_lib.anomaly_detection_ae(predicted_labels1, ire1, IREth)
|
||||
lab02_lib.ire_plot('test', ire1, IREth, 'AE1')
|
||||
lab02_lib.anomaly_detection_ae(predicted_labels2, ire2, IREth2)
|
||||
lab02_lib.ire_plot('test', ire1, IREth, 'AE2')
|
||||
|
||||
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
---
|
||||
|
||||
## ЗАДАНИЕ 2: Работа с реальными данными Cardio
|
||||
|
||||
### Загрузка и изучение данных Cardio
|
||||
```python
|
||||
train = np.loadtxt('cardio_train.txt', dtype=float)
|
||||
test = np.loadtxt('cardio_test.txt', dtype=float)
|
||||
```
|
||||
|
||||
**Описание:** Загружаются данные Cardio, которые содержат измерения частоты сердечных сокращений плодаи сокращений матки на кардиотокограммах.
|
||||
|
||||
### Создание и обучение автокодировщика
|
||||
```python
|
||||
from time import time
|
||||
start = time()
|
||||
ae3_trained, IRE3, IREth3 = lab02_lib.create_fit_save_ae(train,'out/AE3.h5','out/AE3_ire_th.txt',
|
||||
85000, False, 7500, early_stopping_delta = 0.004)
|
||||
print("Время на обучение: ", time() - start)
|
||||
```
|
||||
|
||||
**Результаты обучения:**
|
||||
Время на обучение: 2023.5726425647736
|
||||
- loss: 0.0381
|
||||
Порог IREth3: 3.12
|
||||
|
||||
|
||||
```python
|
||||
predicted_labels3, ire3 = lab02_lib.predict_ae(ae3_trained, test, IREth3)
|
||||
```
|
||||
|
||||
|
||||
### Тестирование автокодировщика
|
||||
```python
|
||||
lab02_lib.anomaly_detection_ae(predicted_labels3, ire3, IREth3)
|
||||
lab02_lib.ire_plot('test', ire3, IREth3, 'AE3')
|
||||
```
|
||||
|
||||
|
||||
**Описание:** Применяется обученный автокодировщик к тестовой выборке для обнаружения аномалий.
|
||||
|
||||
**Результаты обнаружения аномалий:**
|
||||
```
|
||||
i Labels IRE IREth
|
||||
97 [1.] [2.89] 2.83
|
||||
98 [0.] [1.98] 2.83
|
||||
99 [0.] [2.1] 2.83
|
||||
100 [0.] [1.67] 2.83
|
||||
101 [0.] [1.94] 2.83
|
||||
102 [0.] [2.2] 2.83
|
||||
103 [0.] [2.12] 2.83
|
||||
104 [0.] [2.08] 2.83
|
||||
105 [0.] [2.38] 2.83
|
||||
106 [0.] [1.9] 2.83
|
||||
107 [0.] [1.57] 2.83
|
||||
108 [1.] [4.19] 2.83
|
||||
Обнаружено 84.0 аномалий
|
||||
```
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## ИТОГОВЫЕ РЕЗУЛЬТАТЫ
|
||||
|
||||
### Таблица 1 - Результаты задания №1
|
||||
| | Количество скрытых слоев | Количество нейронов в скрытых слоях | Количество эпох обучения | Ошибка MSE_stop | Порог ошибки реконструкции | Значение показателя Excess | Значение показателя Approx | Количество обнаруженных аномалий |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| **AE1** | 1 | 1 | 1000 | 0.0134 | 0.56 | 2.(1) | 0.321 | |
|
||||
| **AE2** | 5 | 3 2 1 2 3 | 3000 | 0.0096 | 0.48 | 1.2(7) | 0.439 | |
|
||||
|
||||
### Таблица 2 - Результаты задания №2
|
||||
| Dataset name | Количество скрытых слоев | Количество нейронов в скрытых слоях | Количество эпох обучения | Ошибка MSE_stop | Порог ошибки реконструкции | % обнаруженных аномалий |
|
||||
|--------------|--------------------------|-------------------------------------|--------------------------|-----------------|----------------------------|-------------------------|
|
||||
| Cardio | 15 | 21 19 17 15 17 19 21 | 31000 | 0.0381 | 0.482 | 77% |
|
||||
|
||||
---
|
||||
|
||||
## ВЫВОДЫ
|
||||
|
||||
### Требования к данным для обучения
|
||||
- Обучающая выборка должна содержать только нормальные (неаномальные) образцы.
|
||||
- Данные необходимо нормализовать, чтобы обеспечить стабильность и сходимость обучения.
|
||||
- Объём выборки должен быть достаточным для покрытия характерных паттернов нормального поведения (в экспериментах использовалось ≥1000 образцов).
|
||||
### Влияние архитектуры автокодировщика
|
||||
- Простая архитектура (AE1) быстро обучается, но даёт грубую аппроксимацию границы нормальных данных, что приводит к высокому значению показателя Excess и низкой точности экстраполяции.
|
||||
- Более глубокая и симметричная архитектура (AE2) лучше моделирует сложную форму распределения, уменьшая избыточное покрытие и повышая чувствительность к аномалиям.
|
||||
### Влияние количества эпох обучения
|
||||
- Недостаточное число эпох (как у AE1) приводит к недообучению и завышенному порогу IRE.
|
||||
- Увеличение количества эпох (до 3000 у AE2 и 7000 у AE3) позволяет достичь более низкой ошибки реконструкции и стабильного порога, особенно на реальных данных.
|
||||
### Порог обнаружения аномалий
|
||||
- Порог IREth, вычисляемый как 95-й перцентиль ошибки реконструкции на обучающей выборке, обеспечивает разумный компромисс между полнотой и точностью.
|
||||
- Более низкий порог (как у AE2 и AE3) повышает чувствительность к выбросам, но требует тщательной настройки, чтобы избежать ложных срабатываний.
|
||||
### Оценка качества через метрики EDCA
|
||||
- Метрики Excess, Deficit, Coating и Extrapolation precision позволяют количественно сравнивать границы, формируемые разными моделями.
|
||||
- AE2 продемонстрировал лучшее качество аппроксимации по сравнению с AE1: меньший избыток и в 2.8 раза выше точность экстраполяции.
|
||||
- Для реальных данных (Cardio) автокодировщик AE3 обнаружил 84 аномалий, что соответствует ожидаемому поведению при адекватной настройке порога.
|
||||
|
После Ширина: | Высота: | Размер: 31 KiB |
|
После Ширина: | Высота: | Размер: 12 KiB |
|
После Ширина: | Высота: | Размер: 12 KiB |
|
После Ширина: | Высота: | Размер: 130 KiB |
|
После Ширина: | Высота: | Размер: 12 KiB |
|
После Ширина: | Высота: | Размер: 11 KiB |
|
После Ширина: | Высота: | Размер: 26 KiB |
|
После Ширина: | Высота: | Размер: 35 KiB |
|
После Ширина: | Высота: | Размер: 54 KiB |
@ -0,0 +1,528 @@
|
||||
# Лабораторная работа №3: Распознование изображений
|
||||
**Фонов А.Д., Хнытченков А.М. — А-01-22**
|
||||
## Вариант 2
|
||||
|
||||
### Цель работы
|
||||
Получить практические навыки создания, обучения и применения сверточных нейронных сетей для распознавания изображений. Познакомиться с классическими показателямикачества классификации.
|
||||
|
||||
---
|
||||
|
||||
## ЗАДАНИЕ 1:
|
||||
|
||||
### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки модули.
|
||||
```python
|
||||
# импорт модулей
|
||||
import os
|
||||
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab3')
|
||||
|
||||
from tensorflow import keras
|
||||
from tensorflow.keras import layers
|
||||
from tensorflow.keras.models import Sequential
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from sklearn.metrics import classification_report, confusion_matrix
|
||||
from sklearn.metrics import ConfusionMatrixDisplay
|
||||
```
|
||||
|
||||
### 2) Загрузили набор данных MNIST, содержащий размеченные изображения рукописных цифр.
|
||||
```python
|
||||
#загрузка датасета
|
||||
from keras.datasets import mnist
|
||||
(X_train,y_train),(X_test,y_test)=mnist.load_data()
|
||||
```
|
||||
### 3) Разбили набор данных на обучающие и тестовые данные в соотношении 60 000:10 000 элементов. Параметр random_state выбрали равным (4k – 1)=11, где k=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=1)
|
||||
#вывод размерностей
|
||||
print('ShapeofXtrain:',X_train.shape)
|
||||
print('Shapeofytrain:',y_train.shape)
|
||||
print('ShapeofXtest:',X_test.shape)
|
||||
print('Shapeofytest:',y_test.shape)
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
Shape of X train: (60000, 28, 28)
|
||||
Shape of y train: (60000,)
|
||||
Shape of X test: (10000, 28, 28)
|
||||
Shape of y test: (10000,)
|
||||
```
|
||||
|
||||
### 4) Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения сверточной нейронной сети. Входные данные принимают значения от 0 до 1, метки цифр закодированы по принципу «one-hot encoding». Вывели размерности предобработанных обучающих и тестовых массивов данных.
|
||||
|
||||
```python
|
||||
# Зададим параметры данных и модели
|
||||
num_classes = 10
|
||||
input_shape = (28, 28, 1)
|
||||
|
||||
# Приведение входных данных к диапазону [0, 1]
|
||||
X_train = X_train / 255
|
||||
X_test = X_test / 255
|
||||
|
||||
# Расширяем размерность входных данных, чтобы каждое изображение имело
|
||||
# размерность (высота, ширина, количество каналов)
|
||||
|
||||
X_train = np.expand_dims(X_train, -1)
|
||||
X_test = np.expand_dims(X_test, -1)
|
||||
print('Shape of transformed X train:', X_train.shape)
|
||||
print('Shape of transformed X test:', X_test.shape)
|
||||
|
||||
# переведем метки в one-hot
|
||||
y_train = keras.utils.to_categorical(y_train, num_classes)
|
||||
y_test = keras.utils.to_categorical(y_test, num_classes)
|
||||
print('Shape of transformed y train:', y_train.shape)
|
||||
print('Shape of transformed y test:', y_test.shape)
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
Shape of transformed X train: (60000, 28, 28, 1)
|
||||
Shape of transformed X test: (10000, 28, 28, 1)
|
||||
Shape of transformed y train: (60000, 10)
|
||||
Shape of transformed y test: (10000, 10)
|
||||
```
|
||||
|
||||
### 5) Реализовали модель сверточной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети.
|
||||
|
||||
```python
|
||||
# создаем модель
|
||||
model = Sequential()
|
||||
model.add(layers.Conv2D(32, kernel_size=(3, 3), activation="relu", input_shape=input_shape))
|
||||
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
|
||||
model.add(layers.Conv2D(64, kernel_size=(3, 3), activation="relu"))
|
||||
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
|
||||
model.add(layers.Dropout(0.5))
|
||||
model.add(layers.Flatten())
|
||||
model.add(layers.Dense(num_classes, activation="softmax"))
|
||||
|
||||
model.summary()
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
Model: "sequential"
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
│ conv2d (Conv2D) │ (None, 26, 26, 32) │ 320 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ max_pooling2d (MaxPooling2D) │ (None, 13, 13, 32) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ conv2d_1 (Conv2D) │ (None, 11, 11, 64) │ 18,496 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ max_pooling2d_1 (MaxPooling2D) │ (None, 5, 5, 64) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dropout (Dropout) │ (None, 5, 5, 64) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ flatten (Flatten) │ (None, 1600) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense (Dense) │ (None, 10) │ 16,010 │
|
||||
└─────────────────────────────────┴────────────────────────┴───────────────┘
|
||||
Total params: 34,826 (136.04 KB)
|
||||
Trainable params: 34,826 (136.04 KB)
|
||||
Non-trainable params: 0 (0.00 B)
|
||||
```
|
||||
|
||||
```python
|
||||
# компилируем и обучаем модель
|
||||
batch_size = 512
|
||||
epochs = 15
|
||||
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
|
||||
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)
|
||||
```
|
||||
|
||||
### 6) Оценили качество обучения на тестовых данных. Вывели значение функции ошибки и значение метрики качества классификации на тестовых данных.
|
||||
|
||||
```python
|
||||
# Оценка качества работы модели на тестовых данных
|
||||
scores = model.evaluate(X_test, y_test)
|
||||
print('Loss on test data:', scores[0])
|
||||
print('Accuracy on test data:', scores[1])
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 8ms/step - accuracy: 0.9884 - loss: 0.0407
|
||||
Loss on test data: 0.0380745530128479
|
||||
Accuracy on test data: 0.988099992275238
|
||||
```
|
||||
|
||||
### 7) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания.
|
||||
|
||||
```python
|
||||
# вывод двух тестовых изображений и результатов распознавания
|
||||
|
||||
for n in [3,26]:
|
||||
result = model.predict(X_test[n:n+1])
|
||||
print('NN output:', result)
|
||||
|
||||
plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))
|
||||
plt.show()
|
||||
print('Real mark: ', np.argmax(y_test[n]))
|
||||
print('NN answer: ', np.argmax(result))
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
NN output: [[9.9974984e-01 1.1346071e-09 4.2711710e-07 9.8862856e-08 1.8424662e-07
|
||||
1.0386100e-06 1.1210213e-06 4.2410937e-09 1.0569496e-04 1.4153722e-04]]
|
||||
Real mark: 0
|
||||
NN answer: 0
|
||||
```
|
||||

|
||||
```
|
||||
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 39ms/step
|
||||
NN output: [[1.6414211e-06 3.8204837e-07 6.8303052e-06 7.4757695e-06 4.4060772e-07
|
||||
4.1652779e-04 4.2315129e-05 3.0511899e-10 9.9951470e-01 9.6667927e-06]]```
|
||||

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

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

|
||||
|
||||
### 9) Загрузили, предобработали и подали на вход обученной нейронной сети собственное изображение, созданное при выполнении лабораторной работы №1. Вывели изображение и результат распознавания.
|
||||
|
||||
```python
|
||||
# загрузка собственного изображения
|
||||
from PIL import Image
|
||||
|
||||
file_data = Image.open('9.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))
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
!(9.png)
|
||||
```
|
||||
I think it's 9
|
||||
```
|
||||
|
||||
### 10) Загрузили с диска модель, сохраненную при выполнении лабораторной работы №1. Вывели информацию об архитектуре модели. Повторили для этой модели п. 6.
|
||||
|
||||
```python
|
||||
LR1_model = keras.models.load_model("best_model.keras")
|
||||
LR1_model.summary()
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
Model: "sequential_16"
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
│ dense_26 (Dense) │ (None, 100) │ 78,500 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense_27 (Dense) │ (None, 10) │ 1,010 │
|
||||
└─────────────────────────────────┴────────────────────────┴───────────────┘
|
||||
Total params: 79,512 (310.60 KB)
|
||||
Trainable params: 79,510 (310.59 KB)
|
||||
Non-trainable params: 0 (0.00 B)
|
||||
Optimizer params: 2 (12.00 B)
|
||||
```
|
||||
|
||||
```python
|
||||
# Оценка качества работы модели на тестовых данных
|
||||
scores = LR1_model.evaluate(X_test, y_test)
|
||||
print('Loss on test data:', scores[0])
|
||||
print('Accuracy on test data:', scores[1])
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
accuracy: 0.9153 - loss: 0.3012
|
||||
Loss on test data: 0.299849271774292
|
||||
Accuracy on test data: 0.9138000011444092
|
||||
```
|
||||
|
||||
### 11) Сравнили обученную модель сверточной сети и наилучшую модель полносвязной сети из лабораторной работы №1 по следующим показателям:
|
||||
|
||||
###- количество настраиваемых параметров в сети
|
||||
###- количество эпох обучения
|
||||
###- качество классификации тестовой выборки.
|
||||
|
||||
###Сделали выводы по результатам применения сверточной нейронной сети для распознавания изображений.
|
||||
Таблица 1:
|
||||
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|
||||
|-----------------|-------------------------------------|--------------------------|-----------------------------------------|
|
||||
| Сверточная | 34,826 | 15 | accuracy: 0.9869 - loss: 0.0416 |
|
||||
| Полносвязная | 79,512 | 500 | accuracy: 0.9163 - loss: 0.2937 |
|
||||
|
||||
### По результатам таблицы можно сделать вывод, чьл сверточная НС гораздо лучше справляется с задачей распознавания изображений, чем полносвязная. У нее меньше настраиваемых параметров, ей требуется меньше эпох обучения и ее показатели качества лучше, чем у полносвязной.
|
||||
|
||||
## Задание 2
|
||||
|
||||
### В новом блокноте выполнили п. 2–8 задания 1, изменив набор данных MNIST на CIFAR-10, содержащий размеченные цветные изображения объектов, разделенные на 10 классов.
|
||||
|
||||
### При этом:
|
||||
* в п.3 разбиение данных на обучающие и тестовые произвести в соотношении 50000:10000
|
||||
* после разбиения данных(между п. 3 и 4)вывести 25 изображений из обучающей выборки с подписями классов
|
||||
* в п.7 одно из тестовых изображений должно распознаваться корректно, а другое – ошибочно.
|
||||
|
||||
### 1) Загрузили набор данных CIFAR-10, содержащий цветные изображения размеченные на 10 классов: самолет, автомобиль, птица, кошка, олень, собака, лягушка, лошадь, корабль, грузовик.
|
||||
|
||||
```python
|
||||
# загрузка датасета
|
||||
from keras.datasets import cifar10
|
||||
|
||||
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
|
||||
```
|
||||
|
||||
### 2) Разбили набор данных на обучающие и тестовые данные в соотношении 50 000:10 000 элементов. Параметр random_state выбрали равным (4k – 1)=11, где k=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 = 11
|
||||
)
|
||||
# вывод размерностей
|
||||
print('Shape of X train:', X_train.shape)
|
||||
print('Shape of y train:', y_train.shape)
|
||||
print('Shape of X test:', X_test.shape)
|
||||
print('Shape of y test:', y_test.shape)
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
Shape of X train: (50000, 32, 32, 3)
|
||||
Shape of y train: (50000, 1)
|
||||
Shape of X test: (10000, 32, 32, 3)
|
||||
Shape of y test: (10000, 1)
|
||||
```
|
||||
|
||||
### Вывели 25 изображений из обучающей выборки с подписью классов.
|
||||
|
||||
```python
|
||||
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer','dog', 'frog', 'horse', 'ship', 'truck']
|
||||
|
||||
plt.figure(figsize=(10,10))
|
||||
for i in range(25):
|
||||
plt.subplot(5,5,i+1)
|
||||
plt.xticks([])
|
||||
plt.yticks([])
|
||||
plt.grid(False)
|
||||
plt.imshow(X_train[i])
|
||||
plt.xlabel(class_names[y_train[i][0]])
|
||||
plt.show()
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
|
||||

|
||||
|
||||
### 3) Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения сверточной нейронной сети. Входные данные принимают значения от 0 до 1, метки цифр закодированы по принципу «one-hot encoding». Вывели размерности предобработанных обучающих и тестовых массивов данных.
|
||||
|
||||
```python
|
||||
# Зададим параметры данных и модели
|
||||
num_classes = 10
|
||||
input_shape = (32, 32, 3)
|
||||
|
||||
# Приведение входных данных к диапазону [0, 1]
|
||||
X_train = X_train / 255
|
||||
X_test = X_test / 255
|
||||
|
||||
print('Shape of transformed X train:', X_train.shape)
|
||||
print('Shape of transformed X test:', X_test.shape)
|
||||
|
||||
# переведем метки в one-hot
|
||||
y_train = keras.utils.to_categorical(y_train, num_classes)
|
||||
y_test = keras.utils.to_categorical(y_test, num_classes)
|
||||
print('Shape of transformed y train:', y_train.shape)
|
||||
print('Shape of transformed y test:', y_test.shape)
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
Shape of transformed X train: (50000, 32, 32, 3)
|
||||
Shape of transformed X test: (10000, 32, 32, 3)
|
||||
Shape of transformed y train: (50000, 10)
|
||||
Shape of transformed y test: (10000, 10)
|
||||
```
|
||||
|
||||
### 4) Реализовали модель сверточной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети.
|
||||
|
||||
```python
|
||||
model = Sequential()
|
||||
model.add(layers.Conv2D(32, kernel_size=(3, 3), activation="relu", input_shape=input_shape))
|
||||
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
|
||||
model.add(layers.Conv2D(64, kernel_size=(3, 3), activation="relu"))
|
||||
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
|
||||
model.add(layers.Conv2D(128, kernel_size=(3, 3), activation="relu"))
|
||||
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
|
||||
model.add(layers.Flatten())
|
||||
model.add(layers.Dense(128, activation='relu'))
|
||||
model.add(layers.Dropout(0.5))
|
||||
model.add(layers.Dense(num_classes, activation="softmax"))
|
||||
model.summary()
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
Model: "sequential_1"
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
│ conv2d_2 (Conv2D) │ (None, 32, 32, 32) │ 896 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ batch_normalization │ (None, 32, 32, 32) │ 128 │
|
||||
│ (BatchNormalization) │ │ │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ conv2d_3 (Conv2D) │ (None, 32, 32, 32) │ 9,248 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ batch_normalization_1 │ (None, 32, 32, 32) │ 128 │
|
||||
│ (BatchNormalization) │ │ │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ batch_normalization_2 │ (None, 32, 32, 32) │ 128 │
|
||||
│ (BatchNormalization) │ │ │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dropout_1 (Dropout) │ (None, 32, 32, 32) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ conv2d_4 (Conv2D) │ (None, 32, 32, 64) │ 18,496 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ conv2d_5 (Conv2D) │ (None, 32, 32, 64) │ 36,928 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ max_pooling2d_2 (MaxPooling2D) │ (None, 16, 16, 64) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dropout_2 (Dropout) │ (None, 16, 16, 64) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ conv2d_6 (Conv2D) │ (None, 16, 16, 128) │ 73,856 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ max_pooling2d_3 (MaxPooling2D) │ (None, 8, 8, 128) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dropout_3 (Dropout) │ (None, 8, 8, 128) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ flatten_1 (Flatten) │ (None, 8192) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense_1 (Dense) │ (None, 128) │ 1,048,704 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dropout_4 (Dropout) │ (None, 128) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense_2 (Dense) │ (None, 10) │ 1,290 │
|
||||
└─────────────────────────────────┴────────────────────────┴───────────────┘
|
||||
Total params: 1,189,802 (4.54 MB)
|
||||
Trainable params: 1,189,610 (4.54 MB)
|
||||
Non-trainable params: 192 (768.00 B)
|
||||
```
|
||||
|
||||
```python
|
||||
# компилируем и обучаем модель
|
||||
batch_size = 64
|
||||
epochs = 50
|
||||
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
|
||||
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)
|
||||
```
|
||||
|
||||
### 5) Оценили качество обучения на тестовых данных. Вывели значение функции ошибки и значение метрики качества классификации на тестовых данных.
|
||||
|
||||
```python
|
||||
scores = model.evaluate(X_test, y_test)
|
||||
print('Loss on test data:', scores[0])
|
||||
print('Accuracy on test data:', scores[1])
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
```
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 5ms/step - accuracy: 0.7982 - loss: 0.6423
|
||||
Loss on test data: 0.6325967311859131
|
||||
Accuracy on test data: 0.8019000291824341
|
||||
```
|
||||
|
||||
### 6) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания.
|
||||
|
||||
```python
|
||||
for n in [7, 16]:
|
||||
result = model.predict(X_test[n:n+1])
|
||||
plt.imshow(X_test[n].reshape(32,32,3), cmap=plt.get_cmap('gray'))
|
||||
plt.show()
|
||||
print('Real mark: ', np.argmax(y_test[n]))
|
||||
print('NN answer: ', np.argmax(result))
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
|
||||
|
||||

|
||||
|
||||
```
|
||||
Real mark: 4
|
||||
NN answer: 0
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
Real mark: 4
|
||||
NN answer: 4
|
||||
```
|
||||
|
||||
### 7) Вывели отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки.
|
||||
|
||||
```python
|
||||
true_labels = np.argmax(y_test, axis=1)
|
||||
# предсказанные метки классов
|
||||
predicted_labels = np.argmax(model.predict(X_test), axis=1)
|
||||
# отчет о качестве классификации
|
||||
print(classification_report(true_labels, predicted_labels, target_names=class_names))
|
||||
# вычисление матрицы ошибок
|
||||
conf_matrix = confusion_matrix(true_labels, predicted_labels)
|
||||
# отрисовка матрицы ошибок в виде "тепловой карты"
|
||||
display = ConfusionMatrixDisplay(confusion_matrix=conf_matrix, display_labels=class_names)
|
||||
display.plot()
|
||||
plt.show()
|
||||
```
|
||||
|
||||
**Результат выполнения:**
|
||||
|
||||

|
||||
|
||||
### По результатам классификации датасета CIFAR-10 с использованием сверточной НС можно сделать вывод, что она достаточно хорошо справляется с поставленной задачей.
|
||||
|
||||
|
||||
|
||||
|
После Ширина: | Высота: | Размер: 54 KiB |
@ -0,0 +1,367 @@
|
||||
# Отчёт по лабораторной работе №4
|
||||
|
||||
**Фонов А.Д., Хнытченков А.М. — А-01-22**
|
||||
|
||||
---
|
||||
|
||||
## 1. В среде Google Colab создали новый блокнот (notebook). Настроили блокнот для работы с аппаратным ускорителем GPU.
|
||||
|
||||
```python
|
||||
from google.colab import drive
|
||||
drive.mount('/content/drive')
|
||||
import os
|
||||
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab4')
|
||||
|
||||
from tensorflow import keras
|
||||
from tensorflow.keras import layers
|
||||
from tensorflow.keras.models import Sequential
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
```
|
||||
|
||||
```python
|
||||
import tensorflow as tf
|
||||
device_name = tf.test.gpu_device_name()
|
||||
if device_name != '/device:GPU:0':
|
||||
raise SystemError('GPU device not found')
|
||||
print('Found GPU at: {}'.format(device_name))
|
||||
```
|
||||
|
||||
```
|
||||
Found GPU at: /device:GPU:0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Загрузили набор данных IMDb, содержащий оцифрованные отзывы на фильмы, размеченные на два класса: позитивные и негативные. При загрузке набора данных параметр seed выбрали равным (4k – 1) = 11, где k = 3 – номер бригады. Вывели размеры полученных обучающих и тестовых массивов данных.
|
||||
|
||||
```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=11,
|
||||
start_char=1,
|
||||
oov_char=2,
|
||||
index_from=index_from
|
||||
)
|
||||
|
||||
# вывод размерностей
|
||||
print('Shape of X train:', X_train.shape)
|
||||
print('Shape of y train:', y_train.shape)
|
||||
print('Shape of X test:', X_test.shape)
|
||||
print('Shape of y test:', y_test.shape)
|
||||
```
|
||||
|
||||
```
|
||||
Shape of X train: (25000,)
|
||||
Shape of y train: (25000,)
|
||||
Shape of X test: (25000,)
|
||||
Shape of y test: (25000,)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Вывели один отзыв из обучающего множества в виде списка индексовслов. Преобразовали список индексов в текст и вывели отзыв в виде текста. Вывели длину отзыва. Вывели метку класса данного отзыва и название класса (1 – Positive, 0 – Negative).
|
||||
|
||||
```python
|
||||
# создание словаря для перевода индексов в слова
|
||||
# загрузка словаря "слово:индекс"
|
||||
word_to_id = imdb.get_word_index()
|
||||
|
||||
# уточнение словаря
|
||||
word_to_id = {key:(value + index_from) for key,value in word_to_id.items()}
|
||||
word_to_id["<PAD>"] = 0
|
||||
word_to_id["<START>"] = 1
|
||||
word_to_id["<UNK>"] = 2
|
||||
word_to_id["<UNUSED>"] = 3
|
||||
|
||||
# создание обратного словаря "индекс:слово"
|
||||
id_to_word = {value:key for key,value in word_to_id.items()}
|
||||
```
|
||||
|
||||
```python
|
||||
print(X_train[39])
|
||||
print('len:',len(X_train[39]))
|
||||
```
|
||||
|
||||
```
|
||||
[1, 3206, 2, 3413, 3852, 2, 2, 73, 256, 19, 4396, 3033, 34, 488, 2, 47, 2993, 4058, 11, 63, 29, 4653, 1496, 27, 4122, 54, 4, 1334, 1914, 380, 1587, 56, 351, 18, 147, 2, 2, 15, 29, 238, 30, 4, 455, 564, 167, 1024, 2, 2, 2, 4, 2, 65, 33, 6, 2, 1062, 3861, 6, 3793, 1166, 7, 1074, 1545, 6, 171, 2, 1134, 388, 7, 3569, 2, 567, 31, 255, 37, 47, 6, 3161, 1244, 3119, 19, 6, 2, 11, 12, 2611, 120, 41, 419, 2, 17, 4, 3777, 2, 4952, 2468, 1457, 6, 2434, 4268, 23, 4, 1780, 1309, 5, 1728, 283, 8, 113, 105, 1037, 2, 285, 11, 6, 4800, 2905, 182, 5, 2, 183, 125, 19, 6, 327, 2, 7, 2, 668, 1006, 4, 478, 116, 39, 35, 321, 177, 1525, 2294, 6, 226, 176, 2, 2, 17, 2, 1220, 119, 602, 2, 2, 592, 2, 17, 2, 2, 1405, 2, 597, 503, 1468, 2, 2, 17, 2, 1947, 3702, 884, 1265, 3378, 1561, 2, 17, 2, 2, 992, 3217, 2393, 4923, 2, 17, 2, 2, 1255, 2, 2, 2, 117, 17, 6, 254, 2, 568, 2297, 5, 2, 2, 17, 1047, 2, 2186, 2, 1479, 488, 2, 4906, 627, 166, 1159, 2552, 361, 7, 2877, 2, 2, 665, 718, 2, 2, 2, 603, 4716, 127, 4, 2873, 2, 56, 11, 646, 227, 531, 26, 670, 2, 17, 6, 2, 2, 3510, 2, 17, 6, 2, 2, 2, 3014, 17, 6, 2, 668, 2, 503, 1468, 2, 19, 11, 4, 1746, 5, 2, 4778, 11, 31, 7, 41, 1273, 154, 255, 555, 6, 1156, 5, 737, 431]
|
||||
len: 274
|
||||
```
|
||||
|
||||
```python
|
||||
review_as_text = ' '.join(id_to_word[id] for id in X_train[39])
|
||||
print(review_as_text)
|
||||
print('len:',len(review_as_text))
|
||||
```
|
||||
|
||||
```
|
||||
<START> troubled <UNK> magazine photographer <UNK> <UNK> well played with considerable intensity by michael <UNK> has horrific nightmares in which he brutally murders his models when the lovely ladies start turning up dead for real <UNK> <UNK> that he might be the killer writer director william <UNK> <UNK> <UNK> the <UNK> story at a <UNK> pace builds a reasonable amount of tension delivers a few <UNK> effective moments of savage <UNK> violence one woman who has a plastic garbage bag with a <UNK> in it placed over her head <UNK> as the definite <UNK> inducing highlight puts a refreshing emphasis on the nicely drawn and engaging true to life characters further <UNK> everything in a plausible everyday world and <UNK> things off with a nice <UNK> of <UNK> female nudity the fine acting from an excellent cast helps matters a whole lot <UNK> <UNK> as <UNK> charming love interest <UNK> <UNK> james <UNK> as <UNK> <UNK> double <UNK> brother b j <UNK> <UNK> as <UNK> concerned psychiatrist dr frank curtis don <UNK> as <UNK> <UNK> gay assistant louis pamela <UNK> as <UNK> <UNK> detective <UNK> <UNK> <UNK> little as a hard <UNK> police chief and <UNK> <UNK> as sweet <UNK> model <UNK> r michael <UNK> polished cinematography makes impressive occasional use of breathtaking <UNK> <UNK> shots jack <UNK> <UNK> <UNK> score likewise does the trick <UNK> up in cool bit parts are robert <UNK> as a <UNK> <UNK> sally <UNK> as a <UNK> <UNK> <UNK> shower as a <UNK> female <UNK> b j <UNK> with in the ring and <UNK> bay in one of her standard old woman roles a solid and enjoyable picture
|
||||
len: 1584
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Вывели максимальную и минимальную длину отзыва в обучающем множестве.
|
||||
|
||||
```python
|
||||
print('MAX Len: ',len(max(X_train, key=len)))
|
||||
print('MIN Len: ',len(min(X_train, key=len)))
|
||||
```
|
||||
|
||||
```
|
||||
MAX Len: 2494
|
||||
MIN Len: 11
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Провели предобработку данных. Выбрали единую длину, к которой будутприведены все отзывы. Короткие отзывы дополнили спецсимволами, а длинные обрезали до выбранной длины.
|
||||
|
||||
```python
|
||||
#предобработка данных
|
||||
from tensorflow.keras.utils import pad_sequences
|
||||
|
||||
max_words = 500
|
||||
X_train = pad_sequences(X_train, maxlen=max_words, value=0, padding='pre', truncating='post')
|
||||
X_test = pad_sequences(X_test, maxlen=max_words, value=0, padding='pre', truncating='post')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Повторили п. 4.
|
||||
|
||||
```python
|
||||
print('MAX Len: ',len(max(X_train, key=len)))
|
||||
print('MIN Len: ',len(min(X_train, key=len)))
|
||||
```
|
||||
|
||||
```
|
||||
MAX Len: 500
|
||||
MIN Len: 500
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Повторили п. 3. Сделали вывод о том, как отзыв преобразовался после предобработки.
|
||||
|
||||
```python
|
||||
print(X_train[39])
|
||||
print('len:',len(X_train[39]))
|
||||
```
|
||||
|
||||
```
|
||||
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 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 3206 2 3413 3852 2 2 73 256 19 4396 3033
|
||||
34 488 2 47 2993 4058 11 63 29 4653 1496 27 4122 54
|
||||
4 1334 1914 380 1587 56 351 18 147 2 2 15 29 238
|
||||
30 4 455 564 167 1024 2 2 2 4 2 65 33 6
|
||||
2 1062 3861 6 3793 1166 7 1074 1545 6 171 2 1134 388
|
||||
7 3569 2 567 31 255 37 47 6 3161 1244 3119 19 6
|
||||
2 11 12 2611 120 41 419 2 17 4 3777 2 4952 2468
|
||||
1457 6 2434 4268 23 4 1780 1309 5 1728 283 8 113 105
|
||||
1037 2 285 11 6 4800 2905 182 5 2 183 125 19 6
|
||||
...
|
||||
2 2 3510 2 17 6 2 2 2 3014 17 6 2 668
|
||||
2 503 1468 2 19 11 4 1746 5 2 4778 11 31 7
|
||||
41 1273 154 255 555 6 1156 5 737 431]
|
||||
len: 500
|
||||
```
|
||||
|
||||
```python
|
||||
review_as_text = ' '.join(id_to_word[id] for id in X_train[17])
|
||||
print(review_as_text)
|
||||
print('len:',len(review_as_text))
|
||||
```
|
||||
|
||||
```
|
||||
<PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <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> when many people say it's the worst movie i've ever seen they tend to say that about virtually any movie they didn't like however of the nearly <UNK> movies i can remember ever seeing this one is one of two that i walked away from feeling personally <UNK> and angry this is my first movie review by the way and i <UNK> with imdb just to <UNK> at this movie's <UNK> i went to see it when it was in the theaters myself and my two buddies were 3 of 5 people there and after 15 years i can't remember very many <UNK> but my attitude upon leaving the theater is still <UNK> clear br br spoiler alert br br oh my where to begin fat loser left at <UNK> goes on <UNK> weekend meets blonde <UNK> who takes an interest in him takes him home to meet the family they're all <UNK> and he's the main course pathetic attempt at a dramatic escape kicks all their <UNK> and runs off with the <UNK> girlfriend they live happily ever after <UNK> firstly the gags are so bad that it took me a while to understand that they were trying to be funny and that this was a comedy the special effects what few there are look like they were done 15 years earlier the big dramatic ending was so <UNK> and poorly acted that it was nearly unbearable to watch he <UNK> out the entire <UNK> family with <UNK> <UNK> in the <UNK> that stand up tom and jerry style when they step on them i'm sure that there's much much more but i have no intention on seeing it again for a <UNK>
|
||||
len: 2741
|
||||
```
|
||||
|
||||
### После предобработки отзыв был приведён к фиксированной длине: в начале последовательности появились токены <PAD>, которые заполнили недостающие позиции. Содержательная часть отзыва сохранилась, но была сдвинута вправо, что обеспечивает единый формат данных для подачи в нейронную сеть.
|
||||
|
||||
---
|
||||
|
||||
## 8. Вывели предобработанные массивы обучающих и тестовых данных и их размерности.
|
||||
|
||||
```python
|
||||
# вывод данных
|
||||
print('X train: \n',X_train)
|
||||
print('X train: \n',X_test)
|
||||
|
||||
# вывод размерностей
|
||||
print('Shape of X train:', X_train.shape)
|
||||
print('Shape of X test:', X_test.shape)
|
||||
```
|
||||
|
||||
```
|
||||
X train:
|
||||
[[ 0 0 0 ... 7 4 2407]
|
||||
[ 0 0 0 ... 34 705 2]
|
||||
[ 0 0 0 ... 2222 8 369]
|
||||
...
|
||||
[ 0 0 0 ... 11 4 4596]
|
||||
[ 0 0 0 ... 574 42 24]
|
||||
[ 0 0 0 ... 7 13 3891]]
|
||||
X train:
|
||||
[[ 0 0 0 ... 6 52 20]
|
||||
[ 0 0 0 ... 62 30 821]
|
||||
[ 0 0 0 ... 24 3081 25]
|
||||
...
|
||||
[ 0 0 0 ... 19 666 3159]
|
||||
[ 0 0 0 ... 7 15 1716]
|
||||
[ 0 0 0 ... 1194 61 113]]
|
||||
Shape of X train: (25000, 500)
|
||||
Shape of X test: (25000, 500)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Реализовали модель рекуррентной нейронной сети, состоящей из слоев Embedding, LSTM, Dropout, Dense, и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети. Добились качества обучения по метрике accuracy не менее 0.8.
|
||||
|
||||
```python
|
||||
embed_dim = 32
|
||||
lstm_units = 64
|
||||
|
||||
model = Sequential()
|
||||
model.add(layers.Embedding(input_dim=vocabulary_size, output_dim=embed_dim, input_length=max_words, input_shape=(max_words,)))
|
||||
model.add(layers.LSTM(lstm_units))
|
||||
model.add(layers.Dropout(0.5))
|
||||
model.add(layers.Dense(1, activation='sigmoid'))
|
||||
|
||||
model.summary()
|
||||
```
|
||||
|
||||
```
|
||||
Model: "sequential_2"
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
||||
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
||||
│ embedding_2 (Embedding) │ (None, 500, 32) │ 160,000 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ lstm_2 (LSTM) │ (None, 64) │ 24,832 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dropout_2 (Dropout) │ (None, 64) │ 0 │
|
||||
├─────────────────────────────────┼────────────────────────┼───────────────┤
|
||||
│ dense_2 (Dense) │ (None, 1) │ 65 │
|
||||
└─────────────────────────────────┴────────────────────────┴───────────────┘
|
||||
Total params: 184,897 (722.25 KB)
|
||||
Trainable params: 184,897 (722.25 KB)
|
||||
Non-trainable params: 0 (0.00 B)
|
||||
```
|
||||
|
||||
```python
|
||||
# компилируем и обучаем модель
|
||||
batch_size = 64
|
||||
epochs = 3
|
||||
model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"])
|
||||
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.2)
|
||||
```
|
||||
|
||||
```
|
||||
Epoch 1/3
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 8s 20ms/step - accuracy: 0.6648 - loss: 0.5901 - val_accuracy: 0.8204 - val_loss: 0.4243
|
||||
Epoch 2/3
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 7s 22ms/step - accuracy: 0.8623 - loss: 0.3341 - val_accuracy: 0.8492 - val_loss: 0.3553
|
||||
Epoch 3/3
|
||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 6s 19ms/step - accuracy: 0.8987 - loss: 0.2659 - val_accuracy: 0.8632 - val_loss: 0.3416
|
||||
<keras.src.callbacks.history.History at 0x7f1e723806b0>
|
||||
```
|
||||
|
||||
```python
|
||||
test_loss, test_acc = model.evaluate(X_test, y_test)
|
||||
print(f"\nTest accuracy: {test_acc}")
|
||||
```
|
||||
|
||||
```
|
||||
782/782 ━━━━━━━━━━━━━━━━━━━━ 7s 9ms/step - accuracy: 0.8770 - loss: 0.3202
|
||||
|
||||
Test accuracy: 0.8710799813270569
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Оценили качество обучения на тестовых данных:
|
||||
- вывести значение метрики качества классификации на тестовых данных,
|
||||
- вывести отчет о качестве классификации тестовой выборки.
|
||||
- построить ROC-кривую по результату обработки тестовой выборки и вычислить площадь под ROC-кривой (AUC ROC).
|
||||
|
||||
```python
|
||||
#значение метрики качества классификации на тестовых данных
|
||||
print(f"\nTest accuracy: {test_acc}")
|
||||
```
|
||||
|
||||
```
|
||||
Test accuracy: 0.8710799813270569
|
||||
```
|
||||
|
||||
```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']))
|
||||
```
|
||||
|
||||
```
|
||||
782/782 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step
|
||||
precision recall f1-score support
|
||||
|
||||
Negative 0.89 0.85 0.87 12500
|
||||
Positive 0.86 0.89 0.87 12500
|
||||
|
||||
accuracy 0.87 25000
|
||||
macro avg 0.87 0.87 0.87 25000
|
||||
weighted avg 0.87 0.87 0.87 25000
|
||||
```
|
||||
|
||||
```python
|
||||
#построение ROC-кривой и AUC ROC
|
||||
from sklearn.metrics import roc_curve, auc
|
||||
|
||||
fpr, tpr, thresholds = roc_curve(y_test, y_score)
|
||||
plt.plot(fpr, tpr)
|
||||
plt.grid()
|
||||
plt.xlabel('False Positive Rate')
|
||||
plt.ylabel('True Positive Rate')
|
||||
plt.title('ROC')
|
||||
plt.show()
|
||||
print('AUC ROC:', auc(fpr, tpr))
|
||||
```
|
||||
|
||||

|
||||
|
||||
```
|
||||
AUC ROC: 0.9419218976
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. Сделали выводы по результатам применения рекуррентной нейронной сети для решения задачи определения тональности текста.
|
||||
|
||||
### В результате выполнения лабораторной работы была построена рекуррентная нейронная сеть на основе слоёв Embedding и LSTM, которая успешно справилась с задачей определения тональности текста. Модель достигла требуемого качества: accuracy выше 0.8 и AUC ROC выше 0.9, что подтверждает её способность эффективно различать позитивные и негативные отзывы. Полученные результаты демонстрируют, что рекуррентные сети хорошо подходят для анализа текстовой информации и работы с последовательностями.
|
||||
|
После Ширина: | Высота: | Размер: 31 KiB |
|
После Ширина: | Высота: | Размер: 12 KiB |
|
После Ширина: | Высота: | Размер: 12 KiB |
|
После Ширина: | Высота: | Размер: 12 KiB |
|
После Ширина: | Высота: | Размер: 11 KiB |