北京 上海巡回站 | NVIDIA DLI深度学习培训
2018年1月26/1月12日

NVIDIA 深度学习学院 带你快速进入火热的DL领域
阅读全文                                                                                                          
>

正文共4931个字,11张图,预计阅读时间30分钟。

前言

根据我个人的经验,学好AI,有五个必修:数学、数据结构、Python数据分析、ML、DL,必修之外,有五个选修可供选择:NLP、CV、DM、量化、Spark,然后配套七月在线的这些必修和选修课程刷leetcode、kaggle,最后做做相关开源实验。

今天,咱们就来看一看:如何用百行代码实现Kaggle排名Top 5%的图像分类比赛。

1、NCFM图像分类任务简介

为了保护和监控海洋环境及生态平衡,大自然保护协会(The Nature Conservancy)邀请Kaggle[1]社区的参赛者们开发能够出机器学习算法,自动分类和识别远洋捕捞船上的摄像头拍摄到的图片中鱼类的品种,例如不同种类的吞拿鱼和鲨鱼。大自然保护协会一共提供了3777张标注的图片作为训练集,这些图片被分为了8类,其中7类是不同种类的海鱼,剩余1类则是不含有鱼的图片,每张图片只属于8类中的某一类别。

图1给出了数据集中的几张图片样例,可以看到,有些图片中待识别的海鱼所占整张图片的一小部分,这就给识别带来了很大的挑战性。此外,为了衡量算法的有效性,还提供了额外的1000张图片作为测试集,参赛者们需要设计出一种图像识别的算法,尽可能地识别出这1000张测试图片属于8类中的哪一类别。Kaggle平台为每一个竞赛都提供了一个榜单(Leaderboard),识别的准确率越高的竞赛者在榜单上的排名越靠前。

图1. NCFM图像分类比赛

2、问题分析与求解思路
2.1、卷积神经网络

从问题的描述我们可以发现,NCFM竞赛是一个典型的“单标签图像分类”问题,即给定一张图片,系统需要预测出图像属于预先定义类别中的哪一类。在计算机视觉领域,目前解决这类问题的核心技术框架是深度学习(Deep Learning),特别地,针对图像类型的数据,是深度学习中的卷积神经网络(Convolutional Neural Networks, ConvNets)架构(关于卷积神经网络的介绍和算法,这里有个视频教程可以看下:CNN之卷积计算层,本博客也写过:CNN笔记)。

总的来说,卷积神经网络是一种特殊的神经网络结构,即通过卷积操作可以实现对图像特征的自动学习,选取那些有用的视觉特征以最大化图像分类的准确率。

图2. 卷积神经网络架构

图2给出了一个简单的猫狗识别的卷积神经网络结构,在最底下(同时也是最大的)的点块表示的是网络的输入层(Input Layer),通常这一层作用是读入图像作为网络的数据输入。在最上面的点块是网络的输出层(Output Layer),其作用是预测并输出读入图像的类别,在这里由于只需要区分猫和狗,因此输出层只有2个神经计算单元。而位于输入和输出层的,都称之为隐含层(Hidden Layer),图中有3个隐含层,正如前文提到的,图像分类的隐含层都是由卷积操作完成的,因此这样的隐含层也成为卷积层(Convolutional Layer)。

因此,输入层、卷积层、输出层的结构及其对应的参数就构成了一个典型的卷积神经网络。当然,我们在实际中使用的卷积神经网络要比这个示例的结构更加复杂,自2012年的ImageNet比赛起,几乎每一年都会有新的网络结构诞生,已经被大家认可的常见网络有AlexNet[5], VGG-Net[6], GoogLeNet[7], Inception V2-V4[8, 9], ResNet[10]等等。

2.2、一种有效的网络训练技巧—微调

我们没有必要从头开始一个一个的参数去试验来构造一个深度网络,因为已经有很多公开发表的论文已经帮我们做了这些验证,我们只需要站在前人的肩膀上,去选择一个合适的网络结构就好了。且选择已经公认的网络结构另一个重要的原因是,这些网络几乎都提供了在大规模数据集ImageNet[11]上预先训练好的参数权重(Pre-trained Weights)。这一点非常重要!因为我们只有数千张训练样本,而深度网络的参数非常多,这就意味着训练图片的数量要远远小于参数搜索的空间,因此,如果只是随机初始化深度网络然后用这数千张图片进行训练,非常容易产生“过拟合”(Overfitting)的现象。

