绪论:从第一次图像分类比赛开始~

来源:互联网 发布:排课表的软件 编辑:程序博客网 时间:2024/06/06 02:46

  本博客主要讲述关于图像分类的相关内容,从入门到最后(因为我也在学习,也不知道能学成什么样子,所以也不好说精通),希望有兴趣的各位同学积极留言~

  就在近期本人参加了“2017 中国大数据人工智能创新创业大赛 ”的“病理切片识别 AI 挑战赛”。该比赛的题目是根据所给出的训练集进行图像的分类及分割。数据集是一组胃癌数字病理样本,为常规 HE 染色,放大倍数 20×,图片大小为 2048×2048像素,比赛数据为整体切片的部分区域,数据格式为 tiff 格式。所有数据均按照国际通行医疗信息脱敏标准进行脱敏处理,切实保障数据安全。数据集包含560个正样本(cancer)与140个反样本(non_cancer),对于正样本还单独给出了其中癌细胞位置的标注(svg)图片,由于后期癌症部位的分割。

  初赛是进行图像分类,复赛是进行图像分割(或者说是癌细胞的识别)。然而,就像大家想象的,我并没有进入复赛,排名三位数,具体就不说了,挺丢人的。但是实话说知耻而后勇,有了这次的失败,激发了我对于深度学习更深层次的思考。深度学习,尤其在其应用的方面,所涉及的内容要比目前所看到的教程、课程等要深和广。如果仅仅将深度学习定义为下载一个模型,之后在调调参数的话,很难有长足的进步。所以在哪跌倒的在哪爬起来,我就开设了这样的一个专栏,让自己从不完美逐步走向完美。

一、对于题目的初步理解

  在最开始看这道题的时候,我的心里很开心,暗自觉得这道题实际上很适合我们小白来进行练手,说不定还会取得很好的成绩。在我最初的理解,这道题的就是一个十分简单的图像分类,在网上随便down一个卷积神经网络,在用它进行去掉顶层的深度学习就可以完美实现了。

  但是随着比赛的进行,我发现这是一个十分看似平常却内涵丰富(ManShiDaKeng)的题目。首先在于训练集中图像的数量,560张正样本与140张反样本,正反比例为4:1,这是一个很明显的不均衡数据,因此一定要考虑如何针对不平衡数据设计自己的图像分类器;其次这里的图像是组织切片图像,其中题干也有写“数据集是一组胃癌数字病理样本,为常规 HE 染色,放大倍数 20×”,注意,是经过染色的细胞的切片,所以不同部位的染色的深浅可能是不同的,或者说染色本身会对图像带来一些畸变或者说是噪声,如何克服这一点也是十分重要的;最后是正样本是否真的是正样本,将组织切片的标记覆盖在正样本上可以看到,在正样本上并不是所有的区域都是癌变的细胞,有的细胞是出于正常状态的细胞,所以这就相当于在正样本的一个单个样本之中又混杂着负样本,我们可以启发式的联想一下,CNN从这样的网络中很难将正负两种数据彻底分开。

  对于数据其实是正负样本混合的这件事情我也是读了官方提供的参考论文《A Deep Convolutional Neural Network for segmenting and classifying epithelial and stromal regions in histopathological images》。说实话我对于改论文中的分类和分割的方法还是有一点不确定。但是可以确定的是,作者没有用整张的图像进行分类或者分割训练,而是通过将图像进行分块(滑动窗口截取和超像素两种)的方式进行的。所以这就启示我们不要用 整体的图像训练图像分类器,而应该用分块的方式进行训练。然而……当我发现这一点的时候,比赛还剩不到12小时结束,结果……嗯,就是这样。

