本文地址:http://blog.csdn.net/mounty_fsc/article/details/53114698
本文内容:
涉及LSTM算法原理的部分可以参考其他文章见如 理解 LSTM 网络等。
LSTM为处理具有时间维度以及类似时间维度信息的RNN深度神经网络的一种改进模型,参考文献[1,2],在不少问题上能弥补CNN只能处理空间维度信息的缺陷。不同于CNN的深度体现在网络层数及参数规模上,RNN/LSTM的深度主要体现在时间节点上的深度。
Caffe中的LSTM相关代码由Jeff Donahue基于文献[1]的实验Merge而来。文献[3]中有三个关于使用LSTM的实验:(1)行为识别(介绍及代码) (2)图像描述(图像标注,介绍及代码) (3)视频描述。 三个实验难度依次递增。其中前两个实验代码开源。
本文主要从文献[3]第一个实验出发,介绍LSTM的接口的使用。
实验使用UCF-101 数据集。行为识别实验目的为给定一视频片段,判断出视频片段人物的行为。
如1.1图所示,该实验的方法为:
N 为LSTM同时处理的独立流的个数,在该实验中为输入LSTM相互独立的视频的个数,以该实验测试网络为例,本文取 T=3 。
T 为LSTM网络层处理的时间步总数,在该实验中为输入LSTM的任意一独立视频的视频帧个数,以该实验测试网络为例,本文取 T=16 。
因此fc-reshape层输出维度为 T×N×4096 . 4096为AlexNet中全连接层的维度,即CNN特征的维度。
reshape-cm的输出维度为 T×N ,即每一个帧有一个是否连续帧的标志。
reshape-label的维度同样为 T×N
主要类说明见官方文档 RecurrentLayer、LSTMLayer、LSTMUnitLayer。
其中:
由官方文档可知,一个 RecurrentLayer/LSTMLayer 的输入为三个Blob:
Caffe中通过展开LSTMLayer网络层,得到另一个网络从而实现LSTM,即一个LSTMLayer即为一个LSTM网络。以实验中测试网络为例,及 T=16,N=3 ,CNN特征维度为4096,LSTM特征维度为256,来介绍展开网络的各网络层及数据流动情况。
如图所示:
计算公式如下:
注意:
一个RNN/LSTM网络层可以通过从时间维度上进行展开来进行理解( 理解 LSTM 网络)。同样的,Caffe在实现LSTM时也是通过展开LSTM层来实现,等价于一个LSTM 网络层 即为一个LSTM 网络。
实验使用coco caption数据集。给定一张图片,其目标为产生一段语句对该图片进行描述。
这部分实验属于图像描述的基础实验。图像描述在该实验基础上拓展而来,且相对图像描述来说更为简单,因而先介绍该小实验。
语言模型实验为训练一个语言模型,使其能够完成:
(1)给定一个词,如some,该模型能产生下人类语言中能搭配该词的下一个次,如some people, some apple。
(2)在(1)的基础上,该模型能产生一个完整的语句。
链接处为作者给出的该模型的实例与教程。
该模型的训练过程与行为检测的训练过程类似。如图所示,LSTM层的输入为两个Blob:
(1)训练数据Blob,维度为 T×N×1000 ,其中1000为每个词的特征,即语言模型的训练数据中,一个词对应于行为识别中的一张图片(行为识别的训练数据维度为 T×N×4096 )。
注意,此处说的维度为embedded_input_sentence
的维度。而输入数据的input_sentence
的维度为 T×N×8801 , 8801 为词典(词库)的规模 N ,即输入数据为该词在该词典中的独热向量(one-hot vector) y˜,y˜∈R8801 。该独热向量通过权重层Embed层产生一个 1000 维的特征向量 y,y∈R1000 。该Embed层等价于实现 y=Wey˜,We∈R1000×8801 。由于 y˜ 为独热向量,所以也可以理解为 We 为一个查找表,每一列为一个词的特征向量。
(2)连续性标志Blob。与行为识别类似,维度为 T×N
该模型的产生一个完整句子的过程推理如下图所示。
说明:
1. 生成一个完整的句子需要反复多次调用该语言模型,即前一次的结果作为下一次的输入,直至最后的输出为语句终止符EOS
2. 推理时的输入LSTM维度为 1×N×1000 ,如果是只产生单个语句,则为 1×1×1000
不同于行为识别实验以及语言模型小实验,图像描述实验的LSTM层使用了第三个输入参数,静态输入 xstatic 。有 xstatic LSTM层的训练模型如下图所示:
注意:
图像描述实验是在语言描述实验的基础上,增加图像的CNN特征作为LSTM的静态输入特征。
文献[1]提出三个组合方式,如下图所示:
1)第一种为一层LSTM,为最朴素的方法。
2)第二种为两层LSTM,静态输入在第一个LSTM层。
3)第三种为两层LSTM,静态输入在第二个LSTM层。最后取的是该种方法。
[1] Hochreiter, Sepp, and Schmidhuber, Jürgen. “Long short-term memory.” Neural Computation 9, no. 8 (1997): 1735-1780.
[2] Zaremba, Wojciech, and Sutskever, Ilya. “Learning to execute.” arXiv preprint arXiv:1410.4615 (2014).
[3] Donahue, J., et al. “Long-term recurrent convolutional networks for visual recognition and description.” Computer Vision and Pattern Recognition IEEE, 2015.
另外,对于caffe中lstmlayer的理解,可以参考一下:
You are understanding the role of N_ and T_ correctly.
There are one general solution and another solution for some cases:
Use N_=1 and clip appropriately as you said.
This is actually very inefficient because the model cannot process different streams in parallel.
If you are using softmax loss
as loss function, you can put 5 videos with different frames into streams (N=5) by fixing T as the maximum length (say T=100) and filling extra input frames with zeros (x_99=0, x_100=0 for 98-length video).
In order to remove unnecessary losses caused by extra frames, you can specify ignore_label: -1
in theloss_param
and provide -1 as labels for the extra time steps.
This will set loss/gradient to 0 for the extra time steps.
I think Caffe should support a mask indicator for all loss layers so that we can selectively ignore losses for specific examples/time steps.
I have a question about caffe-lstm.
There are members N_ and T_ in class LstmLayer ( I found default value of N_ is 1 ) and their comments are batch size and length of sequence. I am not sure if that means: there are N_ independent sequences and each one of them has T_ frames. For example, If I have 5 videos and each one has 100 frames. I must set N_ = 5 and T_ = 100. Like this, if I have only one video with 100 frames, I must set N_ = 1 and T_ = 100.
But if I have 5 videos with different frames, say, video1 has 100 frames, video2 has 90 frames, videos3 has 96 frames, video4 has 88 frames, video5 has 99 frames, I feel N_ must be set 1 and use 'clip' to solve this training. If N_ is not 1, there is no solution.
Above is my understand about the members in LstmLayer class. Could you tell me if that is right? Thanks!