蒋竺波

新加坡研究院 AI Department 公众号:follow_bobo

首发于专栏:https://zhuanlan.zhihu.com/c_141391545

个人公众号:follow_bobo

能不能点个赞,就是那种看起来写的还不错的样子


我们先来总结一下上一期的数据情况,顺便补充一点上一期没有讲到的:

目标类别一共20类,每类数量400-50不等

单从数据的情况,数据量少,并且不平衡,这个时候一个最基础的判断是用Pretrained model 实现两个Solution:

  1. Fine tune with Pretrained model

对于Google自己家的模型,比如Inception系列,我们用Tensorflow来fine tune,,毕竟自己家的模型,总会特别优化一点, 对于其他Pretrained model, 主要用Keras。

可能有人会问,Pretrained model 都是用ImageNet 训练的,但是ImageNet 里面并没有医疗数据呀?

首先,我们的数据量比较少,不建议Train from scratch.

第二,你可以理解为用Pretrained model 的参数来初始化model 的参数,而这些Pretrained model 的参数 的是经过专家们精确调参出来,效果肯定比随机生成参数好很多。最后也证明Fine tune with Pretrained model 在20个epochs 时就收敛了,并且有90%以上的Accuracy。

2. Extracting features with Pretrained model + Xg boost

这是在Kaggle 比赛中很常见的一种做法,特别是针对数据集比较少的时候。在这里最后效果不如 Fine tune,并且考虑到日后我们的数据越来越多,暂时不用这个方法。

如果有读者想有此法,我提醒一下。在提取特征之前,需要对model进行Domain Transfer, 什么意思,举个例子,Pretrained model 用的是ImageNet 训练,Domain 分布来自ImageNet, 我们的Domain来自医疗数据,如果模型中有Batch Normalization, 算法如下:

其中的mean, variance, scale γ and shift β 是来自于ImageNet 数据,你需要在这里转换成你的数据的mean, variance, scale γ , shift β.

怎么转换?很简单啦。

Freeze 住BN层以外的所有参数,将learning rate 设为1,训练几个Epoch就可以了。

mean, variance 可以在前向传播中学到,scale γ , shift β可以在反向传播中学到.

数据形式比较统一(都是超声波图和多普勒图),背景比较单一(都是黑色),图片质量参差不齐,亮度,颜色不一致,很多情况下图片包含大量噪声

展示数据 2

也就是说我们要对数据去噪,提取重要部分,并且还要进行标准化

图片数据是由上(超声波,label 为 A ),下(多普勒,label 为B)两部分组成,经过和医生讨论,医生主要看的是B,A作为辅助判断,但是A 和 B 是有关联的,所有我们实验了以下多个模型:

模型 1.0

模型 2.0

模型 3 .0

模型 3 虽然最节省资源,但表现略差,模型1 和2 结果接近,但 因为B为主输出,A 为副输出,我们可以容忍A有一定的预测误差,所有模型 1 更符合我们的目的

在经过几十次模型结构的调整以及调参(上节提过),最终模型 1.0 的平均分类准确率已经可以约94%了.

Step 6 : 数据增强

有小伙伴问,你有尝试做数据增强(Augmentation)吗?

考虑到医疗数据的特殊性,轻微的变动(比如旋转,放大等)都会影响到数据的label, 以及未来更多数据会陆陆续续进来,因此我们在这不做数据增强。

Step 7 : 额外信息

这一步其实我认为比较重要,这一步也显示出科研和工程的不同,工程就是为了达到目的不择手段的。按理说,如果再专注一模型层面上,准确率是还有可能提升的,但是需要耗费的时间成本过大,我们决定把方向转向一些未知方向。

在和医生详细沟通之后,我们发现除了图片数据,跟随着病人的还有一份Dicom数据,什么是Dicom 数据,下面是从Wiki 嫖下来的Dicom数据的解释:

在所有的用途上都是使用相同的格式,包括了网络应用和档案处理,和其他格式不同的是它统合了所有的资讯在同一个资料内,也就是说,如果有一张胸腔X光影像在你的病人个人资料内,这个影像决不可能意外地再从你的病人资料中分离。
DICOM的档案是由标准化且自由型式的开头再加上一连串的影像数据,单一个DICOM的物件只包含一张影像,但是此影像可能会有多个套图,这是为了能储存动态影像以及其他复图形式的资料。

