Programing

훈련 중 nans의 일반적인 원인

lottogame 2020. 10. 30. 07:41
반응형

훈련 중 nans의 일반적인 원인


훈련 중에 자주 발생하는 것이 NAN소개되고 있음을 알았습니다 .

종종 내부 제품 / 완전 연결 또는 컨볼 루션 레이어의 가중치로 인해 발생하는 것처럼 보입니다.

그래디언트 계산이 폭발하기 때문에 발생합니까? 아니면 가중치 초기화 때문입니까 (그렇다면 가중치 초기화가이 효과가있는 이유)? 아니면 입력 데이터의 특성 때문일까요?

여기서 가장 중요한 질문은 간단합니다. NAN이 훈련 중에 발생하는 가장 일반적인 이유는 무엇입니까? 두 번째로,이 문제를 해결하기위한 몇 가지 방법은 무엇이며 왜 작동합니까?


좋은 질문.
나는이 현상을 여러 번 보았습니다. 내 관찰은 다음과 같습니다.


그라데이션 폭발

이유 : 그라디언트가 크면 학습 과정이 벗어납니다.

예상해야 할 사항 : 런타임 로그를 보면 반복 당 손실 값을 살펴 봐야합니다. 반복에서 반복으로 손실이 크게 증가하기 시작하고 결국 손실이 너무 커서 부동 소수점 변수로 표현할 수 없으며 nan.

당신이 할 수있는 일 : 감소 base_lr(적어도) 규모의 명령에 의해합니다 (solver.prototxt에서). 손실 레이어가 여러 개있는 경우 로그를 검사하여 어떤 레이어가 그래디언트 파열을 담당하는지 확인하고 loss_weight해당 레이어에 대한 일반 base_lr.


잘못된 학습률 정책 및 매개 변수

이유 : caffe가 유효한 학습률을 계산하지 못하고 가져 'inf'오거나 'nan'대신이 잘못된 비율이 모든 업데이트를 곱하여 모든 매개 변수를 무효화합니다.

예상해야 할 사항 : 런타임 로그를 보면 학습률 자체가 다음 'nan'같이되는 것을 확인할 수 있습니다 .

... sgd_solver.cpp:106] Iteration 0, lr = -nan

수행 할 수있는 작업 :'solver.prototxt' 파일 의 학습률에 영향을 미치는 모든 매개 변수를 수정 합니다.
예를 들어, 당신이 사용하는 경우 lr_policy: "poly"당신이 정의하는 것을 잊지 max_iter매개 변수를 사용하면 될 겁니다 lr = nan...
, CAFFE의 속도를 학습에 대한 자세한 내용은 다음을 참조 이 스레드를 .


결함 손실 기능

이유 : 때때로 손실 계층의 손실 계산으로 인해 nans가 나타납니다. 예를 들어, InfogainLoss정규화되지 않은 값이있는 Feeding 레이어 , 버그가있는 사용자 지정 손실 레이어 사용 등.

예상해야 할 사항 : 런타임 로그를 보면 비정상적인 것을 눈치 채지 못할 것입니다. 손실이 점차 감소하고 갑자기 a nan가 나타납니다.

수행 할 수있는 작업 : 오류를 재현 할 수 있는지 확인하고 손실 레이어에 인쇄물을 추가하고 오류를 디버그합니다.

예를 들어 : 일괄 라벨 발생 빈도에 따라 패널티를 정규화 한 손실을 사용한 적이 있습니다. 훈련 레이블 중 하나가 배치에 전혀 나타나지 않으면 계산 된 손실이 nans를 생성했습니다 . 이 경우 세트의 레이블 수와 관련하여 충분히 큰 배치로 작업하면이 오류를 피할 수있었습니다.


잘못된 입력

이유 : 당신은 nan그것에 대한 입력이 있습니다!

