多标签分类问题概况 及 医学影像分类的思考

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多标签分类问题概况 及 医学影像分类的思考相关的知识,希望对你有一定的参考价值。

参考技术A 最近在做眼底图像的多标签分类,读了一下武大的刘威威老师的综述 The Emerging Trends of Multi-Label Learning 1 ,自己也看了一点医学影像分类和自然图像多标签分类的文章。本文主要总结一下阅读之后对多标签分类(multi-label classification, MLC)问题的理解,以及对于医学影像上的多标签问题的特点的一点思考。

综述的概括

为了偷懒这里就不列各个方法的引用了,在概括综述内容的基础上加了一点自己的理解,是跳着读的所以只有部分内容。

综述结构

MLC问题的研究重点包含几个方面:

Extreme MLC : XMLC, 就是类别数非常大的MLC场景。随着大数据时代的到来,这个场景的研究意义重大。

大部分工作是基于SLEEC之后做的,主要有基于one-vs-all分类器、树、embedding三种思路。

理论层面需要针对标签稀疏,处理长尾分布问题。

MLC with missing/nosiy label :非全监督学习的MLC版本,主要针对标签的问题进行处理。

missing label:预设有的类别无label

semi-supervised:传统半监督学习的迁移,部分data有label,部分没有

partial multi-label: 部分label不可信,即模糊标签的场景

online MLC for stream data :由于现在web端实时产出大量流数据,针对线上实时场景的MLC被大量关注。

流数据无法预读到内存里获取全局,一般需要实时处理每个时间戳

现有offline MLC model在序列数据上的效果一般

online MLC领域目前在实验和理论上暂无特别好的效果(very limited)

§4 Deep Learning for MLC

BP-MLL

最早在MLC中使用NN结构的是BP-MLL, 它提出了一种pairwise的loss函数,如下:

Ei=1∣yi1∣∣yi0∣∑(p,q)∈yi1×yi0exp⁡(−(F(xi)p−F(xi)q))E_i=\frac1\left|y_i^1\right|\left|y_i^0\right| \sum_(p, q) \in y_i^1 \times y_i^0 \exp \left(-\left(F\left(x_i\right)^p-F\left(x_i\right)^q\right)\right)Ei​=∣yi1​∣∣yi0​∣1​(p,q)∈yi1​×yi0​∑​exp(−(F(xi​)p−F(xi​)q))

其中p,qp,qp,q分别为预测为1和0的类别,使用e−xe^-xe−x形式惩罚项,使得不同的类别间差值尽可能大,整体是一种rank loss的思路。

在随后的研究中发现,BP-MLL可以使用cross-entropy loss,再加上一点ReLu/Dropout/AdaGrad之类的trick,可以再经典BP-MLL无法应用的大规模文本分类的场景获得新的SOTA性能。

C2AE

经典的Embedding方法只能获取label本身的语意dependency,不可能获取更高维的联系,C2AE(Canonical Correlated AutoEncoder)是第一个基于Embedding的MLC方法,它通过自编码器提取特征,利用DCCA(deep canonical correlation analysis)基于特征提取label间的联系,属于embedding层。

C2AE整体目标函数定义如下:

min⁡Fx,Fe,FdΦ(Fx,Fe)+αΓ(Fe,Fd)\min _F_x, F_e, F_d \Phi\left(F_x, F_e\right)+\alpha \Gamma\left(F_e, F_d\right)Fx​,Fe​,Fd​min​Φ(Fx​,Fe​)+αΓ(Fe​,Fd​)

Fx,Fe,FdF_x, F_e, F_dFx​,Fe​,Fd​分别为 特征映射、编码函数、解码函数,α\alphaα是平衡两个惩罚项的权重项。Φ,Γ\Phi, \GammaΦ,Γ分别为latent空间(feature和encoding之间)和output空间上(encoding和decoding之间)的loss。

借鉴了CCA的思路,C2AE使instance和label的联系尽可能大(最小化差距)