所谓过拟合,就是深度网络只看过了少量的样本,因而“坐井观天”,导致只能识别这小部分的图片,丧失了“泛化”(Generalization)能力,不能够识别其它没见过、但是也是相似的图片。为了解决这样的问题,我们一般都会使用那些已经在数百万甚至上千万上训练好的网络参数作为初始化参数,可以想象这样一组参数的网络已经“看过”了大量的图片,因此泛化能力大大提高了,提取出来的视觉特征也更加的鲁棒和有效。

接下来我们就可以使用已经标注的三千多张海鱼图片接着进行训练,注意为了防止错过了最优解,此时的训练节奏(其实应该称为“学习速率”)应该比较缓慢,因此这样的训练策略我们称为“微调技术”(Fine-tune)。

当我们使用自己的标注数据微调某个预先训练的网络时候,有一些经验值得借鉴。以总图3为例,假设我们的网络结构是类似AlexNet这样的7层结构,其中前5层是卷积层,后2层是全连接层。

(1)

(1)我们首先微调最后一层Softmax分类器,假设原来的网络是用来分类1000类物体的(例如ImageNet的目标),而现在我们的数据只有10个类别标签,因此我们最后一层输出层(FC8)的神经元个数变为10。我们使用很小的学习率来学习层FC7与FC8之间的权重矩阵而固定这之前所有层的权重;

(2)

(2)一旦网络趋于收敛,我们进一步扩大微调的范围,这时微调两个全连接层,即FC6与FC7,以及FC7与FC8之间的权重,与此同时固定FC6之前的所有卷积层权重不变;

(3)

(3)我们将微调的范围扩大至倒数第一个卷积层C5;

(4)

(4)我们将微调的范围扩大至更多的卷积层。不过事实上,我们会认为位置相对靠前的卷积层提取出来的特征更加的底层和具有通用性,而位置相对靠后的卷积层以及全连接层更加与数据集的相关性大一些,因此有时候我们并不会微调前几个卷积层。

3、算法实现和分析