예상해야 할 사항 : 학습 과정이 "적중"되면이 잘못된 입력 출력은 nan. 런타임 로그를 보면 비정상적인 것을 발견하지 못할 것입니다. 손실이 점차 감소하고 갑자기 a nan가 나타납니다.

할 수있는 일 : 입력 데이터 세트 (lmdb / leveldn / hdf5 ...)를 다시 빌드하여 훈련 / 검증 세트에 잘못된 이미지 파일이 없는지 확인합니다. 디버그를 위해 입력 레이어를 읽고 그 위에 더미 손실이 있고 모든 입력을 통과하는 간단한 네트를 구축 할 수 있습니다. 그중 하나에 결함이있는 경우이 더미 네트도 nan.


"Pooling"에서 커널 크기보다 큰 보폭

어떤 이유로 풀링을 위해 stride> kernel_size선택하면 nans 가 표시 될 수 있습니다 . 예를 들면 :

layer {
  name: "faulty_pooling"
  type: "Pooling"
  bottom: "x"
  top: "y"
  pooling_param {
    pool: AVE
    stride: 5
    kernel: 3
  }
}

와 결과 nan에의 y.


불안정 "BatchNorm"

일부 설정 에서 수치 불안정으로 인해 s를 "BatchNorm"출력 할 수 있다고보고되었습니다 nan.
문제 는 bvlc / caffe에서 발생했으며 PR # 5136 에서 수정을 시도하고 있습니다.


최근에, 나는 알게되었다 debug_info플래그 : 설정 debug_info: true에서 'solver.prototxt'훈련 기간 동안 (그라데이션 크기 및 활성화 값을 포함하여) 더 디버그 정보를 기록 CAFFE 인쇄를 만들 것입니다 :이 정보는 수 교육 과정에서 그라데이션 파열에 다른 문제를 안보에 도움이 .


제 경우에는 convolution / deconvolution 레이어에 편향을 설정하지 않는 것이 원인이었습니다.

솔루션 : 컨볼 루션 계층 매개 변수에 다음을 추가하십시오.

bias_filler {유형 : "상수"값 : 0}


This answer is not about a cause for nans, but rather proposes a way to help debug it. You can have this python layer:

class checkFiniteLayer(caffe.Layer):
  def setup(self, bottom, top):
    self.prefix = self.param_str
  def reshape(self, bottom, top):
    pass
  def forward(self, bottom, top):
    for i in xrange(len(bottom)):
      isbad = np.sum(1-np.isfinite(bottom[i].data[...]))
      if isbad>0:
        raise Exception("checkFiniteLayer: %s forward pass bottom %d has %.2f%% non-finite elements" %
                        (self.prefix,i,100*float(isbad)/bottom[i].count))
  def backward(self, top, propagate_down, bottom):
    for i in xrange(len(top)):
      if not propagate_down[i]:
        continue
      isf = np.sum(1-np.isfinite(top[i].diff[...]))
        if isf>0:
          raise Exception("checkFiniteLayer: %s backward pass top %d has %.2f%% non-finite elements" %
                          (self.prefix,i,100*float(isf)/top[i].count))

Adding this layer into your train_val.prototxt at certain points you suspect may cause trouble:

layer {
  type: "Python"
  name: "check_loss"
  bottom: "fc2"
  top: "fc2"  # "in-place" layer
  python_param {
    module: "/path/to/python/file/check_finite_layer.py" # must be in $PYTHONPATH
    layer: "checkFiniteLayer"
    param_str: "prefix-check_loss" # string for printouts
  }
}

I was trying to build a sparse autoencoder and had several layers in it to induce sparsity. While running my net, I encountered the NaN's. On removing some of the layers (in my case, I actually had to remove 1), I found that the NaN's disappeared. So, I guess too much sparsity may lead to NaN's as well (some 0/0 computations may have been invoked!?)

참고URL : https://stackoverflow.com/questions/33962226/common-causes-of-nans-during-training

반응형