这一篇博客主要讨论在用卷积神经网络进行图像识别或者目标检测时的数据增强手段,并讨论其作用。
首先整理两篇比较有代表性的论文里的数据增强,再说说我自己工作中使用的数据增强,最后讨论这些数据增强的意义(我个人的理解)。

个人觉得,如果你的网络设置的没什么问题,代码也没写错,但是跑出来的效果不尽如人意,比如你希望有80%的准确率,但实际只有70%,那你就应该试一试数据增强,这绝对比你调模型的参数或者结构要有效得多。

而且在实际中,打标数据是很珍贵的,数量可能根本没有达到能够让你训练出一个满足要求的神经网络。这时候数据增强就会显得特别重要。


首先介绍的是2012年令深度学习大放异彩的alexnet中的数据增强,alexnet在2012年的imagenet大赛中获得了冠军,首次把深度学习使用到了图片分类领域,并取得极大成功。
alexnet的输入是一张224x224x3的图片,imagenet的原始图片大小是256x256x3的,作者做了如下数据增强:

  • 训练:原来的图片是256x256,现在依次裁剪出224x224的图片,这样横向有256-224次移动,竖着也有这么多,再加上左右的翻转镜像,相当于把数据集扩大了(256-224)x(256-224)x2=2048倍。
  • 预测:选择一张图片的四个角的224x224加上中间的224x224(加上左右镜像的)一共10张图片的平均值做结果。

这样的数据增强主要是对图片做了裁剪,造成的效果是本来可能是一个完整的人在图片中,现在就剩半个人了,但这样却让模型知道了,这样的半个人他也是人,增强了模型的能力,所谓见多识广。


再来看看vgg中的数据增强,背景和alexnet是一样的,也是imagenet比赛,但比alexnet稍微复杂点:

  • 训练:同样是图片扩大再截取的做法,作者提出了两种方案,一种是把所有图片扩大到统一的尺寸,然后用224x224x3去截取,一种是让每张图片随机在一个范围内扩大,然后再用224x224x3去截取。
    最终作者用了一轮预训练加正式训练,
    预训练时把图片同一扩大到384x384x3,并且学习率都设置为0.001,训练过程保持不变。
    正式训练时以预训练的结果为初始值,把图片在(256~512)之间随机扩大,截取后再训练。
  • 预测:记训练时图片的尺寸为S(比如上面的预训练时,S=384),预测时的尺寸为Q。在预测时把图片固定到Q尺寸,Q和S不一定要相等,然后先在Q尺寸上做卷积,到全连接层时做划窗,得到很多结果做平均,再将不同Q的结果做平均。
    对每个S使用多个Q对提升准确率是有用的。

对于使用固定的S训练的模型,测试时使用的Q不能和S相差太多,作者使用了三个Q的值,分别是S-32,S,S+32。
对于使用随机S训练的模型,测试时的Q相对来说可以比固定S时有更多的选择,作者选择的三个Q值分别为S的最小值,S,和S的最大值。


纵观上面两种数据增强的方式,基本都是对图片进行各种各样的裁剪,使得网络在训练时能够见到更多的“不一样的图片”,这样为什么可以增强模型的性能?
假设这样一个场景,测试图片是一只猫躲在窗帘后,只露出了一只尾巴,如果我们的训练集中都是完整的猫图片,那么模型对这个只露出尾巴的图片将毫无办法。再假设我们在数据增强时的各种裁剪,刚好裁到了一只猫的尾巴。
当然,这只是感性的理解。


下面再说说我自己工作中做过的数据增强。
首先说一个这样的需求,请看下面几张图片,有几张是中文字,还有几张是数字,当时需要训练一个神经网络来区分一张图片中是文字还是数字,是个二分类问题。




对于大多数玩神经网络的来说,这个问题太简单了,但有两点问题:

  1. 每张图片的大小不一样,有的长有的短,有的高有的矮
  2. 我们仅有的打标数据都是我们自己手动打的,正样本和负样本加起来才83张

对第一个问题,我采用了一个比较笨的方法(当时接触神经网络时间还不长,没有过多其他的想法):

  1. 首先看了下所有图片的最高高度,然后在这个值的基础上再上下增大一些像素,增大的像素是从每张图片的最上面(或最下面)的五行像素里随机选择的一行,保持文字在图片中间,最终定的高度是70
  2. 统一了高度后,对宽度也做了统一,也统一到70,以70的宽度在原始图片上滑框,35个像素点划一次,这样一个宽度为200的图片,就可以划出6张70x70的图片
  3. 基于70x70的图片大小训练了一个二分类的网络,在测试时对原始图片做同样的操作,比如裁剪出5张70x70的图片,那么如果有3张都预测为文字,那么就认为这张图片是文字。

