物体检测作业分享
导语:大家好,我叫胡琦,和大部分小伙伴一样是个AI小白。今天很荣幸能在这里和大家分享我的学习心得和作业实践。我相信大家通过这两周的学习,对AI和一站式AI开发平台ModelArts有了深入的了解,对图像分类、物体检测以及VGG模型、Faster-RCNN模型、YOLO模型等有了一定的认知,甚至可以自己动手实践一个小小的AI应用。当然,我们在学习过程中和作业实践中或多或少会遇到一些困惑和难题,有时候可能我们自身无法解决,那么快速的处理方式就是在交流群或者论坛及时反馈我们的难点,相信通过其他小伙伴的热情解答和社区里众多大佬的悉心辅导,我们遇到的问题都会迎刃而解。当然我不建议一遇到问题就发到群里问题,做过开发的同学一定听说过【提问的艺术】,我建议先自己动手解决,如果10分钟之内都没法解决那就赶紧请求外部协助,这样一定程度上能培养我们独立思考的好习惯。废话不多说,进入我们的正题,先讲讲我是怎么完成作业的(PS:CtrC\CtrV要熟练掌握,哈哈)
前言
有些我认为重要的东西我还是想强调三点:一是学习资料的获取,在群里经常看到有小伙伴说文档里的链接没法点击、教程链接没法打开或者教程中的图片无法显示,其实资料就在那里,永远为我们的索取而等候,可能只是我们打开的方式不对而已;这里建议大家访问ModelArts在gitee上的代码仓库进行学习。二是前置知识的学习,这里前置知识值得是学习视频中介绍部分提到的一些模型、算法、数据集、应用场景的介绍等等;如果仅仅只是把教程中的实践简单地走个过场,估计也只是浮于表面的学习,遇到后面会感觉难度越大从而产生畏难情绪直到放弃,别问我怎么知道,亲身体会!所以,希望每一位小伙伴都能坚持学习,不忘初心!三是学习过后的总结,知识只有沉淀下来了才属于自己,这里的总结不仅仅是自我总结,还有分享,现在社区也变着法子鼓励大家分享内容输出,而且还是真金白银的鼓励,你们心动了吗?(活动详见:【精品帖促进计划】 边学边写、内容输出,豪华大礼等你来拿!https://bbs.huaweicloud.com/forum/thread-59066-1-1.html)
作业一:优化自动学习人车检测模型
作业一是在视频-2.2零代码人车检测模型开发的基础上进行数据集扩充已达到模型调优的目的。零代码开发,相信大家在第一章的学习中已经领略到了ModelArts的魅力,没错,零代码的确能训练出一个精度还可以的模型。一般来说,ModelArts上的零代码开发模型有两种方式:一是自动学习、二是预置算法(或者市场订阅算法)。第一章图像分类中对自动学习和预置算法两种方式进行了对比,我们知道自动学习后台采用类似AoutML的算法,使用者无需关注要选用哪种算法,也不需要进行参数调优,所以要进行调优的话可能只有从数据集入手了。扩充数据集、修改训练集与验证集的比例等有限的手段在一定程度上能增加模型的识别度。接下开始动手实践吧!前提已经开通了相关的服务,这里尝试OBS的操作通过jupyter notebook中使用华为自研的MoXing进行。
借助ModelArts notebook的Terminal拉取学习资料
notebook新建一个Conda-python3文件拉取学习资料
下载学习资料
%%bash wget https://gitee.com/ModelArts/ModelArts-Lab/repository/archive/master.zip?ref=master&sha=612fc8c07c0215a0e64f806ba4c4b55331dd3810&format=zip&captcha_type=captcha&captcha=cffyra
解压并删除学习资料zip包
%%bash unzip master.zip?ref=master rm -rf master.zip?ref=master
执行完,我们发现notebook下多了一个ModelArts-Lab的文件,这个就是官方正版的学习资料,我们进到ModelArts-LabExeMLExeML_Car_And_Person_Detection目录下打开readme.md并将内容全选复制,新建Conda-python3文件切换到MarkDown模式,粘贴刚复制的内容,点击保存可以重命名为readme,关闭当前窗口再打开readme.ipynb就能愉快的学习了!
nodebook下载数据集和扩充数据集并上传到OBS(不一定对,moxing拷贝可能会有问题)
当然我们要建好OBS桶。这里主要是受老师课上讲的本地、notebook、OBS三者之间的数据互传的启发。
下载数据集
%%bash wget https://modelarts-labs.obs.myhuaweicloud.com/ExeML/ExeML_Car_And_Person_Detection/car_and_person_150.tar.gz tar -zxvf car_and_person_150.tar.gz rm -rf car_and_person_150.tar.gz
下载扩充数据集
%%bash wget https://modelarts-labs-bj4.obs.cn-north-4.myhuaweicloud.com/ExeML/ExeML_Car_And_Person_Detection/VOC2012_select_bus.zip unzip VOC2012_select_bus.zip rm -rf VOC2012_select_bus.zip
上传数据集到OBS
import moxing as mox if mox.file.exists('obs://ai-camp/day02/car_and_person')== False: mox.file.make_dirs('obs://ai-camp/day02/car_and_person') print('创建OBS文件夹,注意改为您自己的桶名') mox.file.copy_parallel('car_and_person_150/train', 'obs://ai-camp/day02/car_and_person/train') mox.file.copy_parallel('car_and_person_150/test', 'obs://ai-camp/day02/car_and_person/test') print('数据集拷贝完成') mox.file.copy_parallel('VOC2012_select_bus/train', 'obs://ai-camp/day02/car_and_person/train') mox.file.copy_parallel('VOC2012_select_bus/test', 'obs://ai-camp/day02/car_and_person/test') print('扩充数据集拷贝完成') print('Done!')
创建自动学习物体检测项目并进行标注
这里一个注意点是数据集输入位置为train目录,切记!这个坑我在第一章图像分类的时候就踩过!其他的注意点是数据集输出位置最好单独新建一个文件夹,我这边看到50张未标注的,标注一两张意思意思一下,不过发现标注有时候鼠标不太好使,需要点下左侧的矩形框才能进行标注;而且没看到标注保存按钮(应该是自动保存)。开始训练
可设置训练验证比例、增量训练版本、预期推理硬件等参数,有些可能对训练结果会有影响,建议第一次做的话严格按照教程来。部署或者继续优化
部署要注意只能创建一个免费的CPU或GPU,有明确的提示:在ModelArts中(含自动学习和部署上线),同一免费规格仅能存在一个运行中的在线服务。
另外在预测的时候,有可能遇到只能识别出5个bus或者7个bus,其实不算问题,重新训练一遍也许就行了!这里也遇到过部署一直在部署中的问题,暂未解决,待排查。建议不要放弃,重新训练重新部署,实在不行重新建立数据集一切重头再来,这是最坏的打算了!
作业二:优化FasterRCNN主干网络
在视频中老师讲解到FasterRCNN的工作原理是首先通过卷积层来提取图像的特征,得到特征图。而卷积层可以是vgg16、resnet50或resnet101等网络结构中的其中一种,不同网络结构的卷积层可以在此处进行灵活的替换。我。卷积层其实有个专业的名称,中文名称为主干网络,英文名称为backbone,它的作用是从图片
中提取特征得到特征图。业界常用的图像领域主干网络有AlexNet、VGG、GoogleNet、Xception、
Inception、ResNet、ResNext、DenseNet、MobileNet、SENet等等。在已经训练好的主干网络的基
础上继续训练自己的数据集,这样可以提升模型训练效率,不用完全从零开始训练。这里直接在之前拉取的代码中进行实现。
我们只需打开 /home/ma-user/work/ModelArts-Lab/notebook/DL_image_object_detection_faster.ipynb 这个文件就能愉快的学习了!
先跑一遍教程,看看大概有哪些步骤,然后再理解一下代码。再来修改进行优化。
教程案例中使用的主干网络是vgg16,一个可用的主干网络由两部分构成:网络结构和网络参数,案例中vgg16主干网络结构参数储存在data/imagenet_weights,我们要修改的就是使用另外的主干网络,所以需要下载其他主干网络文件(如res101.pth)并进行替换就行。
我们在数据准备后面加上下载res101这个主干网络的代码。
# modify import moxing as mox mox.file.copy('obs://modelarts-labsbj4/notebook/DL_object_detection_faster/res101.pth', './data/imagenet_weights/res101.pth')
下载完毕之后,会发现data/imagenet_weights目录下除了默认的vgg16.pth(553M大小),还会新增一个res101.pth文件,这个就是我们后面要使用的主干网络。
当然为了降低难度,官方给出了已经修改过的文件,我们通过简单的一行命令就能下载到notobook:
`%%bash wget https://modelarts-labs-bj4.obs.cn-north-4.myhuaweicloud.com/notebook/DL_object_detection_faster/Faster-R-CNN_assiment.ipynb
提示:
1、替换主干网络需要替换三个内容:网络结构定义、网络结构参数文件路径和网络配置文件路径,在
原来的课程案例代码中只需要修改五处代码即可完成替换。现在给你提供了一个已经修改了三处的代码
文件(点此链接进行下载,点击upload上传到notebook中),已修改的内容请在页面中按ctrl+F,输
入“modify”进行页面内查找查看,还有两处内容留给你来修改;
2、你可以按ctrl+F,输入“vgg16”进行查找,依次观察每一处查找结果,判断一下哪些地方需要修改;
3、再给一个重要提示,刚才下载的代码文件中,新增了下面这么两行代码,这两行代码的作用是从
OBS拷贝了一个resnet101的网络参数文件“res101.pth”到了Notebook中.
结合提示(有点像找茬游戏),我们发现:
引用有修改,需将vgg16的引用替换为resnet_v1
# from nets.vgg16 import vgg16 # modifyfrom nets.resnet_v1 import resnetv1
模型训练超参设置的主干网络路径肯定是要修改的:
修改之后,我们还有确认文件存在# 使用的预训练模型位置# weight = "./data/imagenet_weights/vgg16.pth"weight = "./data/imagenet_weights/res101.pth"# cfg模型文件位置# cfg_file = 'experiments/cfgs/vgg16.yml'cfg_file = 'experiments/cfgs/res101.yml'
设置模型训练参数,在创建卷积层的时候也是要修改的:
# 创建backbone网络# 在案例中使用的是VGG16模型,可以尝试其他不同的模型结构,例如Resnet等# net = vgg16() # modifynet = resnetv1(num_layers=101)
后面的print(sw.net)输出resnetv1()验证了我们成功修改了主干网络。
训练前的日志输出:Loading initial model weights from ./data/imagenet_weights/res101.pth Loaded.
再一次验证了我们成功修改了主干网络
训练完毕模型存放在output/res101/voc_2007_trainval/default/res101_faster_rcnn_iter_100.pth
如果需要跑通测试的话,应该还要下载一个res101的预模型,https://drive.google.com/drive/folders/0B7fNdx_jAqhtNE10TDZDbFRuU0E 这是我找到的,然后估计还有修改模型推理代码。这里就留给大家自由发挥了。
作业三:优化YOLOv3算法anchor参数
在YOLOv3课程案例中,我们使用200张coco数据集的图片跑通了训练,这部分图片在coco/coco_data
目录中,标注文件是一个txt,路径是coco/coco_train.txt,如下图所示,该文件中的每一行是一张图片
的所有物体框标注,标注的格式是“图片的路径 xmin,ymin,xmax,ymax,label_id ...”,物体检测算法就是
根据这些标注框的信息来进行学习。
anchor这个词目前没有一个贴切的中文翻译,从作用上理解,anchor就是从训练集的所有标注框中统
计出来的、在训练集中最经常出现的一些标注框的尺寸大小值和宽高比值。比如,有个检测行人的任
务,训练集中出现站立姿态的人非常多,那么常见的宽高比就是0.3:1,这样模型在学习的时候,就直接
告诉它 “你多尝试0.3:1的检测框,放宽松一点的话,你也可以试试0.2:1和0.4:1,就不要瞎尝试其他比
例的形状了”,比如10:1的形状就不要试了,不会有身体宽度是身高10倍的人。这样,引入anchor其实
是把人的一些先验知识加了进来,让模型更有效地学习。
我们在进行这个实践的时候建议重开一个notebook或者把上一个实践删掉.同样的,我们先试着跑一跑,然后留意一下代码,根据已有的注释加深理解。
善于利用print()
函数来帮助理解。在完成课程实践的过程中,我们似乎已经关注到coco数据anchor值文件存储位置,结合作业,要求,我们
是需要借助代码中自带的kmeans.py脚本来重新生成成anchors参数文件。如果您好奇,一定会点开查看kmeans.py文件,虽然可能和我一样
一脸懵逼,不过凭借我多年的“Copy”经验,能看到调用txt2clusters函数生成了“model_data/yolo_anchors_v2.txt”文件.那就添加!python kmeans.py
看看效果吧。
添加yolo_anchors_v2.txt脚本运行代码
!python kmeans.py
修改anchor_path,再依次执行
# coco数据anchor值文件存储位置# anchor_path = "./model_data/yolo_anchors.txt"anchor_path = "./model_data/yolo_anchors_v2.txt"
如果遇到 File exists: './result/models/,注释掉代码:
# os.makedirs(save_path)
至此,作业已经全部完成,开心地去论坛回帖吧!
总结
多动手,多动脑,多问多总结!