最后更新于
最后更新于
也是一种Metric-based模型. 孪生模型(Siamese Neural Network)在训练和测试的时候使用的样本是以对pair的形式, 判断两张图片, 两句短文本等等是不是属于同一样本. 使用pair这种形式天生的劣势, 在训练和测试时, 如何合适的构造样本都是需要一定的策略的. 例如在训练时相同分类和不同分类的样本比例应为1:1等等.
而Matching Network使用了不同的逻辑, 它的训练和测试样本不再是一对对图片, 文本, 而是如同普通模型一样使用单个样本. 当然在One-shot任务中, 还是要分为support set和batch set的, 只不过set中的每个样本不再是一对图片, 而是一张图片.
Matching Network是一个端到端的模型. 它的结构设计处于以下考虑:
在判断新图片的分类时(上图右侧单图), 能够充分使用support set(上图左侧四图)中的信息. 具体来说是将新图的类别结果来源于support set中的样本标签. 这在Siamese Neural Network中是不存在
新图的标签预测类似于Nearest Neighbors或KDE机制, 比较与support set中样本的近似程度, 通过一定的策略/规则(如相似度加权)从supprot set中的标签, 得到预测标签. 这种类似于Nearest Neighbors或KDE的方法是non-parametric的
对于新的之前从未观测到的类别, 可以直接使用模型在这些类别上进行预测得到高质量的结果, 而且不用对训练好的模型做任何操作
先从模型的最后部分, 如何得到预测样本的类别来看.
这种机制在文中被称为使用了attention mechanism
, 实质上是将support set中的每个样本的表征向量依次与待预测样本的表征向量点积, 然后使用softmax函数进行归一化, 使用这个归一化的权重值, 对support set中所有样本的标签进行加权, 得到预测样本在support set包含的所有类别上的概率值.
这里求取test样本的类别使用了attention mechanism
完成了类似于KDE的效果. 这种方法充分里使用support set中的信息. 相比而言, 以下常用的方法都有着明显的缺点:
最邻近: 也是依次计算test和support set中每个样本的相似度, 然后选择最相似的样本, 以这个样本的类别作为test样本的预测类别
最终只使用了support set中一个样本的信息, 丢弃了大量信息
这种方法类似于kNN(k Nearest Neighbors)机制
这是论文中比较重要的一部分, 但在实际使用中可以选择性使用. 这一章节的目的是使用不同的方法, 分别对test和support set中的样本进行更好的表征, 充分利用support set中的信息. 当然如果不使用本章节的结构, 直接使用神经网络表征器(test, support set共享一套参数)也是可以的.
分别来说.
需要注意:
得到这一步LSTM隐向量之后, 这一步的最终输出如下表示:
首先是计算test样本与support set样本中每个样本的相似度:
这里使用了one-sided cosine similarity.(but why?)
对于包含个样本的support set, 将一个样本的(image, labal)对记为. 对于新的预测样本, 希望得到高质量的预测.
训练好的模型既是一个映射函数, 可以看到样本的预测结果是和support set 紧密相关的, 因此可以将模型记为. 因此test样本的预测类别为:
对于test样本, 使用attention思想去计算它的预测类别:
测试样本与support set中每个样本的注意力计算方法如下, 其中为余弦距离, 而和分别是对test和support表征的函数, 简单来说可以是一些图像或者文本的表征神经网络, 输出表征向量:
在目前为止的框架中, 我们使用和对test和support set中的样本进行embedding, 然后使用attend
, point
, knn
等形式得到对test的类别预测. 这样的形式有两个不足:
support set中的每个样本是相互独立的, 得到embedding向量的过程也是相互独立的, 互相之间不影响
test样本也是用过来得到embedding向量的, 而且现在的和使用的是同样的抽取器. 但由于的类别是由support set中的样本决定的, 那么的embedding向量的抽取, support set也应当参与进来
因此使用Full Context Embeddings这种思想的引领下, 希望对support set中的每个样本以及test样本的样本的embedding, 都应该受到整个support set 的影响.
对于support set中的样本, 它的embedding向量就由变为了. 至于为什么这么做, 作者是这样解释的:
This could be useful when some element is very close to , in which case it may be beneficial to change the function with which we embed .
如何做到整个support set 去影响样本的表征过程呢? 论文中使用了bi-LSTM去对进行编码. 使用这种方法, 就需要把support set中的所有样本考虑成一个序列, 一个一个进行输入, 依次得到每个样本的的表征向量.
这里就产生了一个新的问题, 原来support set中无序的样本, 如何合理的进行排序. 文章参考了这篇论文中的方法.
具体来说, 将原来的表征器得到表征向量(样本之间相互独立)重新记为, 样本新的表征为:
即原始表征向量和bi-LSTM对应输入位置的隐向量的加和:
本质上相当于使用bi-LSTM结构对support set中的样本序列进行表征, 但添加了一个skip connection结构, 即最后加上的, 加快了训练的速度和鲁棒性.
对于test样本, 这里也使用一种带attention的LSMT结构进行表征, 注意这里的LSTM与上面对support set中样本表征使用的是不同的网络(单向, 双向就能体现出来), 由于这里的表征也使用到了整个support set, 因此将新的表征向量记为:
其中是原始的表征器对test样本的表征向量. 是固定的数值, 代表这里LSTM推进的步数. 是一个集合, 包含了support set中每个样本的表征向量(full content embeddings得到的).
具体来说, 在执行到第步时, 使用如下的方式得到这一步的隐向量:
无论在哪一步, 输入都是固定的, 即原始的test样本的表征向量
这里使用的LSTM中的隐向量是和拼接得到的. 因此长度是输入表征向量的两倍, 对输出的维度没有影响
至此, 得隐向量还都是只与test样本相关的, 没有引入support set的作用. 而我们需要通过引入support set中的信息. 为此, 在这一步得到隐向量之后, 计算这个隐向量与support set中所有样本的的表征向量的关系, 这一步也称为计算content based attention.
然后使用这个attention值作为权重, 对support set中所有的表征向量进行加权求和, 得到.
然后再将这个向量与计算得到的这一步的隐向量拼接起来, 作为当前LSTM网络的隐向量, 继续下一步的执行.
因为这里的LSTM要执行步, 就取最后一步的输出, 作为最终对test样本的表征向量.
既是模型中需要训练的参数. 作为一种meta-learning模型, 首先从task中抽样一次episode(meta-learning中一次训练, 即support set + batch set)所需要的label set , 然后再从每个抽取到的label对应的样本集中, 抽取一定的样本, 从而组成了n-way k-shot的训练方法.
需要注意的是, 如果用来测试的与用来训练的差距很大(例如判断动物类别和检测检测人脸)的话, 得到的结果也是不准确的.
代码参考repository: . model.py
中定义了Matching Networks, main.py
中包含了数据集划分为train和test集合的方法, 以及整个训练的过程. 下面是一些需要注意的细节, 帮助更好的理解模型.