Сравнить коммиты
4 Коммитов
| Автор | SHA1 | Дата |
|---|---|---|
|
|
964549a094 | 3 недель назад |
|
|
b344e76a21 | 2 месяцев назад |
|
|
047d249b1f | 2 месяцев назад |
|
|
339fe963d0 | 3 месяцев назад |
@ -1,4 +1,11 @@
|
|||||||
* [Задание](IS_Lab01_2023.pdf)
|
## Лабораторныа работа №1
|
||||||
|
|
||||||
|
## Архитектура и обучение глубоких нейронных сетей
|
||||||
|
|
||||||
|
* [Задание](IS_Lab01_2023.pdf)
|
||||||
|
|
||||||
* [Методические указания](IS_Lab01_Metod_2023.pdf)
|
* [Методические указания](IS_Lab01_Metod_2023.pdf)
|
||||||
|
|
||||||
* <a href="https://youtube.com/playlist?list=PLfdZ2TeaMzfzlpZ60rbaYU_epH5XPNbWU" target="_blank"><s>Какие нейроны, что вообще происходит?</s> Рекомендуется к просмотру для понимания (4 видео)</a>
|
* <a href="https://youtube.com/playlist?list=PLfdZ2TeaMzfzlpZ60rbaYU_epH5XPNbWU" target="_blank"><s>Какие нейроны, что вообще происходит?</s> Рекомендуется к просмотру для понимания (4 видео)</a>
|
||||||
|
|
||||||
* <a href="https://www.youtube.com/watch?v=FwFduRA_L6Q" target="_blank">Почувствуйте себя пионером нейронных сетей в области распознавания образов</a>
|
* <a href="https://www.youtube.com/watch?v=FwFduRA_L6Q" target="_blank">Почувствуйте себя пионером нейронных сетей в области распознавания образов</a>
|
||||||
|
До Ширина: | Высота: | Размер: 6.9 KiB |
|
До Ширина: | Высота: | Размер: 168 B |
|
До Ширина: | Высота: | Размер: 240 B |
|
До Ширина: | Высота: | Размер: 6.4 KiB |
|
До Ширина: | Высота: | Размер: 6.6 KiB |
|
До Ширина: | Высота: | Размер: 6.7 KiB |
|
До Ширина: | Высота: | Размер: 6.8 KiB |
|
До Ширина: | Высота: | Размер: 7.0 KiB |
|
До Ширина: | Высота: | Размер: 25 KiB |
|
До Ширина: | Высота: | Размер: 7.1 KiB |
|
До Ширина: | Высота: | Размер: 258 B |
|
До Ширина: | Высота: | Размер: 317 B |
|
До Ширина: | Высота: | Размер: 6.3 KiB |
@ -1,223 +0,0 @@
|
|||||||
# Отчет по лабораторной работе 1
|
|
||||||
## Ли Тэ Хо, Синявский Степан А-02-22
|
|
||||||
## Бригада 3
|
|
||||||
### Пункт 1
|
|
||||||
В среде GoogleColab создали новый блокнот(notebook).Импортировали необходимые для работы библиотеки и модули.
|
|
||||||
```python
|
|
||||||
from google.colab import drive
|
|
||||||
drive.mount('/content/drive')
|
|
||||||
import os
|
|
||||||
os.chdir('/content/drive/MyDrive/Colab Notebooks')
|
|
||||||
from tensorflow import keras
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import numpy as np
|
|
||||||
import sklearn
|
|
||||||
```
|
|
||||||
### Пункт 2
|
|
||||||
Загрузили набор данных MNIST, содержащий размеченные изображения рукописных цифр.
|
|
||||||
```python
|
|
||||||
from keras.datasets import mnist
|
|
||||||
```
|
|
||||||
### Пункт 3
|
|
||||||
Разбили набор данных на обучающие и тестовые данные в соотношении 60000:10000 элементов. При разбиении параметр random_state выбрали 11.
|
|
||||||
Вывели размерности полученных обучающих и тестовых массивов данных.
|
|
||||||
```python
|
|
||||||
(X_train,y_train),(X_test,y_test)=mnist.load_data()
|
|
||||||
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=11)
|
|
||||||
#вывод размерностей
|
|
||||||
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 элемента обучающих данных
|
|
||||||
```python
|
|
||||||
#вывод изображения
|
|
||||||
plt.imshow(X_train[1],cmap=plt.get_cmap('gray'))
|
|
||||||
plt.show()
|
|
||||||
print(y_train[1])
|
|
||||||
|
|
||||||
plt.imshow(X_train[2],cmap=plt.get_cmap('gray'))
|
|
||||||
plt.show()
|
|
||||||
print(y_train[2])
|
|
||||||
|
|
||||||
plt.imshow(X_train[3],cmap=plt.get_cmap('gray'))
|
|
||||||
plt.show()
|
|
||||||
print(y_train[3])
|
|
||||||
|
|
||||||
plt.imshow(X_train[4],cmap=plt.get_cmap('gray'))
|
|
||||||
plt.show()
|
|
||||||
print(y_train[4])
|
|
||||||
```
|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
### Пункт 5
|
|
||||||
Провели предобработку данных: привели обучающие и тестовые данные к формату, пригодному для обучения нейронной сети.
|
|
||||||
Входные данные должны принимать значения от 0 до 1, метки цифрдолжны быть закодированы по принципу «one-hotencoding».Вывели размерности предобработанных обучающих и тестовых массивов данных.
|
|
||||||
```python
|
|
||||||
#развернем каждое изображение 8*228 в вектор 784
|
|
||||||
num_pixels=X_train.shape[1]*X_train.shape[2]
|
|
||||||
X_train=X_train.reshape(X_train.shape[0],num_pixels) / 255
|
|
||||||
X_test=X_test.reshape(X_test.shape[0],num_pixels) / 255
|
|
||||||
print('Shape of transformed X train:',X_train.shape)
|
|
||||||
```
|
|
||||||
Shape of transformed X train: (60000, 784)
|
|
||||||
```python
|
|
||||||
#переведем метки в one-hot
|
|
||||||
import keras.utils
|
|
||||||
y_train=keras.utils.to_categorical(y_train)
|
|
||||||
y_test=keras.utils.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
|
|
||||||
Реализовали модель однослойной нейронной сети и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети. Вывели график функции ошибки на обучающих и валидационных данных по эпохам.
|
|
||||||
```python
|
|
||||||
from keras.models import Sequential
|
|
||||||
from keras.layers import Dense
|
|
||||||
|
|
||||||
model_1 = Sequential()
|
|
||||||
model_1.add(Dense(units=num_classes, input_dim=num_pixels, activation='softmax'))
|
|
||||||
model_1.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
|
|
||||||
# вывод информации об архитектуре модели
|
|
||||||
print(model_1.summary())
|
|
||||||
Model: "sequential"
|
|
||||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
|
|
||||||
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
|
|
||||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
|
|
||||||
│ dense (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)
|
|
||||||
None
|
|
||||||
|
|
||||||
# Обучаем модель
|
|
||||||
H = model_1.fit(X_train, y_train, validation_split=0.1, epochs=50)
|
|
||||||
|
|
||||||
# вывод графика ошибки по эпохам
|
|
||||||
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()
|
|
||||||
```
|
|
||||||

