Keras에서 BatchNormalization 함수를 어디에서 호출합니까?


167

Keras에서 BatchNormalization 함수를 사용하려면 처음에 한 번만 호출해야합니까?

나는이 문서를 읽었습니다 : 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)

배치 정규화를 포함하여 두 번째 줄로 코드를 실행하고 두 번째 줄없이 코드를 실행하면 비슷한 결과가 나오기 때문에 묻습니다. 따라서 올바른 위치에서 함수를 호출하지 않거나 그렇게 큰 차이를 만들지 않는 것 같습니다.

답변:


225

이 질문에 좀 더 자세히 대답하기 위해 Pavel이 말했듯이 Batch Normalization은 또 다른 계층이므로 원하는 네트워크 아키텍처를 만드는 데 사용할 수 있습니다.

일반적인 사용 사례는 네트워크의 선형 및 비선형 레이어 사이에 BN을 사용하는 것입니다. 활성화 기능의 입력을 정규화하여 활성화 기능의 선형 섹션 (예 : Sigmoid)에 집중하기 때문입니다. 여기에 대한 작은 토론이 있습니다

위의 경우 다음과 같습니다.


# 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)

이것이 좀 더 명확 해지기를 바랍니다.


25
FYI 분명히 배치 정규화는 활성화 기능 후에 실제로 더 잘 작동합니다
Claudiu

10
안녕하세요 @Claudiu,이 FYI를 확장 하시겠습니까? 위의 답변과 직접 모순되는 것으로 보입니다.
Ben Ogorek

7
@benogorek : 확실한 것, 기본적으로 나는 결과에 완전히 기반 여기 relu 더 나은 수행 한 후에 배치 규범을 배치하는 곳. FWIW 내가 시도한 하나의 그물에 그것을 적용하는 데 성공하지 못했습니다
Claudiu

32
흥미 롭군 후속 작업을 계속하면 요약에서 계속 읽으면 최상의 모델 [GoogLeNet128_BN_lim0606]에 실제로 ReLU 이전에 BN 레이어가 있다고합니다. 따라서 정품 인증 후 BN은 격리 된 경우 정확도를 향상시킬 수 있지만 전체 모델이 구성되면 최상의 성능을 발휘할 수 있습니다. 활성화 후 BN을 배치하면 정확도가 향상 될 수 있지만 문제에 따라 달라질 수 있습니다.
Lucas Ramadan

7
@ CarlThomé 종류의. 예를 들어 ReginaldIII 의이 레딧 의견을 참조하십시오 . "BN은 컨볼 루션에서 나오는 피처의 분포를 정규화하고 있습니다. 이러한 피처 중 일부는 음수 일 수 있으며 ReLU와 같은 비선형 성으로 인해 잘릴 수 있습니다. 활성화하기 전에 정규화하면이 음수 값을 "기능 공간에서 컬링하기 직전의 정규화. 활성화 후 BN은 다음 컨볼 루션 레이어로 통과하지 않는 기능으로 통계적으로 바이어스하지 않고 긍정적 인 기능을 정규화합니다."
mab

60

이 스레드는 잘못되었습니다. Lucas Ramadan의 답변에 대해 언급하려고 시도했지만 아직 올바른 권한이 없으므로 여기에 넣겠습니다.

배치 정규화는 활성화 기능 후에 가장 잘 작동하며 여기 또는 여기 에서 이유가 있습니다. 내부 공변량 이동을 방지하기 위해 개발되었습니다. 활성화 의 분포가있을 때 내부 공변량 이동이 발생합니다.레이어의 배치 정규화는 특정 배치로의 입력 (및 이러한 입력은 문자 그대로 활성화 기능의 결과)이 각 배치의 매개 변수 업데이트로 인해 시간이 지남에 따라 변하지 않도록 (또는 적어도 변경을 허용하도록) 사용됩니다. 유리한 방식으로). 배치 통계를 사용하여 정규화를 수행 한 다음 배치 정규화 매개 변수 (원본의 감마 및 베타)를 사용하여 "네트워크에 삽입 된 변환이 항등 변환을 나타낼 수 있도록합니다"(원본에서 인용). 그러나 요점은 레이어에 대한 입력을 정규화하려는 것이므로 항상 네트워크의 다음 레이어 바로 앞에 가야합니다. 그 여부


27
나는 Andrew Ng가 Deeplearning.ai 수업에서 딥 러닝 커뮤니티에서 이에 대한 토론이 있다고 말했습니다. 비선형 성 전에 배치 정규화를 적용하는 것을 선호합니다.
shahensha

3
@kRazzyR 저는 Andrew Ng 교수가 deeplearning에 대한 딥 러닝 수업에서이 주제에 대해 이야기했음을 의미했습니다 .ai 그는 커뮤니티가 올바른 방식으로 나뉘어져 있고 비선형 성을 적용하기 전에 배치 정규화를 적용하는 것을 선호한다고 말했습니다.
shahensha

