李鹏伟的技术博客

  • 首页

  • 分类

  • 归档

  • 关于

RNN应用之Seq2Seq和Attention

发表于 2018-08-05 | 更新于 2018-08-11

序列到序列模型(Seq2Seq)

RNN是一种处理序列数据的神经网络,输入是序列,输出也是序列,所有有人就提出了基于Encoder到Decoder的模型结构来处理序列到序列的应用。最基础的Seq2Seq模型包含了三个部分,即Encoder、Decoder以及连接两者的中间状态向量,Encoder通过学习输入,将其编码成一个固定大小的状态向量S,继而将S传递给Decoder,Decoder再通过对状态向量S的学习来进行输出。以下介绍两种Seq2Seq的模型结构。

1. Seq-to-Seq框架1

该模型来自于论文Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation,其结构图: seq2seq1 Encoder阶段将整个source序列编码成一个固定维度的向量C(也就是RNN最终隐层状态),计算公式: $$C=\tanh(Vh^N)$$ V表示权重矩阵, $h^N$ 表示Encoder阶段最后一个输入的隐层状态(也可以理解为整个序列的编码记忆)。


Decoder也是一个RNN网络, $C$ 作为初始化隐层状态传入(理解为将Encoder序列解码),其隐层状态 $h$ 的计算公式: $$h_t = f(h_{t-1}, y_{t-1}, C)$$ 其中 $h_{t-1}$ 和 $y_{t-1}$ 表示前一时刻隐层值和输出值,而 $y_t$ 的结果就和普通神经网络结果一样,在RNN后面接入fc层和softmax层,求最大概率。

2. Seq2Seq框架2

该模型来自于论文Sequence to Sequence Learning with Neural Networks,其模型结构: seq2seq2 与上一模型不同的是,其source编码后的向量C直接作为Decoder阶段RNN的初始化state,而不是在每次Decoder时都作为RNN的输入,此外,Decoder训练时RNN的输入是target(目标值),而不是前一时刻的输出,训练示意图 seq_train 解码示意图 seq_test

3. Seq2Seq实战

利用TensorFlow来构建一个基础的Seq2Seq模型,通过向我们的模型输入一个单词(字母序列),例如apple,模型将按照字母顺序排序输出,即输出aelpp。 数据集包括source和target,共10000条: 数据集 开发步骤:

  • target数据处理,结果为[GO, x, y, z, EOS, PAD],当然输入不能为字符,所以我们需要建立一个ch2idx和idx3ch的关系
  • gen_batch,一般我们都是一个batch这样一起训练
  • 构建Encoder网络
  • 构建Decoder网络(其中包含train和test的不同结构)
  • 连接Encoder和Decoder,组成Seq2Seq模型
  • Running和predicting

解释一下Seq2Seq框架2中加GO,EOS和PAD的原因,其目的就是告诉Decoder什么时候开始,什么时候结束,真正训练的时候,EOS并没有作为输入传递给RNN,因此我们需要将target中最后一个字符(EOS)去掉,同时还需要再前面加上开始标识(GO)。因为我们是batch一起训练,动态RNN展开,每一个batch需要固定序列长度,所以我们要加PAD。

4. 源码

该实验是用jupyter实现的,python3.6,tenserflow1.8

  • 参考这篇专栏
  • Github源码

Attention

1. Seq2Seq思考

  • Encoder将输入编码为固定大小状态向量,是一个”信息有损压缩“的过程, 信息量越大,那么损失的信息就越多。
  • 随着sequence length的增加,意味着时间维度上的序列很长,RNN模型 会出现梯度弥散
  • 基础的模型连接Encoder和Decoder模块的组件仅仅是一个固定大小的状 态向量,Decoder无法直接去关注到输入信息的更多细节

既然Seq2Seq有这些劣势,那么要如何解决呢,答案就是Attention。


2. 什么叫注意力机制(Attention-based mechanism)?

注意到Decoder设计中,各个时刻都使用相同的记忆C,我们自然想到了可以在不同的时刻采用不同的记忆C,结构如下 attention 以下介绍两种简单的Attention结构。

3. Attention结构1