裁剪后的图片差不多是下面这样:

这样训练集从83张变成几千张了,于是我训练了一个简单的三层卷积加两层全连接的卷积神经网络,但在测试集上的准确率只有88%左右,由于这一个判断是否是数字的模型只是一个工程中的一步,所以如果这一步的准确率只有88%的话,那这个工程最终的准确率只会更低。
对这样的情况,我决定采取数据增强,仔细思考这个问题,现实中这种打印的字体可能会出现深浅不一,缺墨,或者有一块都是墨,拖墨,扫描时摆的不正等,总之真实的打印机打印出来的字会出现各种情况。
所以我对数据做了下面几种处理:

  1. 手工设计了一道公式,使得每张图片从左到右,从右到左,从上到下,从下到上呈现出墨色逐渐变淡的效果
  2. 把本来位于中间的字上移或下移
  3. 对图片进行裁剪,保留一行文字的一部分
  4. 对图片进行随机的旋转
  5. 对图片中的文字部分随机添加背景色的空白条,模拟打印时出现一行一行的缺墨情况
  6. 对上面几种处理方式做随机组合

经过上面这几种处理后的图片大概是下面这个样子的:

上面这些图片的辨认难度相比于没有处理的图片有了很大的提高,经过这样的组合处理后,我的数据集扩大到了几十万,这样训练出来的模型准确率上升到了96%,提升效果很明显。


再说一个我在做目标检测时做的数据增强。
还是上面的文字识别例子,上面的长条形数据是从一张完整的发票上扣下来的,这里使用的就是目标检测的技术,从一张发票中识别出有文字的区域,再扣出这部分区域。
我们遇到了同样的问题,只有40张打标数据,每张发票的大小是2000x3000,我们使用的SSD模型接受的输入是300x300,如果就按照300x300去从这2000x3000张上面去扣也就只有40x6x10=2400张图片。
不过显然可以有重叠的用300x300的去划,这样就会瞬间多出很多图片,虽然图片中的字可能是一样的,但位置还是有细微的变动的。
接着我们又把裁剪下来的300x300的图片随机缩放后再用300x300的去截取,这样图片中的字体大小变化了,位置也变化了,也可以算新的样本。
同时还使用的500x500,300x500,500x300等等不同尺寸的框去2000x3000的大图上框,框完了再resize到300x300。
经过这些步骤,我们的数据集扩大了很多,最终训练出来的模型效果已经可以接受,比如下面这样的(敏感信息做了覆盖):




以上两个例子都是我在实际工作中遇到的数据不足时的处理方案。
方法都比较简单粗暴,但都取得了不错的效果(相比调整模型结构,参数效果要好得多)。
个人觉得,在以往传统算法建模时我们要花费很大的时间去设计特征,做很多特征,而在深度学习阶段我们需要花很大的时间去做数据增强这么一件事:

  • 深度学习参数多,模型复杂,本来就需要大量的数据才能达到比较好的效果,而现实中有标注的数据往往是很珍贵的,所以要利用好当前数据很有必要做数据增强
  • 神经网络模型的拟合能力很强,即使是看着像噪音的数据喂给它,往往也能提升模型的性能,鲁棒性强
  • 是噪音还是提升性能的数据?在使用传统机器学习算法时我们要小心的处理异常值,如果要预测的目标中异常值太多会对模型的性能造成很大的影响。而在深度学习中,像我们上面那样做数据增强,其实是给数据带来了不小的噪音的,但模型的能力却变强了,我个人的理解现实世界就是有各种噪音的,传统算法去除噪音再建模本身就是一个理想化的做法,和真实世界并不相符,但必须这么做,因为那些算法就是建立在“符合高斯分布”这样的假设下的,而深度学习可以更好的对噪音进行处理,关注噪音数据中的关键部分,这样模型的能力相比没见过噪音的就上升了。

以上就是我对数据增强的看法,也许有部分是不对的,但应该还算有参考意义吧。