min⁡Fx,Fe∥Fx(X)−Fe(Y)∥F2 s.t. Fx(X)Fx(X)T=Fe(Y)Fe(Y)T=I\beginaligned \min _F_x, F_e &\left\|F_x(X)-F_e(Y)\right\|_F^2 \\ \text s.t. & F_x(X) F_x(X)^T=F_e(Y) F_e(Y)^T=I \endalignedFx​,Fe​min​ s.t. ​∥Fx​(X)−Fe​(Y)∥F2​Fx​(X)Fx​(X)T=Fe​(Y)Fe​(Y)T=I​

自编码器使用和上文相似的rank loss,使得不同类别的code差别尽可能大。

Γ(Fe,Fd)=∑i=1NEiEi=1∣yi1∣∣yi0∣∑(p,q)∈yi1×yi0exp⁡(−(Fd(Fe(xi))p−Fd(Fe(xi))q))\beginarrayl \Gamma\left(F_e, F_d\right)=\sum_i=1^N E_i \\ E_i=\frac1\left|y_i^1\right|\left|y_i^0\right| \sum_(p, q) \in y_i^1 \times y_i^0 \exp \left(-\left(F_d\left(F_e\left(x_i\right)\right)^p-F_d\left(F_e\left(x_i\right)\right)^q\right)\right) \endarrayΓ(Fe​,Fd​)=∑i=1N​Ei​Ei​=∣yi1​∣∣yi0​∣1​∑(p,q)∈yi1​×yi0​​exp(−(Fd​(Fe​(xi​))p−Fd​(Fe​(xi​))q))​

后续的DCSPE, DBPC等工作进一步提升了文本分类上的SOTA性能和推理速度。

patial and weak-supervised MLC

CVPR 2020中 D. Huynh 的 Interactive multi-label cnn learning with partial labels 和CVPR 2019中 T. Durand 的 Learning a deep convnet for multi-label classification with partial labels (以下根据坐着名称简称D和T)做了相关研究。

T使用BCE Loss训练有标签部分,然后使用GNN提取标签间联系。实验证明部分标注的大数据集比全标注的小数据集效果要好,进一步证明了partial label的MLC领域的研究意义。

D在T的基础上,使用流形学习的思路,将label和feature的流形平滑度作为BCE Loss函数的cost,再使用半监督的思路,CNN学习和similarity同步进行(我没看这篇文章,听综述的这种描述类似于π\piπ模型或者teacher-student结构)。

SOTA的Advanced MLC

分类链 :ADios把label切分成马尔科夫毯链(Markov Blanket Chain),可以提取label间的关系,然后丢进DNN训练。

CRNN :有2篇文章把类别作为序列,使用CRNN或者C-LSTM处理。更进一步对于类别序列的顺序使用attention/RL进行学习,寻找最优顺序。CVPR 2020和AAAI 2020各有一篇此思路的,使用optimal completion distillation+多任务学习/最小alignment的思路,都是尝试动态调整label sequence的order(order-free)。

graph相关

2 建立一个类别间的有向图,然后使用GCN训练。

SSGRL 6 使用embedding进行semantic decoupling, 然后使用GNN学习label+feature构成的-semantic,强化instance和label特征,以学习更高维的label间的联系。

3 对GCN和CNN的一些layer间添加连接,从而实现label-aware的分类学习

4 使用GCN获取rich semantic info,再使用non-local attention获取长语意关联。

5 使用深度森林,一种tree ensemble方式,不依赖回传机制。提出了MLDF(multi-label Deep Forest),据说可以更好地解决过拟合,在6种指标上取得了SOTA的效果,是lightweight设计的一个探索。

医学影像的MLC思考

以前看医学图像分割的文章(DeepIGeoS),国泰对于医学图像的特殊点概括为:

低对比度,高噪声,存在空腔

患者间scale和feature差异巨大

疾病间的不均匀表征

医生定义不同会造成ground-truth特征不一致

这主要针对与分割而言,因为一般分割任务的CT和MRI图像是高Intensity的灰度图像,感觉在MLC场景中1和2基本都不咋适用。

3在MLC中表现为不同类别的feature的不均匀,例如有的疾病可能可观测症状覆盖很大区域,有的就只是很小的部分会出现可观测的症状,感觉类似于FPN的multi-scale策略对于特征提取会有一些帮助,不过这是一个很general的推测,具体效果需要在具体的场景下多做实验。

