先验知识融合机器学习的几种方式
- 第一种是把网络的权重替换成一个在另外一个任务上预训练好的模型权重。经过的预训练的模型(如ImageNet预训练)往往已经具备的识别到一些基本的图片pattern的能力,如边缘,纹理,颜色等等,而识别这些信息的能力是识别一副图片的基础。这个思想和迁移学习类似。
- 第二种是在数据上下功夫。把原始数据的全局特征和局部特征分别训练,然后融合。
- 第三种是通过注意力机制让模型考虑先验知识:注意力放在鸟头,这就是添加先验信息
- 基于CAM图激活限制给模型加入先验知识:基于激活图,通过限制激活图的激活区域,加入目标先验。激活图是基于分类网络的倒数第二层卷积层的输出的 feature_map 的线性加权,权重就是最后一层分类层的权重,由于分类层的权重编码了类别的信息,所以加权后的响应图就有了基于不同类别的区域相应。浅谈Class Activation Mapping(CAM) - 知乎 (zhihu.com)
激活图的样子如下:
上面一张是一只鸮鹦鹉的激活图,下面是一只在天空飞翔的大雁的激活图。因为鸮鹦鹉的Label是0,其他鸟类的Label是1,所以在激活图上,只要是负值的激活区域都是鸮鹦鹉的激活,也就是Label为0的激活,只要是正值的激活都是其他鸟类的激活,也就是Label为1的激活,为了方便展示,我把负值的激活用冷色调来显示,把正值的激活用暖色调来显示,所以就是变成了上面两幅激活图的样子。而右边的数字是具体的激活矩阵(把激活矩阵进行GAP就可以变成最终输出的Logits)。
- 基于辅助学习给模型加入先验知识——多任务学习+辅助模型
上图的左侧是多任务学习的例子,右侧是辅助学习的例子。左侧是个典型的face attribute的task,意思是输入一张人脸,通过多个branch来输出这一张人脸的年龄,性别,发型等等信息,各个branch的任务是独立的,同时又共享同一个backbone。右边是一个典型的辅助学习的task,意思是出入一张人脸,判断这一张人脸的性别,同时另外开一个(或几个)branch,通过这个branch来让网络学一些辅助信息,比如发型,皮肤等等,来帮助网络主任务(分男女)的判别。
在上面的Pipeline中,辅助任务相比如主任务,把其他鸟类做更加细致的分类。这样网络就学到了区分不同其他鸟类的能力。但是从实验效果来看这个Pipeline的精度并不高。经过分析原因,发现在主任务和辅助任务里面都有鸮鹦鹉这一类,这样当回传梯度的时候,相当于把区分鸮鹦鹉和其他鸟类的特征回传了两次梯度,而回传两次梯度明显是没用的,而且会干扰辅助任务学习不同其他鸟类的特征。
所以我们可以把辅助任务的鸮鹦鹉类去除,于是便形成了下面的pipeline:
经过实验发现,这种pipeline是有利于主任务精度提升的,网络对于特征明显的其他鸟类的分类能力得到了一定程度的提升,同时对于困难类别的分类能力也有一定程度的提升。
上面的pipeline除了主任务的label标注,它还同时需要很多的辅助任务的label标注,而标注label是深度学习任务里面最让人头疼的问题(之一)。
介绍一个work,它基于meta-learning的方法,让你不再为给辅助任务标注label而烦恼,它的framework如下:
这个framework采用基于maxl的方案(https://github.com/lorenmt/maxl),辅助任务的数据和label不是由人为手工划分,而是由一个label generator来产生,label generator的优化目标是让主网络在主任务的task上的loss降低,主网络的目标是在主任务和辅助任务上的loss同时降低。
但是这个framework有个缺点,就是训练时间会上升一个数量级,同时label generator会比较难优化。
这篇文章有两个结论倒是很有意思:
- 假设 primary 和 auxiliary task 是在同一个 domain,那么 primary task 的 performance 会提高当且仅当 auxiliary task 的 complexity 高于 primary task。
- 假设 primary 和 auxiliary task 是在同一个 domain,那么 primary task 的最终 performance 只依赖于 complexity 最高的 auxiliary task。