Сравнить коммиты
1 Коммитов
Автор | SHA1 | Дата |
---|---|---|
![]() |
339fe963d0 | 2 недель назад |
До Ширина: | Высота: | Размер: 3.9 KiB |
До Ширина: | Высота: | Размер: 3.9 KiB |
До Ширина: | Высота: | Размер: 854 B |
До Ширина: | Высота: | Размер: 883 B |
До Ширина: | Высота: | Размер: 5.6 KiB |
До Ширина: | Высота: | Размер: 19 KiB |
До Ширина: | Высота: | Размер: 30 KiB |
До Ширина: | Высота: | Размер: 20 KiB |
До Ширина: | Высота: | Размер: 29 KiB |
До Ширина: | Высота: | Размер: 18 KiB |
До Ширина: | Высота: | Размер: 18 KiB |
До Ширина: | Высота: | Размер: 8.6 KiB |
До Ширина: | Высота: | Размер: 8.7 KiB |
До Ширина: | Высота: | Размер: 8.9 KiB |
До Ширина: | Высота: | Размер: 8.7 KiB |
До Ширина: | Высота: | Размер: 13 KiB |
До Ширина: | Высота: | Размер: 24 KiB |
До Ширина: | Высота: | Размер: 16 KiB |
До Ширина: | Высота: | Размер: 28 KiB |
До Ширина: | Высота: | Размер: 16 KiB |
До Ширина: | Высота: | Размер: 28 KiB |
До Ширина: | Высота: | Размер: 16 KiB |
До Ширина: | Высота: | Размер: 27 KiB |
@ -1,508 +0,0 @@
|
||||
# Отчёт по лабораторной работе №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 = 10). Такой фиксированный 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*10 - 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)
|
||||
```
|
||||
|
||||
```
|
||||
Shape of transformed y train: (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()
|
||||
```
|
||||
|
||||

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

|
||||
|
||||
```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])
|
||||
```
|
||||
|
||||
```
|
||||
Loss on test data: 0.2998492121696472
|
||||
Accuracy on test data: 0.9138000011444092
|
||||
```
|
||||
|
||||
### При 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())
|
||||
```
|
||||
|
||||

|
||||
|
||||
```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])
|
||||
```
|
||||
|
||||
```
|
||||
Loss on test data: 0.31299835443496704
|
||||
Accuracy on test data: 0.9107999801635742
|
||||
```
|
||||
|
||||
### При 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())
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
```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])
|
||||
```
|
||||
|
||||
```
|
||||
Loss on test data: 0.31795090436935425
|
||||
Accuracy on test data: 0.909600019454956
|
||||
```
|
||||
|
||||
Мы видим что лучший результат показала модель со 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())
|
||||
```
|
||||
|
||||

|
||||
|
||||
```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])
|
||||
```
|
||||
|
||||
```
|
||||
Loss on test data: 0.3216394782066345
|
||||
Accuracy on test data: 0.9085999727249146
|
||||
```
|
||||
|
||||
### При 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())
|
||||
```
|
||||
|
||||

|
||||
|
||||
```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])
|
||||
```
|
||||
|
||||
```
|
||||
Loss on test data: 0.31788304448127747
|
||||
Accuracy on test data: 0.9128000140190125
|
||||
```
|
||||
|
||||
## 10. Сравнили качество классификации на тестовых данных всех построенных моделей. Сделали выводы.
|
||||
|
||||
| Кол-во слоёв | Нейронов в 1-м | Нейронов во 2-м | Accuracy |
|
||||
|---------------|----------------|-----------------|-----------|
|
||||
| 0 | – | – | 0.9111 |
|
||||
| 1 | 100 | – | 0.9138 |
|
||||
| 1 | 300 | – | 0.9108 |
|
||||
| 1 | 500 | – | 0.9096 |
|
||||
| 2 | 100 | 50 | 0.9086 |
|
||||
| 2 | 100 | 100 | 0.9128 |
|
||||
|
||||
**Вывод:** наилучшей оказалась архитектура с одним скрытым слоем и 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)))
|
||||
```
|
||||

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

|
||||
|
||||
---
|
||||
|
||||
## 13. Создали собственные изображения рукописных цифр, подобное представленным в наборе MNIST. Цифру выбрали как остаток от деления на 10 числа своего дня рождения (14 июля → 14 mod 10 = 4, 7 ноября → 7 mod 10 = 7). Сохранили изображения. Загрузили, предобработали и подали на вход обученной нейронной сети собственные изображения. Вывели изображения и результаты распознавания.
|
||||
|
||||
### Для 7:
|
||||
|
||||

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

|
||||
|
||||
### Для 4:
|
||||
|
||||

|
||||
|
||||
```python
|
||||
from PIL import Image
|
||||
file_data_4=Image.open('/content/drive/MyDrive/Colab Notebooks/IS_lab_4.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('I think it\'s',np.argmax(result))
|
||||
```
|
||||

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

|
||||
|
||||
**Вывод:** модель неустойчива к повороту изображений, так как не обучалась на повернутых данных.
|
||||
|
||||
---
|
||||
|
||||
## Заключение
|
||||
Изучены принципы построения и обучения нейронных сетей в Keras на примере распознавания цифр MNIST. Лучшая точность достигнута простой моделью с одним скрытым слоем из 100 нейронов. При усложнении архитектуры наблюдается переобучение. Сеть корректно классифицирует собственные изображения, но ошибается на повернутых.
|
@ -0,0 +1,4 @@
|
||||
* [Задание](IS_Lab02_2023.pdf)
|
||||
* [Методические указания](IS_Lab02_Metod_2023.pdf)
|
||||
* [Наборы данных](data)
|
||||
* [Библиотека для автокодировщиков](lab02_lib.py)
|