programing

회귀 네트워크 교육 시 NaN 손실

codeshow 2023. 10. 24. 21:38
반응형

회귀 네트워크 교육 시 NaN 손실

저는 260,000 행과 35 열을 가진 "원 핫 인코딩"(모든 1과 0)의 데이터 매트릭스를 가지고 있습니다.저는 케라스를 사용하여 연속형 변수를 예측하기 위한 간단한 신경망을 훈련하고 있습니다.네트워크를 만드는 코드는 다음과 같습니다.

model = Sequential()
model.add(Dense(1024, input_shape=(n_train,)))
model.add(Activation('relu'))
model.add(Dropout(0.1))

model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.1))

model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dropout(0.1))
model.add(Dense(1))

sgd = SGD(lr=0.01, nesterov=True);
#rms = RMSprop()
#model.compile(loss='categorical_crossentropy', optimizer=rms, metrics=['accuracy'])
model.compile(loss='mean_absolute_error', optimizer=sgd)
model.fit(X_train, Y_train, batch_size=32, nb_epoch=3, verbose=1, validation_data=(X_test,Y_test), callbacks=[EarlyStopping(monitor='val_loss', patience=4)] )

하지만 훈련 과정에서는 손실이 잘 줄어드는 것을 보지만, 2차 시기 중반에는 nan으로 넘어갑니다.

Train on 260000 samples, validate on 64905 samples
Epoch 1/3
260000/260000 [==============================] - 254s - loss: 16.2775 - val_loss:
 13.4925
Epoch 2/3
 88448/260000 [=========>....................] - ETA: 161s - loss: nan

사용해 보았습니다.RMSProp대신에SGD,나는 노력했다.tanh대신에relu, 자퇴 여부를 불문하고 시도했지만 소용이 없었습니다.저는 더 작은 모델, 즉 숨겨진 레이어 하나만 가지고 시도했고, 동일한 문제(다른 지점에서 nan이 됨)로 시도했습니다.그러나 5개의 열만 있는 경우와 같이 더 적은 특성으로 작동하며 상당히 좋은 예측을 제공합니다.어떤 종류의 홍수가 있는 것 같지만, 그 손실이 터무니없이 크지 않은 이유를 짐작할 수 없습니다.

리눅스 시스템에서 실행되는 Python 버전 2.7.11, CPU만 해당최신버전의 Theano로 테스트를 해봤는데 Nans도 나와서 Theano 0.8.2로 가봤는데 같은 문제가 생겼습니다.Keras의 최신 버전에서도 동일한 문제가 발생하며, 0.3.2 버전에서도 마찬가지입니다.

신경망을 사용한 회귀 분석은 출력이 무한하기 때문에 작동하기가 어렵습니다. 따라서 특히 폭발적인 그래디언트 문제가 발생하기 쉽습니다(nans의 가능한 원인).

역사적으로 폭발적인 그레이디언트에 대한 핵심 솔루션 중 하나는 학습 속도를 줄이는 것이었지만 Adam과 같은 매개 변수별 적응형 학습 속도 알고리즘의 등장으로 더 이상 좋은 성능을 얻기 위해 학습 속도를 설정할 필요가 없습니다.뉴럴 네트워크 애호가가 아니고 학습 일정을 조정할 줄 아는 것이 아니라면 SGD를 더 이상 추진력 있게 사용할 이유가 거의 없습니다.