|
|
||||||
```python
|
|
||||||
# Оценка качества работы модели на тестовых данных
|
|
||||||
scores = model_1.evaluate(X_test, y_test)
|
|
||||||
print('Loss on test data:', scores[0])
|
|
||||||
print('Accuracy on test data:', scores[1])
|
|
||||||
```
|
|
||||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 3s 8ms/step - accuracy: 0.9219 - loss: 0.2787
|
|
||||||
Loss on test data: 0.2803967595100403
|
|
||||||
Accuracy on test data: 0.9203000068664551
|
|
||||||
|
|
||||||
### Таблица с результатами тестирования нейросетевых моделей
|
|
||||||
|
|
||||||
| Количество скрытых слоёв | Количество нейронов в первом скрытом слое | Количество нейронов во втором скрытом слое | Значение метрики качества классификации |
|
|
||||||
|---------------------------|-------------------------------------------|--------------------------------------------|-----------------------------------------|
|
|
||||||
| 0 | - | - | 0.9203000068664551 |
|
|
||||||
| 1 | 100 | - | 0.9416999816894531 |
|
|
||||||
| | 300 | - | 0.9345999956130981 |
|
|
||||||
| | 500 | - | 0.9279000163078308 |
|
|
||||||
| 2 | (наилучшее из п.8) | 50 | 0.9402999877929688 |
|
|
||||||
| | (наилучшее из п.8) | 100 | 0.9420999884605408 |
|
|
||||||
|
|
||||||
По полученным результатам можно сказать, что лучшая архитектура НН это - с двумя скрытыми слоями, с 100 нейронами на первом скрытом слое, и со 100 на втором скрытом слое.
|
|
||||||
|
|
||||||
### Пункт 11
|
|
||||||
Сохранили наилучшую нейронную сеть на диск.
|
|
||||||
```python
|
|
||||||
model_5.save('best_model.keras')
|
|
||||||
```
|
|
||||||
|
|
||||||
### Пункт 12
|
|
||||||
Вывели результаты тестирования модели
|
|
||||||
```python
|
|
||||||
# вывод тестового изображения и результата распознавания 1
|
|
||||||
n = 123
|
|
||||||
result = model_5.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)))
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
Real mark: 0
|
|
||||||
NN answer: 0
|
|
||||||
|
|
||||||
### Пункт 13
|
|
||||||
Создали собственные изображения чисел
|
|
||||||

|
|
||||||

|
|
||||||
Сохранили их и подали на вход для распознования
|
|
||||||
```python
|
|
||||||
# загрузка собственного изображения
|
|
||||||
from PIL import Image
|
|
||||||
file_data = Image.open('5.png')
|
|
||||||
file_data = file_data.convert('L') # перевод в градации серого
|
|
||||||
test_img = np.array(file_data)
|
|
||||||
|
|
||||||
# вывод собственного изображения
|
|
||||||
plt.imshow(test_img, cmap=plt.get_cmap('gray'))
|
|
||||||
plt.show()
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
```python
|
|
||||||
# предобработка
|
|
||||||
test_img = test_img / 255
|
|
||||||
test_img = test_img.reshape(1, num_pixels)
|
|
||||||
# распознавание
|
|
||||||
result = model_5.predict(test_img)
|
|
||||||
print('I think it\'s ', np.argmax(result))
|
|
||||||
```
|
|
||||||
I think it's 5
|
|
||||||
|
|
||||||
### Пункт 14
|
|
||||||
Создали копию нарисованных чисел и повернем их на 90 градусов. Протестируем работу нейронной сети.
|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
```python
|
|
||||||
file_data = Image.open('2_1.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_5.predict(test_img)
|
|
||||||
print('I think it\'s ', np.argmax(result))
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
I think it's 4
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
I think it's 7
|
|
||||||
|
|
||||||
Нейросеть неправильно определила повернутые изображения цифр. Она не определяет саму цифру, для нее ориентация не имеет значения, 1 это вертикальная черта, а повернутая 1 это просто горизонтальная черта.
|
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
## Лабораторныа работа №2
|
||||||
|
|
||||||
|
## Обнаружение аномалий
|
||||||
|
|
||||||
|
* [Задание](IS_Lab02_2023.pdf)
|
||||||
|
|
||||||
|
* [Методические указания](IS_Lab02_Metod_2023.pdf)
|
||||||
|
|
||||||
|
* [Наборы данных](data)
|
||||||
|
|
||||||
|
* [Библиотека для автокодировщиков](lab02_lib.py)
|
||||||
@ -1,4 +0,0 @@
|
|||||||
2.72 2.72
|
|
||||||
3.28 2.71
|
|
||||||
2.70 3.29
|
|
||||||
3.30 3.27
|
|
||||||
|
До Ширина: | Высота: | Размер: 41 KiB |
|
До Ширина: | Высота: | Размер: 21 KiB |
|
До Ширина: | Высота: | Размер: 30 KiB |
|
До Ширина: | Высота: | Размер: 27 KiB |
|
До Ширина: | Высота: | Размер: 22 KiB |
|
До Ширина: | Высота: | Размер: 68 KiB |
|
До Ширина: | Высота: | Размер: 101 KiB |
|
До Ширина: | Высота: | Размер: 32 KiB |
|
До Ширина: | Высота: | Размер: 77 KiB |
|
До Ширина: | Высота: | Размер: 87 KiB |
|
До Ширина: | Высота: | Размер: 30 KiB |
|
До Ширина: | Высота: | Размер: 61 KiB |
|
До Ширина: | Высота: | Размер: 71 KiB |
|
До Ширина: | Высота: | Размер: 84 KiB |
|
До Ширина: | Высота: | Размер: 94 KiB |
|
До Ширина: | Высота: | Размер: 51 KiB |
|
До Ширина: | Высота: | Размер: 51 KiB |
@ -1 +0,0 @@
|
|||||||
2.0
|
|
||||||
@ -1 +0,0 @@
|
|||||||
0.39
|
|
||||||
@ -1 +0,0 @@
|
|||||||
1.84
|
|
||||||
@ -1 +0,0 @@
|
|||||||
1.4
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
------------Оценка качества AE2 С ПОМОЩЬЮ НОВЫХ МЕТРИК------------
|
|
||||||
Approx = 0.8076923076923076
|
|
||||||
Excess = 0.23809523809523808
|
|
||||||
Deficit = 0.0
|
|
||||||
Coating = 1.0
|
|
||||||
@ -1,417 +0,0 @@
|
|||||||
# Отчёт по лабораторной работе №2
|
|
||||||
|
|
||||||
**Ли Тэ Хо, Синявский Степан — А-02-22**
|
|
||||||
|
|
||||||
---
|
|
||||||
## Задание 1
|
|
||||||
|
|
||||||
### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# импорт модулей
|
|
||||||
import os
|
|
||||||
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab2')
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import lab02_lib as lib
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2) Сгенерировали индивидуальный набор двумерных данных в пространстве признаков с координатами центра 3, 3), где 3 – номер бригады. Вывели полученные данные на рисунок и в консоль.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# генерация датасета
|
|
||||||
data = lib.datagen(3, 3, 1000, 2)
|
|
||||||
|
|
||||||
# вывод данных и размерности
|
|
||||||
print('Исходные данные:')
|
|
||||||
print(data)
|
|
||||||
print('Размерность данных:')
|
|
||||||
print(data.shape)
|
|
||||||
```
|
|
||||||

