一、写在前面

一直都没有写公开心得的习惯,因为一路上都在不断犯错,错误的理解,错误的观点,错误的代码,自己并非科班出身(学了7年的规划学科),常常担心会误导了别人。最近开始找工作,发现保持输出,学会学习表达和交流也是一项重要的能力。我要做一些大胆的事!(这里指发一篇可能会有很多错的心得)!由于学识尚浅,假如各位有缘人能看到这篇文章,对于写的不对的地方请不吝赐教,谢谢!

看到飞桨的课程其实是在一些公众号上(这年头谁没几个贩卖焦虑的公众号)。而被飞桨的课程吸引到则是因为:1、免费课程 2、免费的GPU(Tesla V100) 3、百度的名声 4、百度的结业证书 5、丰厚的奖品。但是核心因素还是因为GPU,自己的老年960实在没办法做正经训练,然而由于AIStudio中只能选择paddlepaddle的框架,所以希望通过课程能够快速上手飞桨。明明很功利地来的,使用之后却被圈粉了。感兴趣的可以直接搜索paddlepaddle的公众号,或者从Aistudio的官网上关注最新的或者往期课程https://aistudio.baidu.com/aistudio/index。

下面进入正题,这门课程主要是对深度学习进行目标检测的pipline进行讲解,相比自己以前上过的其他课程我觉得更加用心也很细致,所有的代码可以直接在AIstudio上运行,也可以下载至本地。同时课程包含notebook以及对应的视频讲解,如果时间比较紧张也可以只看notebook,遇到瓶颈再看视频。但是每个人需求不同,还是要自己体验了才知道好坏。课程的最后提供了一周的时间开展CV练习赛:AI识虫。作为CV领域的经典任务:目标检测,与不久前Kaggle的小麦检测比赛较为相似,并且很好地同课程的内容相契合,课程中覆盖的大部分内容能够在比赛代码中得到体现。所以在此对比赛进行回顾,也是借此对学习内容进行巩固。

二、数据

比赛使用林业病虫数据集,该数据集提供了2183张图片,其中训练集1693张,验证集245,测试集245张,包含7中昆虫,分别是Boerner、Leconte、Linnaeus、acuminatus、armandi、coleoptera和linnaeus。直接在AIStudio的公开数据集中搜索“昆虫数据集”或访问以下链接:https://aistudio.baidu.com/aistudio/datasetdetail/19638 即可获得数据集。
对于训练集和验证集,每张图片还对应一个格式为xml的标注文件,主要内容包含图片尺寸,Ground Truth Box的位置、大小及其对应的昆虫类别。

三、Baseline思路

课程的课节13已给出YOLO-v3的baseline的notebook,且大部分参数都已经根据昆虫数据集进行设置,建议将代码根据功能整理至.py文件中以方便对各个模块进行查找和修改。下面先对baseline的代码思路流程进行总结,并在下一节讨论提升策略。

1 数据读取与数据预处理

读取标注数据

对于每个XML格式的文件,使用xml库进行读入得到dict类型的变量作为一个record,每个record对应一张图片,含有图片路径(非xml中的内容)、目标框、目标昆虫类别及其他图片信息。昆虫类别按照字典{ ‘Boerner’: 0, ‘Leconte’: 1, ‘Linnaeus’: 2, ‘acuminatus’: 3, ‘armandi’: 4, ‘coleoptera’: 5, ‘linnaeus’: 6 }形成对应关系。可以发现即使不读取图片,已经能够获取大部分的数据信息。对数据集中各个昆虫的数量进行统计,得到昆虫占比分布图。可以看出在所提供的数据集中,linnaeus这一类昆虫仅仅存在于训练集,而不存在于验证集中,则会影响验证结果的可信度。有必要对训练集与验证集进行重新划分。

数据生成器

a 读取图像

根据record中的图像路径读取得到图像数据,注意由OpenCV读入的图像通常需要从BGR进一步转化为RGB。

b 图像增广

为了扩大训练数据集,增强模型的泛化能力,baseline中已经提供了较为丰富的数据增广手段:

  • 随机改变亮暗、对比度和颜色等 (采用PIL库,100%概率进行变换,三种变换的顺序随机)
  • 随机填充,即在图像周围按指定值随机填充 (50%概率进行变换,注意变换后需要调整Ground Truth框)
  • 随机裁剪 (100%进行变换,如果裁剪对Ground Truth框的影响超过一定阈值,则重新进行裁剪)
  • 随机缩放 (100%进行变换,按照指定大小和规则对图像进行缩放,训练集与验证集中缩放目标大小为320~640中步长为32的随机值,而对于测试集则固定为608 * 608)
  • 随机翻转 (50%概率进行变换,与旋转不同,仅仅是水平翻转)
  • 随机打乱真实框排列顺序 (对于YOLOv3的影响不大)

c 数据变换

将像素值归一化(除以255),再标准化(减去均值再除以方差),使得像素值均值为0,对于使用梯度下降进行训练的模型有利于模型进行收敛。
将维度从[H,W,C]调整为[C,H,W],飞桨训练模型数据的标准维度为[N,C,H,W],其中N为Batch size, C为通道数(对于RGB图像即为3),H与W为图像尺寸。

构建数据生成器

利用yeild构建数据生成器。
训练及验证数据生成器两者一致,但与测试数据生成器有所不同。主要区别为,训练数据生成器为多线程(以避免数据预处理成为训练瓶颈)、含标签、需要进行数据增广,而测试数据生成器为单线程、不含标签、不需要进行数据增广。需要注意的是,测试数据需要进行与训练数据相同的数据变换(这里指归一化,标准化与维度变化,且变换所采用的均值及方差也要一致)。

2 目标检测的整体思路

这一节简要介绍YOLO-v3的基本思想。整体上可以看作:(1)在图片范围内生成大量候选框,根据真实框对候选框是否包含物体进行标注,对于标注为包含物体的候选框,进一步标注预测位置及类别。(2)由卷积神经网络提取得到特征图,利用特征图对候选区域位置及类别进行预测,根据预测值与标签值建立损失函数。下面进一步说明。

a 候选区域生成及标注

首先需要锚框anchor,锚框的生成步骤为:将图像分成长宽为 32 * 32 的小方格,以小方格为中心生成尺寸不同的n个锚框(baseline中n=9)。锚框的大小为超参数。
将全部候选框与真实框进行对比,选取对应的IOU最大的标注为1,表示目标存在于该候选框中,对于其他候选框,如果IOU本身也很大(大于一个给定的阈值),但不是最大的那个,则标注为-1,不参与损失函数计算(这一步在计算得到预测框后进行)。因为这一类候选框很大程度上也与真实框较为相近,只是不是最好的那个,避免将其标注为负样本而影响模型的训练。
最终的候选区域为预测框,标注的预测框由anchor进行中心调整与长宽调整得到,预测框的中心始终存在于与anchor相同的小方格内。

b 特征提取并计算预测框的位置和类别

YOLOv3的backbone为Darknet53,出于应用的目的,这里将不多介绍网络的架构,具体代码请查看课程的notebook。
得到特征图后,将由特征图计算预测框的位置和类别(注意这里是预测的结果,而a步骤中是标注的结果),同样预测需要包含三个方面:(1)包含昆虫的概率(2)昆虫区域的位置和形状(3)昆虫属于每一个类别的概率。
以C0层次为例,经过卷积核池化,层次的特征图的步幅为32,特征图大小与一开始生成锚框用的小方块的数目一致,因此只要使得特征图的channels数与我们所需要预测对象的数量一致即可,这一点可以通过对特征图进行多次卷积实现,即将特征图与预测值建立联系。

c 损失函数

损失函数同样存在三个方面:(1)是否包含物体的损失函数值(用sigmoid_cross_entropy_with_logits计算)(2)物体位置的损失函数(这里将四个位置变量的损失求和,其中xy由sigmoid_cross_entropy_with_logits计算,hw由abs计算)(3)物体类别的损失函数(用sigmoid_cross_entropy_with_logits计算)

d 多尺度

