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

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

作者:七月在线彭老师

说明:本文最初由彭老师授权翟惠良发布在公众号“七月在线实验室”上,现再由July重新编辑发布到本blog上。

Github: https://github.com/pengpaiSH/Kaggle_NCFM

前言

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

今天,咱们就来看一看:如何用百行代码实现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 卷积神经网络( ConvNets )

从问题的描述我们可以发现, 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 一种 有效的网络训练 技巧—微调 ( Fine-tune )

我们没有必要 从头 开始一个一个的参数去试验来构造一个深度网络, 因为 已经有很多公开发表的论文已经帮我们做了这些验证, 我们 只需要站在前人的肩膀上, 去选择 一个合适的网络结构就好了。且 选择 已经公认的网络结构另一个重要的原因是, 这些 网络 几乎 都提供了在大规模数据集 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.  网络 Finetune的基本 步骤

3. 算法 实现和分析

在这里分析一下 模型 训练文件 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 )技术。试想一下, 其实 我们只要区分海鱼的品种, 由于 摄像头远近 等 关系 ,图片 中海鱼的区域其实只占据一小部分像素点, 更多 的区域都是船体、 桅杆或是 海洋等噪音。 如果 有一种算法能够帮我们把海鱼从照片中 “ 扣 ” (检测)出来, 那么 可以想象, 深度网络 的准确率就能够进一步提升了, 这部分 的工作就留给有兴趣的同学自己做进一步研究了。

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

参考文献

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

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

[7] Going Deep with Convolutions. CVPR 2015.

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

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值