|
|
||||||
```
|
|
||||||
Исходные данные:
|
|
||||||
[[3.01497028 2.9872143 ]
|
|
||||||
[2.95216438 2.93247766]
|
|
||||||
[2.9281138 2.80160426]
|
|
||||||
...
|
|
||||||
[3.10976374 2.91251936]
|
|
||||||
[3.16677716 2.95397464]
|
|
||||||
[3.00503898 3.17135038]]
|
|
||||||
Размерность данных:
|
|
||||||
(1000, 2)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3) Создали и обучили автокодировщик AE1 простой архитектуры, выбрав небольшое количество эпох обучения. Зафиксировали в таблице вида табл.1 количество скрытых слоёв и нейронов в них
|
|
||||||
|
|
||||||
```python
|
|
||||||
# обучение AE1
|
|
||||||
patience = 300
|
|
||||||
ae1_trained, IRE1, IREth1 = lib.create_fit_save_ae(data,'out/AE1.h5','out/AE1_ire_th.txt',
|
|
||||||
1000, True, patience)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4) Зафиксировали ошибку MSE, на которой обучение завершилось. Построили график ошибки реконструкции обучающей выборки. Зафиксировали порог ошибки реконструкции – порог обнаружения аномалий.
|
|
||||||
|
|
||||||
Ошибка MSE_AE1 = 1.4393
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Построение графика ошибки реконструкции
|
|
||||||
lib.ire_plot('training', IRE1, IREth1, 'AE1')
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
### 5) Создали и обучили второй автокодировщик AE2 с усложненной архитектурой, задав большее количество эпох обучения
|
|
||||||
|
|
||||||
```python
|
|
||||||
# обучение AE2
|
|
||||||
ae2_trained, IRE2, IREth2 = lib.create_fit_save_ae(data,'out/AE2.h5','out/AE2_ire_th.txt',
|
|
||||||
3000, True, patience)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6) Зафиксировали ошибку MSE, на которой обучение завершилось. Построили график ошибки реконструкции обучающей выборки. Зафиксировали второй порог ошибки реконструкции – порог обнаружения аномалий.
|
|
||||||
|
|
||||||
Ошибка MSE_AE2 = 0.0102
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Построение графика ошибки реконструкции
|
|
||||||
lib.ire_plot('training', IRE2, IREth2, 'AE2')
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
### 7) Рассчитали характеристики качества обучения EDCA для AE1 и AE2. Визуализировали и сравнили области пространства признаков, распознаваемые автокодировщиками AE1 и AE2. Сделали вывод о пригодности AE1 и AE2 для качественного обнаружения аномалий.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# построение областей покрытия и границ классов
|
|
||||||
# расчет характеристик качества обучения
|
|
||||||
numb_square = 20
|
|
||||||
xx, yy, Z1 = lib.square_calc(numb_square, data, ae1_trained, IREth1, '1', True)
|
|
||||||
```
|
|
||||||