其实一开始甲方是不愿意给Dicom 的,因为这个Dicom 涉及到病人太多隐私信息,经过多方协商后,甲方答应给出一小部分Dicom 做实验。其中我们的图片数据也来自于这份Dicom 数据中

Dicom 示例(图片来源于网络)

上面我们已经知道图片数据是由(A + B )组成,实际上B 还可以由(C+ D)组成

从这个Dicom 数据中,我们发现一个很重要的特征E,来自于正在给病人做检查的仪器设备,它竟然可以把 C 100%分类正确,意味着,当我们用模型 1 预测B时,B 中的C 和 特征E 中的C不一致时,可以轻松过滤掉错误预测。

同时,我们发现,从Dicom 数据中,我们挑选出了近20多类我们认为有价值的meta特征数据(心率等)来训练一个只对D 做分类的ML 分类器,意外的是分类准确率有80%左右。

这个时候我们考虑到将这20多类meta特征和CNN 提取出来的特征结合,然后一起送进B分类器,我们打印出了B分类器的特征rank 排序,发现这些meta特征重要性非常低,实验结果也是对B分类器的结果没有任何帮助。

至此,我们把分类器C,D 单独加进模型 1.0 ,成为模型1.1。

模型 1.1

合分类器的原理是Majority voting ,也就是投票机制。

由于最终模型还没有完成,所以合分类器的细节暂且不表。

由于数据量比较少,模型 1.1 表现和模型1 几乎一样。

但从理论上,C和D 的加入,肯定能给这个模型带来一定的贡献。


Step 8 : 研究超声波数据A

超声波数据A

我们现在把目光放在超声波数据A,我们希望从中发现点什么可以利用的。

等等,这是什么,拥有一双好奇大眼睛的我提出了问题?

中间那个白线是干啥子用的?所有的超声波数据都有着根白线。

于是,我们想办法把这根白线的长度和角度提取出来,看能不能发现什么玄机。

好家伙

每一个多普勒B类数据(对,B类), 在超声波A 类中对应的白线角度是有一个大概分布,比如(A1 + B1 )的白线角度为60-90度,(A2 + B2)的白线角度为90-105度,下图展示了其中3 类的分布:

与多普勒B类数据对应的超声波A类白线角度分布 其中3类分布

从上图可以看到,每一个B类对于的A类白线角度是会有一个大概范围。

但同时也存在大量的overlap 以及 outliers,所以我们把overlap过于大的几类合并在一类

最后大概分类准确率只有80%左右,我们称之为分类器E。

其实对于白线角度的信息,我们在想CNN是否已经学进去,于是我们可视化了CNN最后一层global average pooling 层 学到的特征,并绘制了heat map 图,仍然无法确定CNN是否已经学习了白线的信息。

所以最后,我们仍然把分类器E放进合分类器里。


Step 9 : 挖掘多普勒数据B

在医生沟通的过程中, 我们了解到医生是怎么对多普勒数据分类的

他们主要看三点:

波形中波峰的个数,波峰的宽度,波峰与波峰之间的距离

于是我们提出一个问题:

如果我们把这三点找出来,然后根据医生的判断逻辑,做一个rule-base 分类器F,会不会帮助合分类器?

但是很明显这三点信息,应该是被CNN 学进去了,不出意外,CNN 自己学习的效果,要比rule-base 效果好

考虑到这个项目的下一阶段需要用到这三点信息,我们决定还是把它提取出来

红线表示峰高,黄线表示峰宽,绿线表示峰与峰之间的距离

想要获得这三点信息,就得获得波形;

想要获得波形,很明显传统CV 的Pixel by Pixel 的方法肯定不行的,因为存在大量噪声

我们想到的是:

用Unet 为多普勒B类数据生成一个Mask,然后在Mask 上用CV的方法提取信息。

效果图如下:

这个rule-base 的方法在这不多提,因为这个方法表现不稳定。

当图片质量非常好的时候,它可以有效的提出三个特征。

可是图片质量稍微不好,它就会出岔子。

自此,我们的模型已经由模型1.0 升级成模型1.2 了,特别是C分类器的出现,帮我们过滤了一部分错误答案。

模型 1.2

下期见。

拜了个拜。