4可以联系上MLC中的partial label问题,如果对于疾病的判断是不确定的,例如医生对一个患者得出几种可能病症,此时又没有进一步检查,那么也许可以设计一种方法预测各个label的置信度,哈哈哈感觉这是一个paper的idea了,可惜场景和数据的要求感觉有些苛刻。

另外值得一提的就是类别不平衡,由于一些疾病的病例较少,可能收集到的data里只有个位数的正例,此时这个类别很可能根本学不到啥,目前想法不是很清晰,过几天有时间再专门调研一下这个问题。

最后就是医学图像喜闻乐见的半监督,如果有部分没有标注的数据和一些标注的数据,拿来做半监督对性能也能提升一些,虽然不局限医学图像,但是由于医学标注获取较难,半监督的应用也特别广,大有可为吧可以说

2017知乎看山杯总结(多标签文本分类)

http://blog.csdn.net/jerr__y/article/details/77751885

关于比赛详情,请戳:2017 知乎看山杯机器学习挑战赛

代码:https://github.com/yongyehuang/zhihu-text-classification 
基于:python 2.7, TensorFlow 1.2.1

任务描述:参赛者需要根据知乎给出的问题及话题标签的绑定关系的训练数据,训练出对未标注数据自动标注的模型。

标注数据中包含 300 万个问题,每个问题有 1 个或多个标签,共计1999 个标签。每个标签对应知乎上的一个「话题」,话题之间存在父子关系,并通过父子关系组织成一张有向无环图(DAG)。

由于涉及到用户隐私及数据安全等问题,本次比赛不提供问题、话题描述的原始文本,而是使用字符编号及切词后的词语编号来表示文本信息。同时,鉴于词向量技术在自然语言处理领域的广泛应用,比赛还提供字符级别的 embedding 向量和词语级别的 embedding 向量,这些 embedding 向量利用知乎上的海量文本语料,使用 google word2vec 训练得到。

简单来说,这是一个多标签文本分类问题,基本上都是使用深度学习方法。

结果:在public board 上排名第五,private board 上排名第六。

技术分享图片
技术分享图片
图1 public board
图2 private board

我是从7月1号开始报名比赛,一直到8月16日早上结束,一共一个半月时间,除了开始三周有些其他事情,后面差不多一个月时间基本上都在做比赛。之前也做过一个文本的比赛(命名实体识别+分类),但是之前积累不够,有没有找到合适的队友,所以那个比赛最后成绩很差,后期基本上就放弃了。这次还是一个人参赛(一个人打比赛好累…)这一个半月确实很累,经常写代码写到半夜,然后一大早又起来看模型跑的结果,发现出错了赶紧改过来;跟同学抢机器;各种想法没提升;有一次把验证集写成训练集来用结果过拟合白白高兴了…和我一个实验室的还有两组同学参加了,他们分别拿了第一和第二…唉唉,自己还是太菜了。不过在这次比赛中,确实学习了好多,这里写下比赛中的一些经验,希望对大家特别是对于竞赛入门者能有所帮助。下面的相关经验主要是和深度学习相关。

硬件准备

在这次比赛中,训练集有300万个问题;测试集有21.7万个问题。赛方提供了预训练好的词向量矩阵,一共有40+万个词。所以数据量还是非常大的,如果没有服务器,基本上没法做。我们组一共就一台服务器,一块显卡titan X,64G内存,CPU12进程。但是,我们有十几个同学呀,虽然平时主要就三四个人用,但是和其他大佬们多卡多机相比,这配置确实寒酸。跑一个模型几个小时到二三十个小时,所以,没有机器,根本别想取得好成绩。

此外,一定要准备充足的硬盘空间,最好能有500G, 1T或者更多。因为在这次比赛中,我就因为硬盘满了,只能把数据放在两个分区进行操作,可能是前期没有注意管理,导致后来文件组织非常混乱。

文件管理

所有的比赛都应该一样, 就是“不择手段”地达到更好的成绩,而要取得较好的成绩,不可避免地会用到集成学习,所以你不可能靠一两个模型就能够取得很好的结果。在这次比赛中最后获奖的所有队伍都用了模型融合,模型数量少的有十几个,多个两百多个,我最后提交的结果用了37个模型。所以从一开始,你就应该管理好模型和文件的命名,这样才不至于后期命名混乱,因为缺乏经验,所以我也在这上面吃了不少亏。

