Набор данных «MNIST» представляет собой рукописную задачу цифровой классификации, которая обычно используется в глубоком обучении. Он состоит из 60 000 значений от 0 до 9 (включительно), представленных на сетке градаций серого размером 28x28 пикселей. Эти значения «написаны от руки», что означает, что они не выглядят идеально. В этом пошаговом руководстве я разработаю простую сверточную нейронную сеть для набора данных MNIST с целью достижения точности более 99%. Это будет свидетельствовать о топовой модели.

Среда

В этом пошаговом руководстве предполагается, что зритель использует Keras (TensorFlow) в сочетании с Python 3. Ниже приведено руководство по установке Keras и TensorFlow в вашей среде кодирования.



Прохождение

Необходимые пакеты

Сначала мы начнем это пошаговое руководство с импорта всех необходимых пакетов, необходимых для этого руководства. Сюда входят Numpy, Keras, Layers и Pyplot (для визуальных эффектов).

import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
from matplotlib import pyplot as plt

Подготовка данных/визуализация

На следующем этапе пошагового руководства я буду импортировать набор данных MNIST из Keras. Прежде чем мы сможем визуализировать данные, необходимо выполнить несколько шагов предварительной обработки. Они будут следовать следующему порядку:

  • Разделите данные между тестовыми и обучающими наборами
  • Масштабировать изображения в диапазоне от 0 до 1
  • Убедитесь, что изображения имеют правильную форму ввода (каждый ввод имеет форму пикселя размером 28x28).
  • Преобразование векторов классов в бинарные матрицы классов

Разделение на тестовые/тренировочные данные

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

Масштабирование изображений

В этом разделе значения пикселей для каждого изображения в наборе данных находятся в диапазоне от 0 до 255. Эти значения связаны со значениями в диапазоне от черного до белого. Поэтому, чтобы правильно их масштабировать, значения сначала нужно преобразовать в числа с плавающей запятой, а затем разделить на 255.

x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255

Исправление формы ввода

x_train = np.expand_dims(x_train, -1)
x_test = np.expand_dims(x_test, -1)
print("x_train shape:", x_train.shape)
print(x_train.shape[0], "train samples")
print(x_test.shape[0], "test samples")

Преобразование предсказанного значения в матрицы бинарных классов

Библиотека Keras Utility может быть очень полезна при выполнении функций с массивами Numpy. Наш желаемый результат — перейти от массива к матрице. Таким образом, предсказание [2] будет представлено как [0,0,1,0,0,0,0,0,0,0]. Числовые классы в данном случае равны 10, что представляет все возможные значения от 0 до 9 (включительно).

num_classes = 10
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print(y_train.shape)

Визуализация данных

Для визуализации я буду отображать первые 9 изображений в наборе данных, чтобы дать представление о том, что я буду прогнозировать. Поскольку это принимает первые 9 значений, будут показаны не все возможные классы.

for i in range(9):
 # define subplot
 plt.subplot(330 + 1 + i)
 # plot raw pixel data
 plt.imshow(x_train[i], cmap=plt.get_cmap('gray'))
# show the figure
plt.show()

Построение модели

Есть несколько ключевых факторов в определении нашей простой сверточной нейронной сети для этой задачи. Эти модели представляют собой специализированный тип нейронной сети, предназначенный для работы с данными двумерного изображения. Эти модели имеют два основных аспекта: интерфейс извлечения признаков и серверная часть классификатора. Цель CNN состоит в том, чтобы преобразовать введенные изображения в форму, которую очень легко обрабатывать, не теряя при этом некоторых функций, которые имеют решающее значение для получения точного прогноза. Пример можно увидеть на изображении ниже:

Как видно на изображении выше, это два основных аспекта, о которых я упоминал ранее. Часть извлечения признаков, включающая сверточные слои, а также функцию активации и объединяющий слой, а также серверную часть классификации. Как видно на изображении, вполне допустимо иметь несколько сверточных слоев для дальнейшего разбиения введенных изображений. В этом примере я буду использовать два сверточных слоя с небольшим размером фильтра (3,3) и фильтрами 32 и 64 соответственно. За обоими этими слоями будет следовать объединяющий слой. Еще более упрощенное изображение можно увидеть ниже:

Большая разница между сверточным слоем и объединяющим слоем заключается в том, что сверточный слой служит для обнаружения шаблонов в подобластях изображения, в то время как объединяющий слой просто уменьшает пространственный размер представления. В модель также будет включен выпадающий слой, который помогает в переоснащении модели. Для получения дополнительной информации по этим темам перейдите по ссылкам ниже:

Код модели

model = keras.Sequential(
    [
        keras.Input(shape=input_shape),
        layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
        layers.MaxPooling2D(pool_size=(2, 2)),
        layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
        layers.MaxPooling2D(pool_size=(2, 2)),
        layers.Flatten(),
        layers.Dropout(0.5),
        layers.Dense(num_classes, activation="softmax"),
    ]
)

model.summary()

Оценка модели

Для оценки нашей модели мы будем использовать размер пакета 128 и скромные 15 эпох. Поскольку мы не используем перекрестную проверку при оценке нашей модели, использование большего размера пакета поможет ускорить обучение, поскольку пакеты распространяются по сети. Кроме того, поскольку у нас есть 10 потенциальных результатов в нашей модели (многоклассовой), нам понадобится категориальная функция потерь при оценке нашей модели. В этом случае categorical_crossentropy будет сильной функцией потерь. Кроме того, мы можем предположить использовать это, учитывая, что Softmax используется в нашем уровне классификации. Показателем производительности, который я буду использовать для оценки модели, является точность. Наконец, validation_split, равный 0,9, позволит использовать обучающий набор из 54 000 изображений и проверочный набор из 6000 изображений.

Обучение модели

batch_size = 128
epochs = 15

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

model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)

Оценка обученной модели

score = model.evaluate(x_test, y_test, verbose=0)
print("Test loss:", score[0])
print("Test accuracy:", score[1])

Окончательная оценка для нашей модели показала точность теста ~ 99,2 % с тестовой потерей ~ 2,2. Это свидетельствует о сильной производительности модели. Хотя есть потенциал для дальнейшей настройки и разработки модели с более высокой точностью (посмотрите на скорость обучения, нормализацию пакетов, увеличение глубины модели и т. д.), этот пример дает обзор простой модели и потенциал для CNN.

Источники

Браунли, Джейсон. Как разработать CNN для классификации рукописных цифр Mnist. Мастерство машинного обучения, 14 ноября 2021 г., https://machinelearningmastery.com/how-to-develop-a-convolutional-neural-network-from-scratch-for-mnist-handwriting-digit -классификация/.

фшолле. Документация Keras: простая сеть Mnist. Keras, 21 апреля 2015 г., https://keras.io/examples/vision/mnist_convnet/.

Саха, Сумит. Полное руководство по сверточным нейронным сетям — путь eli5. Medium, Towards Data Science, 17 декабря 2018 г., https://towardsdatascience.com/a-comprehensive-guide-to-convolutional-neural-networks-the-eli5-way-3bd2b1164a53.