Python 通过实例理解LSTM

Python 通过实例理解LSTM,python,neural-network,lstm,recurrent-neural-network,Python,Neural Network,Lstm,Recurrent Neural Network,我想在LSTM中编码一个时间步。我的重点是理解忘记门层、输入门层、候选值、当前和未来单元状态的功能 假设我在t-1和xt的隐藏状态如下。为了简单起见,我们假设权重矩阵是恒等矩阵,所有偏差都为零 htminus1 = np.array( [0, 0.5, 0.1, 0.2, 0.6] ) xt = np.array( [-0.1, 0.3, 0.1, -0.25, 0.1] ) 我知道遗忘状态是htminus1和xt 那么,是吗 ft = 1 / ( 1 + np.exp( -( htminus

我想在LSTM中编码一个时间步。我的重点是理解忘记门层输入门层候选值当前未来单元状态的功能


假设我在t-1和xt的隐藏状态如下。为了简单起见,我们假设权重矩阵是恒等矩阵,所有偏差都为零

htminus1 = np.array( [0, 0.5, 0.1, 0.2, 0.6] )
xt = np.array( [-0.1, 0.3, 0.1, -0.25, 0.1] )
我知道遗忘状态是
htminus1
xt

那么,是吗

ft = 1 / ( 1 + np.exp( -( htminus1 + xt ) ) )

>> ft = array([0.47502081, 0.68997448, 0.549834  , 0.4875026 , 0.66818777])
我指的是一个块LSTM的一次迭代的实现。链接上说,
ft
应该是0或1。我是不是遗漏了什么

如何根据下图中给出的模式获得忘记门层?一个例子将对我起到说明作用。

按照同样的思路,如何获得输入门层,
it
和新候选值的向量,
\tilde{C}\u t
,如下图所示?

最后,如何根据下图给出的方案获得新的隐藏状态
ht

一个简单的例子将有助于我理解。提前谢谢


从图中看这并不明显,但下面是它的工作原理-

  • 如果您看到两行连接形成一行,则这是一个串联操作。您已将其解释为添加

  • 无论您在哪里看到
    sigmoid
    tanh
    块,都意味着与可训练权重矩阵相乘

  • 如果两行由显式的
    x
    +
    连接,则分别执行元素乘法和加法

  • 因此,正确的操作应该是
    sigmoid(Wf*np.concatenate(htminus1+xt))+bf
    ,而不是
    sigmoid(htminus1+xt)
    Wf
    是可训练参数的矩阵,
    bf
    是相应的偏差项

    请注意,我刚刚用numpy在图像的右侧写下了方程式,其他的不多。将
    [a,b]
    解释为
    a
    b
    之间的关联运算

    您可以类似地定义其他操作

    ft = sigmoid(Wf * np.concatenate(htminus1, xt)) + bf
    it = sigmoid(Wi * np.concatenate(htminus1, xt)) + bi
    Ctt = tanh(Wc * np.concatenate(htminus1, xt)) + bc
    Ot = sigmoid(Wo * np.concatenate(htminus1, xt)) + bo
    
    Ct = (C_{t-1} * ft) + (Ctt * it)
    ht = Ot * tanh(Ct)
    

    注:我将
    C^{tilda}
    表示为
    Ctt

    除了已经介绍的细节之外,我还想阐明计算和连接的一些更精细的方面

    权重矩阵
    W_f
    实际上由两个并排连接的权重矩阵组成,即沿轴=1,每个权重矩阵处理之前的时间步激活(
    htminus1
    )和当前输入(
    xt
    )。然而,符号
    [htminus1,xt]
    表示通过堆叠(即沿轴=0)将
    htminus1
    xt
    垂直串联而获得的矩阵

    这些忽略偏差的矩阵计算可以这样表示-

    了解这些计算是如何在tensorflow LSTM模型中进行的也是一个信息。下面的代码块仅包含与此处讨论相关的主要计算,因为完整的代码如下所示

    电流输入的门层计算 x_i=K.dot(输入_i,self.kernel_i) x_f=K.dot(输入,self.kernel) x_c=K.dot(输入、self.kernel、self.kernel) x_o=K.dot(输入,self.kernel) #增加偏见 如果使用self.u偏差: x_i=K.bias_add(x_i,self.bias_i) x\u f=K.bias\u add(x\u f,self.bias\u f) x_c=K.bias_add(x_c,self.bias_c) x_o=K.bias_add(x_o,self.bias_o) #使用先前输出的门层计算--->h_tm1,即htminus1 i=self.recurtive_激活(x_i+K.dot(h_tm1,self.recurtive_kernel_i)) f=自循环激活(x_f+K.dot(h_tm1,自循环内核) c=f*c_tm1+i*self.activation(x_c+K.dot(h_tm1,self.recurrent_kernel_c)) o=自循环激活(x_o+K.dot(h_tm1,自循环内核)
    为什么不包括权重矩阵,您/打算如何初始化权重?为简单起见,假设权重矩阵是一个单位矩阵,偏差为零。谢谢您的回答。这很有帮助。即使在连接之后,我们怎么能在忘记门中只得到0或1呢?你能告诉我在博客中说忘记门应该是0或1的确切位置吗?因为据我所知,它应该在0和1之间,这正是sigmoid给出的结果。在遗忘门中不能只得到0或1:sigmoid输出一个介于[0,1]之间的值。训练完你的重量后,当忘记门被触发时,这个门的输出将非常接近1。阿南达,伊尼戈:明白了。它表示在[0,1]之间。谢谢