CNN入门实战:我如何把准确率从86% 提高到99%(中)相关推荐

  1. 【QGIS入门实战精品教程】4.5:QGIS打开Excel中的点坐标,并生成矢量文件

    QGIS中可以很方便添加Excel或其他文本格式的点坐标,并将其转为矢量等多种格式的文件. 扩展阅读: [ArcGIS风暴]ArcGIS 10.2导入Excel数据X.Y坐标(经纬度.平面坐标),生成 ...

  2. IDEA Java Junit单元测试入门实战

    IDEA Java Junit单元测试入门实战 1.下载jar包 2.在IDEA中添加jar包 3.创建单元测试代码 junit的使用: junit不是javase的一部分,想要使用需要导入jar包. ...

  3. [TensorFlow深度学习入门]实战九·用CNN做科赛网TibetanMNIST藏文手写数字数据集准确率98%+

    [TensorFlow深度学习入门]实战九·用CNN做科赛网TibetanMNIST藏文手写数字数据集准确率98.8%+ 我们在博文,使用CNN做Kaggle比赛手写数字识别准确率99%+,在此基础之 ...

  4. 网易云课程:深度学习与PyTorch入门实战

    网易云课程:深度学习与PyTorch入门实战 01 深度学习初见 1.1 深度学习框架简介 1.2 pytorch功能演示 2开发环境安装 3回归问题 3.1简单的回归问题(梯度下降算法) 3.3回归 ...

  5. 自然语言处理入门实战2:基于深度学习的文本分类

    自然语言处理入门实战2:基于深度学习的文本分类 数据集 数据预处理 模型 模型训练 模型测试 参考 本文参考复旦大学自然语言处理入门练习,主要是实现基于深度学习的文本分类. 环境:python3.7 ...

  6. Spark入门实战系列--8.Spark MLlib(上)--机器学习及SparkMLlib简介

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 1.机器学习概念 1.1 机器学习的定义 在维基百科上对机器学习提出以下几种定义: l&qu ...

  7. Fastlane 入门实战教程从打包到上传iTunes connect

    有关神器 Fastlane 持续集成\部署的文章网上挺多,本文定位是入门教程,针对 iOS 应用的持续部署,只需一条命令就可实现从 Xcode 项目到 编译\打包\构建\提交审核 文章稍微有点长,涵盖 ...

  8. Spark入门实战系列--6.SparkSQL(中)--深入了解SparkSQL运行计划及调优

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 1.1  运行环境说明 1.1.1 硬软件环境 l  主机操作系统:Windows 64位, ...

  9. Gerrit代码Review入门实战

    代码审核(Code Review)是软件研发质量保障机制中非常重要的一环,但在实际项目执行过程中,却因为种种原因被Delay甚至是忽略.在实践中,给大家推荐一款免费.开放源代码的代码审查软件Gerri ...

最新文章

  1. 细说SSO单点登录(转)
  2. 最简单的composer 包 使用
  3. SAP中凭证类型的作用
  4. java向量数组异常,数组中空异常指针的Java错误处理
  5. 64 源码_【ClickHouse内核】源码阅读策略
  6. 【正在直播】:CSDN直播间专属福利!1399买Airpods Pro
  7. 计算机在生活中应用视频,计算机在腐蚀防护中的应用教学视频
  8. Symfony2Book16:Symfony2内部03-事件调度
  9. svm分类器_用人话讲明白支持向量机SVM(上)
  10. mesa3d源代码阅读笔记
  11. List集合去重的常见几种方式
  12. Office 2007 SP3 正试版补丁包下载
  13. 家庭网络布线工程图布线方案
  14. adobe怎么统计字数_pdf文档统计字数的问题
  15. 总结2023Android开发面试题(含答案)
  16. Redis用来干嘛的?
  17. “bang” in JavaScript
  18. 我们的秘密是绿色的!他喵的
  19. Python3 钉钉建群助手(批量拉人)
  20. 2020年 30K的前端架构面试题总结(持续更新)

热门文章

  1. 震惊!!C++居然可以发出声音!
  2. Unity添加GIF动画
  3. Python中 axis=0、axis=1是行还是列?
  4. 做一个python的旅游系统_Python爬取13个旅游城市,告诉你新年大家最爱去哪玩?...
  5. aardio 读取excel数据问题
  6. NGUI和UGUI的区别
  7. 设计验证Derating测试方法教程
  8. linux如何运行windows游戏,用Steam Play在Linux系统中玩Windows游戏的方法
  9. Autodesk Helius PFA 2019 永久版
  10. 屏幕一直显示android,lenovo!屏幕一直显示poweredbyandroid是什么意思