diff --git a/labworks/LW1/otchet.md b/labworks/LW1/otchet.md new file mode 100644 index 0000000..8cd69bf --- /dev/null +++ b/labworks/LW1/otchet.md @@ -0,0 +1,223 @@ +# Отчет по лабораторной работе 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]) +``` +![photo](images/1.png) +![photo](images/2.png) +![photo](images/3.png) +![photo](images/4.png) + +### Пункт 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() +``` +![photo](images/5.png) +```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))) +``` +![photo](images/6.png) + +Real mark: 0 +NN answer: 0 + +### Пункт 13 +Создали собственные изображения чисел +![photo](images/7.png) +![photo](images/8.png) +Сохранили их и подали на вход для распознования +```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() +``` +![photo](images/9.png) + +```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 градусов. Протестируем работу нейронной сети. +![photo](images/10.png) +![photo](images/11.png) + +```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)) +``` +![photo](images/12.png) + +I think it's 4 + +![photo](images/13.png) + +I think it's 7 + +Нейросеть неправильно определила повернутые изображения цифр. Она не определяет саму цифру, для нее ориентация не имеет значения, 1 это вертикальная черта, а повернутая 1 это просто горизонтальная черта. \ No newline at end of file