在运行 MP-CNN计算句子相似度 阅读笔记 中的代码时,也遇到了loss为Nan的问题,按照作者博文中的提示,使用tf_debug进行了一些尝试性的调试,在此记录一下调试的过程备忘。
关于tf_debug的使用,以下是几个不错的介绍。
https://www.tensorflow.org/programmers_guide/debugger
『教程』TensorFlow代码调试模块tfdbg – 叠加态的猫 – 博客园
了解了tf_debug的基本用法,我对这篇论文的代码进行了一些简单的调试。
开始调试:
运行一次sess.run():
一次运行过程中出现了14239个值为inf或nan的tensor,这些应该就是导致loss为nan的原因。接下来具体定位第一条tensor的情况。
可以看到在64个tensor中出现4个nan值。那这些nan值是怎么来的呢,继续往下看。
通过ni命令显示节点信息,可以看到两个输入分别对应余弦距离计算中的sum和mul操作。再来看一下mul操作。
可以看到对应余弦距离为nan值的地方mul操作提供的数值为0。
使用ni -t 可以定位到具体代码行。
很明显对应在代码里就是余弦距离计算时:dis = sum / mul 操作mul提供的数值中存在0,分母为零导致出现nan值。于是我将代码中距离计算公式后面加上 1e-4 项,然后重新进行测试。(作者博文中提到只在计算欧氏距离时出现nan值,不知为什么我余弦距离计算时也定位到了nan值。。。)。
做完上述修改后继续测试。
很好,这次只有421个tensor出现了inf或者nan值的情况,说明上次修改有效果。继续定位第一条tensor。
可以看到计算欧氏距离时出现inf值。。。继续定位。
不懂这两个输入都是什么意思。继续往下看。
看到数据基本可以猜测这是计算欧式距离的最后一步求平方根以后的数值,按理说这个数值不就应该是最后的计算结果吗,有0没问题啊,继续往下看。
这是计算欧氏距离时第二个输入,这个tensor代表什么?不过这个情况好像跟作者博文里说的去掉sqrt操作就不会出现loss为nan的情况一致,因为就是多了这个tensor导致欧氏距离最后出现inf值。我理解的上一个输出就应该是计算欧式距离的结果了,这个tensor到底是什么意义我最后也没弄明白。
查看了一下sqrt上一步操作也就是sum操作的值。
意料之中,没有问题。然后我想看看刚刚的第二个不知道意义的tensor是什么,结果。。
总之,问题就出在这个tensor上。我索性按照博文里说的将sqrt操作去掉。然后继续测试。
发现计算余弦距离的时候也有同样的问题,于是我把余弦距离的sqrt操作也去掉了(不知道博文作者为什么余弦计算没有问题)。
总而言之,就是距离计算的时候出现了问题,问题不是很清晰,不过第一次用tf_debug,不打算继续深究了。
做完所有修改后,loss为nan的问题是不存在了,不过训练结果很差,训练集倒还勉强收敛,测试集loss持续升高。按照博文里的提示,加入了BN,L2正则化,博文里将欧氏距离去掉,我只是把欧氏距离和余弦距离计算中的sqrt操作去掉,最后勉强收敛了,但效果还是很差。
代码扔到github上了,以后再回过头看吧。
附两张效果不好的截图。
还没训练完,不过看这个正确率估计不会太好。