다음은 잠재적으로 시도해 볼 수 있는 몇 가지 사항입니다.

  1. 분위 정규화 또는 z 스코어링을 통해 출력을 정규화합니다.엄격하게 하기 위해서는 전체 데이터셋이 아닌 훈련 데이터에서 이 변환을 계산해야 합니다.예를 들어, 분위 정규화의 경우, 훈련 세트의 60번째 백분위수에 예제가 있는 경우 0.6의 값을 얻습니다(0번째 백분위수가 -0.5이고 100번째 백분위수가 +0.5가 되도록 분위 정규화된 값을 0.5만큼 낮출 수도 있습니다).

  2. 탈락률을 높이거나 가중치에 L1 및 L2 패널티를 추가하여 정규화를 추가합니다.L1 정규화는 피쳐 선택과 유사하며 피쳐 수를 5개로 줄이면 성능이 좋다고 했으므로 L1도 마찬가지입니다.

  3. 그래도 도움이 되지 않으면 네트워크 크기를 줄입니다.성능을 해칠 수 있기 때문에 이 방법이 항상 최선의 방법은 아니지만, 사용자의 경우 입력 특징(35)에 비해 많은 수의 1층 뉴런(1024)을 가지고 있으므로 도움이 될 수 있습니다.

  4. 배치 크기를 32에서 128로 늘리면 상당히 표준적이며 최적화의 안정성을 높일 수 있습니다.

1"에 의한 답은 꽤 좋습니다.하지만 모든 수정은 직접적인 것이라기 보다는 간접적으로 문제를 해결하는 것 같습니다.그래디언트 클리핑을 사용하는 것이 좋습니다. 그래디언트 클리핑은 특정 값 이상의 그래디언트 클리핑을 사용하는 것이 좋습니다.