|
|
||||||
```
|
|
||||||
amount: 21
|
|
||||||
amount_ae: 226
|
|
||||||
```
|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
```
|
|
||||||
Оценка качества AE1
|
|
||||||
IDEAL = 0. Excess: 9.761904761904763
|
|
||||||
IDEAL = 0. Deficit: 0.0
|
|
||||||
IDEAL = 1. Coating: 1.0
|
|
||||||
summa: 1.0
|
|
||||||
IDEAL = 1. Extrapolation precision (Approx): 0.09292035398230088
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
```python
|
|
||||||
# построение областей покрытия и границ классов
|
|
||||||
# расчет характеристик качества обучения
|
|
||||||
numb_square = 20
|
|
||||||
xx, yy, Z2 = lib.square_calc(numb_square, data, ae2_trained, IREth2, '2', True)
|
|
||||||
```
|
|
||||||

|
|
||||||
```
|
|
||||||
amount: 21
|
|
||||||
amount_ae: 26
|
|
||||||
```
|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
```
|
|
||||||
Оценка качества AE2
|
|
||||||
IDEAL = 0. Excess: 0.23809523809523808
|
|
||||||
IDEAL = 0. Deficit: 0.0
|
|
||||||
IDEAL = 1. Coating: 1.0
|
|
||||||
summa: 1.0
|
|
||||||
IDEAL = 1. Extrapolation precision (Approx): 0.8076923076923076
|
|
||||||
```
|
|
||||||
|
|
||||||
```python
|
|
||||||
# сравнение характеристик качества обучения и областей аппроксимации
|
|
||||||
lib.plot2in1(data, xx, yy, Z1, Z2)
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
### 8) Если автокодировщик AE2 недостаточно точно аппроксимирует область обучающих данных, то подобрать подходящие параметры автокодировщика и повторить шаги (6) – (8).
|
|
||||||
|
|
||||||
Полученные показатели EDCA для автокодировщика AE2 нас устраивают.
|
|
||||||
|
|
||||||
### 9) Изучили сохраненный набор данных и пространство признаков. Создали тестовую выборку, состоящую, как минимум, из 4ёх элементов, не входящих в обучающую выборку. Элементы должны быть такими, чтобы AE1 распознавал их как норму, а AE2 детектировал как аномалии.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# загрузка тестового набора
|
|
||||||
data_test = np.loadtxt('data_test.txt', dtype=float)
|
|
||||||
print(data_test)
|
|
||||||
```
|
|
||||||
```
|
|
||||||
[[2.72 2.72]
|
|
||||||
[3.28 2.71]
|
|
||||||
[2.7 3.29]
|
|
||||||
[3.3 3.27]]
|
|
||||||
```
|
|
||||||
|
|
||||||
### 10) Применили обученные автокодировщики AE1 и AE2 к тестовым данным и вывели значения ошибки реконструкции для каждого элемента тестовой выборки относительно порога на график и в консоль.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# тестирование АE1
|
|
||||||
predicted_labels1, ire1 = lib.predict_ae(ae1_trained, data_test, IREth1)
|
|
||||||
```
|
|
||||||
|
|
||||||
```python
|
|
||||||
# тестирование АE1
|
|
||||||
lib.anomaly_detection_ae(predicted_labels1, ire1, IREth1)
|
|
||||||
lib.ire_plot('test', ire1, IREth1, 'AE1')
|
|
||||||
```
|
|
||||||
```
|
|
||||||
i Labels IRE IREth
|
|
||||||
0 [0.] [1.33] 2.0
|
|
||||||
1 [0.] [1.59] 2.0
|
|
||||||
2 [0.] [1.87] 2.0
|
|
||||||
3 [1.] [2.07] 2.0
|
|
||||||
Обнаружено 1.0 аномалий
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
```python
|
|
||||||
# тестирование АE2
|
|
||||||
predicted_labels2, ire2 = lib.predict_ae(ae2_trained, data_test, IREth2)
|
|
||||||
```
|
|
||||||
|
|
||||||
```python
|
|
||||||
# тестирование АE2
|
|
||||||
lib.anomaly_detection_ae(predicted_labels2, ire2, IREth2)
|
|
||||||
lib.ire_plot('test', ire2, IREth2, 'AE2')
|
|
||||||
```
|
|
||||||
```
|
|
||||||
i Labels IRE IREth
|
|
||||||
0 [1.] [0.39] 0.38
|
|
||||||
1 [1.] [0.4] 0.38
|
|
||||||
2 [1.] [0.42] 0.38
|
|
||||||
3 [1.] [0.41] 0.38
|
|
||||||
Обнаружено 4.0 аномалий
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
### 11) Визуализировали элементы обучающей и тестовой выборки в областях пространства признаков, распознаваемых автокодировщиками AE1 и AE2.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# построение областей аппроксимации и точек тестового набора
|
|
||||||
lib.plot2in1_anomaly(data, xx, yy, Z1, Z2, data_test)
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
### 12) Результаты исследования занесли в таблицу:
|
|
||||||
Табл. 1 Результаты задания №1
|
|
||||||
|
|
||||||
| | Количество<br>скрытых слоев | Количество<br>нейронов в скрытых слоях | Количество<br>эпох обучения | Ошибка<br>MSE_stop | Порог ошибки<br>реконструкции | Значение показателя<br>Excess | Значение показателя<br>Approx | Количество обнаруженных<br>аномалий |
|
|
||||||
|-----:|------------------------------|----------------------------------------|-----------------------------|--------------------|-------------------------------|-------------------------------|--------------------------------|-------------------------------------|
|
|
||||||
| AE1 | 1 | 1 | 1000 | 1.4393 | 2 | 9.76 | 0.0929 | 1 |
|
|
||||||
| AE2 | 5 | 3,2,1,2,3 | 3000 | 0.0108 | 0.38 | 0.238 | 0.80 | 4 |
|
|
||||||
|
|
||||||
### 13) Сделаем выводы о требованиях к:
|
|
||||||
- данным для обучения,
|
|
||||||
- архитектуре автокодировщика,
|
|
||||||
- количеству эпох обучения,
|
|
||||||
- ошибке MSE_stop, приемлемой для останова обучения,
|
|
||||||
- ошибке реконструкции обучающей выборки (порогу обнаружения
|
|
||||||
аномалий),
|
|
||||||
- характеристикам качества обучения EDCA одноклассового
|
|
||||||
классификатора для качественного обнаружения аномалий в данных.
|
|
||||||
|
|
||||||
1) Для качественного обнаружения аномалий обучающая выборка должна содержать только нормальные данные и быть однородной.
|
|
||||||
2) Архитектура должна быть достаточно сложной, чтобы адекватно аппроксимировать форму области нормальных данных. Слишком простые сети (как AE1) даже на тех же данных дают огромное превышение области и практически не описывают реальную структуру выборки.
|
|
||||||
3) Количество эпох для качественного обучения сети должно быть около 3000, это обеспечит более качественную реконструкцию.
|
|
||||||
4) Значение MSE_stop должно быть умеренным — не слишком большим, чтобы избежать недообучения, и не слишком маленьким, чтобы избежать переобучения. AE2 с MSE_stop ≈ 0.01 показывает оптимальное качество.
|
|
||||||
5) Порог должен быть максимально низким и стабильным, чтобы корректно отделять нормальные объекты от аномальных. Значение порога в районе 0.38.
|
|
||||||
6) Значение Excess не больше 0.4, значение Deficit равное 0, значение Coating равное 1, значение Approx не меньше 0.75
|
|
||||||
|
|
||||||
## Задание 2
|
|
||||||
|
|
||||||
### 1) Изучить описание своего набора реальных данных, что он из себя представляет
|
|
||||||
|
|
||||||
Бригада 3 => набор данных Cardio. Это реальный набор данных, который состоит из измерений частоты сердечных сокращений плода и
|
|
||||||
сокращений матки на кардиотокограммах, классифицированных экспертами
|
|
||||||
акушерами. Исходный набор данных предназначен для классификации. В нем
|
|
||||||
представлено 3 класса: «норма», «подозрение» и «патология». Для обнаружения
|
|
||||||
аномалий класс «норма» принимается за норму, класс «патология» принимается за
|
|
||||||
аномалии, а класс «подозрение» был отброшен.
|
|
||||||
|
|
||||||
| Количество<br>признаков | Количество<br>примеров | Количество<br>нормальных примеров | Количество<br>аномальных примеров |
|
|
||||||
|-------------------------:|-----------------------:|----------------------------------:|-----------------------------------:|
|
|
||||||
| 21 | 1764 | 1655 | 109 |
|
|
||||||
|
|
||||||
### 2) Загрузить многомерную обучающую выборку реальных данных Cardio.txt.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# загрузка обчуающей выборки
|
|
||||||
train = np.loadtxt('cardio_train.txt', dtype=float)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3) Вывести полученные данные и их размерность в консоли.
|
|
||||||
|
|
||||||
```python
|
|
||||||
print('train:\n', train)
|
|
||||||
print('train.shape:', np.shape(train))
|
|
||||||
```
|
|
||||||
```
|
|
||||||
train:
|
|
||||||
[[ 0.00491231 0.69319077 -0.20364049 ... 0.23149795 -0.28978574
|
|
||||||
-0.49329397]
|
|
||||||
[ 0.11072935 -0.07990259 -0.20364049 ... 0.09356344 -0.25638541
|
|
||||||
-0.49329397]
|
|
||||||
[ 0.21654639 -0.27244466 -0.20364049 ... 0.02459619 -0.25638541
|
|
||||||
1.1400175 ]
|
|
||||||
...
|
|
||||||
[ 0.85144861 -0.91998844 -0.20364049 ... 0.57633422 -0.65718941
|
|
||||||
1.1400175 ]
|
|
||||||
[ 0.85144861 -0.91998844 -0.20364049 ... 0.57633422 -0.62378908
|
|
||||||
-0.49329397]
|
|
||||||
[ 1.0630827 -0.51148142 -0.16958144 ... 0.57633422 -0.65718941
|
|
||||||
-0.49329397]]
|
|
||||||
train.shape: (1654, 21)
|
|
||||||
```
|
|
||||||
### 4) Создать и обучить автокодировщик с подходящей для данных архитектурой. Выбрать необходимое количество эпох обучения.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# **kwargs
|
|
||||||
# verbose_every_n_epochs - отображать прогресс каждые N эпох (по умолчанию - 1000)
|
|
||||||
# early_stopping_delta - дельта для ранней остановки (по умолчанию - 0.01)
|
|
||||||
# early_stopping_value = значение для ранней остановки (по умолчанию - 0.0001)
|
|
||||||
|
|
||||||
from time import time
|
|
||||||
|
|
||||||
patience = 4000
|
|
||||||
start = time()
|
|
||||||
ae3_v1_trained, IRE3_v1, IREth3_v1 = lib.create_fit_save_ae(train,'out/AE3_V1.h5','out/AE3_v1_ire_th.txt',
|
|
||||||
100000, False, patience, verbose_every_n_epochs = 1000, early_stopping_delta = 0.001)
|
|
||||||
print("Время на обучение: ", time() - start)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5) Зафиксировать ошибку MSE, на которой обучение завершилось. Построить график ошибки реконструкции обучающей выборки. Зафиксировать порог ошибки реконструкции – порог обнаружения аномалий.
|
|
||||||
|
|
||||||
Скрытых слоев 7, нейроны: 48->36->24->12->24->36->48
|
|
||||||
|
|
||||||
Ошибка MSE_AE3_v1 = 0.0073
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Построение графика ошибки реконструкции
|
|
||||||
lib.ire_plot('training', IRE3_v1, IREth3_v1, 'AE3_v1')
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
### 6) Сделать вывод о пригодности обученного автокодировщика для качественного обнаружения аномалий. Если порог ошибки реконструкции слишком велик, то подобрать подходящие параметры автокодировщика и повторить шаги (4) – (6).
|
|
||||||
|
|
||||||
```python
|
|
||||||
# **kwargs
|
|
||||||
# verbose_every_n_epochs - отображать прогресс каждые N эпох (по умолчанию - 1000)
|
|
||||||
# early_stopping_delta - дельта для ранней остановки (по умолчанию - 0.01)
|
|
||||||
# early_stopping_value = значение для ранней остановки (по умолчанию - 0.0001)
|
|
||||||
|
|
||||||
from time import time
|
|
||||||
|
|
||||||
patience = 4000
|
|
||||||
start = time()
|
|
||||||
ae3_v2_trained, IRE3_v2, IREth3_v2 = lib.create_fit_save_ae(train,'out/AE3_V2.h5','out/AE3_v2_ire_th.txt',
|
|
||||||
100000, False, patience, early_stopping_delta = 0.001, verbose_every_n_epochs = 1000)
|
|
||||||
print("Время на обучение: ", time() - start)
|
|
||||||
```
|
|
||||||
|
|
||||||
Скрытых слоев 11, нейроны: 48->40->36->30->24->12->24->30->36->40->48
|
|
||||||
|
|
||||||
Ошибка MSE_AE3_v1 = 0.0065
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Построение графика ошибки реконструкции
|
|
||||||
lib.ire_plot('training', IRE3_v2, IREth3_v2, 'AE3_v2')
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
### 7) Изучить и загрузить тестовую выборку Cardio.txt.
|
|
||||||
|
|
||||||
```python
|
|
||||||
#загрузка тестовой выборки
|
|
||||||
test = np.loadtxt('cardio_test.txt', dtype=float)
|
|
||||||
print('\n test:\n', test)
|
|
||||||
print('test.shape:', np.shape(test))
|
|
||||||
```
|
|
||||||
```
|
|
||||||
test:
|
|
||||||
[[ 0.21654639 -0.65465178 -0.20364049 ... -2.0444214 4.987467
|
|
||||||
-0.49329397]
|
|
||||||
[ 0.21654639 -0.5653379 -0.20364049 ... -2.1133887 6.490482
|
|
||||||
-0.49329397]
|
|
||||||
[-0.3125388 -0.91998844 6.9653692 ... -1.1478471 3.9186563
|
|
||||||
-0.49329397]
|
|
||||||
...
|
|
||||||
[-0.41835583 -0.91998844 -0.16463485 ... -1.4926834 0.24461959
|
|
||||||
-0.49329397]
|
|
||||||
[-0.41835583 -0.91998844 -0.15093411 ... -1.4237162 0.14441859
|
|
||||||
-0.49329397]
|
|
||||||
[-0.41835583 -0.91998844 -0.20364049 ... -1.2857816 3.5846529
|
|
||||||
-0.49329397]]
|
|
||||||
test.shape: (109, 21)
|
|
||||||
```
|
|
||||||
### 8) Подать тестовую выборку на вход обученного автокодировщика для обнаружения аномалий. Вывести график ошибки реконструкции элементов тестовой выборки относительно порога.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# тестирование АE3
|
|
||||||
predicted_labels3_v1, ire3_v1 = lib.predict_ae(ae3_v1_trained, test, IREth3_v1)
|
|
||||||
```
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Построение графика ошибки реконструкции
|
|
||||||
lib.ire_plot('test', ire3_v1, IREth3_v1, 'AE3_v1')
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
```python
|
|
||||||
# тестирование АE3
|
|
||||||
predicted_labels3_v2, ire3_v2 = lib.predict_ae(ae3_v2_trained, test, IREth3_v2)
|
|
||||||
```
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Построение графика ошибки реконструкции
|
|
||||||
lib.ire_plot('test', ire3_v2, IREth3_v2, 'AE3_v2')
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
```python
|
|
||||||
# тестирование АE2
|
|
||||||
lib.anomaly_detection_ae(predicted_labels3_v1, IRE3_v1, IREth3_v1)
|
|
||||||
```
|
|
||||||
|
|
||||||
Для AE3_v1 точность составляет 63%
|
|
||||||
|
|
||||||
```python
|
|
||||||
# тестирование АE2
|
|
||||||
lib.anomaly_detection_ae(predicted_labels3_v2, IRE3_v2, IREth3_v2)
|
|
||||||
```
|
|
||||||
|
|
||||||
Для AE3_v2 точность составляет 82%
|
|
||||||
|
|
||||||
### 9) Если результаты обнаружения аномалий не удовлетворительные (обнаружено менее 70% аномалий), то подобрать подходящие параметры автокодировщика и повторить шаги (4) – (9).
|
|
||||||
|
|
||||||
Результаты обнаружения аномалий удовлетворены.
|
|
||||||
|
|
||||||
### 10) Параметры наилучшего автокодировщика и результаты обнаружения аномалий занести в таблицу:
|
|
||||||
Табл. 2 Результаты задания №2
|
|
||||||
|
|
||||||
| Dataset name | Количество<br>скрытых слоев | Количество<br>нейронов в скрытых слоях | Количество<br>эпох обучения | Ошибка<br>MSE_stop | Порог ошибки<br>реконструкции | % обнаруженных<br>аномалий |
|
|
||||||
|:-------------|:-----------------------------|:----------------------------------------|:-----------------------------|:-------------------|:-------------------------------|:---------------------------|
|
|
||||||
| Cardio | 11 | 48, 40, 36, 30, 24, 12, 24, 30, 36, 40, 48 | 100000 | 0.0065 | 1.4 | 82% |
|
|
||||||
|
|
||||||
### 11) Сделать выводы о требованиях к:
|
|
||||||
- данным для обучения,
|
|
||||||
- архитектуре автокодировщика,
|
|
||||||
- количеству эпох обучения,
|
|
||||||
- ошибке MSE_stop, приемлемой для останова обучения,
|
|
||||||
- ошибке реконструкции обучающей выборки (порогу обнаружения
|
|
||||||
аномалий) для качественного обнаружения аномалий в случае, когда размерность пространства признаков высока.
|
|
||||||
|
|
||||||
1) Данные для обучения должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение.
|
|
||||||
2) Большая размерность датасета требует более сложной архитектуры. Оптимальный размер 9-11 скрытых слоев.
|
|
||||||
3) В рамках данного набора данных оптимальное кол-во эпох 100000 с patience 4000 эпох.
|
|
||||||
4) Оптимальная ошибка MSE-stop лежит в районе 0.001, желательно не меньше для предотвращения переобучения
|
|
||||||
5) Значение порога не больше 1.4, он является достаточным, чтобы отделять норму от аномалий.
|
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
## Лабораторныа работа №3
|
||||||
|
|
||||||
|
## Распознавание изображений
|
||||||
|
|
||||||
|
* [Задание](IS_Lab03_2023.pdf)
|
||||||
|
|
||||||
|
* [Методические указания](IS_Lab03_Metod_2023.pdf)
|
||||||
|
|
||||||
|
* <a href="https://youtube.com/playlist?list=PLZDCDMGmelH-pHt-Ij0nImVrOmj8DYKbB" target="_blank">Плейлист с видео о сверточных сетях</a>
|
||||||
|
До Ширина: | Высота: | Размер: 6.7 KiB |
|
До Ширина: | Высота: | Размер: 6.6 KiB |
|
До Ширина: | Высота: | Размер: 31 KiB |
|
До Ширина: | Высота: | Размер: 6.4 KiB |
|
До Ширина: | Высота: | Размер: 6.8 KiB |
|
До Ширина: | Высота: | Размер: 117 KiB |
|
До Ширина: | Высота: | Размер: 12 KiB |
|
До Ширина: | Высота: | Размер: 12 KiB |
|
До Ширина: | Высота: | Размер: 60 KiB |
@ -1,554 +0,0 @@
|
|||||||
# Отчёт по лабораторной работе №3
|
|
||||||
|
|
||||||
**Ли Тэ Хо, Синявский Степан — А-02-22**
|
|
||||||
***Бригада 3***
|
|
||||||
---
|
|
||||||
## Задание 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 = 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: (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 4ms/step - accuracy: 0.9909 - loss: 0.0413
|
|
||||||
Loss on test data: 0.041157860308885574
|
|
||||||
Accuracy on test data: 0.9873999953269958
|
|
||||||
```
|
|
||||||
|
|
||||||
### 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))
|
|
||||||
```
|
|
||||||

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

|
|
||||||
```
|
|
||||||
Real mark: 9
|
|
||||||
NN answer: 9
|
|
||||||
```
|
|
||||||
|
|
||||||
### 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()
|
|
||||||
```
|
|
||||||
```
|
|
||||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step
|
|
||||||
precision recall f1-score support
|
|
||||||
|
|
||||||
0 0.99 1.00 0.99 1018
|
|
||||||
1 0.99 0.99 0.99 1098
|
|
||||||
2 0.99 0.98 0.98 1010
|
|
||||||
3 0.99 0.98 0.98 992
|
|
||||||
4 0.99 0.98 0.99 998
|
|
||||||
5 0.99 0.99 0.99 951
|
|
||||||
6 0.99 0.99 0.99 933
|
|
||||||
7 0.98 0.99 0.98 1010
|
|
||||||
8 0.99 0.99 0.99 960
|
|
||||||
9 0.98 0.99 0.98 1030
|
|
||||||
|
|
||||||
accuracy 0.99 10000
|
|
||||||
macro avg 0.99 0.99 0.99 10000
|
|
||||||
weighted avg 0.99 0.99 0.99 10000
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
### 9) Загрузили, предобработали и подали на вход обученной нейронной сети собственное изображение, созданное при выполнении лабораторной работы №1. Вывели изображение и результат распознавания.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# загрузка собственного изображения
|
|
||||||
from PIL import Image
|
|
||||||
|
|
||||||
for name_image in ['2.png', '5.png']:
|
|
||||||
file_data = Image.open(name_image)
|
|
||||||
file_data = file_data.convert('L') # перевод в градации серого
|
|
||||||
test_img = np.array(file_data)
|
|
||||||
|
|
||||||
# вывод собственного изображения
|
|
||||||
plt.imshow(test_img, cmap=plt.get_cmap('gray'))
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
# предобработка
|
|
||||||
test_img = test_img / 255
|
|
||||||
test_img = np.reshape(test_img, (1,28,28,1))
|
|
||||||
|
|
||||||
# распознавание
|
|
||||||
result = model.predict(test_img)
|
|
||||||
print('I think it\'s', np.argmax(result))
|
|
||||||
```
|
|
||||||

