Пошаговое объяснение с реализацией архитектуры Keras.

Сверточные нейронные сети (CNN) - это наиболее широко используемые архитектуры глубокого обучения при обработке изображений и распознавании изображений. Учитывая их превосходство в поле зрения, вполне естественно, что будут опробованы реализации в различных областях машинного обучения. В этой статье я попытаюсь объяснить важную терминологию, касающуюся CNN, с точки зрения обработки естественного языка, также будет предоставлена ​​короткая реализация Keras с пояснениями кода.

Концепция скольжения или сворачивания заранее определенного окна данных является центральной идеей, по которой CNN называются так, как они есть. Иллюстрация этой концепции приведена ниже.

Первое, на что следует обратить внимание, - это метод, с помощью которого каждое слово (токен) представляется в виде трехмерных векторов слов. Затем весовая матрица 3x3 скользит по предложению горизонтально на один шаг (также известный как шаг), захватывая по три слова за раз. Эта весовая матрица называется фильтром; Каждый фильтр также имеет функцию активации, аналогичную тем, которые используются в нейронных сетях с прямой связью. Из-за некоторых математических свойств функция активации ReLU (выпрямленный линейный блок) в основном используется в CNN и глубоких нейронных сетях. Возвращаясь к классификации изображений, общая интуиция, лежащая в основе этих фильтров, заключается в том, что каждый фильтр может обнаруживать различные особенности изображения, чем глубже фильтр, тем больше вероятность, что он захватит более сложные детали, например, самые первые фильтры в вашем Convnet обнаружит простые особенности, такие как края и линии, но особенности в самой задней части могут быть в состоянии обнаруживать определенные типы животных. Все это делается без жесткого кодирования каких-либо фильтров. Обратное распространение гарантирует, что веса этих фильтров извлекаются из данных.
Следующим важным шагом является вычисление выходных данных (функция свертки). Для примера ниже мы рассмотрим изображение 5 * 5 и фильтр 3 * 3 (при работе с CNN вы в основном будете работать с квадратными матрицами) выходной слой рассчитывается путем суммирования по поэлементному умножению, когда каждый фильтр скользит по окно данных по одному шагу за раз, каждый пиксель умножается на его соответствующий вес в фильтре. В приведенном ниже примере показано, как рассчитывается первая ячейка в выходном слое; красные числа на изображении представляют веса в фильтре.

Расчет выглядит следующим образом: (1 ∗ 2) + (1 ∗ 1) + (1 ∗ 0) + (0 ∗ 1) + (2 ∗ 0) + (0 ∗ 1) + (0 ∗ 0) + (2 ∗ 1) + (0 ∗ 4) = 5

Код python с функцией активации будет:

z_0 = max (сумма (x * w), 0)

В случае 2D-фильтра Размер выходного слоя можно рассчитать по следующей формуле:

(N-F)/S +1

N = размер изображения, F = размер фильтра S = шаг (1 в нашем случае)

При применении к тексту вы будете использовать фильтр, который скользит на 3 шага по горизонтали по окну в одномерном измерении:

Заполнение

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

  1. Заполните внешние края нулевыми векторами (заполнение нулями)
  2. игнорировать часть матрицы, которая не соответствует фильтру (допустимое заполнение)

Объединение

Объединение в пул эквивалентно уменьшению размерности CNN. Основная идея состоит в том, что мы должны разделить выходные слои на подсекции и вычислить значение, которое лучше всего представляет результат. Причина, по которой это так эффективно, заключается в том, что он помогает алгоритму изучать представления данных более высокого порядка, сокращая при этом количество параметров. Типы пулинга:

  1. Суммарный пул
  2. Максимальное объединение
  3. Средний пул

Вот пример максимального пула:

Полностью связанный слой

Полностью подключенный уровень в конце получает входные данные от предыдущих слоев пула и сверточных слоев, а затем выполняет задачу классификации. В нашем примере мы будем классифицировать окно слов из 300 токенов в 1-позитивное настроение. 0-негативное настроение. Последний нейрон в полностью подключенном слое примет средневзвешенное значение 250 нейронов как сигмовидную функцию (возвращает значение между (0,1))

Реализация Keras

В этом разделе мы постараемся сделать код как можно более общим для случаев использования в НЛП. Для простоты мы не будем вдаваться в подробности предварительной обработки данных, но общая процедура заключается в токенизации и векторизации данных. В нашем примере использовалось встраивание word2vec, при этом каждый токен был представлен как 300-мерный вектор слова. Наши данные также были дополнены так, чтобы каждое предложение содержало 400 токенов, длинные предложения были обрезаны после 400 токенов, а более короткие предложения были дополнены нулями. В результате размерность каждого предложения составляет 300 * 400. Затем мы разделяем данные на x_train и x_test; мы не будем использовать набор данных проверки для этого проекта. Теперь, когда у нас есть данные, мы можем определить некоторые гиперпараметры.

##hyper parameters
batch_size = 32
embedding_dims = 300 #Length of the token vectors
filters = 250 #number of filters in your Convnet
kernel_size = 3 # a window size of 3 tokens
hidden_dims = 250 #number of neurons at the normal feedforward NN
epochs = 2

Теперь мы можем приступить к построению модели с помощью библиотеки Keras.

model = Sequential()
model.add(Conv1D(filters,kernel_size,padding = 'valid' , activation = 'relu',strides = 1 , input_shape = (maxlen,embedding_dims)))

Здесь мы утверждаем, что заполнение допустимо, что означает, что мы не будем поддерживать размер ввода, результирующая свернутая матрица будет иметь размер 100 * 1. Максимальный уровень объединения, который принимает максимальное значение в окне из двух.

model.add(GlobalMaxPooling1D())
#GlobalMaxPooling1D(n) default = 2.

Затем мы добавляем полностью связанный слой с коэффициентом отсева 0,2 (мы используем это, чтобы противодействовать переобучению). Наконец, выходной нейрон сработает на основе функции активации сигмовидной кишки. Керас классифицирует все, что ниже 0,5, как 0, а все, что выше 0,5, как 1.

model.add(Dense(hidden_dims))
model.add(Dropout(0.2))
model.add(Activation('relu'))
model.add(Dense(1))
model.add(Activation('sigmoid'))

Последний шаг - скомпилировать и подогнать модель.

model.compile(loss = 'binary_crossentropy',optimizer = 'adam', metrics = ['accuracy'])
model.fit(x_train,y_train,batch_size = batch_size,epochs = epochs , validation_data = (x_test,y_test))

Теперь вы можете сесть и посмотреть, как тренируется ваша модель. Мы смогли достичь точности 90%, используя 60% данных обучения Стэнфорда. вы можете найти более подробную информацию в 7-й главе книги: Обработка естественного языка в действии.

Резюме

  1. CNN могут использоваться для различных задач классификации в NLP.
  2. Свертка - это окно, которое скользит по большим входным данным с акцентом на подмножество входной матрицы.
  3. Получение данных в правильных размерах чрезвычайно важно для любого алгоритма обучения.