比赛背景

想象一下,在失明发生之前就能够发现病变。数以百万计的人患有糖尿病性视网膜病变,这是导致老年人失明的主要原因。印度的Aravind眼科医院希望在农村地区的人们中发现并预防这种疾病,而那里的医疗筛查很难进行。目前,Aravind技术人员前往这些农村地区拍摄图像,然后依靠训练有素的医生对图像进行检查并提供诊断。因此kaggle举办了场比赛来加快疾病筛查。(本人排名:top6%,151/2987)

数据状况

图像为在各种成像条件下使用眼底摄影拍摄的大量视网膜图像。并由临床医生对每幅糖尿病视网膜病变的严重程度进行了0到4分的评分。

类别有5类,分别为:

0 - No DR
1 - Mild
2 - Moderate
3 - Severe
4 - Proliferative DR

各个类别下的图片数目为:{0: 1805, 1: 370, 2: 999, 3: 193, 4: 295},如下图:

补充数据:https://www.kaggle.com/tanlikesmath/diabetic-retinopathy-resized,此数据来自于2015年的比赛:https://www.kaggle.com/c/diabetic-retinopathy-detection/

1st解决方案

验证策略

在早期阶段,作者使用2015年的数据(训练和测试数据)作为训练集,并用2019年的训练数据作为验证集,但是验证结果与LB相差比较大。因此作者将2015年和2019年的数据作为训练集,依靠LB结果来验证结果。

预处理

作者认为图像质量已经非常好了,不需要进行预处理,只是进行resize。

模型与输入大小

作者使用了集成学习的思想,使用了8个模型进行分类,并表示如果比赛还有两个星期的话,还会使用EfficientNets。作者使用的模型及输入大小如下:

2 x inception_resnet_v2, input size 512
2 x inception_v4, input size 512
2 x seresnext50, input size 512
2 x seresnext101, input size 384

作者观察了2015年的比赛发现更大的输入能取得更好的结果,但是作者发现输入大小超过384之后并没有带来多大性能提升。

损失函数

作者只使用了nn.SmoothL1Loss()作为损失函数,来简化集成学习过程。

数据增强

contrast_range=0.2,
brightness_range=20.,
hue_range=10.,
saturation_range=20.,
blur_and_sharpen=True,
rotate_range=180.,
scale_range=0.2,
shear_range=0.2,
shift_range=0.2,
do_mirror=True,

池化

对于最后一个池化层,作者发现广义平均池化(generalized mean pooling,https://arxiv.org/pdf/1711.02512.pdf) 效果比原始的平均池化效果好,代码地址:https://github.com/filipradenovic/cnnimageretrieval-pytorch。

from torch.nn.parameter import Parameter
def gem(x, p=3, eps=1e-6):return F.avg_pool2d(x.clamp(min=eps).pow(p), (x.size(-2), x.size(-1))).pow(1./p)
class GeM(nn.Module):def __init__(self, p=3, eps=1e-6):super(GeM,self).__init__()self.p = Parameter(torch.ones(1)*p)self.eps = epsdef forward(self, x):return gem(x, p=self.p, eps=self.eps)       def __repr__(self):return self.__class__.__name__ + '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist()[0]) + ', ' + 'eps=' + str(self.eps) + ')'
model = se_resnet50(num_classes=1000, pretrained='imagenet')
model.avg_pool = GeM()

训练和测试

训练过程可以分为两个阶段。

  1. 单独训练这8个模型通过public LB来验证。而为了得到更稳定的结果,作者将模型进行成对评估(每种模型都有2个,使用不同的随机种子)。作者减少超参数的自由度来减轻过拟合问题,比如,为了确定训练的最佳epoch数目,以5为步长来增加训练epoch数目。以下是第1阶段训练后的优化结果:
inceptionresnetv2 public: 0.831 private: 0.927
inception_v4 public: 0.826 private: 0.924
seresnext50 public: 0.826 private: 0.931
seresnext101 public: 0.819 private: 0.923 (the 2nd best result, missing the best)
ensemble public: 0.844 private: 0.934
  1. 将public测试数据添加伪标签,再使用另外两个数据集(Idrid和Messidor),将它们添加到训练集中。

2nd解决方案

数据

使用2015年的数据对模型进行预训练,public LB只有0.73~0.75.

使用2019年数据训练,2015年数据进行测试。

模型

作者使用了se-resnet50,se-resnet101,densenet,效果都不行,唯一效果好的网络是efficient-net,因此作者集成了efficient-net b3, b4, b5。

  • b3图像尺寸:300
  • b4图像尺寸:460
  • b5图像尺寸:456

预处理

作者截取掉了图像中黑色的区域,然后只是对图像进行resize。

数据增强

作者使用了有生以来最多的数据增强操作:Blur, Flip, RandomBrightnessContrast, ShiftScaleRotate, ElasticTransform, Transpose, GridDistortion, HueSaturationValue, CLAHE, CoarseDropout。它们都来自于albumentations库。

训练

使用2015年的数据进行预训练模型(b3训练大概80轮,b5训练大概15轮),使用2019年的数据进行训练(b3训练大概50轮,b5训练大概15轮),选取表现最好的模型,然后把这两个模型的结果求均值。作者也使用了TTA。

