Сверточная нейронная сеть на Python и Keres

Наконец то мы продолжим писать нейронные сети на Питоне. Сегодня мы познакомимся с сверточными сетями. Будем опять распознавать рукописные цифры из базы MNIST. В сверточные сети так же входит полносвязная сеть, например персептрон. По этому читаем первую статью.

Немного теории.

Свёрточная нейронная сеть (англ.convolutional neural networkCNN) — специальная архитектура искусственных нейронных сетей, предложенная Яном Лекуном в 1988 году и нацеленная на эффективное распознавание образов, Использует некоторые особенности зрительной коры, в которой были открыты так называемые простые клетки, реагирующие на прямые линии под разными углами, и сложные клетки, реакция которых связана с активацией определённого набора простых клеток. 

ВикипедиЯ

Свёрточными сети называются так из за операции свертки, которая является основой всей сети. В этих сетях нету привычных связей и весовых коэффициентов. Вместо этого используется ядро свертки размером от 3х3 до 7х7. Операция свертки выделяет какой то признак в картинке, например переход от светлого пикселя к темному. Признаки зависят от ядра. Например в базе MNIST наши рукописные цифры это черно-белая картинка размером 28х28 (каждый пиксель имеет значения яркости от 0 до 255). По этой матрице мы проходим ядром и производим операцию свертки. После этого мы получаем слой свертки ( обычно такового размера , но бывает что большего или меньшего) или карту признака.

Автор: Michael Plotke

Следующая операция Пулинг . Это как бы сжатие картинки или слоя свёртки по максимум или среднему значению, при этом группа пикселей (обычно размера 2×2) уплотняется до одного пикселя. По факту мы увеличиваем область которую захватывает ядро свертки в два раза. Переходя от маленьких деталей изображения к более крупным. Так же пулингом мы объединяем карты признаков (полученные сверткой) в более абстрактные признаки, уже не пиксела , а черточки и т.д.

Автор: Aphex34

Keras. Создаем сеть.

Keras — открытая нейросетевая библиотека, написанная на языке Python. Она представляет собой надстройку над фреймворками TensorFlow, упрощая работу с последним.

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

Первым делом ставим TensorFlow , потом Keras. Далее нам надо будет понизить ваш numpy до 1.16.4.

pip install tensorflow
pip install keras
pip uninstall numpy 
pip install numpy==1.16.4

База MNIST уже есть в данных нашей библиотеки, загружаем базу:

# Подключаем датасет.
from keras.datasets import mnist
#Загружаем данные x_train и x_test содержат двухмерный массив с изображение цифр
# x_test, y_test массив с проверочными данными сети.  
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# Трансформируем из двухмерного массива в трех мерный(28х28х1 канал)
x_train = x_train.reshape(60000,28,28,1)
x_test = x_test.reshape(10000,28,28,1)

Функция reshape() изменяет форму массива без изменения его данных.

Numpy

Тестовые данные нам тоже надо преобразовать.

from keras.utils import to_categorical
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

keras.utils.to_categorical(y, num_classes=None, dtype=’float32′) . Преобразует вектор класса (целые числа) в двоичную матрицу классов.

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

Теперь у нас все готово к построению нашей нейро-сети.

from keras.models import Sequential
from keras.layers import Dense, Conv2D, Flatten
# создание модели
model = Sequential()
# Добавляем слой
model.add(Conv2D(64, kernel_size=3, activation='relu', input_shape=(28,28,1)))

Первый слой будет сверточный двухмерный (Conv2D) . Эти сверточные слои будут работать с входными изображениями, которые рассматриваются как двумерные матрицы. kernel_size=3 — размер ядра 3х3. Функция активации 'relu' ( Rectified Linear Activation ) , 64 это число ядер свертки( сколько признаком будем искать)

# Второй сверточный слой
model.add(Conv2D(32, kernel_size=3, activation='relu'))
# Создаем вектор для полносвязной сети.
model.add(Flatten())

Flatten() – слой, преобразующий 2D-данные в 1D-данные.

Keras
# Создадим однослойный перцептрон
model.add(Dense(10, activation='softmax'))

Dense() — полносвязный слов, число выходов — 10 , функция активации 'softmax'.

Далее, нам нужно скомпилировать нашу модель. Компиляция модели использует три параметра: оптимизатор, потери и метрики.

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

Оптимизатор весов optimizer='adam' (Адам: метод стохастической оптимизации). Функция потерь : loss='categorical_crossentropy' категориальная перекрестная энтропия (categorical crossentropy CCE). Последний параметр я не очень понял что такое :

metrics: List of metrics to be evaluated by the model during training and testing. Typically you will use metrics=['accuracy']. To specify different metrics for different outputs of a multi-output model, you could also pass a dictionary, such as metrics={'output_a': 'accuracy'}.

Теперь запускаем обучение сети :

hist = model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=1)
print(hist.history)

epochs=1 число эпох , validation_data=(x_test, y_test) — проверочные данные

Визуализация, эксперименты, сохранение.

Давайте построим графики обучения для наглядности. Благо метод fit() возвращает историю обучения.

import matplotlib.pyplot as plt
history = model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=5)

# Plot training & validation accuracy values
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()
#
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

Добавим слой Пулинг по Максимуму, и запустим на 10 эпох. Так же поменяем функцию ошибки и оптимизации.

from keras.layers import Dense, Conv2D, Flatten, MaxPooling2D

model.add(Conv2D(64, kernel_size=3, activation='relu', input_shape=(28, 28, 1)))
model.add(MaxPooling2D())
model.add(Conv2D(128, kernel_size=3, activation='relu'))
model.add(Flatten())
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='sgd', loss='mean_squared_error', metrics=['accuracy'])
history = model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=10)
'val_acc': [0.8221, 0.9609, 0.9733, 0.9756, 0.9797, 0.9809, 0.9821, 0.9828, 0.9836, 0.9841]

Сохранение / загрузка целых моделей (архитектура + веса + состояние оптимизатора)

Вы можете использовать model.save(filepath)для сохранения модели Keras в один файл HDF5, который будет содержать:

  • архитектура модели, позволяющая воссоздать модель
  • весовые коэффициенты модели
  • конфигурация обучения (потеря, оптимизатор)
  • состояние оптимизатора, позволяющее возобновить тренировку именно там, где вы остановились.
from keras.models import load_model

model.save('my_model.h5')  # Создание HDF5 файла 'my_model.h5'
del model  # Удаление модели.

# Загрузка модели обратно
model = load_model('my_model.h5')

Использование GPU.

Если вы работаете на TensorFlow или CNTK backends, ваш код автоматически запускается на GPU, если обнаружен какой-либо доступный GPU.

  • tensorflow —Latest stable release for CPU-only
  • tensorflow-gpu —Latest stable release with GPU support (Ubuntu and Windows)

Я думаю у вас еще много вопросов, но к сожаления разобраться со всем в одной статье очень трудно. Изучайте в месте со мной официальную документацию и экспериментируйте ))