本文是深度学习和日常代码中遇到的报错汇总,因时间比较久,暂时都没有图片,只有文字描述。解决方案也大多参考网上的解决方案,有些有用,有些没有效果,本文章中的问题,也仅是本人遇到的问题,使用列举的方案已经解决。
处理:调用的方法是一个类,需要先进行实例化在进行调用
处理:尝试了网上大家的方式,都没有解决这个问题,后来将pytorch和cuda都降低了版本,问题解决了(要调试网络,看具体在那一步导致的loss为nan)。
网络上找到的其他人总结的解决方式:
1)如果在迭代的100轮以内,出现NaN,一般情况下的原因是因为你的学习率过高,需要降低学习率。可以不断降低学习率直至不出现NaN为止,一般来说低于现有学习率1-10倍即可。
2)如果当前的网络是类似于RNN的循环神经网络的话,出现NaN可能是因为梯度爆炸的原因,一个有效的方式是增加“gradient clipping”(梯度截断来解决)
3)可能用0作为了除数;
4)可能0或者负数作为自然对数
5)需要计算loss的数组越界(尤其是自己,自定义了一个新的网络,可能出现这种情况)
6)在某些涉及指数计算,可能最后算得值为INF(无穷)(比如不做其他处理的softmax中分子分母需要计算exp(x),值过大,最后可能为INF/INF,得到NaN,此时你要确认你使用的softmax中在计算exp(x)做了相关处理(比如减去最大值等等))
7)若模型训练开始时出现,增大或减小batch_size的值,需要增大或减小后去跑模型观察情况,是否还会出现;优化神经网络结构(增加或减少网络深度)
8)若模型运行过程中出现,需要考虑是否是梯度爆炸引起,需要调低学习率或对梯度进行优化。
特殊情况,换激活函数
卷积在使用BN之后,可以换成sigmoid或tanh激活函数
解决方式:
1)减小batch_size
2)减小网络
原因:
1、引用了父类Module,但是在初始化中没有对父类的初始化函数进行重构
解决方式:
1、在init初始化中,使用super()对父类的初始化函数进行重构
解决方式:
1)在循环的最后加上 torch.cuda.empty_cache()
2)检查在代码中是否有SummerWrite(),有的情况禁用相关代码在进行调试
3)在代码中加上os.environ["CUDA_LAUNCH_BLOCKING"] = "1"
解决方式:
1)在尝试在代码开始部分加入如下2个代码:
torch.backends.cudnn.enabled = True
torch.backends.cudnn.benchmark = True
原因:因为模型中用了batchnomolization,训练中用batch训练的时候当前batch恰好只含一个值,而由于BatchNorm操作需要多于一个数据计算平均值,因此造成该错误
解决方式:
1、加大Batch_Size
2、网络设置eval模式
3、去掉网络中的batchnormal
调整输入,使batchnormal不止是1个值
原因:pt文件损坏,无法加载
解决方式:重新训练
原因:数据精度不一致导致的问题
处理方式:1、检查所有数据的精度是不是一样(标签、模型输入和输出、损失函数的输入和输出数据的精度),不一样的情况,需要修改为相同精度
原因:EOFError是IOError的子类。表示没有按照正确的读写模式操作文件,会报此错。
本人是因为训练过程中突然断电,有电后重新加载参数进行训练时报的这个错误
解决方式:
1、本人解决方式是删除参数文件,并重新跑
网上有解决方式说在Dataloader中,将num_workers设置为0就可以。本人尝试无效,猜测可能是造成原因不同,导致该操作无效。
原因:
1)环境的虚拟内存不足
2)batch-size太大,
3)数据问题
解决方式:
前2种情况可以参考博客:https://blog.csdn.net/weixin_53660567/article/details/126635843,一般前两种情况遇到比较多。
1)增大环境的虚拟内存(环境所在盘的虚拟内存)
2)调小batch-size,或者将workers设置为0
处理数据
原因:1、torch和torchvision版本不同,比如torch是支持cuda的,但是torchvision不支持cuda
2、torch和cuda版本不对
解决方式:
1、卸载torch和torchvision,重新一起安装 相同的torch和torchvision
2、卸载torch和cuda,并分别重新安装,使版本匹配
原因:不支持long类型的运算
解决方式:将报错代码输入数据类型设置为float,我是在使用torch.histc()方法时出现的错误。
原因:此时图片的数据方式是numpy的array,不能进行图片相关操作,需要转换为图片数据
解决方式:将图片数据转化为Image的数据格式在进行图片操作。转换方式:Image.fromarray(np.uint8(img))
原因:需要检查numpy.ndarray的数据的格式,是否是(H,W,C)格式,如果是(C,H,W)格式的话,需要换轴处理
解决方式:将numpy.ndarray数据进行换轴操作(img = img.transpose((1, 2, 0))),换成(H,W,C)格式,换轴之后在进行转换
原因:图片通道数发生变化导致,例如训练时使用的是3通道图片进行训练,测试时使用单通道图片进行测试
解决方案:对传入的图片进行处理,转为单通道图片或转为3通道图片,根据实际项目调整。
原因:抠图时,传入的坐标值为nump.ndarray ,没有__round__这个方法
解决方案:使用np.round(data)对数据进行处理之后,在传入到抠图的方法中即可。
原因:张量中存在多个tensor张量列表,导致在dim=1的轴上进行索引时,存在多个张量数组,程序报错,数据格式类似如下:
tensor([
tensor([1]),
tensor([b])])
解决方式:检测前面步骤的数据处理,是否存在问题,可以参考以下处理方式:
1、使用索引方式获取数据,一次性获取所有所需要数据
2、使用cat将不同张量数据整合为一个张量数据
将张量数据转化为numpy数据,在将数据组合到一起之后,在转为tensor张量
解决方式:
1、若使用的是NllLoss损失函数,则标签的损失不需要处理成one-hot编码格式,只需要是0或1维的标签数据就可以。
2、若是其他损失函数,需要检查计算损失的2个张量的大小和形状是否一致
分析:图片或文件路径问题,可以将cv2.imread()的图片打印出来,看返回是否有数据还是None,我的情况是返回的是None。
解决措施:
1)如果是路径问题,处理图片路径
2)如果是图片问题,可以尝试使用PIL打开图片,在转换成cv2格式进行操作
from PIL import Image
import cv2
img = cv2.imread(file_path)
#将cv2打开的图片转换为PIL格式的图片
img_pil = Image.fromarray(np.asarray(cv2.cvtColor(crop_img, cv2.COLOR_BGR2RGB)))
#将PIL打开的图片转换为CV2 格式
img1 = Image.open(file_path)
img_cv2 = cv2.cvtColor(numpy.asarray(img1), cv2.COLOR_RGB2BGR)
解决措施:在代码文件开始,添加该代码:ImageFile.LOAD_TRUNCATED_IMAGES = True,我遇到这个问题,是因为处理的图片超出了上限,导致截断数据流,报出这个错误。
原因:安装包下面存在多个tensorboard,删除/卸载一个就好
解决措施:浏览了网络上很多的解决方式都不管用,最后使用网络上的一段代码,查看了tensorboard的包,发现有一个~ensorboard的包,把这个包删除之后就好了(一般和tensorboard的包在同一个位目录内,我的是在D:\ProgramData\anaconda3\Lib\site-packages里面)。
#查看安装的包:
import pkg_resources
for entry_point in pkg_resources.iter_entry_points('tensorboard_plugins'):
print(entry_point.dist)