|
|
||||||
```
|
|
||||||
I think it's 2
|
|
||||||
```
|
|
||||||

|
|
||||||
```
|
|
||||||
I think it's 5
|
|
||||||
```
|
|
||||||
|
|
||||||
### 10) Загрузили с диска модель, сохраненную при выполнении лабораторной работы №1. Вывели информацию об архитектуре модели. Повторили для этой модели п. 6.
|
|
||||||
|
|
||||||
```python
|
|
||||||
model_lr1 = keras.models.load_model("best_model.keras")
|
|
||||||
|
|
||||||
model_lr1.summary()
|
|
||||||
```
|
|
||||||
**Model: "sequential_10"**
|
|
||||||
| Layer (type) | Output Shape | Param # |
|
|
||||||
|------------------|-------------:|--------:|
|
|
||||||
| dense_14 (Dense) | (None, 100) | 78,500 |
|
|
||||||
| dense_15 (Dense) | (None, 50) | 10,100 |
|
|
||||||
| dense_16 (Dense) | (None, 10) | 1,010 |
|
|
||||||
**Total params:** 89,612 (350.05 KB)
|
|
||||||
**Trainable params:** 89,610 (350.04 KB)
|
|
||||||
**Non-trainable params:** 0 (0.00 B)
|
|
||||||
**Optimizer params:** 2 (12.00 B)
|
|
||||||
|
|
||||||
|
|
||||||
```python
|
|
||||||
# развернем каждое изображение 28*28 в вектор 784
|
|
||||||
X_train, X_test, y_train, y_test = train_test_split(X, y,
|
|
||||||
test_size = 10000,
|
|
||||||
train_size = 60000,
|
|
||||||
random_state = 11)
|
|
||||||
num_pixels = X_train.shape[1] * X_train.shape[2]
|
|
||||||
X_train = X_train.reshape(X_train.shape[0], num_pixels) / 255
|
|
||||||
X_test = X_test.reshape(X_test.shape[0], num_pixels) / 255
|
|
||||||
print('Shape of transformed X train:', X_train.shape)
|
|
||||||
print('Shape of transformed X train:', X_test.shape)
|
|
||||||
|
|
||||||
# переведем метки в one-hot
|
|
||||||
y_train = keras.utils.to_categorical(y_train, num_classes)
|
|
||||||
y_test = keras.utils.to_categorical(y_test, num_classes)
|
|
||||||
print('Shape of transformed y train:', y_train.shape)
|
|
||||||
print('Shape of transformed y test:', y_test.shape)
|
|
||||||
```
|
|
||||||
```
|
|
||||||
Shape of transformed X train: (60000, 784)
|
|
||||||
Shape of transformed X train: (10000, 784)
|
|
||||||
Shape of transformed y train: (60000, 10)
|
|
||||||
Shape of transformed y test: (10000, 10)
|
|
||||||
```
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Оценка качества работы модели на тестовых данных
|
|
||||||
scores = model_lr1.evaluate(X_test, y_test)
|
|
||||||
print('Loss on test data:', scores[0])
|
|
||||||
print('Accuracy on test data:', scores[1])
|
|
||||||
```
|
|
||||||
```
|
|
||||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.9406 - loss: 0.2055
|
|
||||||
Loss on test data: 0.1955890655517578
|
|
||||||
Accuracy on test data: 0.9426000118255615
|
|
||||||
```
|
|
||||||
|
|
||||||
### 11) Сравнили обученную модель сверточной сети и наилучшую модель полносвязной сети из лабораторной работы №1 по следующим показателям:
|
|
||||||
### - количество настраиваемых параметров в сети
|
|
||||||
### - количество эпох обучения
|
|
||||||
### - качество классификации тестовой выборки.
|
|
||||||
### Сделали выводы по результатам применения сверточной нейронной сети для распознавания изображений.
|
|
||||||
|
|
||||||
Таблица1:
|
|
||||||
|
|
||||||
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|
|
||||||
|----------|-------------------------------------|---------------------------|-----------------------------------------|
|
|
||||||
| Сверточная | 34 826 | 15 | accuracy:0.987 ; loss:0.0413 |
|
|
||||||
| Полносвязная | 89 612 | 50 | accuracy:0.943 ; loss:0.2055 |
|
|
||||||
|
|
||||||
|
|
||||||
##### По полученной таблице можно сделать выводы о том, что сверточная модель лучше по всем показателям, она имеет более высокое качество классификации, мненьшее время обученя, а также вдвое меньше параметров.
|
|
||||||
|
|
||||||
## Задание 2
|
|
||||||
|
|
||||||
### В новом блокноте выполнили п. 2–8 задания 1, изменив набор данных MNIST на CIFAR-10, содержащий размеченные цветные изображения объектов, разделенные на 10 классов.
|
|
||||||
### При этом:
|
|
||||||
### - в п. 3 разбиение данных на обучающие и тестовые произвели в соотношении 50 000:10 000
|
|
||||||
### - после разбиения данных (между п. 3 и 4) вывели 25 изображений из обучающей выборки с подписями классов
|
|
||||||
### - в п. 7 одно из тестовых изображений должно распознаваться корректно, а другое – ошибочно.
|
|
||||||
|
|
||||||
### 1) Загрузили набор данных CIFAR-10, содержащий цветные изображения размеченные на 10 классов: самолет, автомобиль, птица, кошка, олень, собака, лягушка, лошадь, корабль, грузовик.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# загрузка датасета
|
|
||||||
from keras.datasets import cifar10
|
|
||||||
|
|
||||||
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2) Разбили набор данных на обучающие и тестовые данные в соотношении 50 000:10 000 элементов. Параметр random_state выбрали равным (4k – 1)=23, где k=6 –номер бригады. Вывели размерности полученных обучающих и тестовых массивов данных.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# создание своего разбиения датасета
|
|
||||||
|
|
||||||
# объединяем в один набор
|
|
||||||
X = np.concatenate((X_train, X_test))
|
|
||||||
y = np.concatenate((y_train, y_test))
|
|
||||||
|
|
||||||
# разбиваем по вариантам
|
|
||||||
X_train, X_test, y_train, y_test = train_test_split(X, y,
|
|
||||||
test_size = 10000,
|
|
||||||
train_size = 50000,
|
|
||||||
random_state = 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()
|
|
||||||
|
|
||||||
# Блок 1
|
|
||||||
model.add(layers.Conv2D(32, (3, 3), padding="same",
|
|
||||||
activation="relu", input_shape=input_shape))
|
|
||||||
model.add(layers.BatchNormalization())
|
|
||||||
model.add(layers.Conv2D(32, (3, 3), padding="same", activation="relu"))
|
|
||||||
model.add(layers.BatchNormalization())
|
|
||||||
model.add(layers.MaxPooling2D((2, 2)))
|
|
||||||
model.add(layers.Dropout(0.25))
|
|
||||||
|
|
||||||
# Блок 2
|
|
||||||
model.add(layers.Conv2D(64, (3, 3), padding="same", activation="relu"))
|
|
||||||
model.add(layers.BatchNormalization())
|
|
||||||
model.add(layers.Conv2D(64, (3, 3), padding="same", activation="relu"))
|
|
||||||
model.add(layers.BatchNormalization())
|
|
||||||
model.add(layers.MaxPooling2D((2, 2)))
|
|
||||||
model.add(layers.Dropout(0.25))
|
|
||||||
|
|
||||||
# Блок 3
|
|
||||||
model.add(layers.Conv2D(128, (3, 3), padding="same", activation="relu"))
|
|
||||||
model.add(layers.BatchNormalization())
|
|
||||||
model.add(layers.Conv2D(128, (3, 3), padding="same", activation="relu"))
|
|
||||||
model.add(layers.BatchNormalization())
|
|
||||||
model.add(layers.MaxPooling2D((2, 2)))
|
|
||||||
model.add(layers.Dropout(0.4))
|
|
||||||
|
|
||||||
model.add(layers.Flatten())
|
|
||||||
model.add(layers.Dense(128, activation='relu'))
|
|
||||||
model.add(layers.Dropout(0.5))
|
|
||||||
model.add(layers.Dense(num_classes, activation="softmax"))
|
|
||||||
|
|
||||||
|
|
||||||
model.summary()
|
|
||||||
```
|
|
||||||
**Model: "sequential_9"**
|
|
||||||
| Layer (type) | Output Shape | Param # |
|
|
||||||
|--------------------------------------------|-------------------|---------:|
|
|
||||||
| conv2d_41 (Conv2D) | (None, 32, 32, 32) | 896 |
|
|
||||||
| batch_normalization_6 (BatchNormalization) | (None, 32, 32, 32) | 128 |
|
|
||||||
| conv2d_42 (Conv2D) | (None, 32, 32, 32) | 9,248 |
|
|
||||||
| batch_normalization_7 (BatchNormalization) | (None, 32, 32, 32) | 128 |
|
|
||||||
| max_pooling2d_26 (MaxPooling2D) | (None, 16, 16, 32) | 0 |
|
|
||||||
| dropout_24 (Dropout) | (None, 16, 16, 32) | 0 |
|
|
||||||
| conv2d_43 (Conv2D) | (None, 16, 16, 64) | 18,496 |
|
|
||||||
| batch_normalization_8 (BatchNormalization) | (None, 16, 16, 64) | 256 |
|
|
||||||
| conv2d_44 (Conv2D) | (None, 16, 16, 64) | 36,928 |
|
|
||||||
| batch_normalization_9 (BatchNormalization) | (None, 16, 16, 64) | 256 |
|
|
||||||
| max_pooling2d_27 (MaxPooling2D) | (None, 8, 8, 64) | 0 |
|
|
||||||
| dropout_25 (Dropout) | (None, 8, 8, 64) | 0 |
|
|
||||||
| conv2d_45 (Conv2D) | (None, 8, 8, 128) | 73,856 |
|
|
||||||
| batch_normalization_10 (BatchNormalization)| (None, 8, 8, 128) | 512 |
|
|
||||||
| conv2d_46 (Conv2D) | (None, 8, 8, 128) | 147,584 |
|
|
||||||
| batch_normalization_11 (BatchNormalization)| (None, 8, 8, 128) | 512 |
|
|
||||||
| max_pooling2d_28 (MaxPooling2D) | (None, 4, 4, 128) | 0 |
|
|
||||||
| dropout_26 (Dropout) | (None, 4, 4, 128) | 0 |
|
|
||||||
| flatten_9 (Flatten) | (None, 2048) | 0 |
|
|
||||||
| dense_17 (Dense) | (None, 128) | 262,272 |
|
|
||||||
| dropout_27 (Dropout) | (None, 128) | 0 |
|
|
||||||
| dense_18 (Dense) | (None, 10) | 1,290 |
|
|
||||||
**Total params:** 552,362 (2.11 MB)
|
|
||||||
**Trainable params:** 551,466 (2.10 MB)
|
|
||||||
**Non-trainable params:** 896 (3.50 KB)
|
|
||||||
|
|
||||||
```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 ━━━━━━━━━━━━━━━━━━━━ 7s 10ms/step - accuracy: 0.8615 - loss: 0.4696
|
|
||||||
Loss on test data: 0.4909549355506897
|
|
||||||
Accuracy on test data: 0.857200026512146
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6) Подали на вход обученной модели два тестовых изображения. Вывели изображения, истинные метки и результаты распознавания.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# вывод двух тестовых изображений и результатов распознавания
|
|
||||||
|
|
||||||
for n in [3,15]:
|
|
||||||
result = model.predict(X_test[n:n+1])
|
|
||||||
print('NN output:', result)
|
|
||||||
|
|
||||||
plt.imshow(X_test[n].reshape(32,32,3), cmap=plt.get_cmap('gray'))
|
|
||||||
plt.show()
|
|
||||||
print('Real mark: ', np.argmax(y_test[n]))
|
|
||||||
print('NN answer: ', np.argmax(result))
|
|
||||||
```
|
|
||||||

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