3
@jmancuso, BN은 활성화 전에 적용됩니다. 종이 자체에서 식은입니다 g(BN(Wx + b)). 여기서 g활성화 함수는 어디 입니까?
yashgarg1232

43

이 스레드는 BN이 현재 계층의 비선형 성 전에 적용되어야하는지 또는 이전 계층의 활성화에 적용되어야하는지에 대한 상당한 논쟁을 가지고 있습니다.

정답은 없지만 Batch Normalization의 저자 는 현재 레이어의 비선형 성 직전에 적용해야 한다고 말합니다 . 이유 (원본에서 인용)-

"x = Wu + b를 정규화하여 비선형 성 직전에 BN 변환을 추가합니다. 계층 입력 u를 정규화 할 수도 있었지만 u는 다른 비선형 성의 출력 일 가능성이 있기 때문에 분포의 모양이 변경 될 때 훈련과 첫 번째와 두 번째 모멘트를 제한해도 공변량 이동이 제거되지는 않지만, Wu + b는 대칭적이고 비스 파스 분포를 가질 가능성이 더 높습니다 ( "가우시안") (Hyv¨arinen & Oja, 2000) 정상화되면 안정적인 분포로 활성화를 일으킬 수 있습니다. "


3
내 개인적인 경험에서 그것은 큰 차이를 만들지 않지만 다른 모든 것은 동일합니다. 비 선형성 (활성화 기능 이전) 전에 배치 정규화가 적용될 때 BN이 약간 더 나은 것을 항상 보았습니다.
Brad Hesse

31

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(BatchNormalization())에서 다른model.add(BatchNormalization(axis=bn_axis))
kRazzy R

@kRazzR tensorflow백엔드 로 사용 하는 경우 다르지 않습니다 . keras.applications모듈 에서 이것을 복사했기 때문에 여기에 작성되었습니다 . 형식 과 형식을 bn_axis모두 지원하려면 지정해야합니다 . channels_firstchannels_last
ldavid

9
누군가 이것이 OP 질문과 어떻게 관련되는지 자세히 설명해 주시겠습니까? (나는 오히려 NN에 초보자이므로 어쩌면 뭔가를 놓칠 수 있습니다.)
Pepacz

30

거의 뒤에 층 Conv2DReLu오는 추세가되었습니다 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)))

7
이걸 케 라스로 밀어?
sachinruk

6

다른 유형의 레이어이므로 모델의 적절한 위치에 레이어로 추가해야합니다.

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

https://github.com/fchollet/keras/blob/master/examples/kaggle_otto_nn.py 에서 예를 참조하십시오.


1
BatchNormalization을 추가 한 후 val_acc는 모든 에포크가 증가하는 것을 중지했습니다. val_acc는 BatchNormalization을 추가 한 후 모든 에포크 후에 동일한 수로 정체 상태를 유지했습니다. Batch Normalization이 val_acc를 증가시켜야한다고 생각했습니다. 제대로 작동하는지 어떻게 알 수 있습니까? 이 문제의 원인을 알고 있습니까?
pr338

불행히도 링크는 더 이상 유효하지 않습니다 :(
user2324712

Keras 포크 (예 : github.com/WenchenLi/kaggle/blob/master/otto/keras/… ) 에 해당 예의 사본이 있지만 원래 Keras 저장소에서 제거 된 이유를 모르겠습니다. 코드는 최신 Keras 버전과 호환됩니다.
Pavel Surmenok

4

배치 정규화는 활성화의 평균 및 스케일링을 조정하여 입력 레이어와 숨겨진 레이어를 정규화하는 데 사용됩니다. 심층 신경망에서 추가 레이어로 인한 정규화 효과로 인해 네트워크는 그라디언트를 없애거나 폭발시키지 않고 더 높은 학습 속도를 사용할 수 있습니다. 또한 일괄 정규화는 네트워크를 정규화하여 일반화하기가 쉬우므로 드롭 아웃을 사용하여 과적 합을 완화 할 필요가 없습니다.

Keras에서 Dense () 또는 Conv2D ()를 사용하여 선형 함수를 계산 한 직후에는 레이어의 선형 함수를 계산하는 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에 a [l-1]을 입력했다고 가정하자. 또한 레이어 l에 대한 가중치 W [l] 및 바이어스 단위 b [l]이 있습니다. a [l]은 레이어 l에 대해 계산 된 (즉, 비선형 성을 추가 한 후) 활성화 벡터이고 z [l]은 비선형 성을 추가하기 전에 벡터가되도록합니다.

  1. a [l-1]과 W [l]을 사용하여 레이어 l에 대한 z [l]을 계산할 수 있습니다
  2. 일반적으로 피드 포워드 전파에서는이 z [l] + b [l]과 같이이 단계에서 z [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])를 계산하여 a [l]

a[l] = tanh(z_norm[l])
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.