数据增强在卷积神经网络中的应用相关推荐

  1. 深入学习卷积神经网络中卷积层和池化层的意义(转)

    为什么要使用卷积呢? 在传统的神经网络中,比如多层感知机(MLP),其输入通常是一个特征向量:需要人工设计特征,然后将这些特征计算的值组成特征向量,在过去几十年的经验来看,人工找到的特征并不是怎么好用 ...

  2. 填充和步幅在卷积神经网络中的应用

    填充和步幅在卷积神经网络中的应用 引言 填充 理论推导 计算步骤 例子 步幅 理论推导 计算步骤 例子 结构图 结论 参考文献 引言 在卷积神经网络中,填充和步幅是两个重要的概念.填充是指在输入数据周 ...

  3. 深入学习卷积神经网络中卷积层和池化层的意义

    为什么要使用卷积呢? 在传统的神经网络中,比如多层感知机(MLP),其输入通常是一个特征向量:需要人工设计特征,然后将这些特征计算的值组成特征向量,在过去几十年的经验来看,人工找到的特征并不是怎么好用 ...

  4. xml文件 卷积神经网络_理解卷积神经网络中的输入与输出形状(Keras实现)

    即使我们从理论上理解了卷积神经网络,在实际进行将数据拟合到网络时,很多人仍然对其网络的输入和输出形状(shape)感到困惑.本文章将帮助你理解卷积神经网络的输入和输出形状. 让我们看看一个例子.CNN ...

  5. 【TensorFlow】TensorFlow从浅入深系列之十一 -- 教你深入理解卷积神经网络中的卷积层

    本文是<TensorFlow从浅入深>系列之第11篇 TensorFlow从浅入深系列之一 -- 教你如何设置学习率(指数衰减法) TensorFlow从浅入深系列之二 -- 教你通过思维 ...

  6. 卷积神经网络中的池化是什么意思

    卷积神经网络中的池化是什么意思 pooling 理论在于,图像中相邻位置的像素是相关的.对一幅图像每隔一行采样,得到的结果依然能看. 经过一层卷积以后,输入的图像尺寸变化不大,只是缩小了卷积核-1.根 ...

  7. 卷积神经网络中feature map的含义

    卷积神经网络中feature map的含义 在每个卷积层,数据都是以三维形式存在的.你可以把它看成许多个二维图片叠在一起,其中每一个称为一个feature map.在输入层,如果是灰度图片,那就只有一 ...

  8. 卷积神经网络中feature map是什么

    个人理解卷积神经网络中feature map的含义 在每个卷积层,数据都是以三维形式存在的.你可以把它看成许多个二维图片叠在一起,其中每一个称为一个feature map.在输入层,如果是灰度图片,那 ...

  9. 卷积层和全连接层的区别_卷积神经网络中全连接层作用理解总结

    前言 一般来说,卷积神经网络会有三种类型的隐藏层--卷积层.池化层.全连接层.卷积层和池化层比较好理解,主要很多教程也会解释. •  卷积层(Convolutional layer)主要是用一个采样器 ...

最新文章

  1. boost::random模块使用多精度类型测试所有与浮点相关的生成器和分布的测试程序
  2. MySql的连接查询
  3. 单片机魔法编程百度云_[2020][欧美][喜剧][魔法教母]高清资源百度云,高清1080P资源在线!...
  4. 从1天到10分钟的超越,华为云DRS在背后做了这些
  5. zynq开发系列6:创建AXI IP实现PS对PL的数据配置(步骤一)
  6. 从零实现深度学习框架——常见运算的计算图
  7. PHP $_SERVER['PHP_SELF']、$_SERVER['SCRIPT_NAME'] 与 $_SERVER['REQUEST_URI'] 之间的区别
  8. php fprintf,PHP fprintf() 函数 - PHP 教程 - 菜鸟学堂-脚本之家
  9. PMP-PMBOK(第六版)--49个过程ITTO记忆口诀(第一辑)
  10. K8S你知道,K9S你可能也知道,那Lens呢?
  11. win7自带照片查看器
  12. DNS域名解析中A、AAAA、CNAME、MX、NS、TXT、SRV、SOA、PTR各项记录的作用
  13. 你们想要知道的跳一跳都在这了,23333333
  14. Linux系统安装--LInix系统随笔(二)
  15. 信阳毛尖大山茶、高山茶、小山茶的辨别
  16. 历史最全、最细、近一年最新 知识图谱相关经典论文分享
  17. qt中各种类型转成uchar
  18. c语言人民币小写转换成大写,C语言实现人民币小写转大写
  19. 手机文件管理android可以删除吗,手机上什么文件可以删除?答案都在这里了
  20. Java代码给csv文件加水印_闪电PDF虚拟打印机如何给文件加上水印?

热门文章

  1. 游戏合集 (4) 极品飞车21:热度 无双大蛇3 帝国时代2:决定版 死或生6 城市:天际线
  2. oracle新建数据库schema-建立数据库、表空间和用户
  3. 一个分析飞信的牛人网站
  4. 2017年你错过了哪些AI圈大事?最全盘点,值得收藏!
  5. 【8086汇编】条件转移指令应用 jxxx
  6. html地址栏转换乱码,如何解决jquery url中文乱码的问题
  7. opencv——waitkey()函数
  8. pyqt5+eric6--PyQt开发最佳实践
  9. 职场面试技巧有哪些?
  10. BFS 搜索 Problem 1012 Rescue 拯救天使