2. 我的方法

  在这里简单记录一下我的分类方法,一来将这段时间自己的想法进行记录,二来也希望大家多多指出自己方法的不足。

  首先是解决数据不均衡问题。通过查找一些资料(百度一下,你就知道),你会发现有很多处理不平衡数据的方法。我觉得其中的一种方法比较有趣,他首先将训练集图像进行聚类,比如说在这里将正样本聚类为4类,之后将负样本分别对其中的每一类构建一个分类器,一共构建四个分类器,之后再利用这四个分类器进行分类并投票,得到最终的分类结果。但是这样有两个问题,首先这个问题就比较尴尬了,在目前的 Ubuntu 环境中博主还没有使用过聚类算法,而且如何通过聚类算法的结果对图像进行划分也是一个问题。所以我就偷了一个懒,使用随机抽样的方法构建这四个分类器,就是首先通过不重复的随机抽样,将正样本分为四个部分,在从正样本总体中抽取1/4的样本作为第五个正样本。将抽取出的五个正样本与与那一个负样本进行训练,构成五个训练器,在进行投票,这样就可以解决4个分类器,很有可能2:2投票的尴尬境地了。

  通过上部分的内容,我们相当于获得了五组正负样本数量相同的数据集,在这里取其中的一组作为例子进行介绍。由于实战能力不是很强,所以采用迁移学习的方法作为自己的主要训练方法。

  现在看来,数据集中的正负样本数量都太少了,虽然神经网络不必非要在海量数据上才能获得好的效果,但是数据量太少的话很容易造成数据的过拟合,所以首先需要做的是数据扩充,这里主要采用了三种数据扩充方式。首先将图像随机剪切,剪切的宽度控制为 [50, 100] 之间均匀分布的随机数,这样将剪裁后的图像与原始图像放在同一个文件夹下,我们就有了原来2倍数量的数据了;其次是通过一些几何变化方法,如水平翻转、垂直翻转、剪切变换、绕中心点旋转一定角度等,并将这些经过几何变化的图像 resize 到统一大小进行训练;最后在输入图像上加入均值为 1 方差为 0.3 高斯随机噪声。

  之后就是迁移学习的不分了。在网上下载已经 train 好的VGG16 模型,去除原有的全连接层,将这时的输出取出作为通过VGG16网络提取出来的特征;并将它们作为输入加入自己的32个 Relu 神经元的隐层,与一个 sigmoid 神经元的输出层,开始 5 折交叉训练。在训练的过程中采用 Adam 的的优化算法,模型的评价指标主要有训练集和验证集loss 、acc 和 F1 值。这里的F1值需要注意一下,博主使用的是Keras2.04,但是在这个版本中已经移除了Recall, Precision & F1_score这三个指标,因此只好根据之前的版本,将这些函数定义在所搭建的模型的下面,在训练的过程调用,就像 Keras 文档”性能评估“中关于如何自定义评价函数所讲述的一样。但是发现通过这样的方法所计算出的F1值与实际的值不相等,很是头疼,着希望有知道的小伙伴指点一下应该如何修改。所以最后我是用的验证集正确率作为 EarlyStopping 、Model Checkpoint & ReduceLROnPateau的依据。在训练的过程中训练五次,选取这五次中验证集正确率最高的模型作为最终的分类模型。

  输出分类结果,提交。

3. 本模型的可改进之处

  首先肯定是对于数据不均衡情况的处理方法啦。这里采用的随机分类的方法实际上是一种很不负责任的方法,因为这与原本的聚类方法的初衷很不吻合。聚类方法是假设同样是癌细胞,也可以分为不同的癌细胞;而随机抽取的方法明显是达不到这样的一种要求的。

  其次,在的对数据进行扩充的过程中,加入了高斯噪声,说实话,我也不是很清楚是否应该加入这部分高斯噪声,只是看了paper 说加了噪声相当于扩充了数据,所以就加了。有懂这部分的大佬可以对我指点一下。

  然后是模型本身,训练 VGG 使用的是 ImageNet,明显跟医学切片的图像半毛钱关系都没有,但是在介绍迁移学习的资料中都说其可以应用在其他图像上(就是与原先的训练集不同的类的图像),所以就用了,究竟用这个模型能达到一种什么样的效果我也不清楚。有懂这部分的大神可以指点一下。

  最后当然是如何在Keras下正确调用F1的计算方法,我尝试很多种方法均没有成功,还希望成功实现的可以分享一下代码。

4. 接下来本专栏将介绍的主要内容

  痛定思痛,笔者决定从这次比赛中吸取教训,主要从一下几个方面增强自己的实力。因此本专栏头几篇文章的将围绕这些展开,但是后期的文章将随博主的学习进程而定。

原创粉丝点击