Сверточная нейронная сеть на Python и Keras
Наконец то мы продолжим писать нейронные сети на Питоне. Сегодня мы познакомимся с сверточными сетями. Будем опять распознавать рукописные цифры из базы 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= .
Теперь запускаем обучение сети :
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)
Я думаю у вас еще много вопросов, но к сожаления разобраться со всем в одной статье очень трудно. Изучайте в месте со мной официальную документацию и экспериментируйте ))
Ошибка в тексте? Выделите её и нажмите «Ctrl + Enter»