该模型来自于论文 Neural Machine Translation by Jointly Learning to Align and Translate,其模型结构如下 att1 Attention是为了得到不同时刻的C,那么我们从公式角度来看不同时刻C的计算过程: att2 解释如下: $h_j$ 表示的是Encoder的隐层记忆, $s_i$表示Decoder结构中 $i$ 时刻的隐层记忆。公式从下往上看

  • $s_i$ 是由 $s_{i-1}, y_{i-1}, c_i$ 三个值计算出来,分别表示Decoder上一时刻隐层记忆、输出和当前时刻的记忆
  • 计算 $c_i$ 需要计算 $\alpha_{ij}$ 和 $e_{ij}$
  • $e_{ij}$ 通过 $s_{i-s}, h_j$ 计算得来,那么计算方法 $a$ 可以用一个小型的神经网络来逼近
  • 计算 $\alpha_{ij}$ 可以用一个类似softmax的方法用 $e_{ij}$ 计算得来

通过这种计算,在Decoder过程中,每个时刻的 $s_i$ 都可以计算出对应的 $c_i$ ,训练和预测的方法和Seq2Seq的方式一样。

4. Attention结构2

该模型来自于论文 Effective Approaches to Attention-based Neural Machine Translation,结构如图 attention2 模型公式如下: att_ex 公式解释:同样是要 $c_t$ ,只是计算方式不同,这里指的是 $score$ 这个函数,一般有三种计算方式,论文指出general的方式取得了比较好的结果,看公式: $$socre(h_t, \bar h_s) = h_t^{\top} W_a \bar h_s$$ 表示的是Decoder的隐层记忆 $h_t^{\top}$ 与 Encoder的隐层记忆 $\bar h_s$ 通过一个注意力权重 $W_a$ 连起来,表示从target到source的映射关系,这个权重可以在训练过程中学习得到。

5、加入Attention的Seq2Seq如何实现?

Tensorflow提供了很多种Attention的API,这里我们使用第二种Attention的方式,官方示例如下: code_att1 接入Decoder的解码过程 code_att2 模型实现示例图 exam_att 结果 res_att 预测 pre_att

6、源码

加入Attention的实现是在基础Seq2Seq上改进得来,也是jupyter版本。

  • Github源码

总结

  • 加入Attention的seq2seq有很多应用场景,在翻译领域取得了较好结果
  • Attention的变形有很多,需要进一步研究
  • Attention的一个最要优点就是可视化注意力权重,这里没用做

参考资料

  • Seq2seq模型及注意力机制
  • Tensorflow官方机器翻译模型
  • 《attention is all you need》解读

CNN多标签分类实战

发表于 2018-08-03

图像分类已经领域,深度学习方法已经超越了人类,其中google公开的Inception模型在图像分类大赛上取得了比人类识别还要低的错误率。研究已经成功的模型对我们学习也有很大的帮助,今天我们使用Inception模型作为预训练,我做我们的多便签图片分类任务。

Inception模型

获得高质量模型最保险的做法是增加模型深度或者是其宽度,但是会出现很多缺陷:参数过多,过拟合,计算复杂度高,梯度易消失,难以优化。Inception架构的主要思想是找出如何用密集成分来近似最优的局部稀疏连接 Inception 对图加以说明:

  • 采用不同大小的卷积核,意味着不同大小的感受野,最后意味着不同尺度特征的融合
  • 之所以卷积核大小采用11,33,5*5,主要是为了方便对齐,设定stride=1之后,只要分别设定padding=0、1、2,采用same卷积可以得到相同维度的特征,然后拼接在一起
  • 文章说pooling层很有效,所以Inception里面加了pooling
  • 网络越到后面越抽象,感受野也更大,所以33,55卷积的比例也要增加

Inception的作用:代替人工确定卷积层中过滤器类型或者确定是否需要创建卷积层和池化层,都由网络自行决定,自己学习参数。

Inception的缺陷:计算成本高,使用55的卷积核仍然会带来巨大的计算量,约需要1.2亿次的计算量 inception2 为了减少计算成本,采用11卷积核来进行降维,如图 inception3 在33和55的过滤器前面、max pooling后分别加上11的卷积核,最后将他们全部以通道/厚度 为轴拼接起来,最终输出大小是2828*256,卷积的参数比原来少了4倍,得到最终的Inception模块: inception4

GoogLeNet介绍

1.googLeNet----Inception V1结构

