提交 e6aa2ba9 编写于 作者: Y Youwei Song 提交者: hong

Refine cn layers: dynamic_lstm, dynamic_lstmp, lstm (#1452)

* refine lstm

* refine LSTMs, test=develop

* fix notice color, test=develop
上级 d7f3538b
......@@ -5,88 +5,87 @@ dynamic_lstm
.. py:function:: paddle.fluid.layers.dynamic_lstm(input, size, h_0=None, c_0=None, param_attr=None, bias_attr=None, use_peepholes=True, is_reverse=False, gate_activation='sigmoid', cell_activation='tanh', candidate_activation='tanh', dtype='float32', name=None)
LSTM,即Long-Short Term Memory(长短期记忆)运算
该OP实现了 LSTM,即 Long-Short Term Memory(长短期记忆)运算 - `Hochreiter, S., & Schmidhuber, J. (1997) <http://deeplearning.cs.cmu.edu/pdfs/Hochreiter97_lstm.pdf>`_
默认实现方式为diagonal/peephole连接(https://arxiv.org/pdf/1402.1128.pdf),公式如下:
.. raw:: html
<style> .red {color:red; font-weight:bold} </style>
.. role:: red
:red:`注意:`
- :red:`该OP仅支持 LoDTensor 作为输入,如果您需要处理的是Tensor,请使用` :ref:`cn_api_fluid_layers_lstm` 。
- :red:`在实现的时候为了提升效率,用户必须将LSTM的输入先进行线性映射,将维度为 [T, hidden_size] 的输入映射为 [T, 4 × hidden_size] 输入,然后再传给该OP。`
该OP的默认实现方式为 diagonal/peephole 连接,参见 `Gers, F. A., & Schmidhuber, J. (2000) <ftp://ftp.idsia.ch/pub/juergen/TimeCount-IJCNN2000.pdf>`_。
如果需要禁用 peephole 连接方法,将 use_peepholes 设为 False 即可。
该OP对于序列中每一个时间步的计算公式如下:
.. math::
i_t=\sigma (W_{ix}x_{t}+W_{ih}h_{t-1}+W_{ic}c_{t-1}+b_i)
.. math::
f_t=\sigma (W_{fx}x_{t}+W_{fh}h_{t-1}+W_{fc}c_{t-1}+b_f)
.. math::
\widetilde{c_t}=act_g(W_{ct}x_{t}+W_{ch}h_{t-1}+b_{c})
o_t=\sigma (W_{ox}x_{t}+W_{oh}h_{t-1}+W_{oc}c_{t-1}+b_o)
.. math::
o_t=\sigma (W_{ox}x_{t}+W_{oh}h_{t-1}+W_{oc}c_{t}+b_o)
\widetilde{c_t}=act_g(W_{ct}x_{t}+W_{ch}h_{t-1}+b_{c})
.. math::
c_t=f_t\odot c_{t-1}+i_t\odot \widetilde{c_t}
.. math::
h_t=o_t\odot act_h(c_t)
W 代表了权重矩阵(weight matrix),例如 :math:`W_{xi}` 是从输入门(input gate)到输入的权重矩阵, :math:`W_{ic}` ,:math:`W_{fc}` , :math:`W_{oc}` 是对角权重矩阵(diagonal weight matrix),用于peephole连接。在此实现方式中,我们使用向量来代表这些对角权重矩阵。
其中:
- :math:`b` 表示bias向量( :math:`b_i` 是输入门的bias向量)
- :math:`σ` 是非线性激励函数(non-linear activations),比如逻辑sigmoid函数
- :math:`i` ,:math:`f` ,:math:`o` 和 :math:`c` 分别为输入门(input gate),遗忘门(forget gate),输出门(output gate),以及神经元激励向量(cell activation vector)这些向量和神经元输出激励向量(cell output activation vector) :math:`h` 有相同的大小。
- :math:`⊙` 意为按元素将两向量相乘
- :math:`act_g` , :math:`act_h` 分别为神经元(cell)输入、输出的激励函数(activation)。常常使用tanh函数。
- :math:`\widetilde{c_t}` 也被称为候选隐藏状态(candidate hidden state)。可根据当前输入和之前的隐藏状态计算而得
将 ``use_peepholes`` 设为False来禁用 peephole 连接方法。 公式等详细信息请参考 http://www.bioinf.jku.at/publications/older/2604.pdf 。
注意, :math:`W_{xi}x_t, W_{xf}x_t, W_{xc}x_t,W_{xo}x_t` 这些在输入 :math:`x_t` 上的操作不包括在此运算中。用户可以在LSTM operator之前选择使用全连接运算。
公式中的概念信息如下:
- :math:`x_{t}` 表示时间步 :math:`t` 的输入
- :math:`h_{t}` 表示时间步 :math:`t` 的 hidden 状态
- :math:`h_{t-1}, c_{t-1}` 分别表示前一个时间步的 hidden 和 cell 状态
- :math:`\widetilde{c_t}` 表示候选的 cell 状态
- :math:`i_t` ,:math:`f_t` 和 :math:`o_t` 分别为 input gate,forget gate,output gate
- :math:`W` 表示 weight (例如, :math:`W_{ix}` 是在计算 input gate :math:`i_t` 时,对输入 :math:`x_{t}` 做线性变换的 weight)
- :math:`b` 表示 bias (例如, :math:`b_{i}` 是 input gate 的 bias)
- :math:`\sigma` 表示 gate 的非线性激活函数,默认为 sigmoid
- :math:`act_g, act_h` 分别表示 cell 输入和 cell 输出的非线性激活函数,默认为 tanh
- :math:`\odot` 表示矩阵的 Hadamard product,即对两个维度相同的矩阵,将相同位置的元素相乘,得到另一个维度相同的矩阵
参数:
- **input** ( :ref:`api_guide_Variable` ) 维度为 :math:`[T, 4*hidden\_size]` 的多维 LoDTensor(必须在传入该OP前对维度为 :math:`[T, hidden\_size]` 的输入经过线性变换得到),其中 T 为 batch 中所有样本的长度之和,hidden_size 为隐层大小,数据类型为 float32 或者 float64。
- **size** (int) – 必须为 4*hidden_size。
- **h_0** ( :ref:`api_guide_Variable` ,可选) 维度为 :math:`[batch\_size, hidden\_size]` 的多维 Tensor,其中 hidden_size 为隐层大小,数据类型为 float32 或者 float64。如果为 None,该OP会自动设置为全0的向量。默认值为None。
- **c_0** ( :ref:`api_guide_Variable` ,可选) 维度为 :math:`[batch\_size, hidden\_size]` 的多维 Tensor,其中 hidden_size 为隐层大小,数据类型为 float32 或者 float64。如果为 None,该OP会自动设置为全0的向量;:math:`h_0, c_0` 如果要设置为None,必须同时为None。默认值为None。
- **param_attr** (ParamAttr,可选) – 指定权重参数属性的对象。如果为None,表示使用默认的权重参数属性。具体用法请参见 :ref:`cn_api_fluid_ParamAttr` 。如果用户需要设置此属性,维度必须等于 :math:`[hidden\_size, 4*hidden\_size]`。默认值为None。
- **bias_attr** (ParamAttr,可选) – 指定偏置参数属性的对象。如果为None,表示使用默认的偏置参数属性。具体用法请参见 :ref:`cn_api_fluid_ParamAttr` 。如果用户需要设置此属性,如果 use_peepholes=true,维度需为 :math:`[1, 4*hidden\_size]`, use_peepholes=true,维度需为 :math:`[1, 7*hidden\_size]`。默认值为None。
- **use_peepholes** (bool,可选) – 是否使用 peephole 连接。默认值为True。
- **is_reverse** (bool,可选) – 是否将输入的数据根据根据样本长度进行逆序,同时会将输出进行逆序,用户拿到结果之后,不需要再逆序。默认值为False。
- **gate_activation** (str,可选) – 应用于input gate,forget gate, output gate 的激活函数。默认值为sigmoid。
- **cell_activation** (str,可选) – 用于cell输入的激活函数。默认值为tanh。
- **candidate_activation** (str,可选) – 用于cell输出的激活函数。默认值为tanh。
- **dtype** (str,可选) – 数据类型为 float32 或者 float64。默认值为 float32。
- **name** (str,可选) – 具体用法请参见 :ref:`api_guide_Name` ,默认值为None。
返回:经过lstm运算输出的 hidden 和 cell 的状态的tuple,包括
- hidden:LSTM hidden的输出结果,维度为 :math:`[T, hidden\_size]` 的LoDTensor,且LoD保持与输入一致,数据类型与input一致。
- cell:LSTM cell的输出结果,维度为 :math:`[T, hidden\_size]` 的LoDTensor,且LoD保持与输入一致,数据类型与input一致。
参数:
- **input** (Variable) (LoDTensor) - LodTensor类型,支持variable time length input sequence(时长可变的输入序列)。 该LoDTensor中底层的tensor是一个形为(T X 4D)的矩阵,其中T为此mini-batch上的总共时间步数。D为隐藏层的大小、规模(hidden size)
- **size** (int) – 4 * 隐藏层大小
- **h_0** (Variable) – 最初的隐藏状态(hidden state),可选项。默认值为0。它是一个(N x D)张量,其中N是batch大小,D是隐藏层大小。
- **c_0** (Variable) – 最初的神经元状态(cell state), 可选项。 默认值0。它是一个(N x D)张量, 其中N是batch大小。h_0和c_0仅可以同时为None,不能只其中一个为None。
- **param_attr** (ParamAttr|None) – 可学习的隐藏层权重的参数属性。
注意:
- Weights = :math:`\{W_{ch}, W_{ih}, W_{fh}, W_{oh} \}`
- 形为(D x 4D), 其中D是hidden size(隐藏层规模)
如果它被设为None或者 ``ParamAttr`` 属性之一, dynamic_lstm会创建 ``ParamAttr`` 对象作为param_attr。如果没有对param_attr初始化(即构造函数没有被设置), Xavier会负责初始化参数。默认为None。
- **bias_attr** (ParamAttr|None) – 可学习的bias权重的属性, 包含两部分,input-hidden bias weights(输入隐藏层的bias权重)和 peephole connections weights(peephole连接权重)。如果 ``use_peepholes`` 值为 ``True`` , 则意为使用peephole连接的权重。
另外:
- use_peepholes = False - Biases = :math:`\{ b_c,b_i,b_f,b_o \}` - 形为(1 x 4D)。
- use_peepholes = True - Biases = :math:`\{ b_c,b_i,b_f,b_o,W_{ic},W_{fc},W_{oc} \}` - 形为 (1 x 7D)。
如果它被设为None或 ``ParamAttr`` 的属性之一, ``dynamic_lstm`` 会创建一个 ``ParamAttr`` 对象作为bias_attr。 如果没有对bias_attr初始化(即构造函数没有被设置),bias会被初始化为0。默认值为None。
- **use_peepholes** (bool) – (默认: True) 是否使用diagonal/peephole连接方式
- **is_reverse** (bool) – (默认: False) 是否计算反LSTM(reversed LSTM)
- **gate_activation** (str) – (默认: "sigmoid")应用于input gate(输入门),forget gate(遗忘门)和 output gate(输出门)的激励函数(activation),默认为sigmoid
- **cell_activation** (str) – (默认: tanh)用于神经元输出的激励函数(activation), 默认为tanh
- **candidate_activation** (str) – (默认: tanh)candidate hidden state(候选隐藏状态)的激励函数(activation), 默认为tanh
- **dtype** (str) – 即 Data type(数据类型)。 可以选择 [“float32”, “float64”],默认为“float32”
- **name** (str|None) – 该层的命名,可选项。如果值为None, 将会自动对该层命名
返回:隐藏状态(hidden state),LSTM的神经元状态。两者都是(T x D)形,且LoD保持与输入一致
返回类型: 元组(tuple)
返回类型: tuple( :ref:`api_guide_Variable` , :ref:`api_guide_Variable` )
**代码示例**
.. code-block:: python
import paddle.fluid as fluid
emb_dim = 256
vocab_size = 10000
hidden_dim = 512
data = fluid.layers.data(name='x', shape=[1],
dtype='int32', lod_level=1)
emb = fluid.layers.embedding(input=data, size=[vocab_size, emb_dim], is_sparse=True)
forward_proj = fluid.layers.fc(input=emb, size=hidden_dim * 4,
bias_attr=False)
forward, _ = fluid.layers.dynamic_lstm(
input=forward_proj, size=hidden_dim * 4, use_peepholes=False)
import paddle.fluid as fluid
emb_dim = 256
vocab_size = 10000
hidden_dim = 512
data = fluid.layers.data(name='x', shape=[1], dtype='int32', lod_level=1)
emb = fluid.layers.embedding(input=data, size=[vocab_size, emb_dim], is_sparse=True)
forward_proj = fluid.layers.fc(input=emb, size=hidden_dim * 4, bias_attr=False)
forward, cell = fluid.layers.dynamic_lstm(input=forward_proj, size=hidden_dim * 4, use_peepholes=False)
forward.shape # (-1, 512)
cell.shape # (-1, 512)
......
......@@ -4,101 +4,117 @@ dynamic_lstmp
-------------------------------
.. py:function:: paddle.fluid.layers.dynamic_lstmp(input, size, proj_size, param_attr=None, bias_attr=None, use_peepholes=True, is_reverse=False, gate_activation='sigmoid', cell_activation='tanh', candidate_activation='tanh', proj_activation='tanh', dtype='float32', name=None, h_0=None, c_0=None, cell_clip=None, proj_clip=None)
动态LSTMP层(Dynamic LSTMP Layer)
.. raw:: html
LSTMP层(具有循环映射的LSTM)在LSTM层后有一个分离的映射层,从原始隐藏状态映射到较低维的状态,用来减少参数总数,减少LSTM计算复杂度,特别是输出单元相对较大的情况下。 `Long Short-Term Memory Recurrent Neural Network Architectures for Large Scale Acoustic Modeling <https://research.google.com/pubs/archive/43905.pdf>`_
<style> .red {color:red; font-weight:bold} </style>
公式如下:
.. role:: red
.. math::
:red:`注意:在实现的时候为了提升效率,用户必须将输入先进行线性映射,将维度为 [T, hidden_size] 的输入映射为 [T, 4×hidden_size] 输入,然后再传给该OP。`
i_t & = \sigma(W_{ix}x_{t} + W_{ir}r_{t-1} + W_{ic}c_{t-1} + b_i)\\
f_t & = \sigma(W_{fx}x_{t} + W_{fr}r_{t-1} + W_{fc}c_{t-1} + b_f)\\
\tilde{c_t} & = act_g(W_{cx}x_t + W_{cr}r_{t-1} + b_c)\\
o_t & = \sigma(W_{ox}x_{t} + W_{or}r_{t-1} + W_{oc}c_t + b_o)\\
c_t & = f_t \odot c_{t-1} + i_t \odot \tilde{c_t}\\
h_t & = o_t \odot act_h(c_t)\\
r_t & = \overline{act_h}(W_{rh}h_t)\\
该OP实现了LSTMP(LSTM Projected)层。LSTMP层在LSTM层之后有一个单独的的线性映射层。 -- `Sak, H., Senior, A., & Beaufays, F. (2014) <https://ai.google/research/pubs/pub43905.pdf>`_。
与标准的LSTM层相比,LSTMP多出来的线性映射层,用于从原始隐藏状态 :math:`h_t` 映射到较低维的状态 :math:`r_t`,
从而减少参数总数和计算复杂度,特别是输出单元相对较大的情况下。
在以上公式中:
- :math:`W` : 代表权重矩阵(例如 :math:`W_{xi}` 是输入门道输入的权重矩阵)
- :math:`W_{ic}` , :math:`W_{fc}` , :math:`W_{oc}` : peephole connections的对角权重矩阵。在我们的实现中,外面用向量代表这些对角权重矩阵
- :math:`b` : 代表偏差向量(例如 :math:`b_{i}` 是输入偏差向量)
- :math:`\delta` : 激活函数,比如逻辑回归函数
- :math:`i,f,o` 和 :math:`c` :分别代表输入门,遗忘门,输出门和cell激活函数向量,四者的大小和cell输出激活函数向量 :math:`h` 的四者大小相等
- :math:`h` : 隐藏状态
- :math:`r` : 隐藏状态的循环映射
- :math:`\tilde{c_t}` : 候选隐藏状态
- :math:`\odot` : 向量的元素状态生成
- :math:`act_g` 和 :math:`act_h` : cell输入和cell输出激活函数,通常使用 :math:`tanh`
- :math:`\overline{act_h}` : 映射输出的激活函数,通常用 :math:`identity` 或等同的 :math:`act_h`
该OP的默认实现方式为 diagonal/peephole 连接,参见 `Gers, F. A., & Schmidhuber, J. (2000) <ftp://ftp.idsia.ch/pub/juergen/TimeCount-IJCNN2000.pdf>`_。
如果需要禁用 peephole 连接方法,将 use_peepholes 设为 False 即可。
将 ``use_peepholes`` 设置为False,断开窥视孔连接(peephole connection)。在此省略公式,详情请参照论文 `LONG SHORT-TERM MEMORY <http://www.bioinf.jku.at/publications/older/2604.pdf>`_ 。
该OP对于序列中每一个时间步的计算公式如下:
注意输入 :math:`x_{t}` 中的 :math:`W_{xi}x_{t},W_{xf}x_{t},W_{xc}x_{t},W_{xo}x_{t}` 不在此操作符中。用户选择在LSTMP层之前使用全链接层。
.. math::
i_t = \sigma(W_{ix}x_{t} + W_{ir}r_{t-1} + W_{ic}c_{t-1} + b_i)
.. math::
f_t = \sigma(W_{fx}x_{t} + W_{fr}r_{t-1} + W_{fc}c_{t-1} + b_f)
.. math::
o_t = \sigma(W_{ox}x_{t} + W_{or}r_{t-1} + W_{oc}c_{t-1} + b_o)
.. math::
\widetilde{c_t} = act_g(W_{cx}x_t + W_{cr}r_{t-1} + b_c)
.. math::
c_t = f_t \odot c_{t-1} + i_t \odot \widetilde{c_t}
.. math::
h_t = o_t \odot act_h(c_t)
.. math::
r_t = \overline{act_h}(W_{rh}h_t)
公式中的概念信息如下:
- :math:`x_{t}` 表示时间步 :math:`t` 的输入
- :math:`h_{t}` 表示时间步 :math:`t` 的 hidden 状态
- :math:`r_{t}` : 隐藏状态循环的映射输出的状态
- :math:`h_{t-1}, c_{t-1}, r_{t-1}` 分别表示前一个时间步的 hidden 状态,cell 状态和循环映射输出状态
- :math:`\widetilde{c_t}` 表示候选的 cell 状态
- :math:`i_t` ,:math:`f_t` 和 :math:`o_t` 分别为 input gate,forget gate,output gate
- :math:`W` 表示 weight (例如, :math:`W_{ix}` 是在计算 input gate :math:`i_t` 时,对输入 :math:`x_{t}` 做线性变换的 weight)
- :math:`b` 表示 bias (例如, :math:`b_{i}` 是 input gate 的 bias)
- :math:`\sigma` 表示 gate 的非线性激活函数,默认为 sigmoid
- :math:`act_g, act_h, \overline{act_h}` 分别表示 cell 输入 cell 输出和映射输出的非线性激活函数,默认为 tanh
- :math:`\odot` 表示矩阵的 Hadamard product,即对两个维度相同的矩阵,将相同位置的元素相乘,得到另一个维度相同的矩阵
参数:
- **input** (Variable) - dynamic_lstmp层的输入,支持输入序列长度为变量的倍数。该变量的张量为一个矩阵,维度为(T X 4D),T为mini-batch的总时间步长,D是隐藏大小
- **size** (int) - 4*隐藏状态大小(hidden size)
- **proj_size** (int) - 投影输出的大小
- **param_attr** (ParamAttr|None) - 可学习hidden-hidden权重和投影权重的参数属性
说明:
- Hidden-hidden (隐藏状态到隐藏状态)权重 = :math:`\{ W_{ch},W_{ih},W_{fh},W_{oh} \}`
- hidden-hidden权重的权重矩阵为(P*4D),P是投影大小,D是隐藏大小。
- 投影(Projection)权重 = :math:`\{ W_{rh} \}`
- 投影权重的shape为(D\*P)
如果设为None或者ParamAttr的一个属性,dynamic_lstm将创建ParamAttr为param_attr。如果param_attr的初始函数未设置,参数则初始化为Xavier。默认:None
- **bias_attr** (ParamAttr|None) - 可学习bias权重的bias属性,包含输入隐藏的bias权重和窥视孔连接权重(peephole connection),前提是use_peepholes设为True。
说明:
1.use_peepholes = False
- Biases = { :math:`b_{c},b_{i},b_{f},b_{o}`}.
- 维度为(1*4D)
2.use_peepholes = True
- Biases = { :math:`b_{c},b_{i},b_{f},b_{o},W_{ic},W_{fc},W_{oc}`}
- 维度为(1*7D)
如果设置为None或者ParamAttr的一个属性,dynamic_lstm将创建ParamAttr为bias_attr。bias_attr的初始函数未设置,bias则初始化为0.默认:None。
- **use_peepholes** (bool) - 是否开启诊断/窥视孔链接,默认为True
- **is_reverse** (bool) - 是否计算反向LSTM,默认为False
- **gate_activation** (bool) - 输入门(input gate)、遗忘门(forget gate)和输出门(output gate)的激活函数。Choices = [“sigmoid”,“tanh”,“relu”,“identity”],默认“sigmoid”
- **cell_activation** (str) - cell输出的激活函数。Choices = [“sigmoid”,“tanh”,“relu”,“identity”],默认“tanh”
- **candidate_activation** (str) - 候选隐藏状态(candidate hidden state)的激活状态。Choices = [“sigmoid”,“tanh”,“relu”,“identity”],默认“tanh”
- **proj_activation** (str) - 投影输出的激活函数。Choices = [“sigmoid”,“tanh”,“relu”,“identity”],默认“tanh”
- **dtype** (str) - 数据类型。Choices = [“float32”,“float64”],默认“float32”
- **name** (str|None) - 该层名称(可选)。若设为None,则自动为该层命名
- **h_0** (Variable) - 初始隐藏状态是可选输入,默认为0。这是一个具有形状的张量(N x D),其中N是批大小,D是投影大小
- **c_0** (Variable) - 初始cell状态是可选输入,默认为0。这是一个具有形状(N x D)的张量,其中N是批大小。h_0和c_0可以为空,但只能同时为空。
- **cell_clip** (float) - 如果提供该参数,则在单元输出激活之前,单元状态将被此值剪裁。
- **proj_clip** (float) - 如果 num_proj > 0 并且 proj_clip 被提供,那么将投影值沿元素方向剪切到[-proj_clip,proj_clip]内
返回:含有两个输出变量的元组,隐藏状态(hidden state)的投影和LSTMP的cell状态。投影的shape为(T*P),cell state的shape为(T*D),两者的LoD和输入相同
返回类型:元组(tuple)
- **input** ( :ref:`api_guide_Variable` ) 维度为 :math:`[T, 4*hidden\_size]` 的多维 LoDTensor(必须在传入该OP前对维度为 :math:`[T, hidden\_size]` 的输入经过线性变换得到),其中 T 为 batch 中所有样本的长度之和,hidden_size 为隐层大小,数据类型为 float32 或者 float64
- **size** (int) – 必须为 4 * hidden_size。
- **proj_size** (int) - 投影映射输出的大小。
- **param_attr** (ParamAttr,可选) - 指定权重参数属性的对象。默认值为None,表示使用默认的权重参数属性。具体用法请参见 :ref:`cn_api_fluid_ParamAttr`
说明:
1. 隐藏状态到隐藏状态(Hidden-hidden)权重 = :math:`\{ W_{cr},W_{ir},W_{fr},W_{or} \}`,维度为 [P, 4*hidden_size] ,P是投影大小
2. 投影(Projection)权重 = :math:`\{ W_{rh} \}`,维度为 [D, P]
- **bias_attr** (ParamAttr,可选) - 指定偏置参数属性的对象。默认值为None,表示使用默认的偏置参数属性。具体用法请参见 :ref:`cn_api_fluid_ParamAttr`
说明:
1. use_peepholes = False
- Biases = { :math:`b_{c},b_{i},b_{f},b_{o}`}
- 维度为 [1, 4*hidden_size]
2. use_peepholes = True
- Biases = { :math:`b_{c},b_{i},b_{f},b_{o},W_{ic},W_{fc},W_{oc}`}
- 维度为 [1, 7*hidden_size]
- **use_peepholes** (bool,可选) - 是否使用 peephole 连接。默认值为True。
- **is_reverse** (bool,可选) - 是否计算反向LSTM,默认值为False。
- **gate_activation** (str,可选) - 应用于input gate,forget gate, output gate 的激活函数。可选值包括 sigmoid,tanh,relu,identity。默认值为 sigmoid。
- **cell_activation** (str,可选) - cell输出的激活函数。可选值包括 sigmoid,tanh,relu,identity。默认值为 tanh
- **candidate_activation** (str,可选) - 候选隐藏状态(candidate hidden state)的激活状态。可选值包括 sigmoid,tanh,relu,identity。默认值为 tanh
- **proj_activation** (str,可选) - 投影输出的激活函数。可选值包括 sigmoid,tanh,relu,identity。默认值为 tanh
- **dtype** (str,可选) - 数据类型。可选值包括 float32,float64。默认值为 float32
- **name** (str,可选) - 具体用法请参见 :ref:`api_guide_Name` ,一般无需设置,默认值为None
- **h_0** ( :ref:`api_guide_Variable` ,可选) 维度为 :math:`[batch\_size, hidden\_size]` 的多维 Tensor。如果为 None,该OP会自动设置为全0的向量。默认值为None
- **c_0** ( :ref:`api_guide_Variable` ,可选) 维度为 :math:`[batch\_size, hidden\_size]` 的多维 Tensor。如果为 None,该OP会自动设置为全0的向量;:math:`h_0, c_0` 如果要设置为None,必须同时为None。默认值为None
- **cell_clip** (float,可选) - 如果该参数不为None,则在单元输出激活之前,单元状态将被此值剪裁。默认值为None
- **proj_clip** (float,可选) - 如果 num_proj > 0 并且 proj_clip 不为None,那么将投影值沿元素方向剪切到[-proj_clip,proj_clip]内。默认值为None
返回:经过lstmp运算输出的 hidden 的映射和 cell 状态的tuple,包括
- hidden:LSTM hidden的输出结果,维度为 :math:`[T, P]` 的LoDTensor,且LoD保持与输入一致,数据类型与input一致。
- cell:LSTM cell的输出结果,维度为 :math:`[T, hidden\_size]` 的LoDTensor,且LoD保持与输入一致,数据类型与input一致
返回类型: tuple( :ref:`api_guide_Variable` , :ref:`api_guide_Variable` )
**代码示例**:
.. code-block:: python
.. code-block:: python
import paddle.fluid as fluid
dict_dim, emb_dim = 128, 64
data = fluid.layers.data(name='sequence', shape=[1],
dtype='int32', lod_level=1)
dtype='int32', lod_level=1)
emb = fluid.layers.embedding(input=data, size=[dict_dim, emb_dim])
hidden_dim, proj_dim = 512, 256
fc_out = fluid.layers.fc(input=emb, size=hidden_dim * 4,
act=None, bias_attr=None)
proj_out, _ = fluid.layers.dynamic_lstmp(input=fc_out,
size=hidden_dim * 4,
proj_size=proj_dim,
use_peepholes=False,
is_reverse=True,
cell_activation="tanh",
proj_activation="tanh")
act=None, bias_attr=None)
proj_out, cell = fluid.layers.dynamic_lstmp(input=fc_out,
size=hidden_dim * 4,
proj_size=proj_dim,
use_peepholes=False,
is_reverse=True,
cell_activation="tanh",
proj_activation="tanh")
proj_out.shape # (-1, 256)
cell.shape # (-1, 512)
......
......@@ -5,52 +5,66 @@ lstm
.. py:function:: paddle.fluid.layers.lstm(input, init_h, init_c, max_len, hidden_size, num_layers, dropout_prob=0.0, is_bidirec=False, is_test=False, name=None, default_initializer=None, seed=-1)
如果您的设备是GPU,本op将使用cudnn LSTM实现
.. raw:: html
一个没有 peephole 连接的四门长短期记忆网络。在前向传播中,给定迭代的输出ht和单元输出ct可由递归输入ht-1、单元输入ct-1和上一层输入xt计算,给定矩阵W、R和bias bW, bR由下式计算:
<style> .red {color:red; font-weight:bold} </style>
.. math::
.. role:: red
:red:`注意:该OP仅支持 GPU 设备运行`
i_t &= \sigma(W_{ix}x_{t} + W_{ih}h_{t-1} + bx_i + bh_i)\\
f_t &= \sigma(W_{fx}x_{t} + W_{fh}h_{t-1} + bx_f + bh_f)\\
o_t &= \sigma(W_{ox}x_{t} + W_{oh}h_{t-1} + bx_o + bh_o)\\
\tilde{c_t} &= tanh(W_{cx}x_t + W_{ch}h_{t-1} + bx_c + bh_c)\\
c_t &= f_t \odot c_{t-1} + i_t \odot \tilde{c_t}\\
h_t &= o_t \odot tanh(c_t)
该OP实现了 LSTM,即 Long-Short Term Memory(长短期记忆)运算 - `Hochreiter, S., & Schmidhuber, J. (1997) <http://deeplearning.cs.cmu.edu/pdfs/Hochreiter97_lstm.pdf>`_。
公式中:
- W 项表示权重矩阵(e.g. :math:`W_{ix}` 是从输入门到输入的权重矩阵)
- b 项表示偏差向量( :math:`b_{xi}` 和 :math:`b_{hi}` 是输入门的偏差向量)
- sigmoid 是 logistic sigmoid 函数
- i、f、o、c 分别为输入门、遗忘门、输出门和激活向量,它们的大小与 cell 输出激活向量h相同。
- :math:`\odot` 是向量的元素乘积
- tanh是激活函数
- :math:`\tilde{c_t}` 也称为候选隐藏状态,它是根据当前输入和之前的隐藏状态来计算的
该OP的实现不包括 diagonal/peephole 连接,参见 `Gers, F. A., & Schmidhuber, J. (2000) <ftp://ftp.idsia.ch/pub/juergen/TimeCount-IJCNN2000.pdf>`_。
如果需要使用 peephole 连接方法,请使用 :ref:`cn_api_fluid_layers_dynamic_lstm` 。
sigmoid的计算公式为: :math:`sigmoid(x) = 1 / (1 + e^{-x})` 。
该OP对于序列中每一个时间步的计算公式如下:
.. math::
i_t = \sigma(W_{ix}x_{t} + W_{ih}h_{t-1} + b_{x_i} + b_{h_i})
.. math::
f_t = \sigma(W_{fx}x_{t} + W_{fh}h_{t-1} + b_{x_f} + b_{h_f})
.. math::
o_t = \sigma(W_{ox}x_{t} + W_{oh}h_{t-1} + b_{x_o} + b_{h_o})
.. math::
\widetilde{c_t} = tanh(W_{cx}x_t + W_{ch}h_{t-1} + b{x_c} + b_{h_c})
.. math::
c_t = f_t \odot c_{t-1} + i_t \odot \widetilde{c_t}
.. math::
h_t = o_t \odot tanh(c_t)
公式中的概念信息如下:
- :math:`x_{t}` 表示时间步 :math:`t` 的输入
- :math:`h_{t}` 表示时间步 :math:`t` 的 hidden 状态
- :math:`h_{t-1}, c_{t-1}` 分别表示前一个时间步的 hidden 和 cell 状态
- :math:`\widetilde{c_t}` 表示候选的 cell 状态
- :math:`i_t` ,:math:`f_t` 和 :math:`o_t` 分别为 input gate,forget gate,output gate
- :math:`W` 表示 weight (例如, :math:`W_{ix}` 是在计算 input gate :math:`i_t` 时,对输入 :math:`x_{t}` 做线性变换的 weight)
- :math:`b` 表示 bias (例如, :math:`b_{i}` 是 input gate 的 bias)
- :math:`\sigma` 表示 gate 的非线性激活函数,默认为 sigmoid
- :math:`\odot` 表示矩阵的 Hadamard product,即对两个维度相同的矩阵,将相同位置的元素相乘,得到另一个维度相同的矩阵
参数:
- **input** (Variable) - LSTM 输入张量,形状必须为(seq_len x,batch_size,x,input_size)
- **init_h** (Variable) – LSTM的初始隐藏状态,是一个有形状的张量(num_layers,x,batch_size,x,hidden_size)如果is_bidirec = True,形状应该是(num_layers*2,x, batch_size, x, hidden_size)
- **init_c** (Variable) - LSTM的初始状态。这是一个有形状的张量(num_layers, x, batch_size, x, hidden_size)如果is_bidirec = True,形状应该是(num_layers*2, x, batch_size, x, hidden_size)
- **max_len** (int) – LSTM的最大长度。输入张量的第一个 dim 不能大于max_len
- **hidden_size** (int) - LSTM的隐藏大小
- **num_layers** (int) – LSTM的总层数
- **dropout_prob** (float|0.0) – dropout prob,dropout 只在 rnn 层之间工作,而不是在时间步骤之间。dropout 不作用于最后的 rnn 层的 rnn 输出中
- **is_bidirec** (bool) – 是否是双向的
- **is_test** (bool) – 是否在测试阶段
- **name** (str|None) - 此层的名称(可选)。如果没有设置,该层将被自动命名
- **default_initializer** (Initialize|None) – 在哪里使用初始化器初始化权重,如果没有设置,将进行默认初始化
- **seed** (int) – LSTM中dropout的Seed,如果是-1,dropout将使用随机Seed
返回: 三个张量, rnn_out, last_h, last_c:
- rnn_out为LSTM hidden的输出结果。形为(seq_len x batch_size x hidden_size)如果 ``is_bidirec`` 设置为True,则形为(seq_len x batch_sze hidden_size * 2)
- last_h(Tensor): LSTM最后一步的隐藏状态,形状为(num_layers x batch_size x hidden_size);如果 ``is_bidirec`` 设置为True,形状为(num_layers*2 x batch_size x hidden_size)
- last_c(Tensor): LSTM最后一步的cell状态,形状为(num_layers x batch_size x hidden_size);如果 ``is_bidirec`` 设置为True,形状为(num_layers*2 x batch_size x hidden_size)
返回类型: rnn_out(Tensor),last_h(Tensor),last_c(Tensor)
- **input** ( :ref:`api_guide_Variable` ) - LSTM的输入张量,维度为 :math:`[batch\_size, seq\_len, input\_dim]` 的 3-D Tensor,其中 seq_len 为序列的长度, input_dim 为序列词嵌入的维度。数据类型为 float32 或者 float64。
- **init_h** ( :ref:`api_guide_Variable` ) – LSTM的初始 hidden 状态,维度为 :math:`[num\_layers, batch\_size, hidden\_size]` 的 3-D Tensor,其中 num_layers 是LSTM的总层数,hidden_size 是隐层维度。 如果is_bidirec = True, 维度应该为 :math:`[num\_layers*2, batch\_size, hidden\_size]` 。数据类型为 float32 或者 float64。
- **init_c** ( :ref:`api_guide_Variable` ) - LSTM的初始 cell 状态。维度为 :math:`[num\_layers, batch\_size, hidden\_size]` 的 3-D Tensor,其中 num_layers 是LSTM的总层数,hidden_size 是隐层维度。 如果is_bidirec = True, 维度应该为 :math:`[num\_layers*2, batch\_size, hidden\_size]` 。数据类型为 float32 或者 float64。
- **max_len** (int) – LSTM的最大长度。输入张量的第一个 input_dim 不能大于 max_len。
- **hidden_size** (int) - LSTM hidden 状态的维度。
- **num_layers** (int) – LSTM的总层数。例如,该参数设置为2,则会堆叠两个LSTM,其第一个LSTM的输出会作为第二个LSTM的输入。
- **dropout_prob** (float,可选) – dropout比例,dropout 只在 rnn 层之间工作,而不是在时间步骤之间。dropout 不作用于最后的 rnn 层的 rnn 输出中。默认值为 0.0。
- **is_bidirec** (bool,可选) – 是否是双向的LSTM。默认值为 False。
- **is_test** (bool,可选) – 是否在测试阶段。默认值为 False。
- **name** (str,可选) - 具体用法请参见 :ref:`api_guide_Name` ,一般无需设置,默认值为None
- **default_initializer** (Initializer,可选) – 用于初始化权重的初始化器,如果为None,将进行默认初始化。默认值为 None
- **seed** (int,可选) – LSTM中dropout的seed,如果是-1,dropout将使用随机seed。默认值为 1。
返回: 经过lstm运算输出的三个Tensor的tuple,包括
- rnn_out:LSTM hidden的输出结果的Tensor,数据类型与input一致,维度为 :math:`[seq\_len, batch\_size, hidden\_size]` 。如果 ``is_bidirec`` 设置为True,则维度为 :math:`[seq\_len, batch\_size, hidden\_size*2]`
- last_h:LSTM最后一步的hidden状态的Tensor,数据类型与input一致,维度为 :math:`[num\_layers, batch\_size, hidden\_size]` 。如果 ``is_bidirec`` 设置为True,则维度为 :math:`[num\_layers*2, batch\_size, hidden\_size]`
- last_c:LSTM最后一步的cell状态的Tensor,数据类型与input一致,维度为 :math:`[num\_layers, batch\_size, hidden\_size]` 。如果 ``is_bidirec`` 设置为True,则维度为 :math:`[num\_layers*2, batch\_size, hidden\_size]`
返回类型: tuple( :ref:`api_guide_Variable` , :ref:`api_guide_Variable` , :ref:`api_guide_Variable` )
**代码示例:**
......@@ -67,13 +81,16 @@ sigmoid的计算公式为: :math:`sigmoid(x) = 1 / (1 + e^{-x})` 。
batch_size = 20
max_len = 100
dropout_prob = 0.2
input_size = 100
seq_len = 100
hidden_size = 150
num_layers = 1
init_h = layers.fill_constant( [num_layers, batch_size, hidden_size], 'float32', 0.0 )
init_c = layers.fill_constant( [num_layers, batch_size, hidden_size], 'float32', 0.0 )
rnn_out, last_h, last_c = layers.lstm(emb, init_h, init_c, max_len, hidden_size, num_layers, dropout_prob=dropout_prob)
rnn_out.shape # (-1, 100, 150)
last_h.shape # (1, 20, 150)
layt_c.shape # (1, 20, 150)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册