在NCFM这个比赛的论坛里已经有开源的实现供大家参考(https://www.kaggle.com/c/the-nature-conservancy-fisheries-monitoring/discussion/26202),

在这里分析一下模型训练文件train.py的逻辑结构。

  • ü Import相关的模块以及参数的设置——图4;

  • ü 构建Inception_V3深度卷及网络,使用在ImageNet大规模图片数据集上已经训练好的参数作为初始化,定义回调函数保存训练中在验证集合上最好的模型——图5;

  • ü 使用数据扩增(Data Augmentation)技术加载训练图片,数据扩增技术是控制过拟合现象的一种常见的技巧,其思想很简单,同样是一张图片,如果把它水平翻转一下,或者边角裁剪一下,或者色调再调暗淡或者明亮一些,都不会改变这张图片的类别——图6;

  • ü Inception_V3网络模型训练;

图4. Import和参数设置

图5. 构建Inception_V3网络并加载预训练参数

图6. 使用数据扩增技术加载训练和验证图片集

图7. 模型训练

4、提升排名的若干技巧

一旦我们训练好了模型,我们就用这个模型预测那些测试图片的类别了,论坛中predict.py中的代码就是预测鱼类的并且生成提交文件。这里我们给大家分享一下在机器学习和图像识别类竞赛中常见的两个技巧,简单而有效。它们的思想都是基于平均和投票思想。其背后的原理用一句话总结就是:群众的眼睛是雪亮的!

技巧1:同一个模型,平均多个测试样例

这个技巧指的是,当我们训练好某个模型后,对于某张测试图片,我们可以使用类似数据扩增的技巧生成与改张图片相类似的多张图片,并把这些图片送进我们训练好的网络中去预测,我们取那些投票数最高的类别为最终的结果。Github仓库中的predict_average_augmentation.py实现的就是这个想法,其效果也非常明显。

技巧2:交叉验证训练多个模型

还记得我们之前说到要把三千多张图片分为训练集和验证集吗?这种划分其实有很多种。一种常见的划分是打乱图片的顺序,把所有的图片平均分为K份,那么我们就可以有K种<训练集,验证集>的组合,即每次取1份作为验证集,剩余的K-1份作为训练集。因此,我们总共可以训练K个模型,那么对于每张测试图片,我们就可以把它送入K个模型中去预测,最后选投票数最高的类别作为预测的最终结果。我们把这种方式成为“K折交叉验证”(K-Fold Cross-Validation)。图9表示的就是一种5折交叉验证的数据划分方式。

图9. 五折交叉验证

当然,技巧1和2也可以联合在一起使用。假设我们做了5折交叉验证,并且对于每一张测试图片都用5次数据扩增,那么不难计算,每一张测试图片的投票数目就是25个。采用这种方式,我们的排名可以更进一步。

5、后记

我们回顾了深度学习中的深度卷积网络的典型结构和特点,并且知道了如何使用梯度下降算法来训练一个深度网络。我们展示了如何用微调技术,使用Inception_V3网络来解决Kaggle的NCFM海鱼分类比,并且通过两个简单而有效的小技巧,使得我们的排名能够进入Top 5%。

如果读者对该比赛有兴趣,想进一步提升名次,那么一种值得尝试的方法是:物体检测(Object Detection)技术。试想一下,其实我们只要区分海鱼的品种,由于摄像头远近等关系,图片中海鱼的区域其实只占据一小部分像素点,更多的区域都是船体、桅杆或是海洋等噪音。如果有一种算法能够帮我们把海鱼从照片中“扣”(检测)出来,那么可以想象,深度网络的准确率就能够进一步提升了,这部分的工作就留给有兴趣的同学自己做进一步研究了。

七月在线彭老师、二零一七年五月十日。

参考资料
  1. [1] https://www.kaggle.com/

  2. [2] http://cs231n.github.io/neural-networks-3/

  3. [3] https://github.com/tensorflow/tensorflow

  4. [4] https://github.com/fchollet/keras

  5. [5] Image Classification with Deep Convolutional Neural Networks. NIPS 2012.

  6. [6] Very Deep Convolutional Networks for Large-Scale Image Recognition. ICLR 2015.

  7. [7] Going Deep with Convolutions. CVPR 2015.

  8. [8] Rethinking the Inception Architecture for Computer Vision. CVPR 2016.

  9. [9] Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning. ICLR 2016.

  10. [10] Deep Residual Learning for Image Recognition. CVPR 2016.

  11. [11] http://www.image-net.org/

  12. 七月在线《kaggle案例实战班》

  13. kaggle实战公开课《模型分析与模型融合》

原文链接:http://blog.csdn.net/v_JULY_v/article/details/71598551

查阅更为简洁方便的分类文章以及最新的课程、产品信息,请移步至全新呈现的“LeadAI学院官网”:

www.leadai.org

请关注人工智能LeadAI公众号,查看更多专业文章

大家都在看


LSTM模型在问答系统中的应用

基于TensorFlow的神经网络解决用户流失概览问题

最全常见算法工程师面试题目整理(一)

最全常见算法工程师面试题目整理(二)

TensorFlow从1到2 | 第三章 深度学习革命的开端:卷积神经网络

装饰器 | Python高级编程

今天不如来复习下Python基础

Kaggle—So Easy!百行代码实现排名Top 5%的图像分类比赛相关推荐

  1. python图像分类代码_Kaggle—So Easy!百行代码实现排名Top 5%的图像分类比赛

    Kaggle-So Easy!百行代码实现排名Top 5%的图像分类比赛 作者:七月在线彭老师 说明:本文最初由彭老师授权翟惠良发布在公众号"七月在线实验室"上,现再由July重新 ...

  2. 鱼佬:百行代码入手数据挖掘赛!

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:鱼佬,武汉大学,Datawhale成员 本实践以科大讯飞xData ...

  3. js 监听 安卓事件_百行代码实现js事件监听实现跨页面数据传输

    百行代码实现js事件监听实现跨页面数据传输 使用场景 类似消息队列的使用场景,支持同页面和跨页面通信,发送消息和接收消息 技术原理 跨页面通信: 基于事件监听,通过监听 storage事件监听回调机制 ...

  4. 百行代码打造一个DI容器(支持瞬时生命周期、单利生命周期、构造函数自动注入、属性自动注入、字段自动注入)...

    DI注入在.Net平台是非常流行的, 很多项目都用到了,很多开发人员或多或少也用到DI容器了,感觉DI容器很神奇很厉害.本文将通过百行代码展示DI容器的内部核心代码(包括组件的瞬时生命周期.单利生命周 ...

  5. 猜猜乐游戏php源码,C/C++百行代码实现热门游戏消消乐功能的示例代码

    游戏设计 首先我们需要使用第三方框架,这里我使用的是sfml,不会使用sfml在我的上几篇文章当中-扫雷(上)有详细的开发环境搭建介绍 首先准备图片资源 一张背景图片,一张宝石图片 窗口初始化加载图片 ...

  6. 基于Ganos百行代码实现亿级矢量空间数据在线可视化

    简介: 本文介绍如何使用RDS PG或PolarDB(兼容PG版或Oracle版)的Ganos时空引擎提供的数据库快显技术,仅用百行代码实现亿级海量几何空间数据的在线快速显示和流畅地图交互,且无需关注 ...

  7. Python百日百行代码挑战-day8,day9,day10,游戏实战系列-五子棋

    Python百日百行代码挑战-day8,day9,day10,游戏实战系列-五子棋 写在前面 需要用到的工具包和参考 游戏设定 初始化 切换下棋方 判断五子连珠(核心) 鼠标点击流程事件 成品展示 打 ...

  8. python写百行代码可运行_56 岁潘石屹学俩月 Python ,写下百行代码

    原标题:56 岁潘石屹学俩月 Python ,写下百行代码 By 超神经 内容导读:跨界王潘石屹在近期迷上了编程,不仅高调宣布学习 Python,拜老师,还隔三差五晒出自己的「编程课作业」,和网友进行 ...

  9. php消消乐代码,C/C++百行代码实现热门游戏消消乐功能的示例代码

    游戏设计 首先我们需要使用第三方框架,这里我使用的是sfml,不会使用sfml在我的上几篇文章当中-扫雷(上)有详细的开发环境搭建介绍 首先准备图片资源 一张背景图片,一张宝石图片 窗口初始化加载图片 ...

最新文章

  1. 从 React Router 谈谈路由的那些事
  2. ES6学习笔记(六)数组的扩展
  3. Shopify 英文(多国语言)国际网店 注册指南
  4. 【华为云技术分享】Linux内核的分布式编译(2)
  5. 二叉树+链表+字符串+栈和队列高频面试题合集
  6. java中long的包装类_Java中基本数据的包装类
  7. [转]sqlserver 创建分区表
  8. HTTP协议基本原理简介(三)
  9. BZOJ4542: [Hnoi2016]大数
  10. ThinkPHP商城系统与外部系统用户互通,集成UCenter
  11. IIC协议超详细解释(适合小白入门)
  12. android中期检查表,基于Android的车载视频播控系统的中期检查表.docx
  13. 爱情树代码python_送男朋友礼物送什么比较有意义?
  14. MAC 解压 rar 文件
  15. 2020计算机科学第五轮评估,第五轮学科评估启动,这些非“双一流”建设高校可能获得A+学科...
  16. 安卓电子书格式_[技巧] 无敌的boss级电子书阅读app,全能高手就要一个打十个。...
  17. ☀️光天化日学C语言☀️(07)- ASCII码 | 来,跟我念:阿斯克二马
  18. FaceShifter:新的人脸交换模型
  19. 暑期出境游十大APP推荐
  20. IT售前咨询能力范围

热门文章

  1. java如何脱离ide运行_如何脱离IDE使用自己的jar包?
  2. dbutils java_Dbutils工具类的使用
  3. 如何产生cpk图形_在评估或选型SMT设备的时候,“印刷机、贴片机Cp、Cpk是什么意思...
  4. java消费者生产者设计模式_java 多线程并发设计模式之四: 生产者消费者模式
  5. mysql innodb 报错_mysql报错1286 Unknown storage engine 'InnoDB'
  6. java数字分割的下划线_Java-数值中使用下划线进行分隔
  7. .Net Framework4.5中Asp.net mvc使用Singal R轮训实现导入进度条功能
  8. 20190508——python基础(if...in...循环语句、while循环、两种循环对比)
  9. 类的继承 设计模式
  10. 网络、通信术语及概念