훈련 중 nans의 일반적인 원인


85

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

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

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

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


특정 MATLAB 함수를 호출하고 있습니까? 모두 자신의 코드입니까?
Matthew Gunn 2015

2
@MatthewGunn 나는이 질문이 matlab에 특정한 것이 아니라 오히려 caffe관련 있다고 생각하지 않습니다 .
Shai

답변:


134

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


그라데이션 폭발

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

예상해야 할 사항 : 런타임 로그를 보면 반복 당 손실 값을 살펴 봐야합니다. 손실이 반복에서 반복으로 크게 증가하기 시작하고 결국 손실이 너무 커서 부동 소수점 변수로 표현할 수 없으며 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 인쇄를 만들 것입니다 :이 정보는 수 교육 과정에서 그라데이션 파열에 다른 문제를 안보에 도움이 .


감사합니다. 그 숫자를 어떻게 해석합니까? 이 숫자는 무엇입니까? pastebin.com/DLYgXK5v 레이어 출력 당 하나의 숫자 만있는 이유는 무엇입니까? 누군가가 문제가 있음을 알 수 있도록 숫자가 어떻게 표시되어야합니까?
Rika

@Hossein 이것이 바로이 게시물의 모든 내용입니다.
Shai

이 답변에 감사드립니다. DICE 손실 (작은 엡실론 / 부드러움 상수를 추가 한 후에도)으로 훈련 된 이미지 분할 응용 프로그램에 대해 NAN 손실이 발생합니다. 내 데이터 세트에는 전경 레이블이 포함되지 않은 해당 실측 이미지가 포함되어 있으며 이러한 이미지를 훈련에서 제거했을 때 손실이 안정화되었습니다. 왜 그런지 잘 모르겠습니다.
samra irshad

@samrairshad DICE 손실에서 엡실론을 늘리려 고 했습니까?
Shai

응 나는 했어. 스택 오버플로에서 게시물을 열고 일부 시대에 대한 손실 진화를 붙여 넣었습니다. 참조 : stackoverflow.com/questions/62259112/…
samra irshad

5

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

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

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


matconvnet에서 어떻게 보일까요? 나는 'biases'.init_bias * ones (1,4, single)
h612

4

이 답변은 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
  }
}


-1

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


좀 더 구체적으로 말씀해 주시겠습니까? 가있는 구성 nan및 고정 구성 에 대한 세부 정보를 제공 할 수 있습니까? 어떤 유형의 레이어? 어떤 매개 변수?
Shai

1
@shai 나는 여러 InnerProduct (lr_mult 1, decay_mult 1, lr_mult 2, decay_mult 0, xavier, std : 0.01) 레이어를 각각 사용한 다음 ReLU (마지막 제외)를 사용했습니다. 나는 MNIST와 함께 일하고 있었고, 올바르게 기억한다면 아키텍처는 784-> 1000-> 500-> 250-> 100-> 30 (및 대칭 디코더 단계)이었습니다. ReLU와 함께 30 레이어를 제거하면 NaN이 사라졌습니다.
LKB
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.