[machine-learning] 훈련 중 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}


답변

이 답변은 nans 의 원인에 대한 것이 아니라 디버그를 돕는 방법을 제안합니다. 이 파이썬 레이어를 가질 수 있습니다.

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

train_val.prototxt의심되는 특정 지점 에이 레이어를 추가 하면 문제가 발생할 수 있습니다.

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
  }
}


답변

learning_rate가 높고 줄여야 함 RNN 코드의 정확도는 nan이었으며 학습률에 대해 낮은 값을 선택하여 수정했습니다.


답변

나는 희소 자동 인코더를 만들려고 노력했고 희소성을 유도하기 위해 여러 계층을 가졌습니다. 인터넷을 운영하는 동안 NaN을 만났습니다. 일부 레이어를 제거 할 때 (제 경우에는 실제로 1 개를 제거해야했습니다) NaN이 사라진 것을 발견했습니다. 그래서 너무 많은 희소성이 NaN으로 이어질 수 있다고 생각합니다 (일부 0/0 계산이 호출되었을 수 있습니다!?)


답변