秘方

作者对测试数据进行伪标签标注,然后使用训练数据+带伪标签的测试数据进行fine-tune网络,结果得到了巨大提升,因此作者进行了多次伪标签操作,同样,对2015年的测试数据也打上伪标签来增加训练数据。

(第3名解决方案截止本文发表时,还没有公布)

4th解决方案

预处理

截取掉黑色部分信息(训练和测试都采用),代码来自于这里:

def crop_image_from_gray(img,tol=7):if img.ndim ==2:mask = img>tolreturn img[np.ix_(mask.any(1),mask.any(0))]elif img.ndim==3:gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)mask = gray_img>tolcheck_shape = img[:,:,0][np.ix_(mask.any(1),mask.any(0))].shape[0]if (check_shape == 0): # image is too dark so that we crop out everything,return img # return original imageelse:img1=img[:,:,0][np.ix_(mask.any(1),mask.any(0))]img2=img[:,:,1][np.ix_(mask.any(1),mask.any(0))]img3=img[:,:,2][np.ix_(mask.any(1),mask.any(0))]#         print(img1.shape,img2.shape,img3.shape)img = np.stack([img1,img2,img3],axis=-1)#         print(img.shape)return img

数据增强

使用Dihedral, RandomCrop, Rotation, Contrast, Brightness, Cutout, PerspectiveTransform, Clahe。

模型

作者发现在大模型上使用高分辨率图像更容易过拟合,因此作者使用小模型配高分辨率图像或者大模型配低分辨率图像:

  • EfficientNet-B7 (224x224) LB 0.840
  • EfficientNet-B6 (240x240) LB 0.832
  • EfficientNet-B5 (256x256) LB 0.831
  • EfficientNet-B4 (320x320) LB 0.826
  • EfficientNet-B3 (352x352) *LB Don’t Know
  • EfficientNet-B2 (376x376) LB 0.828

使用5折交叉验证和TTA(8张图片,四个边角图片,然后再翻转)。

训练过程

在2015年所有数据(训练集和测试集)上预训练模型,轮数25轮,不进行验证,然后在2019年数据上进行5折交叉验证。

预测过程

使用5个模型+TTA(8张边角图片),只预处理图片一次来节省时间。

5th解决方案

模型

  • efficientnet-b0
  • efficientnet-b1
  • efficientnet-b2
  • efficientnet-b3

数据预处理和增强

  • 截取掉黑色背景
  • 图像大小:384 x 384
  • 使用Fliplr, Flipud, Randomrotate(0, 360), zoom(1.0, 1.35)和自行设计的透视变换方法。

训练策略

  • 五折交叉验证
  • 不在2015年数据上预训练并在2019年数据上微调,而是将2015年和2019年数据结合起来训练模型,在2015年private test和2019年验证数据上进行验证。
  • lr_schedule:Adam优化器,lrs=[5e-4, 1e-4, 1e-5, 1e-6],训练25轮,在[10, 16, 22]轮进行学习率衰减。
  • 2*TTA
  • threshold:[0.5, 1.5, 2.5, 3.5]

伪标签

  • 作者认为伪标签是赢得比赛的关键,因为不知道2019年private test数据集的分布,所以将三份数据集(2015年数据,2019年训练数据和2019年public数据)结合起来训练模型,使模型能够识别这三种不同的数据分布。
  • 作者没有使用2019年的public数据做伪标签样本,而是选择更高置信度的样本
  • 伪标签降低了本地mse损失,提高了qwk值(二次加权Kappa)。

本人解决方法

2015年数据+2019年数据作为训练验证集,模型使用efficient-net b5,图像大小256,优化器使用了前段时间刚出的RAdam和Ranger。

小贴士

TTA

Test Time Augmentation,测试时增强,这里会为原始图像造出多个不同版本,包括不同区域裁剪和更改缩放程度等,并将它们输入到模型中;然后对多个版本进行计算得到平均输出,作为图像的最终输出分数。这种做法在AlexNet的论文中就已经有了。在fast ai中可以通过以下方式实现:

preds, target = learn.TTA()

伪标签(pseudo label)

对于public test数据,使用训练数据训练出的模型对它进行预测,对于置信度高的样本,我们将预测结果作为它的“标签”——伪标签(又称软标签,soft label),然后将伪标签数据添加到训练数据中。

QWK(二次加权Kappa)

比赛使用QWK来评估结果,对于眼底图像识别,class=0为健康,class=4为疾病晚期非常严重,所以对于把class=0预测成4的行为所造成的惩罚应该远远大于把class=0预测成class=1的行为,使用quadratic的话将0预测成4所造成的惩罚就等于16倍的将0预测成1的惩罚。

