#! https://zhuanlan.zhihu.com/p/126665487
- 本文代码:https://github.com/sgrvinod/a-PyTorch-Tutorial-to-Image-Captioning
作为image caption领域的代表作,本文提出了将attention机制对应用于image caption的encoder-decoder结构进行了改进。
![v2-3d929d6e2675d36392344ffc31444279_b.png](http://img-02.proxy.5ce.com/view/image?&type=2&guid=8bdea32f-be2f-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-3d929d6e2675d36392344ffc31444279_b.png)
如上图所示,模型的输入是一张图像,输出是对图像的文本描述(caption)。输入的图像通过CNN(Encoder)获得图像的特征,该特征通过添加了attention的LSTM并最终获得每个时间帧上预测的单词。
Encoder
![v2-556e24a98cc23c3c37bceaafe99d8143_b.png](http://img-01.proxy.5ce.com/view/image?&type=2&guid=8bdea32f-be2f-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-556e24a98cc23c3c37bceaafe99d8143_b.png)
我们可以用Pre-trained的CNNs作为Encoder提取图像特征。以ResNet101为例,其最后一层卷积层输出的特征大小为
encoder_out
Decoder
Decoder以图像特征作为输入,输出相应的文本描述。对于不采用attention的情况,可以简单地将上述图像特征进行全局池化,得到2048-d的图像向量,并以该向量(可以再通过一层全连接层作为transformer)作为RNN的第一个hidden state输入encoder.每次预测得到的单词可用于预测下一个单词,其过程如下所示:
![v2-83944ce24246df1e983ee943ab35cac9_b.png](http://img-01.proxy.5ce.com/view/image?&type=2&guid=8bdea32f-be2f-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-83944ce24246df1e983ee943ab35cac9_b.png)
具体地,每个LSTM单元的计算情况如下图所示:
![v2-d24374d0745456f0bc7fcb36e5eccc26_b.png](http://img-03.proxy.5ce.com/view/image?&type=2&guid=8bdea32f-be2f-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-d24374d0745456f0bc7fcb36e5eccc26_b.png)
其中
而本文的核心内容在于希望Decoder在预测不同单词时能够通过attention机制关注图像的不同区域。比如,在预测“a man holds a football”中的“football”时,我们希望decoder能够关注图像中的“football”区域。为了实现该目的,我们通过attention获取加权的图像向量,而非像之前的简单全局平均池化。利用该加权的图像向量与上一个预测的单词向量拼合来预测下一个单词。相关示意图如下所示:
![v2-c59179747e2d203f9c1edea10a833b7d_b.png](http://img-01.proxy.5ce.com/view/image?&type=2&guid=8bdea32f-be2f-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-c59179747e2d203f9c1edea10a833b7d_b.png)
具体地,内容向量不再是图像的特征平均后的全局特征向量,而是在不同位置上根据上一层的隐藏状态得到的加权向量。我们用
在得到权重后,每个时刻加权的图像特征向量可由下式得到:
相关的attention机制实现代码如下:
class
至此,整个encoder-decoder结构可表示为:
![v2-d9b60bea393dcf5e123bfa04f7dd8bc8_b.png](http://img-01.proxy.5ce.com/view/image?&type=2&guid=8bdea32f-be2f-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-d9b60bea393dcf5e123bfa04f7dd8bc8_b.png)
scores
Decoder的代码实现:
class
关于pytorch中的nn.LSTM和nn.LSTMCell可参考 https://blog.csdn.net/SHU15121856/article/details/104448734
前者可以一次构造多层LSTM,构造时需要定义的参数包括
而上边代码中所采用的nn.LSTMCell则是构建LSTM中的一个Cell,同一层会共享这个Cell,需要手动处理每个时刻的迭代计算过程。如果需要建立多层的LSTM,就要建立多个nn.LSTMCell。其forward的过程如下:
此处的
Xu, Kelvin, et al. “Show, attend and tell: Neural image caption generation with visual attention.” arXiv preprint arXiv:1502.03044 (2015).