参考
http://www.mamicode.com/info-detail-2167712.html
学习率设置为0.001时候出现了loss=nan错误
将学习率设置为0.0001后
1.问题一;训练CNN的时候出现nan
CNN是我最开始接触的网络,我的研究课题就是利用CNN,LSTM等网络对人体动作做识别。动作数据来源于手机的加速度计,做动作的人在固定位置携带手机并做特定动作,实验人员接收手机的加速度计数值并打上特定的动作标签。
在训练CNN网络时一共遇到两处坑,一是遇到在训练期间遇到nan错误,这个错误很常见。nan的错误多源于你的学习率设置的太大或者batchsize设置的太大,可以10倍10倍的减小学习率直到nan错误不出现。其实要弄明白nan错误怎么出现的才能真正的解决这个错误。
这个错误是因为logits输出太大变成INF,对这个取log就会在求梯度就会变成nan,nan是not a number 的缩写,表示不是一个有理数。所以除了调小学习率这个解决方案,另一个解决方案还可以给loss加正则化项。
2.问题二;在训练CNN的时候loss一直降不下去
我用普通的卷积核对数据做卷积,准确率保持在0.4左右不动了,loss也是到后面基本不降,各种调网络结构终于找到一种深度可分离卷积结构可以使准确率达到0.9左右。深度卷积与我们了解的普通卷积网络的不同点就是它只做单通道卷积,也就是一次卷积后各个通道的卷积结果不相加,各自独立做为一个featuremap。但是这种网络结构的神经元个数增长很快,所以它的训练会比普通卷积慢很多,对于通道数过多的数据并不是很适合,但是这种网络的鲁棒性很好。
其实我这里出现loss不降的原因我后来找到了,是因为我的数据里有错误,数据本身就含有了nan的数据,错误的数据导致网络无法收敛
3.问题三;训练LSTM网络循环出现nan的错误,一到特定的batch就出现nan
一出现这个问题我就意识到肯定是数据出了问题,后来把数据中的nan替换掉就正常了。因为我的数据加载完后是numpy格式的,替换只需要加一句train= np.nan_to_num(train)就可以了
对数据做一个这样的简单处理,普通卷积网也正常了,真是豁然开朗啊,不用深度卷积,只用普通卷积就可以达到0.96的准确率。
4.tf.clip_by_value(t, clip_value_min, clip_value_max, name=None)
功能:
基于定义的min与max对tesor数据进行截断操作,目的是为了应对梯度爆发或者梯度消失的情况
tf.clip_by_value(A, min, max):输入一个张量A,把A中的每一个元素的值都压缩在min和max之间。小于min的让它等于min,大于max的元素的值等于max。
用的是交叉熵cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))的话,最后softmax层输出y_conv的取值范围在[0,1]页就是说允许取0值,有log(0)出现很有可能出现nan啊,cross_entropy = -tf.reduce_mean(y_*tf.log(tf.clip_by_value(y_conv,1e-15,1.0)))在tensorflow里可以限定一下y_conv的取值范围,别的框架不清楚。
import tensorflow as tf;
import numpy as np;
A = np.array([[1,1,2,4], [3,4,8,5]])
with tf.Session() as sess:
print sess.run(tf.clip_by_value(A, 2, 5))
输出:
[[2 2 2 4]
[3 4 5 5]]