Подтвердить что ты не робот

Где я могу назвать функцию BatchNormalization в Keras?

Если я хочу использовать функцию BatchNormalization в Keras, тогда мне нужно вызвать ее один раз только в начале?

Я прочитал эту документацию для него: http://keras.io/layers/normalization/

Я не вижу, где я должен это назвать. Ниже мой код пытается его использовать:

model = Sequential()
keras.layers.normalization.BatchNormalization(epsilon=1e-06, mode=0, momentum=0.9, weights=None)
model.add(Dense(64, input_dim=14, init='uniform'))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(64, init='uniform'))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(2, init='uniform'))
model.add(Activation('softmax'))

sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy', optimizer=sgd)
model.fit(X_train, y_train, nb_epoch=20, batch_size=16, show_accuracy=True, validation_split=0.2, verbose = 2)

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

4b9b3361

Ответ 1

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

Общий прецедент - использовать BN между линейным и нелинейным уровнями в вашей сети, поскольку он нормализует ввод вашей функции активации, так что вы центрированы в линейном разделе функции активации (например, сигмовидной). Там небольшое обсуждение этого здесь

В вашем случае выше это может выглядеть так:


# import BatchNormalization
from keras.layers.normalization import BatchNormalization

# instantiate model
model = Sequential()

# we can think of this chunk as the input layer
model.add(Dense(64, input_dim=14, init='uniform'))
model.add(BatchNormalization())
model.add(Activation('tanh'))
model.add(Dropout(0.5))

# we can think of this chunk as the hidden layer    
model.add(Dense(64, init='uniform'))
model.add(BatchNormalization())
model.add(Activation('tanh'))
model.add(Dropout(0.5))

# we can think of this chunk as the output layer
model.add(Dense(2, init='uniform'))
model.add(BatchNormalization())
model.add(Activation('softmax'))

# setting up the optimization of our weights 
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy', optimizer=sgd)

# running the fitting
model.fit(X_train, y_train, nb_epoch=20, batch_size=16, show_accuracy=True, validation_split=0.2, verbose = 2)

Надеюсь, что это еще раз прояснит ситуацию.

Ответ 2

Этот поток вводит в заблуждение. Пробовал комментировать Lucas Ramadan ответ, но у меня пока нет правильных привилегий, поэтому я просто поставлю это здесь.

Нормальная нормализация партии работает лучше всего после активации, и здесь или здесь, почему: он был разработан для предотвращения внутреннего ковариационного сдвига. Внутренний сдвиг ковариации происходит, когда распределение активаций слоя значительно изменяется во время тренировки. Стандартизация партии используется так, что распределение входов (и эти входы в буквальном смысле является результатом функции активации) на определенный уровень не изменяется со временем из-за обновлений параметров из каждой партии (или, по крайней мере, позволяет изменять выгодным способом). Он использует статистическую статистику для нормализации, а затем использует параметры нормализации партии (гамма и бета в исходной бумаге), чтобы убедиться, что преобразование, вставленное в сеть, может представлять собой преобразование идентичности "(цитата из оригинальной статьи). Но дело в том, что мы пытаемся нормализовать входные данные для слоя, поэтому он всегда должен идти непосредственно перед следующим уровнем в сети. Независимо от того, зависит ли это от функции активации от соответствующей архитектуры.

Ответ 3

В этой ветке ведутся серьезные дебаты о том, следует ли применять BN до нелинейности текущего слоя или для активаций предыдущего слоя.

Хотя нет правильного ответа, авторы Batch Normalization говорят, что он должен быть применен непосредственно перед нелинейностью текущего слоя. Причина (цитата из оригинальной статьи) -

"Мы добавляем преобразование BN непосредственно перед нелинейностью, нормализуя x = Wu + b. Мы могли бы также нормализовать входы слоя u, но, поскольку u, вероятно, является выходом другой нелинейности, форма его распределения, вероятно, изменится во время тренировка и ограничение его первого и второго моментов не устранят ковариатный сдвиг. Напротив, Wu + b более вероятно будет иметь симметричное, не разреженное распределение, то есть "более гауссово" (Hyv¨arinen & Oja, 2000) нормализация может привести к активациям со стабильным распределением ".

Ответ 4

Теперь уже становится трендом, чтобы иметь Conv2D, за которым следует ReLu, за которым следует BatchNormalization. Поэтому я сделал небольшую функцию, чтобы сразу вызвать всех. Делает определение модели более чистым и более легким для чтения.

def Conv2DReluBatchNorm(n_filter, w_filter, h_filter, inputs):
    return BatchNormalization()(Activation(activation='relu')(Convolution2D(n_filter, w_filter, h_filter, border_mode='same')(inputs)))

Ответ 5

Теперь use_bias=False поддерживает use_bias=False, поэтому мы можем сохранить некоторые вычисления, написав

model.add(Dense(64, use_bias=False))
model.add(BatchNormalization(axis=bn_axis))
model.add(Activation('tanh'))

или же

model.add(Convolution2D(64, 3, 3, use_bias=False))
model.add(BatchNormalization(axis=bn_axis))
model.add(Activation('relu'))

Ответ 7

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

Сразу после вычисления линейной функции, скажем, Dense() или Conv2D() в Keras, мы используем BatchNormalization(), которая вычисляет линейную функцию в слое, а затем мы добавляем нелинейность в слой, используя Activation().

from keras.layers.normalization import BatchNormalization
model = Sequential()
model.add(Dense(64, input_dim=14, init='uniform'))
model.add(BatchNormalization(epsilon=1e-06, mode=0, momentum=0.9, weights=None))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(64, init='uniform'))
model.add(BatchNormalization(epsilon=1e-06, mode=0, momentum=0.9, weights=None))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(2, init='uniform'))
model.add(BatchNormalization(epsilon=1e-06, mode=0, momentum=0.9, weights=None))
model.add(Activation('softmax'))

sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy', optimizer=sgd)
model.fit(X_train, y_train, nb_epoch=20, batch_size=16, show_accuracy=True, 
validation_split=0.2, verbose = 2)

Как применяется нормализация партии?

Предположим, мы ввели слой [l-1] в слой l. Также у нас есть веса W [l] и единица смещения b [l] для слоя l. Пусть a [l] будет вектором активации, вычисленным (т.е. после добавления нелинейности) для слоя l, а z [l] будет вектором до добавления нелинейности

  1. Используя [l-1] и W [l] мы можем вычислить z [l] для слоя l
  2. Обычно в распространении с прямой связью мы добавим единицу смещения к z [l] на этом этапе, как этот z [l] +b [l], но в нормализации партии этот шаг добавления b [l] не требуется и параметр b [l] не используется.
  3. Рассчитать z [l] означает и вычесть его из каждого элемента
  4. Разделите (z [l] - среднее), используя стандартное отклонение. Назовите это Z_temp [l]
  5. Теперь определите новые параметры γ и β, которые изменят масштаб скрытого слоя, следующим образом:

    z_norm [l] = γ.Z_temp [l] + β

В этом фрагменте кода Dense() берет a [l-1], использует W [l] и вычисляет z [l]. Затем немедленная BatchNormalization() выполнит вышеуказанные шаги, чтобы получить z_norm [l]. И тогда немедленная Activation() вычислит tanh (z_norm [l]), чтобы получить [l], т.е.

a[l] = tanh(z_norm[l])