In [9]:
from tensorflow.keras.datasets import mnist
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import Sequential
from tensorflow.keras import utils
from tensorflow.keras.preprocessing import image
import numpy as np
import matplotlib.pyplot as plt
from scipy.misc import toimage
%matplotlib inline

import warnings
warnings.filterwarnings("ignore")

Загружаем набор данных с рукописными цифрами

In [2]:
# В Keras встроены средства работы с популярными наборами данных
(X_train, y_train), (X_test, y_test) = mnist.load_data()
In [10]:
plt.imshow(toimage(X_train[2]).convert('RGBA'))
plt.show()

Преобразование размерности данных в наборе

In [13]:
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1]*X_train.shape[2])
X_test = X_test.reshape(X_test.shape[0], X_test.shape[1]*X_test.shape[2])

Нормализация данных

In [15]:
X_train = X_train.astype('float32')
X_train = X_train / 255 

Преобразуем метки в формат one hot encoding

In [16]:
y_train = utils.to_categorical(y_train, 10)

Создаем последовательную модель

In [17]:
model = Sequential()

Архитекрура сети

In [18]:
# Входной полносвязный слой, 800 нейронов, 784 входа в каждый нейрон
model.add(Dense(800, input_dim=784, activation="relu"))
# Выходной полносвязный слой, 10 нейронов (по количеству рукописных цифр)
model.add(Dense(10, activation="softmax"))

Компилируем сеть

In [19]:
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])

print(model.summary())
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 800)               628000    
_________________________________________________________________
dense_1 (Dense)              (None, 10)                8010      
=================================================================
Total params: 636,010
Trainable params: 636,010
Non-trainable params: 0
_________________________________________________________________
None
In [21]:
model.fit(X_train, y_train, batch_size=200, epochs=20,  verbose=1)
Epoch 1/20
60000/60000 [==============================] - 3s 51us/step - loss: 0.2749 - acc: 0.9226
Epoch 2/20
60000/60000 [==============================] - 3s 47us/step - loss: 0.1112 - acc: 0.9678
Epoch 3/20
60000/60000 [==============================] - 3s 49us/step - loss: 0.0713 - acc: 0.9792
Epoch 4/20
60000/60000 [==============================] - 3s 46us/step - loss: 0.0495 - acc: 0.9860
Epoch 5/20
60000/60000 [==============================] - 3s 46us/step - loss: 0.0366 - acc: 0.9892
Epoch 6/20
60000/60000 [==============================] - 3s 45us/step - loss: 0.0266 - acc: 0.9925
Epoch 7/20
60000/60000 [==============================] - 3s 46us/step - loss: 0.0197 - acc: 0.9951
Epoch 8/20
60000/60000 [==============================] - 3s 46us/step - loss: 0.0138 - acc: 0.9971
Epoch 9/20
60000/60000 [==============================] - 3s 46us/step - loss: 0.0104 - acc: 0.9980
Epoch 10/20
60000/60000 [==============================] - 3s 43us/step - loss: 0.0075 - acc: 0.9987
Epoch 11/20
60000/60000 [==============================] - 2s 41us/step - loss: 0.0072 - acc: 0.9986
Epoch 12/20
60000/60000 [==============================] - 2s 41us/step - loss: 0.0061 - acc: 0.9988
Epoch 13/20
60000/60000 [==============================] - 2s 41us/step - loss: 0.0050 - acc: 0.9990
Epoch 14/20
60000/60000 [==============================] - 3s 45us/step - loss: 0.0036 - acc: 0.9994
Epoch 15/20
60000/60000 [==============================] - 3s 45us/step - loss: 0.0033 - acc: 0.9994
Epoch 16/20
60000/60000 [==============================] - 3s 45us/step - loss: 0.0016 - acc: 0.9999
Epoch 17/20
60000/60000 [==============================] - 3s 45us/step - loss: 7.5468e-04 - acc: 1.0000
Epoch 18/20
60000/60000 [==============================] - 3s 45us/step - loss: 5.2419e-04 - acc: 1.0000
Epoch 19/20
60000/60000 [==============================] - 3s 46us/step - loss: 4.0966e-04 - acc: 1.0000
Epoch 20/20
60000/60000 [==============================] - 3s 45us/step - loss: 3.5036e-04 - acc: 1.0000
Out[21]:
<tensorflow.python.keras.callbacks.History at 0x1316ed358>
Вот и все, у нас готова нейронная сеть, которая умеет распозновать рукописные цифры.

Давайте попробуем ее в деле

Я попросил ученика Винсента Ван Гога нарисовать для нас это охуительное олицетворение твоего среднего балла в универе, сейчас проверим распознает ли его наша сетка

In [55]:
img_path = '2.png'
img = image.load_img(img_path, target_size=(28, 28), color_mode = "grayscale")
In [56]:
plt.imshow(img.convert('RGBA'))
plt.show()
In [57]:
# Преобразуем картинку в массив
x = image.img_to_array(img)
# Меняем форму массива в плоский вектор
x = x.reshape(1, 784)
# Инвертируем изображение
x = 255 - x
# Нормализуем изображение
x /= 255
In [58]:
prediction = model.predict(x)
In [59]:
print(np.argmax(prediction))
2

Успех