За последнее десятилетие использование искусственных нейронных сетей (ИНС) значительно возросло. Люди использовали ИНС в медицинских диагнозах, для прогнозирования цен на биткойны и для создания поддельных видео Обамы! Со всей шумихой о глубоком обучении и искусственных нейронных сетях, разве вы всегда не хотели создать их для себя? В этом уроке мы создадим модель для распознавания рукописных цифр.
В этом руководстве мы будем использовать библиотеку Keras для обучения модели. Keras — это высокоуровневая библиотека на Python, являющаяся оболочкой TensorFlow, CNTK и Theano. По умолчанию Keras по умолчанию использует бэкэнд TensorFlow, и мы будем использовать его для обучения нашей модели.
Искусственные нейронные сети
Искусственная нейронная сеть
Источник
Искусственная нейронная сеть — это математическая модель, которая преобразует набор входных данных в набор выходных данных через ряд скрытых слоев. ИНС работает со скрытыми слоями, каждый из которых представляет собой переходную форму, связанную с вероятностью. В типичной нейронной сети каждый узел слоя принимает в качестве входных данных все узлы предыдущего слоя. Модель может иметь один или несколько скрытых слоев.
ИНС получают входной слой для его преобразования через скрытые слои. ИНС инициализируется путем присвоения случайных весов и смещений каждому узлу скрытых слоев. Когда обучающие данные вводятся в модель, она изменяет эти веса и смещения, используя ошибки, генерируемые на каждом этапе. Следовательно, наша модель «узнает» шаблон при просмотре обучающих данных.
Запутанные нейронные сети
В этом уроке мы собираемся идентифицировать цифры — это простая версия классификации изображений. Изображение, по сути, представляет собой набор точек или пикселей. Пиксель можно идентифицировать по составляющим его цветам (RGB). Таким образом, входные данные изображения представляют собой двумерный массив пикселей, каждый из которых представляет цвет.
Если бы мы обучали обычную нейронную сеть на основе данных изображения, нам пришлось бы предоставить длинный список входных данных, каждый из которых был бы связан со следующим скрытым слоем. Это затрудняет масштабирование процесса.
Архитектура сверточной нейронной сети
Архитектура сверточной нейронной сети
В свернутой нейронной сети (CNN) слои расположены в виде трехмерного массива (координата по оси X, координата по оси Y и цвет). Следовательно, узел скрытого слоя будет связан только с небольшой областью вблизи соответствующего входного слоя, что сделает процесс гораздо более эффективным, чем традиционная нейронная сеть. Поэтому CNN популярны, когда дело доходит до работы с изображениями и видео.
Слои сверточной нейронной сети
Слои сверточной нейронной сети
Различные типы слоев в CNN следующие:
сверточные слои: они пропускают ввод через определенные фильтры, которые идентифицируют функции на изображении.
объединяющие слои: они объединяют сверточные функции, помогая уменьшить количество функций
сгладить слои: они преобразуют
слой классификации: последний слой, который сообщает нам окончательный результат
Давайте теперь исследуем данные.
Исследуйте набор данных MNIST
Как вы, возможно, уже поняли, нам нужны помеченные данные для обучения любой модели. В этом уроке мы будем использовать набор рукописных цифр MNIST. Этот набор данных является частью пакета Keras. Он содержит обучающий набор из 60 000 примеров и тестовый набор из 10 000 примеров. Мы обучим данные на тренировочном наборе и проверим результаты на основе тестовых данных. Далее мы создадим собственное изображение, чтобы проверить, может ли модель правильно предсказать его.
from keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data ()
Давайте попробуем визуализировать цифры в наборе данных. Если вы используете блокноты Jupyter, используйте следующую волшебную функцию для отображения встроенных графиков Matplotlib:
%matplotlib inline
Затем импортируйте pyplotмодуль из matplotlibи используйте.imshow () метод для отображения изображения:
import matplotlib.pyplot as plt
image_index = 35
print (y_train[image_index])
plt.imshow (x_train[image_index], cmap='Greys’)
plt.show ()
Метка изображения печатается, а затем изображение отображается.
распечатывается этикетка и отображается изображение
Давайте проверим размеры обучающих и тестовых наборов данных:
print (x_train.shape)
print (x_test.shape)
Обратите внимание, что каждое изображение имеет размеры 28×28:
(60000, 28, 28)
(10000, 28, 28)
Затем мы также можем захотеть изучить зависимую переменную, хранящуюся в y_train. Напечатаем все метки до цифры, которую мы визуализировали выше:
print (y_train[: image_index + 1])
[5 0 4 1 9 2 1 3 1 4 3 5 3 6 1 7 2 8 6 9 4 0 9 1 1 2 4 3 2 7 3 8 6 9 0 5]
Очистка данных
Теперь, когда мы увидели структуру данных, давайте поработаем над ней, прежде чем создавать модель.
Для работы с Keras API нам нужно преобразовать каждое изображение в формат (M x N x 1). мы будем использовать.reshape () метод для выполнения этого действия. Наконец, нормализуйте данные изображения, разделив значение каждого пикселя на 255 (поскольку значения RGB могут варьироваться от 0 до 255):
# save input image dimensions
img_rows, img_cols = 28, 28
x_train = x_train.reshape (x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape (x_test.shape[0], img_rows, img_cols, 1)
x_train /= 255
x_test /= 255
Далее нам нужно преобразовать зависимую переменную в виде целых чисел в бинарную матрицу классов. Этого можно добиться с помощью to_categorical () функции:
from keras.utils import to_categorical
num_classes = 10
y_train = to_categorical (y_train, num_classes)
y_test = to_categorical (y_test, num_classes)
Теперь мы готовы создать модель и обучить ее!
Разработать модель
Процесс проектирования модели является наиболее сложным фактором, оказывающим непосредственное влияние на производительность модели. Для этого урока мы будем использовать этот дизайн из документации Keras.
Чтобы создать модель, мы сначала инициализируем последовательную модель. Он создает пустой объект модели. Первый шаг — добавить сверточный слой, который принимает входное изображение:
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
model = Sequential ()
model.add (Conv2D (32, kernel_size= (3, 3),
activation='relu’,
input_shape= (img_rows, img_cols, 1)))
Активация relu означает «Выпрямленные линейные единицы», которая принимает максимальное значение или ноль. Затем мы добавляем еще один сверточный слой, а затем объединяющий слой:
model.add (Conv2D (64, (3, 3), activation='relu’))
model.add (MaxPooling2D (pool_size= (2, 2)))
Далее мы добавляем слой «выпадающий». Пока нейронные сети обучаются на огромных наборах данных, может возникнуть проблема переобучения. Чтобы избежать этой проблемы, мы случайным образом сбрасываем юниты и их связи в процессе обучения. В этом случае мы сбросим 25% юнитов:
model.add (Dropout (0.25))
Затем мы добавляем сглаживающий слой, чтобы преобразовать предыдущий скрытый слой в одномерный массив:
model.add (Flatten ())
После того, как мы объединили данные в одномерный массив, мы можем добавить плотный скрытый слой, что является нормальным для традиционной нейронной сети. Затем добавьте еще один выпадающий слой перед добавлением последнего плотного слоя, который классифицирует данные:
model.add (Dense (128, activation='relu’))
model.add (Dropout (0.5))
model.add (Dense (num_classes, activation='softmax’))
Активация softmax используется, когда мы хотим классифицировать данные по нескольким заранее определенным классам.
Скомпилируйте и обучите модель
В процессе разработки модели мы создали пустую модель без целевой функции. Нам нужно скомпилировать модель и указать функцию потерь, функцию оптимизатора и метрику для оценки производительности модели.
Нам нужно использовать функцию sparse_categorical_crossentropy () потерь, если у нас есть целочисленная переменная. Для зависимой переменной на основе вектора, такой как массив из десяти размеров, в качестве выходных данных каждого тестового примера, используйте categorical_crossentropy. В этом примере мы будем использовать adamоптимизатор. Метрика является основой для оценки производительности нашей модели, хотя мы можем судить об этом и не используем на этапе обучения:
model.compile (loss='sparse_categorical_crossentropy’,
optimizer='adam’,
metrics=['accuracy’])
Теперь мы готовы обучить модель с помощью.fit () метода. Нам нужно указать эпоху и размер партии при обучении модели. Эпоха — это один проход вперед и один проход назад всех обучающих примеров. Размер партии — это количество обучающих примеров за один проход вперед или назад.
Наконец, сохраните модель после завершения обучения, чтобы использовать ее результаты на более позднем этапе:
batch_size = 128
epochs = 10
model.fit (x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data= (x_test, y_test))
score = model.evaluate (x_test, y_test, verbose=0)
print ('Test loss:', score[0])
print ('Test accuracy:', score[1])
model.save («test_model.h5»)
Когда мы запускаем приведенный выше код, во время работы модели отображается следующий вывод. На Macbook Air 2018 года с ноутбуками Jupyter это занимает около десяти минут:
Train on 60000 samples, validate on 10000 samples
Epoch 1/10
60000/60000 [==============================] — 144s 2ms/step — loss: 0.2827 — acc: 0.9131 — val_loss: 0.0612 — val_acc: 0.9809
Epoch 2/10
60000/60000 [==============================] — 206s 3ms/step — loss: 0.0922 — acc: 0.9720 — val_loss: 0.0427 — val_acc: 0.9857
...
Epoch 9/10
60000/60000 [==============================] — 142s 2ms/step — loss: 0.0329 — acc: 0.9895 — val_loss: 0.0276 — val_acc: 0.9919
Epoch 10/10
60000/60000 [==============================] — 141s 2ms/step — loss: 0.0301 — acc: 0.9901 — val_loss: 0.0261 — val_acc: 0.9919
Test loss: 0.026140549496188395
Test accuracy: 0.9919
В конце последней эпохи точность тестового набора данных составляет 99,19%. Трудно комментировать, насколько высокой должна быть точность. Для пробного прогона точность более 99% — это очень хорошо. Однако есть много возможностей для улучшения путем настройки параметров модели. Есть заявка на конкурс по распознаванию цифр на Kaggle, точность которого достигла 99,7%.
Тест с рукописными цифрами
Теперь, когда модель готова, давайте воспользуемся пользовательским изображением для оценки производительности модели. Я разместил пользовательскую цифру 28×28 на Imgur.
import imageio
import numpy as np
from matplotlib import pyplot as plt
im = imageio.imread («https: //i.imgur.com/a3Rql9C.png»)
Затем преобразуйте значения RGB в оттенки серого. Затем мы можем использовать.imshow () описанный выше метод для отображения изображения:
gray = np.dot (im[...,:3], [0.299, 0.587, 0.114])
plt.imshow (gray, cmap = plt.get_cmap ('gray’))
plt.show ()
5
Затем измените форму изображения и нормализуйте значения, чтобы подготовить его к использованию в модели, которую мы только что создали:
# reshape the image
gray = gray.reshape (1, img_rows, img_cols, 1)
# normalize image
gray /= 255
Загрузите модель из сохраненного файла с помощью load_model () функции и предскажите цифру с помощью.predict () метода:
# load the model
from keras.models import load_model
model = load_model («test_model.h5»)
# predict digit
prediction = model.predict (gray)
print (prediction.argmax ())
Модель правильно предсказывает цифру, показанную на изображении:
5
Последние мысли
В этом руководстве мы создали нейронную сеть с помощью Keras, используя серверную часть TensorFlow для классификации рукописных цифр. Хотя мы достигли точности 99%, возможности для улучшения все еще есть. Мы также научились классифицировать пользовательские рукописные цифры, которые не были частью тестового набора данных. Этот учебник, однако, только коснулся поверхности области искусственных нейронных сетей. Существует бесконечное количество применений нейронных сетей, которые ограничены только нашим воображением.