kaggle糖尿病视网膜病变失明检测top5解决方案相关推荐

  1. 2022讯飞——糖尿病遗传风险检测挑战赛解决方案

    目录: 0. 赛事背景 1. 读取数据 2. 数据探索及预处理 2.1 缺失值 2.2 分析字段类型 2.3 计算字段相关性 3. 特征工程 3.1 特征构造 4. 模型训练 4.1 LightGBM ...

  2. Python基于逻辑回归的糖尿病视网膜病变检测(数据集messidor_features.arff)

    一. 引言 本项目基于逻辑回归理论,运用Python语言对数据集messidor_features.arff进行分析,实现对糖尿病视网膜病变的检测.糖尿病视网膜病变(DR)是糖尿病最常见的微血管并发症 ...

  3. 糖尿病视网膜病变检测 (Diabetic Retinopathy Detection)

    文章目录 前言 一.任务目标 二.数据处理 1.数据分析 2.模型训练 2.1模型准备 2.2参数设置 2.3读取数据并转换为tensor类型 2.4开始训练 2.5测试模型准确率 三.未完成的问题 ...

  4. Idx推出AI系统检测糖尿病视网膜病变

    文章来源:ATYUN AI平台 AI正在成为几乎所有行业的关键工具,但AI的一个特别强大的应用是医疗保健,人们已经看到了其潜力. 位于爱荷华州的Idx是一家使用AI来检测特定医疗状况的早期迹象的初创公 ...

  5. 基于逻辑回归(Logistic Regression)的糖尿病视网膜病变(Diabetic Retinopathy)检测

    基于逻辑回归的糖尿病视网膜病变检测 说明 数据集 探索性数据分析 方法 结果 代码 说明 这是我学机器学习的一个项目, 基于逻辑回归(Logistic Regression)的糖尿病视网膜病变(Dia ...

  6. 糖尿病视网膜病变的深度学习系统笔记

    糖尿病视网膜病变的深度学习系统笔记 论文地址:A deep learning system for detecting diabetic retinopathy across the disease ...

  7. 常用眼底图像数据集简介及下载--糖尿病视网膜病变 EyePacs,APTOS2019,STARE数据集

    1.糖尿病视网膜病变图像介绍 1.微动脉瘤通常出现在病变早期,它是由于眼部毛细血管缺氧导致血管壁变薄,从而在视网膜上呈现出深红色的点状物 2.出血点一般出现在血管附近,它是由于血管阻塞导致血液渗出形成 ...

  8. Eyenuk宣布FDA核准EyeArt自主AI系统用于糖尿病视网膜病变筛查

    EyeArt是FDA首次核准用于自主检测轻度以上和威胁视力的糖尿病视网膜病变的AI技术 洛杉矶--(美国商业资讯)--Eyenuk, Inc.是一家全球性人工智能(AI)医疗技术和服务公司,是AI眼病 ...

  9. 湖大计算机学院荣辉桂,湖大计算机专业学生能看病?人工智能3秒筛查糖尿病视网膜病变...

    长沙晚报掌上长沙5月31日讯(通讯员 曾欢欢 李妍蓉 记者 徐媛) 计算机专业的学生能帮助看病?听起来不可思议,然而因为人工智能的存在,这成为了现实.今日,记者从湖南大学获悉,该校信息科学与工程学院一 ...

最新文章

  1. 安德鲁斯Launcher得到的装在手机的应用程序列表
  2. 我理解的Hanlder--android消息传递机制
  3. 基于JAVA+SpringMVC+Mybatis+MYSQL的公司管理系统
  4. 沈大海38节jquery强化教程2016视频下载
  5. java导出文件名乱码
  6. linux socket cups,Linux打印系统CUPS原理分析
  7. 外接显示器显示“HDMI电缆没有连接”怎么办?
  8. win32-c语言实现俄罗斯方块
  9. java数字猜大小游戏_Java之数字猜大小
  10. flex 4 dropdownlist skin自定义 1
  11. 微信小程post问题
  12. 监控硬盘与计算机硬盘区别,视频存储烦恼 监控硬盘和普通硬盘区别
  13. C++添加防火墙例外——检测目标程序不在例外列表时才进行添加,防止重复添加
  14. 计算机专业毕业设计—JAVA语言系统设计(共80套打包)
  15. Centos7重新配置网络后出现Restarting network (via systemctl): Job for network.service failed because the contr
  16. 蓝桥杯三羊生瑞气,暴力破解
  17. 认证鉴权对于 API 网关的重要性
  18. N诺刷题(基础算法)
  19. vue ElementUi Tree效果 展开、收起、查询
  20. 【OpenSEES新材料/单元开发教程】第一讲 综述

热门文章

  1. 1.8 正则表达式【匹配一个或多个字符】
  2. 编程语言中的鸭子类型 Duck Typing
  3. Jmeter(三) - 从入门到上天 - 常用原件 (详解教程)
  4. 怎么安装打印机驱动?有没有快捷的方法?
  5. Unity 5.4公開測試,免費用戶也能下載使用!
  6. 凉哥核心圈程序员必备十大图书推荐(一)
  7. 中科院90多科研人员集体辞职后续:已低调处理,被质疑所长新添重要职务
  8. 本人编写的近乎全部《仙境传说》(RO)服务器工具下载 包含源代码
  9. 自学C++编程,掌握这三项技能就可以工作了
  10. pip命令下载第三方依赖的彩色进度条的具体实现