Где я могу вызвать функцию 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)

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

6 89

6 ответов:

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

общий случай использования-использовать 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)

надеюсь, что это проясняет вещи немного больше.

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

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

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

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

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

это почти стало тенденцией теперь иметь Conv2D затем ReLu затем

Keras теперь поддерживает 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'))

это другой тип слоя, поэтому вы должны добавить его в качестве слоя в соответствующем месте вашей модели

model.add(keras.layers.normalization.BatchNormalization())

Смотрите пример здесь:https://github.com/fchollet/keras/blob/master/examples/kaggle_otto_nn.py