Tensorflow建立深度神经网络时出现nan及交叉熵损失函数的探讨

(作者:陈玓玏)
在使用tensorflow建立深度神经网络的过程中,在几次迭代之后发现所有的权重都变为了nan,导致整个网络都无法正常工作。出现这个问题我知道的可能有以下两个原因。

1) 样本未进行归一化

因为每次迭代都要计算 σ ( x ∗ ω + b ) \sigma(x*\omega+b) σ(xω+b),而深度神经网络的参数众多,如果样本不进行归一化,很容易出现 x ∗ ω + b x*\omega+b xω+b溢出的情况。

解决方案:
我一般都是先用sklearn中的preprocessing.MinMaxScaler()函数将每一个特征在[最小值,最大值]区间进行尺度缩放,缩放到[0,1]区间。这样处理过后再出现nan就不会特征的问题了。

2)损失函数未进行溢出处理

2.1) 为什么使用交叉熵损失函数?

当输出层使用sigmoid激活函数时,如果在神经网络中使用平方损失函数,即使用
( y − σ ) 2 / 2 (y-\sigma)^2/2 (yσ)2/2
作为损失函数,那么参数更新的公式为(仅考虑一层时,也就是不需要使用到反向传播):
ω = ω − α ( y − σ ) σ ( 1 − σ ) x \omega = \omega-\alpha(y-\sigma)\sigma(1-\sigma)x ω=ωα(yσ)σ(1σ)x
其中 σ ( 1 − σ ) \sigma(1-\sigma) σ(1σ)为sigmoid激活函数导数,使用这个损失函数就因为这一项导数存在一个问题:当我们犯的错误越大时,神经网络更新越慢。考虑二分类问题,y不是0就是1,预测值与0或1差别大,即接近0或1,但与真实值为相反的方向,此时z( σ \sigma σ的自变量)是离x=0轴非常远的,从sigmoid函数的图像上看也知道,此时导数几乎为0,因为参数更新就会非常慢。

因此我们得出一个结论,sigmoid激活函数不适合与平方损失函数一起用,因为我们希望我们犯错严重时,更新更快。而交叉熵损失函数可以帮助我们达到这个目的。交叉熵损失函数公式如下:
− 1 / 2 m ∗ ∑ i = 1 m ( y ln ⁡ σ + ( 1 − y ) ln ⁡ ( 1 − σ ) ) -1/2m*\sum_{i=1}^m(y\ln \sigma+(1-y)\ln(1-\sigma)) 1/2mi=1m(ylnσ+(1y)ln(1σ))
导数自己求就可以,总之就是不再有sigmoid的导数那一项,仅仅是 y − σ y-\sigma yσ乘以系数,那么预测值和真实差距大则参数更新快,差距小则参数更新慢。

这里有一个有意思的问题,就是交叉熵公式中预测值在对数内,真实值在对数外,能不能互换位置呢?这个问题我稍微想了以下,如果交换过来,那么损失函数的导数波动范围将会非常广,因为导数会是 − 1 / 2 m ∗ ∑ i = 1 m ( σ ( 1 − σ ) ln ⁡ y − σ ( 1 − σ ) ln ⁡ ( 1 − y ) ) x -1/2m*\sum_{i=1}^m(\sigma(1-\sigma)\ln y-\sigma(1-\sigma)\ln(1-y))x 1/2mi=1m(σ(1σ)lnyσ(1σ)ln(1y))x
化简一下:
− 1 / 2 m ∗ ∑ i = 1 m σ ( 1 − σ ) ln ⁡ y / ( 1 − y ) x -1/2m*\sum_{i=1}^m\sigma(1-\sigma)\ln y/(1-y)x 1/2mi=1mσ(1σ)lny/(1y)x
这样不仅之前平方损失函数的问题依然存在,还可能有一个新的问题: y / ( 1 − y ) y/(1-y) y/(1y)可能会出现分子或分母为0的情况,即使不出现,放到 ln ⁡ \ln ln中也可能会出现正负无穷的情况,导数太不稳定,因此不适合交换预测值和真实值的位置。

2.2) 使用交叉熵损失函数要注意的问题

交叉熵损失函数中存在对数,如果 ln ⁡ \ln ln作用在0上,则是负无穷,就会溢出,因此需要考虑到这种可能,在代码中加入一个很小的常量,比如np.pow(10,-9),也就是 1 0 − 9 10^-9 109,避免溢出。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值