에서는 케라스를 할 수 .clipnorm=1(norm이 1 이상인 모든 그래디언트를 간단히 잘라내려면 https://keras.io/optimizers/) 을 참조하십시오.

전에도 같은 문제에 직면했습니다.저는 이 질문과 답변을 검색해 봅니다.위에서 언급한 모든 트릭은 심층 신경망을 훈련하는 데 중요합니다.다 해봤는데도 NAN이 나왔어요.

저도 여기서 이 질문을 발견합니다.https://github.com/fchollet/keras/issues/2134 .필자는 저자의 요약을 다음과 같이 인용했습니다.

나중에 이런 문제가 발생할 수 있는 다른 사람들을 위해 보관할 수 있도록 이 점을 지적하고 싶었습니다.훈련 과정에 너무 많이 들어간 후에 갑자기 나노를 반납하는 분실 기능을 보게 되었습니다.저는 relus, optimizer, loss 함수, relus에 따라 저의 탈락 여부, 제 네트워크의 크기와 네트워크의 모양을 확인했습니다.저는 아직도 상실감을 느끼고 있었고 결국에는 낭자로 변했고 저는 꽤 좌절하고 있었습니다.

그때 저는 생각이 났습니다.제가 잘못 입력한 것 같습니다.알고 보니 제가 CNN에 넘기고 있던 이미지 중 하나는 0의 이미지에 불과했습니다.평균을 차감하고 std 편차로 정규화하여 nan's뿐인 예제 행렬을 만들었을 때 이 경우를 확인하지 않았습니다.정규화 기능을 고치고 나면 이제 네트워크가 완벽하게 훈련됩니다.

위의 관점에 동의합니다. 입력은 네트워크에 민감합니다.저의 경우 밀도 추정의 로그 값을 입력으로 사용합니다.절대값은 매우 클 수 있으며, 이로 인해 몇 단계의 그라디언트 후 NaN이 발생할 수 있습니다.저는 인풋 체크가 필요하다고 생각합니다.첫째, 입력에 -inf 또는 일부 극단적으로 큰 절대값의 숫자가 포함되어 있지 않은지 확인해야 합니다.

저는 LSTM을 사용하는 것과 같은 문제에 직면했습니다. 문제는 표준화 후에 제 데이터에 약간의 nan 값이 있다는 것입니다. 따라서 표준화 후에 입력 모델 데이터를 확인해야 합니다.

print(np.any(np.isnan(X_test)))
print(np.any(np.isnan(y_test)))

이와 같이 Std에 작은 값(0.000001)을 더하면 이를 해결할 수 있습니다.

def standardize(train, test):


    mean = np.mean(train, axis=0)
    std = np.std(train, axis=0)+0.000001

    X_train = (train - mean) / std
    X_test = (test - mean) /std
    return X_train, X_test

여기에 언급된 솔루션과 이 Github 토론에서 언급된 다양한 솔루션을 요약하면 물론 특정 상황에 따라 달라질 수 있습니다.

  • 가중치에 l1 또는 l2 패널티를 추가하기 위해 정규화를 추가합니다.그렇지 않으면 더 작은 l2 reg. 즉 l2(0.001)를 시도하거나 이미 있는 경우 제거합니다.
  • 더 작은 탈락률을 시도해 봅니다.
  • 그래디언트의 폭발을 방지하기 위해 그래디언트를 자릅니다.예를 들어 Keras에서는 clipnorm=1을 사용할 수 있습니다.또는 clipvalue=1.을(를) 최적화 도구의 매개 변수로 지정합니다.
  • 입력의 유효성을 확인합니다(NaN이 없거나 0인 경우도 있음).즉, df는 ().니가 아닙니다.
  • Optimizer를 다루기 쉬운 Adam으로 교체합니다.때로는 sgd를 rmsprop로 교체하는 것도 도움이 될 것입니다.
  • 기울기 폭발을 방지하기 위해 규칙화가 심한 RMS Propop을 사용합니다.
  • 데이터를 정규화하거나 정규화 과정에서 잘못된 값이 있는지 검사해 보십시오.
  • 올바른 활성화 함수를 사용하고 있는지 확인합니다(예: 다중 클래스 분류에 시그모이드 대신 소프트맥스를 사용).
  • 최적화의 안정성을 높이기 위해 배치 크기(예: 32에서 64 또는 128)를 늘립니다.
  • 학습률을 낮추도록 하세요.
  • 배치 크기와 다를 수 있는 마지막 배치 크기를 확인합니다.

저는 비슷한 문제에 직면했고, 이것이 제가 실행하게 된 방법입니다.

먼저 활성화를 LeakyRe로 변경하는 것이 좋습니다.류나 탄을 사용하는 대신에 LU.그 이유는 계층 내의 많은 노드가 0의 활성화를 가지고 있고, 역방향 전파는 기울기도 0이기 때문에 이러한 노드에 대한 가중치를 업데이트하지 않기 때문입니다.이 문제는 dying ReLU 문제라고도 합니다(자세한 내용은 여기 https://datascience.stackexchange.com/questions/5706/what-is-the-dying-relu-problem-in-neural-networks) 에서 확인할 수 있습니다).

이를 위해서는 LeakyRe를 가져올 수 있습니다.다음을 사용하여 LU 활성화:

from keras.layers.advanced_activations import LeakyReLU

다음과 같이 계층에 통합할 수 있습니다.

model.add(Dense(800,input_shape=(num_inputs,)))
model.add(LeakyReLU(alpha=0.1))

또한 출력 피쳐(예측하려는 연속형 변수)가 불균형 데이터 집합이고 0이 너무 많을 수 있습니다.이 문제를 해결하는 한 가지 방법은 스무딩(smoothing)을 사용하는 것입니다.이 열에 있는 모든 값의 분자에 1을 더하고 이 열의 각 값을 1/(이 열에 있는 모든 값의 평균)으로 나눔으로써 이 작업을 수행할 수 있습니다.

이렇게 하면 기본적으로 모든 값이 0에서 0보다 큰 값으로 이동합니다(이 값은 여전히 매우 작을 수 있음).그러면 곡선이 0을 예측하고 손실을 최소화하는 것을 방지합니다(결국 NaN이 됩니다).값이 작으면 큰 값보다 더 큰 영향을 받지만, 전체적으로 데이터 집합의 평균은 그대로 유지됩니다.

저도 같은 문제가 있었습니다. 다변량 회귀 문제에 Keras를 사용하고 있었습니다.나중에 알게 된 사실은 데이터 세트의 일부 값이 nan이고 그것이 nan 손실로 이어졌다는 것입니다.명령을 사용했습니다.

df=df.dropna()

그리고 제 문제를 해결해 줬습니다.

저는 이 페이지에 있는 모든 제안을 시도해 보았지만 아무 소용이 없었습니다.팬더와 함께 csv 파일을 가져온 다음keras Tokenizer단어와 단어 벡터 행렬을 만들기 위해 텍스트 입력을 사용합니다.일부 CSV 파일이 nan으로 이어지는 것을 발견한 후, 우리는 갑자기 파일의 인코딩을 보고 ASCII 파일이 keras와 함께 작동하지 않음을 깨닫고 다음으로 이어졌습니다.nan의 손실과 정확성0.0000e+00; 하지만 utf-8 파일과 utf-16 파일은 잘 작동하고 있었습니다!돌파구.

텍스트 분석을 수행하고 있는 경우nan이러한 제안을 시도한 후 손실, 사용file -i {input}(linux) 또는file -I {input}(osx) 파일 형식을 검색합니다.에.ISO-8859-1아니면us-ascii, 전환을 시도해 보다utf-8아니면utf-16le해 본, 나는 가 있을 후자를 시도해 본 적은 없지만 저는 그것이 효과가 있을 것이라고 생각합니다.이것이 매우 좌절한 누군가에게 도움이 되기를 바랍니다!

훈련 시작과 동시에 첫 번째 시대에 난으로서 손실을 입고 있었습니다.입력 데이터에서 NAS를 제거하는 것만큼 간단한 솔루션이 효과적이었습니다(df.dropna()).

이것이 비슷한 문제를 겪는 사람에게 도움이 되었으면 합니다.

저는 keras LSTM 레이어에 대한 RNN에 동일한 문제가 있어서 위에서 각각의 솔루션을 시도했습니다.이미 데이터 크기를 조정했습니다.sklearn.preprocessing.MinMaxScaler), 없음NaN스케일링 후 내 데이터의 값.LeakyRelU를 사용하거나 학습률을 변경하는 것과 같은 솔루션은 도움이 되지 않았습니다.

그래서 스케일러를 변경하기로 했습니다.MinMaxScaler로.StandardScaler, 나에게는 아무것도 없었음에도NaN가치관과 나는 그것을 이상하게 여겼지만 그것은 효과가 있었습니다!

문제는 이진 분류를 위해 이전 작업을 복사 붙여넣고 사용한 것입니다.sigmoid대신 출력 레이어에 활성화softmax(새로운 네트워크는 다중 계층 분류에 관한 것이었습니다.)

저도 케라를 사용하는데 비슷한 문제가 있었습니다.두 번째 배치가 입력된 후 손실이 NAN으로 변경되었습니다.

저는 이렇게 하려고 했습니다.

  1. softmax를 출력 밀집 계층의 활성화로 사용
  2. 입력에서 드랍난
  3. 입력 정규화

하지만, 그것은 효과가 없었습니다.그래서 저는 이렇게 하려고 했습니다.

  1. 학습률 감소

문제는 해결됐습니다.

NAN 값이 있는지 데이터를 확인해 보십시오.NAN 값을 제거하면 문제가 해결됩니다.

교육 데이터 항목 중 하나에 nan이 포함되어 있을 때 이 문제가 발생했습니다.

로그 손실, MAE 등이 모두 NA인 것과 비슷한 문제가 있었습니다.데이터를 조사해보니 NA의 기능이 거의 없었습니다.나는 NA의 것을 대략적인 값으로 돌렸고 문제를 해결할 수 있었습니다.

저도 CNN과 같은 문제가 있었는데, 다른 것들과 마찬가지로 학습률 감소, 열차 데이터에서의 무효성 제거, 데이터 정규화, 드롭아웃 계층 추가 등 위의 모든 해결책을 시도했지만 난 문제를 해결할 수 없었고, 시그모이드에서 소프트맥스로 분류기(마지막) 계층에서 변경 활성화 기능을 시도했습니다.됐습니다! 마지막 레이어의 활성화 기능을 소프트맥스로 변경해보세요!

바운딩 박스 리저버를 만들었을 때 저는 같은 것을 얻었습니다.내 신경망은 당신 것보다 층이 더 컸습니다.탈락값을 높여서 적합한 결과를 얻었습니다.

나의 분류망을 위해 NaN을 얻는 중이었습니다.누군가에게 도움이 될 수도 있기 때문에 여기에 대답하는 것.

실수를 저질렀습니다.

교육 레이블의 수업 수는 5개, 즉 0개에서 4개였습니다.

마지막으로 밀도가 높은 분류 계층에서는 4개의 노드가 있었는데, 이는 4개의 클래스를 의미합니다.

마지막 네트워크 계층의 노드 수를 5개로 변경하면 문제가 해결되었습니다.

비슷한 문제가 있어서 Sigmoid에서 Softmax로, RelU에서 LeakyRelU로 활성화를 변경해보았는데 문제가 해결되었습니다.그래서 저는 우선 입력에 NaN이 없고 학습률을 낮추려고 노력하는 한, 실행 가능한 해결책은 활동을 가지고 노는 것입니다.

내 상황:

Train Loss: nan, Train Accuracy: 0.0, Validation Loss: nan, Validation Accuracy: 0.0

나중에 나는 그것이 내 꼬리표 때문이라는 것을 알았습니다.1, 2, 3, 40으로 시작하지 않습니다.그래서 라벨을 다시 붙였어요.0, 1, 2, 3대신에1, 2, 3, 4표식으로문제 해결!

제 대답이 도움이 되기를 바랍니다!

케라에서 클래스 레이블은 0부터 시작합니다.예를 들어, 클래스가 7개인 경우, 0부터 6까지 레이블링을 시작하고 (softmax 활성화 함수가 있는) 마지막 조밀 레이어에 단위=7을 공급합니다.또는 데이터에 1부터 7까지 레이블을 지정해야 하는 경우, 이 경우 (마지막 조밀 레이어에서) units=8을 설정해야 합니다.

저는 지금.nan이진 분류를 위한 값들 그리고 나서 나는 손실 함수를 범주형 교차 엔트로피에서 '이진 교차 엔트로피'로 바꿨고 그것은 잘 작동했습니다.

그건 그렇고, 그것은 폭발하지 않는 죽어가는 기울기인 것 같습니다.

  • 뉴런은 그 입력이 모든 트레이닝 인스턴스에 대해 부정적일 때 사망합니다.

여기 'adam' 옵티마이저가 NaNs에 대항해서 도움을 줬습니다.하지만 상황을 고려할 때, 데이터셋 & loss= 'squared_mean_error'의 크기를 조정한 적이 있습니다(사용자의 경우와 다르게).

model.compile(optimizer = 'adam', loss = keras.losses.mean_squared_error, metrics=keras.metrics.mean_absolute_error)

이 오류는 데이터에 다음과 같은 문제가 있을 때 발생할 수 있습니다.

입력에 NaN, 무한대 또는 dtype('float64')에 대해 너무 큰 값이 포함되어 있습니다.이 경우 다음과 같은 NaN 값을 제거하여 해결할 수 있습니다.

`df = df.dropna()`

또는 그 밖의 것fillna()방법들

참고: 이 방법은 팬더의 데이터 프레임에만 적용됩니다.

nan 값이 포함된 행을 제거하거나 데이터셋 또는 데이터프레임에서 nan 값을 일부 값으로 바꿉니다.그것은 오류를 해결할 것입니다.

저도 똑같은 문제가 생겼어요.회귀 분석을 위해 케라를 성공적으로 사용할 수 있습니다.모든 데이터를 내 문제를 해결한 반올림 숫자로 변환합니다.23.43 ~ 23

저도 같은 문제가 있었습니다.데이터를 조사해보니 데이터 획득 중 오류가 발생했음을 알 수 있었습니다.

언급URL : https://stackoverflow.com/questions/37232782/nan-loss-when-training-regression-network

반응형