Darknet53可以得到C0、C1、C2三个尺度的特征图,不同尺度的特征图在捕捉不同尺度目标的能力上存在差异,因此采用多尺度检测以适应不同大小的昆虫。每个尺度的特征图分别对应每个小方框区域生成的3个anchor和预测框。总的损失函数等于三个层级的损失函数相加。完成损失函数后,就可以开启端到端的训练了。

3 预测及结果筛选-非极大值抑制

在得到预测结果之后,不难想象会有多个预测框对应同一个真实框,那么仅需要保留得分最高的预测框,而将其他冗余框丢弃。判断两个预测框对应同一个物体的规则为:假如两个预测框类别一致,且重合度大于一定阈值,则可认为其预测的是同一个物体。对于预测同一个物体的预测框,保留该类别得分最高的预测框,假如剩下的预测框与其IoU大于阈值,则说明重合度过高,需要丢弃。

四、优化策略

竞赛说明中已给出部分调优策略:
1.使用其他模型如faster rcnn等
2.使用其他数据增广方法如旋转和裁剪
3.修改anchor参数的设置
4.调整优化器、学习率策略、正则化系数等

结合飞桨在paddleDetection中的YOLOv3增强模型的提升策略(https://paddledetection.readthedocs.io/featured_model/YOLOv3_ENHANCEMENT.html):
1.将YOLOv3骨架网络更换为ResNet50-vd
2.引入Deformable Convolution v2 (可变形卷积)替换原始卷积操作
3.在FPN部分中增加DropBlock模块,提升模型泛化能力
4.增加IoU Loss分支,提高BBox定位精度,缩小一阶段和两阶段检测网络的差距
5.增加IoU Aware分支,预测输出BBox和真实BBox的IoU,修正用于NMS的评分
6.使用Object365数据集得到预训练模型(提供了相应的预训练模型的下载链接)

考虑到本身竞赛时间不长,且平日里学业压力也比较大。实际操作中我仅仅采用了以下容易实现的模型提升策略。

  1. 数据增广
  • 增加mixup数据增广,即将图片与另一张随机图片进行叠加,考虑是检测问题,将混合比例取为1:1
  • 对图像进行随机旋转,同样要注意不能对GroundTruth框有太大影响
  1. 修改anchor参数的设置
  • Baseline中提供的anchor参数依据coco数据集进行设置,考虑昆虫数据集中ground truth相对图像本身而言尺寸较小,有必要对train和valid数据集中的真实框的长宽进行重新聚类,这里采用kmeans聚类方法,代码参考自https://blog.csdn.net/hrsstudy/article/details/71173305?utm_source=itdadao&utm_medium=referral。
  1. 替换骨架网络为ResNet50,代码参考自paddle源码(https://github.com/PaddlePaddle/PaddleDetection/blob/release/0.2/ppdet/modeling/backbones/resnet.py)。
  2. 学习率策略采用cosine_decay,即学习率随step数变化呈余弦函数,使得模型在训练后期能有机会跳出局部最优点。

模型训练最大epoch设置为200(在此设置较大的epoch也是因为没有时间尝试更多的提升策略,希望通过长时间炼丹来产生奇迹),训练过程中保存最优模型参数及优化器参数至文件中。训练过程显示模型精度不断波动,但是整体存在上升趋势,在中后期才提升到90左右的水平 (以后有经验应该写个log记录训练过程)。

PaddlePaddle21天深度学习训练营学习心得相关推荐

  1. 强化学习训练营-学习笔记

    强化学习是什么? 简单来说 强化学习是一类通过不断与环境交互来学习如何达到设定目标的一类算法,比如走迷宫,传统的运筹学算法往往是通过遍历所有的点来完成路径规划,而强化学习则是实现一个anget,让这个 ...

  2. 两日公开课:伯克利深度强化学习训练营 | 视频+PPT

    千平 发自 凹非寺 量子位 出品 | 公众号 QbitAI 又有新公开课放出~ 加州大学伯克利分校的Pieter Abbeel教授,最近联合他的两位博士生Yan (Rocky) Duan.Xi (Pe ...

  3. 深度学习训练营之灵笼人物识别

    深度学习训练营之灵笼人物识别 原文链接 环境介绍 前置工作 设置GPU 导入数据 数据查看 数据预处理 加载数据 可视化数据 检查数据 配置数据集 `prefetch()`功能详细介绍: 归一化 查看 ...

  4. 深度学习训练营之海贼王人物识别

    深度学习训练营之海贼王人物识别 原文链接 环境介绍 前置工作 设置GPU 导入数据 数据查看 数据预处理 加载数据 可视化数据 检查数据 配置数据集 `prefetch()`功能详细介绍: 归一化 查 ...

  5. 深度学习训练营之识别宝可梦人物和角色

    深度学习训练营之识别宝可梦人物和角色 原文链接 环境介绍 前置工作 设置GPU 数据加载 数据查看 数据预处理 加载数据 可视化数据 检查数据 配置数据集 `prefetch()`功能详细介绍: 调用 ...

  6. 深度学习训练营第6周好莱坞明星人脸识别

    365天深度学习训练营-第6周:好莱坞明星识别

  7. 深度学习训练营之优化器对比

    深度学习训练营之优化器对比 原文链接 环境介绍 前置工作 设置GPU 数据处理 导入数据 数据集处理 数据集可视化 模型构造 模型训练 结果可视化 原文链接

  8. 深度学习-学习路线-个人心得体会

    深度学习的学习路线和体会心得 时间轴 个人的学习路线和时间轴,包含基础知识.部分实践,不包含具体的科研项目 一点心得 我是非计算机出身的,研究生研究方向深度学习,可以说是零基础. 零基础一定一定要打好 ...

  9. 人工神经网络与深度学习学习历程,心得及资料分享

    人工神经网络(Artificial Neural Network,即ANN ),是20世纪80 年代以来人工智能领域兴起的研究热点.它从信息处理角度对人脑神经元网络进行抽象, 建立某种简单模型,按不同 ...

最新文章

  1. 盛夏海边,用Python分析青岛哪些景点性价比高
  2. gulp 与 Webpack 的 异曲同工之处
  3. windows或Ubuntu中请求github.com请求超时,或在下载GitHub文件出现:<urlopen error [Errno 110] Connection timed out>
  4. 【Python】青少年蓝桥杯_每日一题_7.03_输出符合要求的字母
  5. 全球及中国家用非金属材质水槽行业产销模式及投资规模预测报告2022-2027年
  6. 【收藏】Kubernetes(十七) 基于NFS的动态存储申请
  7. 禁止snmpd往syslog中写入无用信息
  8. linux目录规范及简单说明
  9. 【转】WPF PRISM开发入门一( 初始化PRISM WPF程序)
  10. iOS获取iPhone系统等信息和服务器返回空的异常处理
  11. VMware vCenter Server安装与配置
  12. iOS之iCloud云存档实现笔记
  13. 重发布直连路由到 OSPF
  14. 51单片机学习笔记——DA转换
  15. 【Unity3D】资源文件 ③ ( Unity 资源包简介 | 导出 Unity 资源包 | 导出资源包的包含依赖选项 | 导入 Unity 资源包 | Unity 资源商店 )
  16. 665. Non-decreasing Array
  17. 回望2019,不仅是“自由自在“,更是 AI 领域不平凡的一年
  18. 阿里王坚:用“机器智能”取代“人工智能”概念
  19. 小综述 | 深度学习在数学文本相关领域的研究梳理
  20. 2021-2027全球与中国双面身份证打印机市场现状及未来发展趋势

热门文章

  1. 傅立叶变换(Fourier Transform)分析理解
  2. 全志uboot修改_全志固件修改工具全系列
  3. 从威客到互联网进化论的五年历程
  4. 2012智能手机发展格局解析
  5. 22,Horizontal Pod Autoscaler(HPA),自动扩缩容
  6. 计算机的人文素养知识,人文素养知识要点
  7. spring源码分析06-spring配置类解析
  8. 1分钟链圈 | 马化腾:大湾区可挖掘更多的区块链应用场景,比如区块链电子发票...
  9. 七牛云对象存储绑定个人域名
  10. SRS与SOW与PM