模型训练中出现NaN Loss的原因及解决方法

1 梯度爆炸

  • 原因:学习的过程中,梯度变得非常大,使得学习的过程偏离了正常的轨迹。
  • 症状:观察每次迭代的loss值,会发现loss明显增长,最后因为loss值太大以至于不能用浮点去表示,所以变成了Nan。
  • 可采取的措施:1 降低学习速率,2 如果模型中有多个loss层,就需要找到梯度爆炸的层,然后降低该层的loss weight。

2 学习率过高

  • 原因:过高的学习率乘上所有的梯度使得所有参数变成无效的值。
  • 症状:观察输出日志,会发现学习率变成nan
  • 可采取的措施:设置合适的学习速率

损失函数有误

  • 原因:损失函数的计算,如交叉熵损失函数的计算可能出现log(0),所以就会出现loss为Nan的情况
  • 症状: loss逐渐下降,突然出现Nan,或loss正常下降,突然出现Nan
  • 可采取的措施: 尝试重现该错误,打印损失层的值进行调试。对预测数据增加最小值偏移,避免0,例如:
  • y_pred = tf.clip_by_value(y_pred, 1e-15, 99999.)  # clip to avoid nan in cce

    4 输入数据有误

  • 原因: 你的输入中存在Nan
  • 症状: loss逐渐下降,突然出现Nan
  • 可采取的措施: 逐步去定位错误数据,然后删掉这部分数据. 可以使用一个简单的网络去读取输入,如果有一个数据是错误的,这个网络的loss值也会出现Nan

5 Pooling层的步长大于核的尺寸

6 设置远距离的Label会得到NAN

  • 标记[0..100]的训练没问题,
  • 标签[0..100]加上一个附加标签8000,然后得到了NAN。
  • from keras.models import Sequential
    from keras.layers import Dense, Activation
    import numpy as np
     
    X=np.random.random(size=(20,5))
    y=np.random.randint(0,high=5, size=(20,1))
     
    model = Sequential([
                Dense(10, input_dim=X.shape[1]),
                Activation('relu'),
                Dense(5),
                Activation('softmax')
                ])
    model.compile(optimizer = "Adam", loss = "sparse_categorical_crossentropy", metrics = ["accuracy"] )
     
    print('fit model with labels in range 0..5')
    history = model.fit(X, y, epochs= 5 )
     
    X = np.vstack( (X, np.random.random(size=(1,5))))
    y = np.vstack( ( y, [[8000]]))
    print('fit model with labels in range 0..5 plus 8000')
    history = model.fit(X, y, epochs= 5 )

    结果:

  • fit model with labels in range 0..5
    Epoch 1/5
    20/20 [==============================] - 0s 25ms/step - loss: 1.8345 - acc: 0.1500
    Epoch 2/5
    20/20 [==============================] - 0s 150us/step - loss: 1.8312 - acc: 0.1500
    Epoch 3/5
    20/20 [==============================] - 0s 151us/step - loss: 1.8273 - acc: 0.1500
    Epoch 4/5
    20/20 [==============================] - 0s 198us/step - loss: 1.8233 - acc: 0.1500
    Epoch 5/5
    20/20 [==============================] - 0s 151us/step - loss: 1.8192 - acc: 0.1500
    fit model with labels in range 0..5 plus 8000
    Epoch 1/5
    21/21 [==============================] - 0s 142us/step - loss: nan - acc: 0.1429
    Epoch 2/5
    21/21 [==============================] - 0s 238us/step - loss: nan - acc: 0.2381
    Epoch 3/5
    21/21 [==============================] - 0s 191us/step - loss: nan - acc: 0.2381
    Epoch 4/5
    21/21 [==============================] - 0s 191us/step - loss: nan - acc: 0.2381
    Epoch 5/5
    21/21 [==============================] - 0s 188us/step - loss: nan - acc: 0.2381

    我的理解是,模型采用了交叉熵损失函数,当标签过于分散的时候,比方说标签为8000的数据,其概率分布值就会变成了比较小的数值,也就是会出现类似于log(0)这种情况,从而模型的loss为Nan.

    修改自:模型训练中出现NaN Loss的原因及解决方法 - 知乎1 梯度爆炸原因:学习的过程中,梯度变得非常大,使得学习的过程偏离了正常的轨迹。症状:观察每次迭代的loss值,会发现loss明显增长,最后因为loss值太大以至于不能用浮点去表示,所以变成了Nan。可采取的措施:1…https://zhuanlan.zhihu.com/p/114150904

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值