Часть 3
Сверточные нейронные сети (ConvNets) используются для обработки естественного языка и компьютерного зрения. Ключевое различие между многослойными персептронами (MLP) и ConvNet заключается в том, что MLP имеет плотно связанные слои, которые изучают глобальные шаблоны, тогда как ConvNet изучает локальные шаблоны с помощью фильтров.
Успех ConvNet в конкурсе классификации изображений в 2011 году привел к более широкому вниманию к области глубокого обучения.
ConvNets предназначены для работы со структурированными входными данными сетки, которые имеют сильные особые зависимости в локальной области сетки. Например, простейшая структура сетки — это черно-белое изображение, представляющее собой двумерную структуру сетки.
Две интересные характеристики, которыми обладает ConvNet:
- Шаблоны, которые изучает ConvNet, инвариантны к трансляции.
- ConvNet может изучать специальные иерархии шаблонов.
В ConvNet состояния в каждом слое располагаются в соответствии со специальной структурой сетки. Эти особые отношения наследуются от одного слоя к другому. Важно поддерживать эти особые отношения между ячейками сетки, потому что сверточная операция и преобразование к следующему слою критически зависят от этих отношений.
Типичная ConvNet имеет три типа слоев: свертка, объединение и ReLu (как показано на изображении выше).
В нашем примере мы используем набор данных CIFRA10. Набор данных CIFRA10 был разработан Канадским институтом перспективных исследований и состоит из 60 000 фотографий размером 32x32 пикселя, разделенных на 10 классов. Набор данных разделен на обучающие и тестовые данные, где 50 000 изображений являются обучающими данными, а 10 000 изображений — тестовыми данными.
Итак, специальные размеры входных данных — 32x32 с глубиной 3, которые должны поддерживаться нашим первым слоем ConvNet.
В ConvNet параметры организованы в наборы трехмерных структурных единиц, называемых фильтрами. Фильтры обычно квадратные с точки зрения специальных размеров, а типичные размеры 3x3, 5x5, 7x7 и более на больших изображениях, и они также называются картой признаков.
Фундаментальное различие между плотно связанным слоем (наш пример из части I) и сверточным слоем заключается в том, что первый изучает глобальные шаблоны в своем входном пространстве признаков, тогда как сверточный слой изучает локальные шаблоны на основе размера фильтров.
Прокладка
Операция свертки уменьшает размер слоя по сравнению с размером предыдущего слоя. Давайте посмотрим на пример. Если у нас есть входное изображение 32x32, после первого слоя операции свертки вы получите изображение 28x28. Если вам нужно получить выходное изображение с теми же пространственными размерами, что и входное изображение, то нам нужно будет использовать заполнение. Заполнение — это метод добавления соответствующего количества строк и столбцов с каждой стороны карты входных объектов, чтобы можно было расположить центральное окно свертки вокруг каждой входной плитки. В библиотеке Keras это достигается путем настройки аргумента заполнения на «одинаковый» в слое Conv2D, что означает, что выходные данные должны иметь ту же ширину и высоту, что и входные данные. Взгляните на пример кода:
# Convolutional Layer 1 model.add(Conv2D(32, (3, 3), input_shape=(32, 32, 3), padding='same', activation='relu', kernel_constraint=maxnorm(3)))
Операция максимального объединения
В приведенном ниже примере вы заметите, что размер карты объектов уменьшается на 50% после каждого слоя MaxPooling2D, который играет роль агрессивного понижения дискретизации карты объектов. Эта операция концептуально похожа на операцию свертки, за исключением того, что вместо преобразования локальных патчей с помощью изученного линейного преобразования она преобразуется с помощью жестко запрограммированной операции максимального тензора. Максимальное объединение обычно выполняется с окнами 2x2, тогда как свертка обычно выполняется с окнами 3x3.
Смысл использования понижающей дискретизации состоит в том, чтобы уменьшить количество обрабатываемых коэффициентов карты признаков. Другой способ добиться понижения дискретизации — использовать шаги в предыдущем слое свертки.
model.add(Conv2D(32, (3, 3), input_shape=(32, 32, 3), padding='same', activation='relu', kernel_constraint=maxnorm(3))) model.add(MaxPooling2D(pool_size=(2, 2)))
Наиболее разумной стратегией подвыборки является создание плотных карт функций, а затем рассмотрение максимальной активации функций на небольших участках.
Методы достижения более высокой точности
Для достижения высокой точности вашей модели следует использовать следующие стратегии:
- Увеличение данных. Он генерирует больше обучающих данных из существующего набора данных, дополняя выборки с помощью ряда случайных преобразований, которые дают правдоподобно выглядящие изображения. Цель состоит в том, чтобы во время обучения ваша модель никогда не видела одну и ту же картинку дважды.
- Извлечение признаков с помощью предварительно обученной сети. Очень эффективным и распространенным способом углубления обучения на небольших наборах данных является использование предварительно обученных сетей. Если набор данных достаточно большой и достаточно общий, то специальная иерархия признаков, изученная предварительно обученной сетью, может эффективно действовать как общая модель и может оказаться полезной для многих различных задач компьютерного зрения. Извлечение признаков — это метод, который использует представления, изученные предыдущей сетью, для извлечения интересных признаков из новых выборок. Затем эти функции проходят через новый классификатор, который обучается с нуля.
- Тонкая настройка предварительно обученной сети. Это еще один очень популярный метод повторного использования модели. Техника точной настройки состоит из размораживания нескольких сверточных базовых слоев и совместного обучения как новых добавленных слоев в модель, так и этих незакрепленных верхних слоев. Это называется тонкой настройкой, так как она немного корректирует более абстрактное представление повторно используемой модели.
Модель CNN и пример кода
Как упоминалось ранее, в этом примере я использую набор данных CIFRA10. Для этого набора данных и после некоторых экспериментов я создал модель, показанную на рисунке ниже:
С этой моделью я добился точности 83,41%; оставляя эту модель с огромными возможностями для улучшения, применяя методы, описанные в этой статье.
Ниже приведен полный код модели сверточных нейронных сетей (CNN):
import numpy as np from keras.models import Sequential from keras.layers import Dense, Activation, Dropout from keras.layers import Flatten from keras.layers.convolutional import Conv2D from keras.layers.convolutional import MaxPooling2D from keras.utils import to_categorical from keras.constraints import maxnorm from keras.optimizers import SGD from keras.datasets import cifar10 import matplotlib.pyplot as plt # network attributes dropout1 = 0.2 dropout2 = 0.5 epochs = 100 learning_rate = 0.01 batch_size = 30 decay = learning_rate/epochs sgd = SGD(lr=learning_rate, momentum=0.9, decay=decay, nesterov=False) # initialize random number generator seed = 7 np.random.seed(seed) ############################################### # Load and prepare dataset ############################################### # load CIFRA10 dataset (x_train, y_train), (x_test, y_test) = cifar10.load_data() # normalize the input from 0-255 to 0.00 - 1.00 X_train = (x_train.astype('float32')) / 255 X_test = (x_test.astype('float32')) / 255 # label encoding - one hot encode y_train = to_categorical(y_train) y_test = to_categorical(y_test) number_classes = y_test.shape[1] ############################################### # Create our CNN model ############################################### def create_model(): model = Sequential() # Convolutional Layer 1 model.add(Conv2D(32, (3, 3), input_shape=(32, 32, 3), padding='same', activation='relu', kernel_constraint=maxnorm(3))) # model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(dropout1)) # Convolutional Layer 2 model.add(Conv2D(32, (3, 3), padding='same', activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) # Convolutional Layer 3 model.add(Conv2D(64, (3, 3), padding='same', activation='relu')) model.add(Dropout(dropout1)) # Convolutional Layer 4 model.add(Conv2D(64, (3, 3), padding='same', activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) # Convolutional Layer 5 model.add(Conv2D(128, (3, 3), padding='same', activation='relu')) model.add(Dropout(dropout1)) # Convolutional Layer 6 model.add(Conv2D(128, (3, 3), padding='same', activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) # Dropout is added as Regulaizer model.add(Flatten()) model.add(Dropout(dropout1)) # multilayer perceptrons part of the network model.add(Dense(512, activation='relu')) model.add(Dropout(dropout1)) model.add(Dense(128, activation='relu')) model.add(Dropout(dropout1)) model.add(Dense(number_classes)) model.add(Activation('softmax')) # compile the model model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy']) return model # build a model model = create_model() # print model summary model.summary() # train the model history = model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=epochs, batch_size=batch_size) # Final evaluation of the model score = model.evaluate(X_test, y_test, verbose=0) print("\n--------------------------------------------") print("\nCNN Accuracy: %.2f%%" % (score[1]*100)) print("\nCNN Error: %.2f%%" % (100-score[1]*100)) # summarize history for accuracy 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() # summarize history for loss 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() # save the model as JSON file # serialize model to JSON model_json = model.to_json() with open("CNN2_model.json", "w") as json_file: json_file.write(model_json) # save the weights # serialized weight to HDF5 model.save_weights("CNN2_model.h5") print("\nCNN model saved to the disk.")
А вот и графики точности и потерь в зависимости от эпох.
Резюме
Это продолжение моего исследования ИИ, и я надеюсь, вам понравилось это чтение. В моей следующей статье я буду говорить о преобразовании данных и подготовке данных.
использованная литература
- Глубокое обучение с помощью Python, Франсуа Шолле, ISBN 9781617294433
- Искусственный интеллект для людей, том 1: основные алгоритмы, Джефф Хитон, ISBN978–1493682225
- Искусственный интеллект для людей, том 3: глубокое обучение и нейронные сети, Джефф Хитон, ISBN978–1505714340
- Разработка моделей глубокого обучения на Theano и TensorFlow с использованием Keras, Джейсон Браунли
- Глубокое обучение, Ян Гудфеллоу, Йошуа Бенджио и Аарон Курвиль, ISBN 9780262035613
- Нейронные сети и обучающие машины, Саймон Хейкин, ISBN 9780131471399
- Нейронные сети и глубокое обучение, Чари К. Аггарвал, ISBN 9783319944623