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

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

Keras. Создаем сеть.
Keras — открытая нейросетевая библиотека, написанная на языке Python. Она представляет собой надстройку над фреймворками TensorFlow, упрощая работу с последним.
TensorFlow — открытая программная библиотека для машинного обучения, разработанная компанией Google для решения задач построения и тренировки нейронной сети с целью автоматического нахождения и классификации образов, достигая качества человеческого восприятия.
Первым делом ставим TensorFlow 2.0.0 , потом Keras. Далее нам надо будет понизить ваш numpy до 1.16.4. Все это дело работает на Python 3.6.8.
pip install tensorflow==2.0.0
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-onlytensorflow-gpu
—Latest stable release with GPU support (Ubuntu and Windows)
Я думаю у вас еще много вопросов, но к сожаления разобраться со всем в одной статье очень трудно. Изучайте в месте со мной официальную документацию и экспериментируйте ))