模型保存

因为词向量非常大,所以每个模型保存下来都非常大(1G+),这样就非常占空间。所以应该怎么保存模型也是有讲究的,我的经验大概如下:

  • 设置一个最低 f1值(last_f1, 这次比赛评价函数是 f1,如果是准确率的话应该设置一个最低的准确率);每迭代 valid_step 步,就预测整个验证集,计算f1值,如果高于last_f1, 则保存模型。
  • 每个网络保存最好的模型即可,也就是说设置 max_keep=1

具体代码可以参照这份代码中的 train_epoch() 函数

为什么只保存最好的一个就好了?我尝试过保存最好的三个模型,假设为m1, m2, m3 然后把这三个模型以平均加权的方式融合得到 M,这样M的结果要比最好模型 m1 的结果好(在这次比赛中,能高2.5个千分点左右,这已经很好了),但是,但是,但是,在后面和其他结构的模型再次融合,M的效果不如直接使用 m1。我觉得可能是与 M 相比,对于每个样本的预测概率,m1 的方差更大些。比如对于样本a和b,m1预测分别属于类别1的概率是0.9 和 0.1; M预测分别属于类别1的概率是0.7和0.3。这种情况下和其他模型融合,m1的作用会更大一些,因为它对正样本的确定性很高,决定性更大。在其他数据或者比赛中,我觉得应该也是一样的。所以,只需要保存最好的一个模型,这样能节省不少硬盘空间。

使用 tensorboard

tensorboard 很好用,通过 tensorboard 查看损失变化能够很好地帮助我们进行调参,当然同时也可以看看模型结构有没有写错了… 但是有一点需要注意,如果你的模型很大,那么tensorboard中保存的数据也会非常大,所以还是很占空间的。 


技术分享图片 
图3 网络结构 

 


技术分享图片 
图4 损失变化 

 

模型构造与调参

在这次比赛中,主要使用的基本模型有 TextCNN, BiGRU, HAN(Hierarchical Attention Networks ), FastText, RNN+CNN(区别与RCNN)。然后各种结构拼接,修改。比赛的目的很明确,就是取得更好的分数。所以我们的目的并不只是把原论文的结构套过来看看结果,而是要在给定的数据集上不断改进,不断调整参数。同样的一个模型,可能就是某个地方有一点小小的差别,或者学习率没调好结果就会差很多。这些都是需要自己不断积累,在实验过程中不断总结出来的。但是在大体上,有些问题还是需要注意的。

  • 关于学习率和学习率衰减。学习率非常重要,一般都会使用自适应的优化器,比如 adam, 但是还是需要严谨地选择初始学习率。至于学习率衰减,TensorFlow 中提供了tf.train.exponential_decay()函数,这函数有个参数staircase,我的经验是一定要设为staircase=True,也就是迭代好多步以后再跳一次,而不是没迭代一次都调整学习率。你会在tensorboard中看到,学习率衰减的那一瞬间,loss都会迅速地下降一次。在TextCNN中特别明显。我看到有些人用adam优化器的时候并没有使用 decay,而是只提供了一个初始学习率,但是我在实验中发现,使用Exponential Decay效果明显要比没用好。而且decay_rate 和 decay_step 的选择也很关键。但是有些队伍根本就没做这个效果却非常好,所以现在我还是比较疑惑。之后弄清楚了再来补充。相关讨论可参考下面:

Tensorflow: Adam Optimizer with Exponential Decay 这里有讨论但是不是很明确。 
Mixing learning rate decay and Adam, is it possible? 
Should we do learningrate decay for adam optimizer 里边下面这个说法我比较认同。

It depends. ADAM updates any parameter with an individual learning rate. This means that every parameter in the network have a specific learning rate associated.

But the single learning rate for parameter is computed using lambda (the initial learning rate) as upper limit. This means that every single learning rate can vary from 0 (no update) to lambda (maximum update).

