之前看了别人写的流程,一团乱遭,缺胳膊少腿,遂决定还是自己也写一下
此流程尽量做到在最小程度上修改源码
1、从Github下载原作者代码
笔者所用的源代码来自这里,请先下载、解压
2、新建文件夹
在根目录下新建data文件夹,在data文件夹下新建coco文件夹,将解压后/data/coco_label.txt放在该coco文件夹下。PS:虽然我也不知道为什么要这么做,但是不放的话代码运行时会一直报错,根本跑不起来
3、VOC数据集
这里默认已经做好了自己的标准格式的VOC格式数据集,如果不了解如何配置VOC格式数据集的请看我的这篇文章.在刚才新建的根目录下的data文件夹下存放VOCdevkit文件夹。
4、修改源代码
4.1修改ssd.pytorch-master/data/config.py(共两处)
# 13--17行的:
# SSD300 CONFIGS
voc = {
'num_classes': 3, #将原来的21改为你的数据集中的类别数+1,这个1是background,一定要加!不然会出错
'lr_steps': (80000, 100000, 120000),
'max_iter': 10000,# 120000 # 这是最大迭代次数,可自行修改
'feature_maps': [38, 19, 10, 5, 3, 1],
4.2 修改ssd.pytorch-master/data/voc0712.py(共两处)
VOC_CLASSES = ( # always index 0
#'aeroplane', 'bicycle', 'bird', 'boat',
#'bottle', 'bus', 'car', 'cat', 'chair',
#'cow', 'diningtable', 'dog', 'horse',
#'motorbike', 'person', 'pottedplant',
#'sheep', 'sofa', 'train', 'tvmonitor')
'cigar','ring') #将原有的类名全部注释掉,然后写上你的类名,如果只有一个类名要写('类名',),逗号千万不能忘!
# 将第97行的:
image_sets=[('2007', 'trainval'), ('2012', 'trainval')],
# 替换为:
image_sets=[('2007', 'trainval),],
4.3修改ssd.pytorch-master/layers/modules/multibox_loss.py
# 在第99行上方插入
loss_c = loss_c.view(pos.size()[0], pos.size()[1])
loss_c[pos] = 0 # filter out pos boxes for now
将第90行代码
loss_l = F.smooth_l1_loss(loc_p, loc_t, size_average=False)
替换为
loss_l = F.smooth_l1_loss(loc_p, loc_t, reduction='sum')
4.4修改ssd.pytorch-master/train.py
# 将167行的 images, targets = next(batch_iterator) 修改为:
try:
images, targets = next(batch_iterator)
except StopIteration:
batch_iterator=iter(data_loader)
images, targets = next(batch_iterator)
# 将183行的
loc_loss += loss_l.data[0]
conf_loss += loss_c.data[0]
# 修改为
loc_loss += loss_l.item()
conf_loss += loss_c.item()
# 将190行的
print('iter ' + repr(iteration) + ' || Loss: %.4f ||' % (loss.data[0]), end=' ')中的
loss.data[0]修改为loss.item()
4.5修改代码中预训练模型导入路径和名字:
训练时,如果没有预训练文件请点击这里下载,如果没有预训练文件将不能进行训练。下载后在ssd目录下新建weight文件夹,将预训练文件放在里面
测试时,指定自己的模型路径,请修改eval.py中第17行:
parser.add_argument(’–trained_model’, default=‘weights/你的模型的名字’
4.6 修改ssd目录下ssd.py:
将第32行中,num_classes 参数的值改为你的类数目,注意,这里不要+1!
以下为非必须修改部分
4.7如果需要对训练loss做实时可视化操作,需在train.py中对代码进行如下修改:
# 将91--93行代码剪切到train函数定义域外
if args.visdom:
import visdom
viz = visdom.Visdom()
# 将191行的
update_vis_plot(iteration, loss_l.data[0], loss_c.data[0],iter_plot, epoch_plot, 'append')
# 修改为
update_vis_plot(epoch, loc_loss, conf_loss,iter_plot, epoch_plot, 'append',epoch_size)
5、至此,应该可以开始正常训练并实时画出loss图像,以下为遇到错误时的解决方案:
5.1 FileNotFound Error:不存在coco_label.txt:参考2
5.2 报错信息为: the shape of mask [32,8732] ar index 0 not match the shape of the indexed tensor [270424,1] at index 0.(参考:https://github.com/amdegroot/ssd.pytorch/issues/421#issuecomment-545861899)
5.3 一次训练完后触发StopIteration(参考4.4)
5.4 AssertionError: Must define a window to update(参考4.6)
5.5 RuntimeError: cuda runtime error (710) : device-side assert triggered
有可能是你的类数目和实际不符,代码中类数目应该是真实数目+1!!!
也有可能是CUDA的原因,可尝试 CUDA_LAUNCH_BLOCKING=1 python train.py
5.6 RuntimeError: Address already in use
运行:CUDA_VISIBLE_DEVICES=0,1 python -m torch.distributed.launch --nproc_per_node=2 --master_port 29501 train.py
5.7 训练时Loss:Nan
Nan表示 Not A Number,梯度爆炸,建议将learning_rate参数,也就是在train.py中的lr参数调小试试
# 训练时
1、先安装visdom:sudo pip install visdom
2、然后在终端中输入 python -m visdom.server 回车
点开提示信息,比如我的是You can navigate to http://localhost:8097 点开这个网页
3、在ssd目录下运行 python train.py
就可以在visdom中实时可视化看到训练信息了
# 测试时,在ssd目录下运行 python eval.py
暂时就记得这一些了。。。趁着还没忘干净赶紧记下来,希望能对你有所帮助。
最后,给一下我的1000个iteration的训练过程图和最后的mAP: