问题描述
最近在对yolov5进行一些改动,想参照IA-YOLO对yolov5做一些改动,感兴趣可以看看(IA-YOLO)。在改动的过程中还是遇到不少问题的,困扰我最久的就是这个BatchNormal层的问题。
可以看到训练时比较正常,但验证时最后得到的P、R等指标都为0,就说明对验证集检测根本无法进行检测。
问题排查
在阅读了Pytorch训练模型损失Loss为Nan或者无穷大(INF)原因这篇博客后,经过排查,最后将问题锁定在BatchNormal层,发现一到验证集时,网络中的BatchNormal层就输出nan,同时其中的running_mean以及running_var也是nan
问题分析
造成这种情况的原因有以下几种
- 验证集和训练集有不同的分布 ,就如图那篇博客所说的,但其实我不是很理解,验证集和训练集一般都是随机划分,或者直接用现有的数据集,为什么会出现不同分布的情况;我抱着试一试的心态将验证集中的数据用训练集替代,还是出现nan,说明不是这个原因
- 调整momentum ,试了也没用;
- 设置track_running_stats=False,可以解决我的问题,但这样并不是BatchNormal层正常运行状态
- BatchNormal层接收了异常输入 ,这是我的代码的问题所在,应该也是大部分BatchNormal层出现问题的原因;我的程序在训练时会有一个全零张量的输入来计算类似计算图尺寸的步骤,当这个张量通过我的一系列预处理步骤后会变成nan,当这个输入到BatchNormal层的时候就会得到nan, 而在训练时BatchNormal层一旦出现nan后续的值将一直为nan。
至于最后为什么nan只出现在验证时,而训练时一切正常,可以参考pytorch BatchNorm参数详解,计算过程