Компьютерное зрение. Машиное обучение с использовнием нейронных сетей (Keras)

Следующим этапом введения в компьютерное зрение является переход к более широкораспространенному инструменту в современных исследованиях, а именно нейронным сетям.

Знакомство с нейронными сетями начнем с фреймворка Keras. И на базе того же датасета MNIST попробуем сначала обучить собственную сверточную нейронную сеть.

По умолчанию Keras имеет в своей основе TensorFlow, который имеет достаточно хорошую поддержку GPU.

Импортируем зависимости, которые нам понадобятся:

import os
import matplotlib.pyplot as plt
import numpy as np
import keras
from keras.datasets import mnist
from sklearn.metrics import confusion_matrix
from sklearn.utils.multiclass import unique_labels

Загрузка датасета

Keras имеет из коробки функционал по загрузке интересующего нас датасета, потому им и воспользуемся.

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

print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

Подготовка датасета и параметров обучения

Далее зададим переменные с параметрами датасета и настройками обучения. В нашем случаем размер изображения 28×28, число классов 10. В качестве настроек обучения примем размер подвыборки 512 изображений и длительность обучения 10 эпох.

Деление датасета на подвыборки приводит к уменьшению общности выборки на которой оптимизируются веса модели, однако позволяет производить обучение на больших датасетах последовательно оптимизируя модель для всех подвыборок из него. Основная причина использования подвыборок — ограничение на объем памяти и размера обучающей модели.

Кроме того, зададим путь для сохранения модели и имя модели.

# Размер изображения
img_rows, img_cols = 28, 28
# Число классов в датасете
num_classes = 10

# Размер подвыборки для обучения
batch_size = 512
# Количество эпох обучения
epochs = 10

# Путь для сохранения обученной модели и имя модели
save_dir = os.path.join(os.getcwd(), 'saved_models')
model_name = 'keras_mnist_trained_model.h5'

Следующие команды преобразуют размерность входных данных в соответствии с форматом изображений, принятым в используемом бэкэнде Keras (это может быть как TensorFlow, так и Teano)

from keras import backend as K

if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    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)
    input_shape = (img_rows, img_cols, 1)

Теперь преобразуем значение пикселя из целочисленного значения в число с плавающей точкой и нормализуем его на диапазон [0, 1]

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

Следующим шагом является преобразование значение класса каждого изображения из целочисленного значения от 0 до 9 в вектор из 10 элементов. Для примера выведем первый.

# Convert class vectors to binary class matrices.
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print(y_test[0])

Создание модели

Следующим шагом является создание нейросетевой модели, например, последовательной модели Keras.

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

Для добавления слоев в последовательную модель используется метод add.

  • В строке 5 создается объект модели.
  • В строке 6 добавляется входной сверточный слой с указанием размерности входа.
  • В последующих строках добавляются слои модели.

В предложенной модели используются следующие слои:

  • Conv2D — сверточный слой
  • Activation — слой активации
  • MaxPooling2D -слой дискретизации на основе выборки . Цель состоит в том, чтобы уменьшить выборку входного представления (изображение, выходную матрицу скрытого слоя и т. Д.), Уменьшив его размерность и сделав допущения относительно предположений о свойствах, содержащихся в выбранных субрегионах. Работает на основе выбора максимального значения из подвыборки размером pool_size. По умолчанию подвыборка сдвигается без перекрытия.
  • Dropout — слой прореживания для решения проблемы переобучения сети
  • Flatten — преобразование в одномерный вектор
  • Dense — полносвязный слой
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D

model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same',
                 input_shape=x_train.shape[1:]))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

После того, как модель сформирована, ее необходимо скомпилировать с указанием функции потерь, оптимизатора и метрики. В нашем случае в качестве функции потерь используется categorical_crossentropy, метрика точности и оптимизатор Ададельта.

После компиляции производится обучение модели методом fit. В метод передаются введенные ранее параметры и данные для обучения и тестирования.

По окончанию обучения проведем проверку, вычислив отклик сети на тестовые данные, и выведем итоговые значения функции потерь и точности.

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

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])

Визуализация результата

Для визуализации результатов обучения также как и ранее воспользуемся confusion matrix.

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

expected = np.argmax(y_test, 1)
predicted = np.argmax(model.predict(x_test), 1)

Введем имена классов и построим матрицу.

class_names = np.array(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"])

# Plot non-normalized confusion matrix
plot_confusion_matrix(expected, predicted, classes=class_names,
                      title='Confusion matrix, without normalization')

Как видно по визуализации матрицы, качество классификатора существенно выше, чем при использовании классических методок машинного обучения.

Colaboratory Jupiter Notebook

Компьютерное зрение. Машиное обучение с использовнием нейронных сетей (Keras): 2 комментария

  1. Уведомление: Компьютерное зрение. Введение | Digiratory

  2. Уведомление: Состязательные (Adversarial) атаки с помощью Keras и TensorFlow | Digiratory

Обсуждение закрыто.