|
|
||||||
```
|
|
||||||
Real mark: 2
|
|
||||||
NN answer: 2
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7) Вывели отчет о качестве классификации тестовой выборки и матрицу ошибок для тестовой выборки.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# истинные метки классов
|
|
||||||
true_labels = np.argmax(y_test, axis=1)
|
|
||||||
# предсказанные метки классов
|
|
||||||
predicted_labels = np.argmax(model.predict(X_test), axis=1)
|
|
||||||
|
|
||||||
# отчет о качестве классификации
|
|
||||||
print(classification_report(true_labels, predicted_labels, target_names=class_names))
|
|
||||||
# вычисление матрицы ошибок
|
|
||||||
conf_matrix = confusion_matrix(true_labels, predicted_labels)
|
|
||||||
# отрисовка матрицы ошибок в виде "тепловой карты"
|
|
||||||
fig, ax = plt.subplots(figsize=(6, 6))
|
|
||||||
disp = ConfusionMatrixDisplay(confusion_matrix=conf_matrix,display_labels=class_names)
|
|
||||||
disp.plot(ax=ax, xticks_rotation=45) # поворот подписей по X и приятная палитра
|
|
||||||
plt.tight_layout() # чтобы всё влезло
|
|
||||||
plt.show()
|
|
||||||
```
|
|
||||||
```
|
|
||||||
313/313 ━━━━━━━━━━━━━━━━━━━━ 4s 10ms/step
|
|
||||||
precision recall f1-score support
|
|
||||||
|
|
||||||
airplane 0.89 0.86 0.87 1000
|
|
||||||
automobile 0.94 0.93 0.93 1019
|
|
||||||
bird 0.80 0.84 0.82 972
|
|
||||||
cat 0.78 0.66 0.72 1014
|
|
||||||
deer 0.84 0.84 0.84 980
|
|
||||||
dog 0.76 0.81 0.79 1051
|
|
||||||
frog 0.90 0.87 0.89 1043
|
|
||||||
horse 0.89 0.89 0.89 1018
|
|
||||||
ship 0.91 0.94 0.92 945
|
|
||||||
truck 0.86 0.94 0.90 958
|
|
||||||
|
|
||||||
accuracy 0.86 10000
|
|
||||||
macro avg 0.86 0.86 0.86 10000
|
|
||||||
weighted avg 0.86 0.86 0.86 10000
|
|
||||||
```
|
|
||||||

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