论文阅读之“YouTube-8M: A Large-Scale Video Classification Benchmark”

  对视频的分析,我之前是从没有学过,这篇论文算是我对短视频分析的入门,收获也是非常多的。论文主要讲了如何为短视频建立模型并分类,大致的思路就是
对视频提帧\longrightarrow将帧数据传到训练好的网络中提取帧特征\longrightarrow\\对帧特征进行降维得到视频特征\longrightarrow将视频特征传到分类网络中得到最终的结果
  这里面的关键就在于第三步——如何对帧特征进行降维得到视频特征?如何降维才能保证信息丢失的最小化?这篇文章提出了两类方法,一类是非deep的方法,一类是deep的方法。

非deep的方法

  非deep的方法,说白了就是降维过程中没有建立DNN,直接用传统的方法解决。我认为这类方法的优势就在于容易理解并实现,泛化能力相对更高。具体实现步骤是:

  1. 假设帧数据经过神经网络(去掉最后的输出层)提取特征后得到一个D维的向量,那么一个视频最终就可以用一个的2维矩阵表示。但是不同的视频提取的帧数量也不一样,为了保证最终每个视频的表示形式一致,就需要对2维矩阵进行处理。
  2. 对2维矩阵提取1阶,2阶和序号统计信息。1阶信息指矩阵在列上的均值,最终得到一个D维的向量;2阶信息指矩阵在列上的方差,也得到一个D维的向量;序号信息指矩阵在列上的前K大的值,最终得到了一个的2维矩阵。将这3种统计特征在列上拼接起来就得到一个新的定长矩阵(维度是),这样一个变长的视频特征矩阵就转换成了定长的统计特征矩阵。统计特征矩阵具体形式如下:
  3. 最后,利用PCA+Whitening对统计特征矩阵进行进一步的降维,最终得到一个D维向量作为视频的表示。

  在实现过程中,我发现在实现第3步时出了点问题。这里我记录下遇到的坑和解决方法。PCA的处理我选择了使用sklearn中的PCA函数,sklearn中要求输入是一个矩阵,每一行的向量代表一个样本,但是这里每个视频对应的统计特征矩阵却是2维矩阵,我的思路就是将矩阵进行平铺得到一个维的向量。这只是一个小的问题,另外一个大的问题在于如何训练这个PCA模型。每个视频对应的表示向量的维度是很大的(),如果将训练集中所有视频对应的表示向量拼接起来,那么这个需要训练的矩阵将会巨大无比,计算机是没法存入这样一个巨大的矩阵的。那么这里我通过查找API,发现了sklearn的PCA类中有一个IncrementalPCA类,专门用来处理这种情况的。IncrementalPCA的优势在于可以迭代式训练,每次只需要传入一个batch的样本进行训练即可。使用IncrementalPCA的另外一个好处在于可以使得模型进行online learning。以后若是有新的视频数据传入,只需要对PCA模型进行迭代式训练即可。

deep的方法

  deep的方法说白了就是模型中加入了DNN,所以对数据的表达能力更强。论文中主要提出两个deep的思路。一个是Deep Bag of Frame (DBoF) Pooling,另一个就是LSTM。
  DBoF其实是借鉴了自然语言处理中的BOW的思想,可以理解为将多个帧特征合成为一个视频特征,最简单的合成方式自然是在列上相加。这里使用了deep的思想,其实就是利用DNN将帧特征映射到更高维度的空间中,在该高维空间中对帧特征进行求和,然后再利用DNN将高维特征映射回低维空间中,方便后面进行分类。这个降维的过程是可学习的过程,我将其理解为deep的思想。其实既然提到了BOW,那么另外两种方法FV和VLAD就也可以扩展到这里来,具体关于FV和VLAD的讲解在我另外的文章中,这里就只是提一下。
  LSTM就更好理解了,不断传入帧数据,用最后的LSTM状态向量来作为视频的表示向量即可。
TODO:这两种方法我都还没实现,等实现了再回来写遇到的问题。

分类网络MoE

  最后我想记录下论文中用到的分类网络MoE(Mixture of Expert,多专家模型)。这个模型其实早在上世纪90年代就提出了,具体结构如下图所示:
双层MoE网络结构.png

我们单看框中的结构(一个框代表了一个单层MoE网络结构),其实单层MoE可以看做是多个模型的加权bagging。输入数据x传到多个专家模型中,每个专家模型都可以得到一个预测结果;同时,将x传到一个门网络中为每个专家模型生成一个权重向量;最后,将预测结果和对应权重向量相乘求和得到最终的预测结果。其实,这个就跟周志华老师的西瓜书中183页提到的加权投票法的思想很像,当然啦,MoE模型的提出可比西瓜书早太多了。论文源码中的MoE实现如下:

gate_activations = slim.fully_connected(model_input, vocab_size * (num_mixtures + 1))
expert_activations = slim.fully_connected(model_input, vocab_size * num_mixtures)
gating_distribution = tf.nn.softmax(tf.reshape(gate_activations, [-1, num_mixtures + 1]))
expert_distribution = tf.nn.sigmoid(tf.reshape(expert_activations, [-1, num_mixtures]))
final_probabilities_by_class_and_batch = tf.reduce_sum(gating_distribution[:, :num_mixtures] * expert_distribution, 1)

我根据代码理解的MoE流程图如下:
MoE具体实现流程图.jpg

你可能感兴趣的:(论文阅读之“YouTube-8M: A Large-Scale Video Classification Benchmark”)