The learning rates adapt themselves during train steps, it’s true, but if you want to be sure that every update step do not exceed lambda you can than lower lambda using exponential decay or whatever. It can help to reduce loss during the latest step of training, when the computed loss with the previously associated lambda parameter has stopped to decrease.

adam对于每个参数都会自动调整学习率,但是我们传进去的学习率是进行适应学习率计算的基础。所以加上decay还是会有作用的,不过具体问题具体尝试才能知道有没有用。

  • 关于模型大小。这个其实很关键,首先要看数据量,像知乎的这次比赛数据量还是非常大的,所以模型也是应该比较大的。就这个数据集,相同结构,大一点的模型可能比小一点的模型更加节省时间。因为模型参数多了,迭代一次学习到的信息要比模型多,所以收敛的速度可能比小模型更加快。所以,在比赛初期,你可以先用小模型把一个结构跑通,然后开始可以尝试改进结构,加深模型,加宽模型。在这次比赛中,第三名的队伍他们的模型比我的基本大了5,6倍,他们最好的CNN模型训了一周,但是对于我来说这是绝对不允许的,因为就一台机器,如果一个模型训上一周意味着我都不用做了,万一效果还不好呢。所以,硬件非常非常关键。

  • 关于 batch_size。一般来说,几十到几百的batch_size都是可以接受的,那么选择大batch_size 还是小的batch_size呢?我认为,在这么大的一个数据集下,尽量把GPU撑满是个不错的选择,但是也不能太大,最好别超过1000。batch_size 大些,收敛速度相对来说应该会快些。batch_size越大,那么梯度的方向相对会更贴合“全局梯度”,更加“准确”。这样的话,我觉得学习率也可以稍微调大一点。但是,因为有很多很多的局部最优点,我们不能把 batch_size 设得太大,这样每个batch 的梯度才会带有一些“噪声”来帮助我们跳出这些局部最优点。具体的大小当然还是要根据数据集,通过实验来选择,还有你的显存大小来选择。

  • 因为赛方提供了预训练好的词向量和字向量,而且都是在更大的数据集上训练的,所以肯定会比自己训练的要好。但是,embedding 可以在迭代一定轮次(epoch)以后再进行fine-tune,这样有两个好处:一是embedding非常大,如果不对embedding计算梯度的话能减少不少计算,节省时间;二是一开始就是用大学习率优化embedding,容易把原本预训练学习到的信息丢失。在TensorFlow中要想先固定embedding,在一定轮次以后再优化的话,可以通过定义两个优化器来实现。可以参考这个代码中main()部分。对于知乎的这个数据集,这样做对于RNN效果比较好,但是对于TextCNN似乎帮助不大。

  • 关于融合。一定要从一开始就为最后模型融合做好准备。模型融合的方法有很多,最常见的比如bagging, stacking 等。在这次比赛中,由于数据量太大,而且计算时间非常长,所以对于我来说,基本上没有办法做stacking,所以最后使用了线性加权。好而不同,这是模型融合最最关键的地方。所以BIGRU与TextCNN融合要比BIGRU与HAN效果好很多,因为TextCNN与BIGRU结构相差非常大,而HAN里边就是用了 BIGRU。所以在训练不同模型时,一定尽量增加模型之间的差异性。在这个比赛中,使用字向量训练的模型要比词向量训练的模型差很多(1个百分点以上),但是在模型融合中,一个好的字向量模型带来的提升非常大。

在这次比赛中,主要使用的模型结构如下:

技术分享图片
技术分享图片
技术分享图片
技术分享图片
技术分享图片
 

其他

比赛结束后,学习其他组的参赛方案,确实有很多值得学习的地方。非常感谢知乎组织的这次比赛,最后他们还公布了所有获奖队伍的参赛方案,详细见:「2017 知乎 · 看山杯机器学习挑战赛」结束,谁获奖了?知乎还会做什么?








以上是关于多标签分类问题概况 及 医学影像分类的思考的主要内容,如果未能解决你的问题,请参考以下文章

【技术综述】多标签图像分类综述

ML-10多分类及多标签分类算法

多标签分类策略

基于Keras的多标签图像分类

逻辑回归——多类别分类

文本分类:多标签文本分类与多类文本分类