Набор данных «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 соответственно. За обоими этими слоями будет следовать объединяющий слой. Еще более упрощенное изображение можно увидеть ниже:
Большая разница между сверточным слоем и объединяющим слоем заключается в том, что сверточный слой служит для обнаружения шаблонов в подобластях изображения, в то время как объединяющий слой просто уменьшает пространственный размер представления. В модель также будет включен выпадающий слой, который помогает в переоснащении модели. Для получения дополнительной информации по этим темам перейдите по ссылкам ниже:
- https://towardsdatascience.com/a-comprehensive-guide-to-convolutional-neural-networks-the-eli5-way-3bd2b1164a53
- https://machinelearningmastery.com/convolutional-layers-for-deep-learning-neural-networks/
- https://keras.io/api/layers/regularization_layers/dropout/
Код модели
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.