Этот пост я решил написать, для тех, кто также искал понятный код и рабочий пример, который можно было взять, вставить в гугл колаб(google colab) и сразу начать "играться" с кодом. Но не нашел. Для вас, друзья!
P.S весь код будет в конце.
Импортируем бэкэнд кераса, по началу, мы его использовать не будем, но некоторые функции нам понадобятся
import tensorflow as tfИмпортируем сам пакет машинного обучения , его и будем использовать.
import kerasМатематические функции которые нам тоже понадобятся.
import numpy as npБиблиотека для вывода изображений.
import matplotlib.pyplot as pltДля чего эта строчка? - нагуглите сами.
%matplotlib inlineИмортируем слои, вернее классы слоёв для нашей нейронной сети.
from keras.layers import Dense, FlattenИмпорт нашей последовательной моде��и.
from keras.models import SequentialИмпортируем набор данных MNIST для нашего обучения.
from keras.datasets import mnistЗагружаем данные функцией load_data из названия нашего датасета mnist и разделяем наш датасет на тренировочную выборку и тестовую.
(X_train, y_train), (X_test, y_test) = mnist.load_data()Давайте посмотрим, что за изображения у нас и в какой они форме.
print(X_train.shape)
Вот, мы видим, что X_train представляет из себя массив данных с 60000 экземпляров картинок, которые имеют разрешение 28 на 28.
Теперь давайте посмотрим , что такое y_train.
print(y_train.shape)
Мы видим , что это просто массив из 60000 значений не и более того.
А теперь давайте посмотрим, что же именно храниться в массивах, если X_train - массив изображений, давайте откроем одно!
Выводим 12 изображение из массива, и это цифра 3
plt.imshow(X_train[12], cmap='binary')
plt.axis('off')
print(y_train[12])
Вот мы и видим цифра 3 и картинку с цифрой 3!
Как вы все знаете, значение пикселя может быть от 0 до 255, и если мы будем подавать в нейронную сеть такие данные. Пиксель со значением 0 и пиксель со значением 255 имеют очень разные масштабы значений. Нам очень тяжело будет учить модель.
И чтобы их "нормировать", чтобы они были от 0 до 1 в идеале, мы разделим все наше "добро" на 255.
0 / 255 = 0 , 255 / 255 = 1, а любое число в диапазоне от 0 не до 255 будет просто дробью.
X_train = X_train/255
X_test = X_test/255Вот что мы получили:
print(y_train[0])
К сожалению, нельзя дать нейронке фото и сказать что это цифра 4, нужно это значение "векторизировать", это делается вот так:
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)Получилось:
print(y_train[0])
Теперь давайте напишем саму модель нейронной сети.
Инициализируем нашу модель.
model = Sequential()Дальше создаем наш первый слой, в нём будет 32 нейрона, также нужно указать форму входимых данных.
model.add(Dense(32, activation='relu', input_shape=(X_train[0].shape)))Ещё дальше создаем 4 нейрона с такой же функцией активации.
model.add(Dense(64, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Dense(256, activation='relu'))
model.add(Dense(512, activation='relu'))Мы вытягиваем данные в вектор.
model.add(Flatten())И тут мы сравниваем вектор с вектором, по сути это так.
model.add(Dense(10, activation='sigmoid'))Тут компилируем нашу модель, оптимайзер - адам, потому-что он очень "классный", "categorical_crossentropy" - т.к мы определяем категории объектов.
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])Теперь тренируем модель:
model.fit(X_train, y_train, epochs=50 )Мы обучили нашу нейронную сеть и теперь, давайте посмотрим на результат.
Будем использовать команду "model.evaluate", если перевести дословно - модель.оценивать
Принимает проверочный датасет и смотрим какая потеря и какая точность:

Как мы видим, точность - 96%.
Создадим переменную k и запишем туда номер изображения в датасете и будем его вызывать.
Указали цифру 6, значит цифра 4 находится под индексом 6.
k = 6
plt.imshow(X_test[k], cmap='binary')
plt.axis('off')
print(y_test[k])
Давайте укажем индекс 10, получили цифру 0.
k = 10
plt.imshow(X_test[k], cmap='binary')
plt.axis('off')
print(y_test[k])
Теперь посмотрим, как именно работает наша нейронная сеть.
k = 6
plt.imshow(X_test[k], cmap='binary')
plt.axis('off')
print(y_test[k])
print(
model.predict(np.array([X_test[k]]))
)
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.] - единичка под индексом 4 , соответственно - цифра 4.
Визуально на картинке мы тоже видим цифру 4.
Теперь давайте рассмотрим ответ нейронной сети:
[[0.0000000e+00, 9.9408084e-18, 2.8947007e-22, 2.9116518e-10, 1.0000000e+00,
4.6417094e-17, 3.7773155e-38, 5.8520163e-07,, 3.7786970e-24, 4.3130936e-07]]
* - буква e это значение степени, рассмотрим число - 4.6417094e-17
число 4.6417094e-17 - это условно 4.6427 в минус 17 степени, это примерно 0.00000000000000004642 то есть очень маленькое число.
Посмотрим на весь массив и увидим, что есть число 0 в 0-ой степени , числа в отрицательной степени , и то, что нам нужно 1 в степени 0, любое число в нулевой степени равно единице.
Максимальный элемент массива под индексом 4, соответственно, цифра- 4.
Изменим индекс и посмотрим, что будет.
k = 10
plt.imshow(X_test[k], cmap='binary')
plt.axis('off')
print(y_test[k])
print(
model.predict(np.array([X_test[k]]))
)
Тут видим, что исходя из степенней и чисел, мы видим, что большее число под индексом 0, соответственно и цифра 0.
Надеюсь, вам понравился мой пост и он будет вам полезен, вот весь код для вставки в гугл колаб:
import tensorflow as tf
import keras
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from keras.layers import Dense, Flatten
from keras.models import Sequential
from keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()
print(X_train.shape)
print(y_train.shape)
plt.imshow(X_train[12], cmap='binary')
plt.axis('off')
print(y_train[12])
X_train = X_train/255
X_test = X_test/255
print(y_train[0])
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)
print(y_train[0])
model = Sequential()
model.add(Dense(32, activation='relu', input_shape=(X_train[0].shape)))
model.add(Dense(64, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Dense(256, activation='relu'))
model.add(Dense(512, activation='relu'))
model.add(Flatten())
model.add(Dense(10, activation='sigmoid'))
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.fit(X_train, y_train, epochs=50 )
k = 6
plt.imshow(X_test[k], cmap='binary')
plt.axis('off')
print(y_test[k])
k = 10
plt.imshow(X_test[k], cmap='binary')
plt.axis('off')
print(y_test[k])2 блок кода:
k = 6
plt.imshow(X_test[k], cmap='binary')
plt.axis('off')
print(y_test[k])
print(
model.predict(np.array([X_test[k]]))
)
k = 10
plt.imshow(X_test[k], cmap='binary')
plt.axis('off')
print(y_test[k])
print(
model.predict(np.array([X_test[k]]))
)
