【目标检测实战】Pytorch—SSD模型训练(VOC数据集

20.jpg

原文发表在:语雀文档

0.说明

SSD:Single Shot MultiBox Detector 和Yolo系列一样,他们都是one-stage系列的目标检测模型,SSD算法的官方实现是用的Caffe框架,源码在↓。有人将其改造成了Pytorch实现版,所以此代码可称为SSD算法的非官方Pytorch实现。

这里,需要说明:

  • 1.目前只支持Python3.X版本
  • 2.高度推荐通过支持CUDA的GPU来训练,用CPU也可以训练,不过非常非常慢
  • 3.目前只支持VOC2007/VOC2012 、COCO数据集、对ImageNet数据集还不能够支持
  • 4.本文的训练在windows10/ubuntu18.04都可正常跑通

推荐按照github首页给出的步骤一步步来:

image

整体来说,比较简单。不过,还是会遇到比较坑的地方,主要是visdom那里,这里直接跳过Visdom安装的步骤,因为即使安了,会发现代码也有报错,且visdom只是用于训练过程中可视化loss的页面,没有也不影响正常训练。


1.安装Pytorch

如果已安装Pytorch,可以直接跳过此步。由于我装了anaconda,所以直接用的conda安装,安装过程见pytorch官网

image

如果不翻墙,conda安装pytorch会比较慢,经常卡住,建议配置国内清华源,再下载速度会快很多

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/

win10和ubuntu系统都建议直接用conda安装,步骤类似。安装完成在conda环境中输入python,进入python后如果import torch不报错则证明pytorch安装成功

2.资源准备

2.1 源码下载

git clone[https://github.com/amdegroot/ssd.pytorch.git](https://link.zhihu.com/?target=https%3A//github.com/amdegroot/ssd.pytorch.git)

或者下载zip包直接下载都可以ssd.pytorch-master.zip

2.2 VOC数据集下载

目前只支持COCO和VOC数据集,鉴于COCO数据集规模太大,这里仅准备VOC数据集。如果已下载好VOC数据集,可跳过此步。

VOC2007

训练集+测试集

http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar

VOC2012

训练集+测试集

http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar 将下载后的文件解压,将VOC2007和VOC2012文件夹共同放入VOCdevkit下,此文件夹路径即为后面代码中需要用到的VOC_ROOT。

例: VOC_ROOT='D:\personalProject\AI\pytorch\dataset\VOC\VOCdevkit' VOC_ROOT = '/home/lyon/AI/DeepLearning/ssd/dataset/VOCdevkit/'

2.3 模型文件下载

下载好的模型文件放入源码包weights文件夹下 vgg16_reducedfc.rar https://s3.amazonaws.com/amdegroot-models/vgg16_reducedfc.pth

3.安装visdom
visdom主要用于训练过程中,可通过浏览器可视化地观察loss情况和训练细节,如果不需要可视化地看训练过程,可跳过此步骤。
3.1安装visdom
pip install visdom
3.2修改源码
下载下来的visdom,如果直接用 python -m visdom.server 启动,浏览器访问http://localhost:8097/会发现页面什么都没有,因为在其源码server.py的1916行,会通过download_scripts()方法动态下载一些css、font、js等静态文件,如果不翻墙下载会失败导致文件缺失,进入页面后什么都没有....

image

解决办法: - 注释掉visdom包下server,py源码1917行的:download_scripts() - 手动将下载好的静态文件,放入visdom的static文件夹下
3.3增加静态文件
如果是conda安装的环境,可用conda env list查看各个环境的路径,然后找到visdom路径 visdom文件夹路径:conda环境路径/lib/site-packages/visdom

image

这里,可直接用我下载好的static.rar,替换掉原static文件,然后即可通过python -m visdom.server 正常启动,并访问http://localhost:8097/

4.模型训练

4.1设置模型参数

主要是在train.py中设置默认数据集,算法模型路径,batch-size,是否启动CUDA加速等等。这里源码默认的batch-size是32,根据自己GPU能力调节大小,我用GTX1060 6G的GPU发现32会崩,可以修改成16,RTX2060 SUPER下可以设置到32。详细配置如下:

# 加载模型初始参数
parser = argparse.ArgumentParser(
    description='Single Shot MultiBox Detector Training With Pytorch')
train_set = parser.add_mutually_exclusive_group()
# 默认加载VOC数据集
parser.add_argument('--dataset', default='VOC', choices=['VOC', 'COCO'],
                    type=str, help='VOC or COCO')
# 设置VOC数据集根路径
parser.add_argument('--dataset_root', default=VOC_ROOT,
                    help='Dataset root directory path')
# 设置预训练模型vgg16_reducedfc.pth
parser.add_argument('--basenet', default='vgg16_reducedfc.pth',
                    help='Pretrained base model')
# 设置批大小,根据自己显卡能力设置,默认为32,此处我改为16
parser.add_argument('--batch_size', default=16, type=int,
                    help='Batch size for training')
# 是否恢复中断的训练,默认不恢复
parser.add_argument('--resume', default=None, type=str,
                    help='Checkpoint state_dict file to resume training from')
# 恢复训练iter数,默认从第0次迭代开始
parser.add_argument('--start_iter', default=0, type=int,
                    help='Resume training at this iter')
# 数据加载线程数,根据自己CPU个数设置,默认为4
parser.add_argument('--num_workers', default=4, type=int,
                    help='Number of workers used in dataloading')
# 是否使用CUDA加速训练,默认开启,如果没有GPU,可改成False直接用CPU训练
parser.add_argument('--cuda', default=True, type=str2bool,
                    help='Use CUDA to train model')
# 学习率,默认0.001
parser.add_argument('--lr', '--learning-rate', default=1e-3, type=float,
                    help='initial learning rate')
# 最佳动量值,默认0.9(动量是梯度下降法中一种常用的加速技术,用于加速梯度下降,减少收敛耗时)
parser.add_argument('--momentum', default=0.9, type=float,
                    help='Momentum value for optim')
# 权重衰减,即正则化项前面的系数,用于防止过拟合;SGD,即随机梯度下降,多指mini-batch梯度下降
parser.add_argument('--weight_decay', default=5e-4, type=float,
                    help='Weight decay for SGD')
# gamma更新,默认值0.1
parser.add_argument('--gamma', default=0.1, type=float,
                    help='Gamma update for SGD')
# 使用visdom将训练过程loss图像可视化
parser.add_argument('--visdom', default=False, type=str2bool,
                    help='Use visdom for loss visualization')
# 权重保存位置,默认存在weights/下
parser.add_argument('--save_folder', default='weights/',
                    help='Directory for saving checkpoint models')
args = parser.parse_args()

设置好参数后,需要配置数据集加载路径,在源码包/data/voc0712.py中注释掉第28行,将VOC数据集路径替换为自己的路径:

image

4.2修改源码

由于Pytorch版本不同,较新版的代码直接运行会报错,需要修改部分代码,主要是将.data[0]的部分改成.item()

修改train.py

修改源码183.184两行

loc_loss += loss_l.data[0]
conf_loss += loss_c.data[0]

改为:

loc_loss += loss_l.item()
conf_loss += loss_c.item()

修改源码188行

print('iter ' + repr(iteration) + ' || Loss: %.4f ||' % (loss.data[0]), end=' ')

改为:

print('iter ' + repr(iteration) + ' || Loss: %.4f ||' % (loss.item()), end=' ')

修改源码165行

# load train data
images, targets = next(batch_iterator)

改为:

try:
    images, targets = next(batch_iterator)
except StopIteration as e:
    batch_iterator = iter(data_loader)
    images, targets = next(batch_iterator)

修改mutibox_loss.py

修改:源码包/layers/modules/mutibox_loss.py 调换第97,98行:

loss_c = loss_c.view(num, -1)
loss_c[pos] = 0 # filter out pos boxes for now

修改第114行为:

N = num_pos.data.sum().double()
loss_l /= N
loss_c /= N

参考:
https://blog.csdn.net/qq_39571318/article/details/89788687 https://blog.csdn.net/dingkm666/article/details/88775428

修改coco.py

由于train.py会from data import ,而data初始化时会加载coco_labels.txt,这个文件在源码包中data/下,无论你是否下载了coco数据集都不影响其加载,加载时需要用到COCO_ROOT这个参数,需要修改COCO_ROOT为你的coco_labels.txt所在的父文件夹目录*。

4.3开始训练

训练方式以下两种都可以:

  • 1.Pycharm中直接训练
  • 2.cmd中进入conda的pytorch环境,python train.py
image

5.模型验证

5.1修改模型路径

第5步训练的模型,默认每迭代5000轮会在weights/下生成.pth模型文件,我这里训练了几个小时,迭代到25000轮。模型验证前,需要修改eval.py第39行,替换为你自己训练好的模型文件l路径。 生成的模型文件ssd300_COCO_25000.zip

image

5.2修改eval.py

运行eval.py,会对测试集中所有图片进行检测,并输出结果。这里实际运行发现windows系统下会有问题,需要做一点修改。 源码71行注释,改成如下形式:

#imgsetpath = os.path.join(args.voc_root, 'VOC2007', 'ImageSets','Main', '{:s}.txt')
imgsetpath = os.path.join(args.voc_root, 'VOC2007', 'ImageSets', 'Main') + os.sep + '{:s}.txt'

如不修改,则imgsetpath 不能正常拼接出来,导致报错

5.3运行eval.py验证模型

训练了几个小时,得到模型ssd300_COCO_25000.pth 验证结果如下:

Evaluating detections
Writing aeroplane VOC results file
Writing bicycle VOC results file
Writing bird VOC results file
Writing boat VOC results file
Writing bottle VOC results file
Writing bus VOC results file
Writing car VOC results file
Writing cat VOC results file
Writing chair VOC results file
Writing cow VOC results file
Writing diningtable VOC results file
Writing dog VOC results file
Writing horse VOC results file
Writing motorbike VOC results file
Writing person VOC results file
Writing pottedplant VOC results file
Writing sheep VOC results file
Writing sofa VOC results file
Writing train VOC results file
Writing tvmonitor VOC results file
VOC07 metric? Yes
Reading annotation for 1/4952
Reading annotation for 101/4952
Reading annotation for 201/4952
Reading annotation for 301/4952
......
......
Reading annotation for 4901/4952
Saving cached annotations to /home/lyon/AI/DeepLearning/ssd/dataset/VOCdevkit/VOC2007/annotations_cache/annots.pkl
AP for aeroplane = 0.7428
AP for bicycle = 0.8042
AP for bird = 0.6725
AP for boat = 0.6337
AP for bottle = 0.4359
AP for bus = 0.8039
AP for car = 0.8236
AP for cat = 0.8543
AP for chair = 0.5490
AP for cow = 0.7241
AP for diningtable = 0.6796
AP for dog = 0.8046
AP for horse = 0.8268
AP for motorbike = 0.7855
AP for person = 0.7249
AP for pottedplant = 0.4448
AP for sheep = 0.7060
AP for sofa = 0.7563
AP for train = 0.8028
AP for tvmonitor = 0.7311
Mean AP = 0.7153
~~~~~~~~
Results:
0.743
0.804
0.672
0.634
0.436
0.804
0.824
0.854
0.549
0.724
0.680
0.805
0.827
0.785
0.725
0.445
0.706
0.756
0.803
0.731
0.715
~~~~~~~~

--------------------------------------------------------------
Results computed with the **unofficial** Python eval code.
Results should be very close to the official MATLAB eval code.
--------------------------------------------------------------

Process finished with exit code 0

得到的mAP:0.7153

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容