1通过自己的经历发现出现nan的一种情况是本身数据可能存在比较大的数据导致的
先说明一下我运用的是韩国大佬https://github.com/Kyubyong/transformer.git的代码,来做了一个闲聊的问答模
情况说明:
由于在之前一直在用tensortflow-gpu ,在之前服务器通过问答数据处理好之后,运行这个模型,没有报错,并且运行成功,效果好不错。
更换公司后,服务器发生变化,但是环境仍然一致,都是python3.5的 tensorflow==1.12.0 ,环境是gpu,
训练就莫名出现训练nan的问题。如图所示:
但是之前明明是好的,为什么换了一台机器就不行了,奇怪的不行,当然。具体原因具体对待,
第一步:我把训练环境全部转变为和之前的服务器一模一样,(唯一不一样的就是,我知道之前那服务机器训练,虽然安装的是tensorflow-gpu==1.12.0,但是实际训练莫名其妙自己用的是cpu,后台就怎么搞都不行,其他代码仍然是gpu能够使用,后来就没有管),更换之后仍然是一样的nan问题。
第二步:根据网上和自己的经验,出现nan更多原因在于最终预测输出
logits = tf.einsum('ntd,dk->ntk', dec, weights) # (N, T2, vocab_size)
logits中出现的异常值导致的。从而导致
ce = tf.nn.softmax_cross_entropy_with_logits_v2(logits=logits, labels=y_)
训练出现nan的原因,
第一种改法就是把异常值用
tf.clip_by_value(logits,1e-8,1.0) 替代logits,这样就会把异常数值去掉,结果也确实解决了出现nan的问题,但是刚开是从损失10.56降低到9.6左右就不在降低。训练了一天的时间,通过预测,不管输出什么样的语句,返回结果都是同一个词语。这说明一个问题tf.clip_by_value(logits,1e-8,1.0)只能解决的是在模型正常情况的非常稀疏的异常值,说明预测大部分结果都在正常分布情况下才可以用。
第二步 :
logits = tf.einsum('ntd,dk->ntk', dec, weights) # (N, T2, vocab_size)在这个代码中增加替换为:
# logits = tf.nn.relu(tf.einsum('ntd,dk->ntk', dec, weights)) # (N, T2, vocab_size)relu函数能够把所有数值映射为整数,结果也同样解决了nan的问题,而且损失从10下降到6多,但是预测结果还是啥也不是,
第三部:通过以上方法说明,如果以上方法都解决不了问题,这说明,你的预测结果大部分都不是正常数值。要从根源上解决。但是代码并没有报错,实在是无法找到问题。也是偶然机会,既然唯一和上一次服务器不一样的就是一个是gpu跑的一个是cpu跑的,那么就把本机的tensorflow改成cpu,然后运行,结果让人狗血的事情出现,报错:如图所示:
骂娘的心都有了,擦,gpu和cpu不一样,虽然google很厉害,但还是要骂一句,能不能对包的返回结果负责,这难道不是bug,gpu找不到错误的原因,整整浪费了三天,本来模型就没有什么改动,结果从上图就可以知道是由于是实际的初始化词表是130000之多的词语,但是我的代码在初始化embedding时候的vocab_size设置为1500,导致找不到词向量。估计gpu版本的直接把没有在词汇表的做啥样的处理?
反正擦浪费三天,仅此记住,很搞笑的说,以后出现问题,把tensorflow换换gpu和cpu换一下,哈哈啊,终于解决了还是。难受,大费周章