inception5 对图做如下说明:

  • 采用了9个Inception模块化结构,共计22层,方便增添修改
  • 网络层最后采用了average pooling来替代全连接层
  • 虽然移除了全连接层,但是网络中依然使用了dropout
  • 为了避免梯度消失,网络增加了2个辅助的softmax用于向前传导梯度,文章说这两个辅助的分类器loss应该加一个衰减系数,此外,实际测试的时候,这两个额外的softmax会被去掉

2.Inception V2结构

大尺寸的卷积核可以带来更大的感受野,也意味着更多的参数,比如5*5卷积核参数是3*3卷积核的25/9=2.78倍。为此,作者提出了2个连续的3*3卷积层(stride=1)组成的小网络来代替单个5*5卷积层,这就是Inception V2结构。保持感受野范围的同时又减少了参数量(25/18)。 inception6 其实V2结构主要是学习了VGG的结构,用两个3*3的卷积代替5*5的大卷积(降低参数并减轻过拟合),还提出了著名了Batch Normalization(BN)方法。使得Inception V2在训练达到Inception V1的准确率时快了14倍,并且模型在收敛时的准确率上限更高。

3.Inception V3结构

大卷积核完全可以由一系列的3*3卷积核来替代,那能不能分解的更小一点呢,V3考虑n*1卷积核,于是,任意n*n的卷积都可以通过1*n卷积后接n*1卷积来替代,实际上,作者发现在网络前期使用这种分解效果并不好,在有中度大小的feature map上使用效果才好,所以中度大小的feature map的大小最好在12-20之间。 inception7 Inception V3主要在两方面做了改进,一是引入了Factorization into small convolutions的思想,将一个较大的二维卷积拆成两个较小的一维卷积。令一方面,Inception V3 优化了 Inception Module 的结构,现在 Inception Module 有35*35、17*17和8*8三种不同结构。这些 Inception Module 只在网络的后部出现,前部还是普通的卷积层。并且 Inception V3 除了在 Inception Module 中使用分支,还在分支中使用了分支(8*8的结构中),可以说是Network In Network In Network。最终取得 top-5 错误率 3.5%。

4.Inception V4

Inception V4 相比 V3 主要是结合了微软的 ResNet,将错误率进一步减少到 3.08%。

深度残差网络。如果深层网络的后面那些层是恒等映射,那么模型就退化为一个浅层网络。那当前要解决的就是学习恒等映射函数了。但是直接让一些层去拟合一个潜在的恒等映射函数 $ H(x) = x $,比较困难,这可能就是深层网络难以训练的原因,但是如果把网络设计为 $ H(x) = F(x) + x $。 resNet 如图,我们可以转换为学习一个残差函数 $ F(x) = H(x) - x $,只要 $ F(x) = 0 $,就构成一个恒等映射 $ H(x) = x $。而且你和残差肯定更容易。 inception_4

多标签分类

1.数据集

数据集采用南京大学开源的数据集(http://lamda.nju.edu.cn/files/miml-image-data.rar),数据集中包含2000张图像,5类,分别为desert、mountains, sea, sunset,trees,每张图片有一个或多个标签。

2.数据处理

  • 输入: image(299*299*3) - label (ont-hot [0,1,0,0,1])
  • 拆分为 train_data, test_data, train_label, test_label
  • batch生成器,一次获取一个batch的数据

3.网络结构

我们使用Inception V3已经训练好的参数来做迁移训练 迁移训练 所有图片经过Inception V3结构,得到中间结果的2048个特征值,然后接自己设计的网络结构做图像5分类任务。网络结构如下图: mu_label1

4.损失函数

不像单分类任务,使用softmax交叉熵,这里是多标签任务,我们需要使用sigmoid交叉熵作为loss函数。原因请参考这篇:机器学习之loss

5.结果

结果

6.tensorboad

loss graph

7.代码

代码已经上传到github。 源代码

参考资料

  • 官方retrain
  • 深度学习卷积神经网络——经典网络GoogLeNet(Inception V3)网络的搭建与实现
  • CNN卷积神经网络_ GoogLeNet 之 Inception(V1-V4)
123…6

李鹏伟

AI

12 日志
1 分类
11 标签
© 2018 李鹏伟
由 Hexo 强力驱动 v3.7.1
|
主题 — NexT.Muse v6.3.0