Pytorch 常见报错 + YOLOv3网络结构+Darknet训练YOLOv3的一些细节

原文:链接:https://www.jianshu.com/p/b206f438e630

1.BUG:

RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation.

        什么是inplace operation:in-place operation在pytorch中是指改变一个tensor的值的时候,不经过复制操作,而是直接在原来的内存上改变它的值。可以把它成为原地操作符。

        pytorch中,通常加后缀“_”来表示原地运算符,例如.add_(),或者python中的 “+=”。

 

2.Bug:

RuntimeError: Expected object of backend CPU but got backend CUDA for argument #2 'weight'

这种情况通常是数据还在cpu上,又要用到gpu上计算导致的,可以尝试数据后面加上.cuda()。

cpu上的tensor和gpu上的tensor是太一样的:PyTorch中的数据类型为Tensor,Tensor与Numpy中的ndarray类似,同样可以用于标量,向量,矩阵乃至更高维度上面的计算。PyTorch中的tensor又包括CPU上的数据类型和GPU上的数据类型,一般GPU上的Tensor是CPU上的Tensor加cuda()函数得到。通过使用Type函数可以查看变量类型。系统默认的torch.Tensor是torch.FloatTensor类型。例如data = torch.Tensor(2,3)是一个2*3的张量,类型为FloatTensor; data.cuda()就将其转换为GPU的张量类型,torch.cuda.FloatTensor类型。

3.Bug:

xxxxxx is not implemented for type torch.LongTensor

尝试将torch.LongTensor转换为:torch.FolatTensor类型。

 

4.Bug:

bool value of Tensor with more than one value is ambiguous

函数或者可调用对象使用时候没有加括号。

 

5.注意:关于减少时间消耗

(1)只要是用到for循环都是在cpu上进行的,会消耗巨量的时间

(2)只要是用到生成矩阵这种操作都是在cpu上进行的,会很消耗时间。

(3)数据往cuda()上搬运会比较消耗时间,也就是说 .cuda()会比较消耗时间,能去掉就去掉。

(4)在服务器上,如果可以在一块gpu上运行就不要采用net = nn.DataParallel(net),这种gpu并行方式比单个gpu要耗时。

6. pytorch debug :断点调试 和 打印可能出错步的结果 真的可以很快的找到错误所在的地方

关于断点调试:pycharm单步调试 - qq_33485434的博客 - CSDN博客


7.UserWarning: To copy construct from a tensor

x= torch.tensor(x)  ------>    x= x.clone()

8.RuntimeError: Expected object of scalar type Long but got scalar type Float for argument #2 'mat2'(期望对象为标量类型长,但得到标量类型浮点数)

这个好奇怪,对于x= torch.matmul(x,one_hot_copy), 只要提前把x和one_hot_copy后面加上.float()就可以解决。

 

**9. 张量乘法(未定):

二维张量相乘: 二维矩阵相乘 A*B: A.mm(B), 多维矩阵相乘 A*B: A.matmul(B), 注意需要long()数据类型。tensor.mul(tensor)

 

原文:https://blog.csdn.net/qq_37541097/article/details/81214953 

1.Darknet-53 network
在论文中虽然有给网络的图,但我还是简单说一下。这个网络主要是由一系列的1x1和3x3的卷积层组成(每个卷积层后都会跟一个BN层和一个LeakyReLU)层,作者说因为网络中有53个convolutional layers,所以叫做Darknet-53(我数了下,作者说的53包括了全连接层但不包括Residual层)。下图就是Darknet-53的结构图,在右侧标注了一些信息方便理解。(卷积的strides默认为(1,1),padding默认为same,当strides为(2,2)时padding为valid)

 

 

看完上图应该就能自己搭建出Darknet-53的网络结构了,上图是以输入图像256 x 256进行预训练来进行介绍的,常用的尺寸是416 x 416,都是32的倍数。下面我们再来分析下YOLOv3的特征提取器,看看究竟是在哪几层Features上做的预测。

2.Feature Extractor
作者在论文中提到利用三个特征层进行边框的预测,具体在哪三层我感觉作者在论文中表述的并不清楚(例如文中有“添加几个卷积层”这样的表述),同样根据代码我将这部分更加详细的分析展示在下图中。注意:原Darknet53中的尺寸是在图片分类训练集上训练的,所以输入的图像尺寸是256x256,下图是以YOLO v3 416模型进行绘制的,所以输入的尺寸是416x416,预测的三个特征层大小分别是52,26,13。

在上图中我们能够很清晰的看到三个预测层分别来自的什么地方,以及Concatenate层与哪个层进行拼接。注意Convolutional是指Conv2d+BN+LeakyReLU,和Darknet53图中的一样,而生成预测结果的最后三层都只是Conv2d。通过上图小伙伴们就能更加容易地搭建出YOLOv3的网络框架了。

 

Darknet训练YOLOv3的一些细节

原文:https://blog.csdn.net/yikeshiguang/article/details/81080842 

1.cfg文件里的batch就是batch_size,subdivisions只是在显存不足的情况下把batch分批放入训练。      ?现在怀疑batch_size = batch/subdivisions。昨天跑的一个训练如果batch = batch_size的话那大约有80个epoch,但还是明显欠拟合,loss很高。所以还在疑惑???

2.epoch = max_batches/(images/bach)   ——  暂时理解应该是这样?

3.max_batches = max_iterations

4.训练的时候batch在小于1000次时每100次保存模型,大于1000后每10000次保存一次模型。可以通过修改/examples/detector.c中的train_detector函数来自己决定多少张图保存一次模型。

5.假设steps = 10000 , scale = .1 ,那意思就是迭代到10000次时学习率衰减10倍。如果调整max_baches的大小,需要同时调整steps,而scale可以自己决定修不修改。

6.训练的时候若数据集小目标较少,106层会大概率输出nan,这是数据集的问题。如果数据集没有问题,可以通过调大batch或者调小learning_rate来解决。(yolo的训练调参略烦)

7.github上暂时还没有发现在pytorch框架下较好用的训练代码,尝试着跑了两个,效果不好,所以还是使用darknet来进行训练。

8.使用voc_label.py输出的是绝对路径。

9.训练的时候用 ./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74 2>1 | tee person_train.txt 保存训练内容

10.由于数据集的问题没有小目标,尝试使用三个数据集一起训练但大幅输出nan,表示训练很糟糕。所以在原有第一个数据集训练最后保存的模型的基础上,进行后续训练。也就是把预训练权重换成自己的xxx.weights,训练的输出暂时看起来较为正常,等训练完成了看结果好坏。(同时需要调整cfg文件的max_batches,比如第一次训练完保存的是100000次,生成了final.weights,那么接下去训练就需要把cfg调大超过10w次,不然会直接保存。)

你可能感兴趣的:(Pytorch 常见报错 + YOLOv3网络结构+Darknet训练YOLOv3的一些细节)