精华内容
下载资源
问答
  • ner-lstm, 基于多层双向LSTM的命名实体识别 这里知识库包含实现以下Arxiv预编译中所述方法的代码: https://arxiv.org/abs/1610.09756,在 ICON-16 会议( http://aclweb.org/anthology/W/W16/W16-63.pd
  • 本文探讨了如何使用深度双向LSTM网络来解决问答社区的问题。
    /* 版权声明:可以任意转载,转载时请标明文章原始出处和作者信息 .*/

                                                         author: 张俊林     


    关于社区问答系统的问题背景,我们在之前的“利用卷积神经网络构造社区问答系统”一文里已经说明得很清楚,本文就不再赘述,不清楚背景的读者可自行参照上文,我们这些相关的研发工作主要是为了开发畅捷通“会计家园”交流社区的相关功能。为了保持行文完整,简明叙述形式化描述的问题如下:


    假设我们已知问答库如下:



    其中,Qi是问答社区中的历史问题,AiQi问题的精华答案;


    现有社区用户提出的新问题:Qnew 


    我们需要学习映射函数:



    意即对于新问题Qnew,我们希望通过学习系统找到社区中已经出现过的语义相同问题Qi,然后将对应的答案Ai推荐给用户。这样就达到了社区信息复用的目的。这个问题其实对于问答社区比如百度知道、知乎等都是存在的,解决问题的思路也完全可以复用到此类问答社区中。


    除了上篇文章讲述的利用CNN来构造ML系统外,我们还尝试了使用RNN及其改进模型LSTM,本文主体内容即为使用深度双向LSTM构造社区问答系统的思路及效果。


    |深度双向LSTM模型



                                                           1 深度双向LSTM


    深度双向LSTM模型的结构如图1所示。首先强调一下,这个结构也是一个解决对比两个句子相似性的通用RNN解决方案,不仅仅能够使用在问答社区,凡是涉及到对比两个句子或者实体关系的场合完全可以套用这个模型来解决,这点希望读者注意。

     

    首先,因为我们面临的问题是对比两个问题QiQj是否语义相同,那么对于RNN来说存在一个神经网络的输入层如何构造的难题。CNN解决这类问题就比较直观,一般一个输入套上一个CNN来抽取出句子特征,然后再套上MLP神经网络来表达两者之间的关系即可。RNN表达单个输入句子是非常直观的,但是直接表达两个句子之间的关系相对而言就没那么直观。一般可以如图1这么做,就是把两个问题QiQj拼接起来,中间用一个特殊分隔符EOS分割,这里EOS不代表一个句子的结束,而是代表两个句子的分隔符号,这个也请读者注意。如此就构造出了RNN的输入层。

     

    有了输入层,上面就好处理了。首先我们在输入层之上,套上一层双向LSTM层,LSTMRNN的改进模型,相比RNN,能够更有效地处理句子中单词间的长距离影响;而双向LSTM就是在隐层同时有一个正向LSTM和反向LSTM,正向LSTM捕获了上文的特征信息,而反向LSTM捕获了下文的特征信息,这样相对单向LSTM来说能够捕获更多的特征信息,所以通常情况下双向LSTM表现比单向LSTM或者单向RNN要好。图1中输入层之上的那个BLSTM层就是这个第一层双向LSTM层神经网络。

     

    我们可以把神经网络的深度不断拓展,就是在第一层BLSTM基础上,再叠加一层BLSTM,叠加方法就是把每个输入对应的BLSTM层的输出作为下一层BLSTM神经网络层相应节点的输入,因为两者完全是一一对应的,所以很好叠加这两层神经网络。如果你觉得有必要,完全可以如此不断叠加更深一层的BLSTM来构造多层深度的BLSTM神经网络。

     

    在最后一层BLSTM神经网络之上,可以使用Mean Pooling机制来融合BLSTM各个节点的结果信息。所谓Mean Pooling,具体做法就是把BLSTM各个节点的输出结果求等权平均,首先把BLSTM各个输出内容叠加,这是pooling的含义,然后除以输入节点个数,这是mean的含义,Mean Pooling就是这个意思。

     

    如何从物理意义上来理解Mean Pooling呢?这其实可以理解为在这一层,两个句子中每个单词都对最终分类结果进行投票,因为每个BLSTM的输出可以理解为这个输入单词看到了所有上文和所有下文(包含两个句子)后作出的两者是否语义相同的判断,而通过Mean Pooling层投出自己宝贵的一票。所以RNN场景下的Mean Pooling可以看作一种深度学习里的“民主党”投票机制。


    Mean Pooling之上,我们还可以套上一层SoftMax层,这样就可以实现最终的分类目的。


    通过以上方式,我们就通过输入层、多层BLSTM层、Mean Pooling层和输出层构造出一个通用的判断两个句子语义是否相同的深度学习系统。其实这个结构是非常通用的,除了判断两个句子关系,对于单句子分类明显也是可以套用这个结构的。


    模型结构已经讲完,后面我们将进入实验部分,因为希望和CNN结果进行效果对比,我们先简单说明下两个同样可以用来解决社区问答问题的CNN结构,这两个结构在之前的“利用卷积神经网络构造社区问答系统”文中都有详细描述,这里不展开讲,只是列出结构图,以方便理解和对比模型。


    |两个CNN模型结构


    两个CNN模型结构参考图2和图3,图2这种结构是利用CNN判断多个输入句子关系的简单直接的结构,含义是先各自抽取每个句子的特征然后比较两者的关系。而图3这种结构的含义是先把两个句子之间的关系明确表达出来作为输入,然后再套上一个CNN模型来进行分类预测。


    2 CNN模型1


    3 CNN模型2


    |实验结果及与两个CNN模型对比


    在之前的文章“利用卷积神经网络构造社区问答系统”中我们使用自己构造的实验数据验证了CNN模型2的效果。之后,我们增加了训练数据的数量,以及加大了负例的难度,其实在这个社区问答问题中,负例的难度对于实验效果指标影响是比较大的。所谓难度,是指负例中两个句子间语义相关程度到底有多强,如果负例中两个句子语义相关程度越强,则分类难度越高。


    至于模型,我们补充了CNN模型1,在新数据集合下测试了CNN模型2的效果,对于BLSTM来说,则做了双层BLSTM和单层BLSTM的实验,所以可以认为有四个模型参与效果对比。


    经过参数调优,这四个模型在这个新的训练集和测试集下,具体实验结果如下:


         CNN模型1             分类精度:89.47%

         CNN模型2             分类精度:80.08%

         双层BLSTM模型   分类精度:84.96%

         单层BLSTM模型   分类精度:89.10%


    可以看出,在这个问答社区问题里,CNN模型1和单层BLSTM效果接近,而双层BLSTM模型效果有下降,这也许跟实验数据规模不够大有一定关系,所以复杂模型的优势发挥不出来,而CNN模型2则效果相对差些,这也许说明了CNN模型2没有将两个句子的原始信息输入到模型里,而是直接将其关系作为输入,这种情况下存在信息损失的可能。

     

    致谢:感谢畅捷通智能平台的沈磊、薛会萍、黄通文、桑海岩等同事在模型训练及训练数据的收集整理方面的工作。



    扫一扫关注微信号:“布洛卡区” ,深度学习在自然语言处理等智能应用的技术研讨与科普公众号。




    展开全文
  • 目录: 1、传统的BP网络和CNN网络 ...5、LSTM和其他网络组合最近在学习LSTM应用在时间序列的预测上,但是遇到一个很大的问题就是LSTM在传统BP网络上加上时间步后,其结构就很难理解了,同时其输入输出数据格式...

    d6037f8d0370a760b5eeff0bda6368b5.png
    目录:
    1、传统的BP网络和CNN网络
    2、LSTM网络
    3、LSTM的输入结构
    4、pytorch中的LSTM
    4.1 pytorch中定义的LSTM模型
    4.2 喂给LSTM的数据格式
    4.3 LSTM的output格式
    5、LSTM和其他网络组合

    最近在学习LSTM应用在时间序列的预测上,但是遇到一个很大的问题就是LSTM在传统BP网络上加上时间步后,其结构就很难理解了,同时其输入输出数据格式也很难理解,网络上有很多介绍LSTM结构的文章,但是都不直观,对初学者是非常不友好的。我也是苦苦冥思很久,看了很多资料和网友分享的LSTM结构图形才明白其中的玄机。

    1、传统的BP网络和CNN网络

    BP网络和CNN网络没有时间维,和传统的机器学习算法理解起来相差无几,CNN在处理彩色图像的3通道时,也可以理解为叠加多层,图形的三维矩阵当做空间的切片即可理解,写代码的时候照着图形一层层叠加即可。如下图是一个普通的BP网络和CNN网络。

    cc030c3f2ffd8aadacaaf1dbbdc27685.png
    BP网络

    9e8735d3e0b9a2df63572e52fdb561b1.png
    CNN网络

    图中的隐含层、卷积层、池化层、全连接层等,都是实际存在的,一层层前后叠加,在空间上很好理解,因此在写代码的时候,基本就是看图写代码,比如用keras就是:

    # 示例代码,没有实际意义
    model = Sequential()
    model.add(Conv2D(32, (3, 3), activation='relu'))  # 添加卷积层
    model.add(MaxPooling2D(pool_size=(2, 2)))         # 添加池化层
    model.add(Dropout(0.25))                          # 添加dropout层
    
    model.add(Conv2D(32, (3, 3), activation='relu'))  # 添加卷积层
    model.add(MaxPooling2D(pool_size=(2, 2)))         # 添加池化层
    model.add(Dropout(0.25))                          # 添加dropout层
    
    ....   # 添加其他卷积操作
    
    model.add(Flatten())                            # 拉平三维数组为2维数组
    model.add(Dense(256, activation='relu'))        添加普通的全连接层
    model.add(Dropout(0.5))
    model.add(Dense(10, activation='softmax'))
    
    ....  # 训练网络

    2、LSTM网络

    当我们在网络上搜索看LSTM结构的时候,看最多的是下面这张图:

    e6c4a068cf5effe9f5dd7f3ce4e3e4c2.png
    RNN网络

    这是RNN循环神经网络经典的结构图,LSTM只是对隐含层节点A做了改进,整体结构不变,因此本文讨论的也是这个结构的可视化问题。

    中间的A节点隐含层,左边是表示只有一层隐含层的LSTM网络,所谓LSTM循环神经网络就是在时间轴上的循环利用,在时间轴上展开后得到右图。

    看左图,很多同学以为LSTM是单输入、单输出,只有一个隐含神经元的网络结构,看右图,以为LSTM是多输入、多输出,有多个隐含神经元的网络结构,A的数量就是隐含层节点数量。

    WTH?思维转不过来啊。这就是传统网络和空间结构的思维。

    实际上,右图中,我们看Xt表示序列,下标t是时间轴,所以,A的数量表示的是时间轴的长度,是同一个神经元在不同时刻的状态(Ht),不是隐含层神经元个数。

    我们知道,LSTM网络在训练时会使用上一时刻的信息,加上本次时刻的输入信息来共同训练。

    举个简单的例子:在第一天我生病了(初始状态H0),然后吃药(利用输入信息X1训练网络),第二天好转但是没有完全好(H1),再吃药(X2),病情得到好转(H2),如此循环往复知道病情好转。因此,输入Xt是吃药,时间轴T是吃多天的药,隐含层状态是病情状况。因此我还是我,只是不同状态的我。

    实际上,LSTM的网络是这样的:

    2287aa425cb87d989e1320852db30f6c.png
    LSTM网络结构

    上面的图表示包含2个隐含层的LSTM网络,在T=1时刻看,它是一个普通的BP网络,在T=2时刻看也是一个普通的BP网络,只是沿时间轴展开后,T=1训练的隐含层信息H,C会被传递到下一个时刻T=2,如下图所示。上图中向右的五个常常的箭头,所的也是隐含层状态在时间轴上的传递。

    9ce3e276eedafa0eeebf18328645acee.png

    注意,图中H表示隐藏层状态,C是遗忘门,后面会讲解它们的维度。

    3、LSTM的输入结构

    为了更好理解LSTM结构,还必须理解LSTM的数据输入情况。仿照3通道图像的样子,在加上时间轴后的多样本的多特征的不同时刻的数据立方体如下图所示:

    7ed6d3da13ca2f31ee9fa09e3bea2e08.png
    三维数据立方体

    右边的图是我们常见模型的输入,比如XGBOOST,lightGBM,决策树等模型,输入的数据格式都是这种(N*F)的矩阵,而左边是加上时间轴后的数据立方体,也就是时间轴上的切片,它的维度是(N*T*F),第一维度是样本数,第二维度是时间,第三维度是特征数,如下图所示:

    a40839657f465e98a7f41143aa5e20af.png

    这样的数据立方体很多,比如天气预报数据,把样本理解成城市,时间轴是日期,特征是天气相关的降雨风速PM2.5等,这个数据立方体就很好理解了。在NLP里面,一句话会被embedding成一个矩阵,词与词的顺序是时间轴T,索引多个句子的embedding三维矩阵如下图所示:

    fdaf7d4842bac5dcfddae89071c09b21.png

    4、pytorch中的LSTM

    4.1 pytorch中定义的LSTM模型

    pytorch中定义的LSTM模型的参数如下

    class 

    结合前面的图形,我们一个个看。

    (1)input_size:x的特征维度,就是数据立方体中的F,在NLP中就是一个词被embedding后的向量长度,如下图所示:

    33b2761e40e77e59d8d022e6af4a0bc4.png

    (2)hidden_size:隐藏层的特征维度(隐藏层神经元个数),如下图所示,我们有两个隐含层,每个隐藏层的特征维度都是5。注意,非双向LSTM的输出维度等于隐藏层的特征维度

    95031f9f66c383f3f6fc79bd2001eb5a.png

    (3)num_layers:lstm隐层的层数,上面的图我们定义了2个隐藏层。

    (4)batch_first:用于定义输入输出维度,后面再讲。

    (5)bidirectional:是否是双向循环神经网络,如下图是一个双向循环神经网络,因此在使用双向LSTM的时候我需要特别注意,正向传播的时候有(Ht, Ct),反向传播也有(Ht', Ct'),前面我们说了非双向LSTM的输出维度等于隐藏层的特征维度,而双向LSTM的输出维度是隐含层特征数*2,而且H,C的维度是时间轴长度*2。

    1d7caffe90c999babc029788116e2b6f.png

    4.2 喂给LSTM的数据格式

    pytorch中LSTM的输入数据格式默认如下:

    input(seq_len, batch, input_size)
    参数有:
        seq_len:序列长度,在NLP中就是句子长度,一般都会用pad_sequence补齐长度
        batch:每次喂给网络的数据条数,在NLP中就是一次喂给网络多少个句子
        input_size:特征维度,和前面定义网络结构的input_size一致。

    前面也说到,如果LSTM的参数 batch_first=True,则要求输入的格式是:

    input(batch, seq_len, input_size)

    刚好调换前面两个参数的位置。其实这是比较好理解的数据形式,下面以NLP中的embedding向量说明如何构造LSTM的输入。

    之前我们的embedding矩阵如下图:

    51157e24951105af567deb7c578aaab3.png

    如果把batch放在第一位,则三维矩阵的形式如下:

    f24fbe8c4770007fbf8070076256ed1a.png

    其转换过程如下图所示:

    c0565ab2cc6e7814e6d91fc36bf4b66d.png

    看懂了吗,这就是输入数据的格式,是不是很简单。

    LSTM的另外两个输入是 h0 c0,可以理解成网络的初始化参数,用随机数生成即可。

    h0(num_layers * num_directions, batch, hidden_size)
    c0(num_layers * num_directions, batch, hidden_size)
    参数:
        num_layers:隐藏层数
        num_directions:如果是单向循环网络,则num_directions=1,双向则num_directions=2
        batch:输入数据的batch
        hidden_size:隐藏层神经元个数

    注意,如果我们定义的input格式是:

    input(batch, seq_len, input_size)

    则H和C的格式也是要变的:

    h0(batc,num_layers * num_directions, h, hidden_size)
    c0(batc,num_layers * num_directions, h, hidden_size)

    4.3 LSTM的output格式

    LSTM的输出是一个tuple,如下:

    output,(ht, ct) = net(input)
        output: 最后一个状态的隐藏层的神经元输出
        ht:最后一个状态的隐含层的状态值
        ct:最后一个状态的隐含层的遗忘门值

    output的默认维度是:

    output(seq_len, batch, hidden_size * num_directions)
    ht(num_layers * num_directions, batch, hidden_size)
    ct(num_layers * num_directions, batch, hidden_size)

    和input的情况类似,如果我们前面定义的input格式是:

    input(batch, seq_len, input_size)

    htct的格式也是要变的:

    ht(batc,num_layers * num_directions, h, hidden_size)
    ct(batc,num_layers * num_directions, h, hidden_size)

    说了这么多,我们回过头来看看ht和ct在哪里,请看下图:

    d12d6fcb2c6eb2a9c8239c889cbf4ab9.png

    output在哪里?请看下图:

    270c7aca145938e25e00cc257cf29de9.png

    5、LSTM和其他网络组合

    还记得吗,output的维度等于隐藏层神经元的个数,即hidden_size,在一些时间序列的预测中,会在output后,接上一个全连接层,全连接层的输入维度等于LSTM的hidden_size,之后的网络处理就和BP网络相同了,如下图:

    a82eaf62bab0689e02b26eab57db8512.png

    用pytorch实现上面的结构:

    import 

    当然,有些模型则是将输出当做另一个LSTM的输入,或者使用隐藏层ht,ct的信息进行建模,不一而足。

    好了,以上就是我对LSTM的一些学习心得,看完记得关注点赞。

    参考:

    曾伊言:LSTM入门例子:根据前9年的数据预测后3年的客流(PyTorch实现)​zhuanlan.zhihu.com
    XI YANG:6 种用 LSTM 做时间序列预测的模型结构 - Keras 实现​zhuanlan.zhihu.com
    61288c606ed279ff4277e162c7125316.png
    刘大力:用「动图」和「举例子」讲讲 RNN​zhuanlan.zhihu.com
    8604f6e9b71f112128760b4c917b8cbd.png
    LSTM神经网络输入输出究竟是怎样的?​www.zhihu.com
    6daa50d88a0cce630c635f781aa97f81.png
    [Pytorch]pytorch中的LSTM模型_人工智能_Forgive Me-CSDN博客​blog.csdn.net
    f04ec7ecda4da455763e7300622389a9.png
    展开全文
  • “他山之石,可以攻玉”,站在巨人的肩膀才能看得更高,走得更远。在科研的道路上,更需借助...作者:知乎—master苏地址:https://www.zhihu.com/people/zhenyu22最近在学习LSTM应用在时间序列的预测上,但是遇到...

    “他山之石,可以攻玉”,站在巨人的肩膀才能看得更高,走得更远。在科研的道路上,更需借助东风才能更快前行。为此,我们特别搜集整理了一些实用的代码链接,数据集,软件,编程技巧等,开辟“他山之石”专栏,助你乘风破浪,一路奋勇向前,敬请关注。

    作者: 知乎—master苏

    地址:https://www.zhihu.com/people/zhenyu22

    最近在学习LSTM应用在时间序列的预测上,但是遇到一个很大的问题就是LSTM在传统BP网络上加上时间步后,其结构就很难理解了,同时其输入输出数据格式也很难理解,网络上有很多介绍LSTM结构的文章,但是都不直观,对初学者是非常不友好的。我也是苦苦冥思很久,看了很多资料和网友分享的LSTM结构图形才明白其中的玄机。

    01

    传统的BP网络和CNN网络

    BP网络和CNN网络没有时间维,和传统的机器学习算法理解起来相差无几,CNN在处理彩色图像的3通道时,也可以理解为叠加多层,图形的三维矩阵当做空间的切片即可理解,写代码的时候照着图形一层层叠加即可。如下图是一个普通的BP网络和CNN网络。
    fbb895468e36beef4b61fbe1de87ac1d.png BP网络

    c7b3eb930fdce93fc26c4b2bcf3c4d60.png

    CNN网络 图中的隐含层、卷积层、池化层、全连接层等,都是实际存在的,一层层前后叠加,在空间上很好理解,因此在写代码的时候,基本就是看图写代码,比如用keras就是:
    # 示例代码,没有实际意义model = Sequential()model.add(Conv2D(32, (3, 3), activation='relu'))  # 添加卷积层model.add(MaxPooling2D(pool_size=(2, 2)))         # 添加池化层model.add(Dropout(0.25))                          # 添加dropout层model.add(Conv2D(32, (3, 3), activation='relu'))  # 添加卷积层model.add(MaxPooling2D(pool_size=(2, 2)))         # 添加池化层model.add(Dropout(0.25))                          # 添加dropout层....   # 添加其他卷积操作model.add(Flatten())                            # 拉平三维数组为2维数组model.add(Dense(256, activation='relu'))        添加普通的全连接层model.add(Dropout(0.5))model.add(Dense(10, activation='softmax'))....  # 训练网络

    02

    LSTM网络

    当我们在网络上搜索看LSTM结构的时候,看最多的是下面这张图:

    0c4df1da5ecb02d187207eef23360363.png

    RNN网络 这是RNN循环神经网络经典的结构图,LSTM只是对隐含层节点A做了改进,整体结构不变,因此本文讨论的也是这个结构的可视化问题。 中间的A节点隐含层,左边是表示只有一层隐含层的LSTM网络,所谓LSTM循环神经网络就是在时间轴上的循环利用,在时间轴上展开后得到右图。 看左图,很多同学以为LSTM是单输入、单输出,只有一个隐含神经元的网络结构,看右图,以为LSTM是多输入、多输出,有多个隐含神经元的网络结构,A的数量就是隐含层节点数量。 WTH?思维转不过来啊。这就是传统网络和空间结构的思维。 实际上,右图中,我们看Xt表示序列,下标t是时间轴,所以,A的数量表示的是时间轴的长度,是同一个神经元在不同时刻的状态(Ht),不是隐含层神经元个数。 我们知道,LSTM网络在训练时会使用上一时刻的信息,加上本次时刻的输入信息来共同训练。 举个简单的例子:在第一天我生病了(初始状态H0),然后吃药(利用输入信息X1训练网络),第二天好转但是没有完全好(H1),再吃药(X2),病情得到好转(H2),如此循环往复知道病情好转。因此,输入Xt是吃药,时间轴T是吃多天的药,隐含层状态是病情状况。因此我还是我,只是不同状态的我。 实际上,LSTM的网络是这样的:
    d0a2e0f624b869805af54d5e3776ed0f.png LSTM网络结构
    上面的图表示包含2个隐含层的LSTM网络,在T=1时刻看,它是一个普通的BP网络,在T=2时刻看也是一个普通的BP网络,只是沿时间轴展开后,T=1训练的隐含层信息H,C会被传递到下一个时刻T=2,如下图所示。上图中向右的五个常常的箭头,所的也是隐含层状态在时间轴上的传递。

    29f3b3c0bf33d0641749e4f0aae15769.png

    注意,图中H表示隐藏层状态,C是遗忘门,后面会讲解它们的维度。

    03

    LSTM的输入结构

    为了更好理解LSTM结构,还必须理解LSTM的数据输入情况。仿照3通道图像的样子,在加上时间轴后的多样本的多特征的不同时刻的数据立方体如下图所示:
    aefb107da86050a38f6ebe0b9548e86c.png 三维数据立方体
    右边的图是我们常见模型的输入,比如XGBOOST,lightGBM,决策树等模型,输入的数据格式都是这种(N*F)的矩阵,而左边是加上时间轴后的数据立方体,也就是时间轴上的切片,它的维度是(N*T*F),第一维度是样本数,第二维度是时间,第三维度是特征数,如下图所示:
    e49ba3c43edb560a501c7a54f73ca3e5.png
    这样的数据立方体很多,比如天气预报数据,把样本理解成城市,时间轴是日期,特征是天气相关的降雨风速PM2.5等,这个数据立方体就很好理解了。在NLP里面,一句话会被embedding成一个矩阵,词与词的顺序是时间轴T,索引多个句子的embedding三维矩阵如下图所示:
    3c23d3cadd471e804d5afc5d04b82afc.png

    04

    pytorch中的LSTM

    4.1 pytorch中定义的LSTM模型

    pytorch中定义的LSTM模型的参数如下
    class torch.nn.LSTM(*args, **kwargs)参数有:    input_size:x的特征维度    hidden_size:隐藏层的特征维度    num_layers:lstm隐层的层数,默认为1    bias:False则bihbih=0和bhhbhh=0. 默认为True    batch_first:True则输入输出的数据格式为 (batch, seq, feature)    dropout:除最后一层,每一层的输出都进行dropout,默认为: 0    bidirectional:True则为双向lstm默认为False
    结合前面的图形,我们一个个看。 (1)input_size:x的特征维度,就是数据立方体中的F,在NLP中就是一个词被embedding后的向量长度,如下图所示:

    7d1453e70ad767b4ae3aaa4c295c48ca.png

    (2)hidden_size:隐藏层的特征维度(隐藏层神经元个数),如下图所示,我们有两个隐含层,每个隐藏层的特征维度都是5。注意,非双向LSTM的输出维度等于隐藏层的特征维度。

    f585f7a2f2bb653d678854dda37a3317.png

    (3)num_layers:lstm隐层的层数,上面的图我们定义了2个隐藏层。 (4)batch_first:用于定义输入输出维度,后面再讲。 (5)bidirectional:是否是双向循环神经网络,如下图是一个双向循环神经网络,因此在使用双向LSTM的时候我需要特别注意,正向传播的时候有(Ht, Ct),反向传播也有(Ht', Ct'),前面我们说了非双向LSTM的输出维度等于隐藏层的特征维度,而双向LSTM的输出维度是隐含层特征数*2,而且H,C的维度是时间轴长度*2。

    34de970d532b36c2ad7a2b2770bd3521.png

    4.2 喂给LSTM的数据格式

    pytorch中LSTM的输入数据格式默认如下:
    input(seq_len, batch, input_size)参数有:    seq_len:序列长度,在NLP中就是句子长度,一般都会用pad_sequence补齐长度    batch:每次喂给网络的数据条数,在NLP中就是一次喂给网络多少个句子    input_size:特征维度,和前面定义网络结构的input_size一致。
    前面也说到,如果LSTM的参数 batch_first=True,则要求输入的格式是:
    input(batch, seq_len, input_size)
    刚好调换前面两个参数的位置。其实这是比较好理解的数据形式,下面以NLP中的embedding向量说明如何构造LSTM的输入。 之前我们的embedding矩阵如下图:
    96b2daa7abcd3e596017933d6ac251a7.png
    如果把batch放在第一位,则三维矩阵的形式如下:
    5fe09bedb1e6fa26db4201fa31d7282e.png
    其转换过程如下图所示:
    cd45acc5c0cbe4396458af1afbfcede3.png
    看懂了吗,这就是输入数据的格式,是不是很简单。 LSTM的另外两个输入是 h0 和 c0,可以理解成网络的初始化参数,用随机数生成即可。
    h0(num_layers * num_directions, batch, hidden_size)c0(num_layers * num_directions, batch, hidden_size)参数:    num_layers:隐藏层数    num_directions:如果是单向循环网络,则num_directions=1,双向则num_directions=2    batch:输入数据的batch    hidden_size:隐藏层神经元个数
    注意,如果我们定义的input格式是:
    input(batch, seq_len, input_size)
    则H和C的格式也是要变的:
    h0(batc,num_layers * num_directions, h, hidden_size)c0(batc,num_layers * num_directions, h, hidden_size)

    4.3 LSTM的output格式

    LSTM的输出是一个tuple,如下:
    output,(ht, ct) = net(input)    output: 最后一个状态的隐藏层的神经元输出    ht:最后一个状态的隐含层的状态值    ct:最后一个状态的隐含层的遗忘门值
    output的默认维度是:
    output(seq_len, batch, hidden_size * num_directions)ht(num_layers * num_directions, batch, hidden_size)ct(num_layers * num_directions, batch, hidden_size)
    和input的情况类似,如果我们前面定义的input格式是:
    input(batch, seq_len, input_size)
    则ht和ct的格式也是要变的:
    ht(batc,num_layers * num_directions, h, hidden_size)ct(batc,num_layers * num_directions, h, hidden_size)
    说了这么多,我们回过头来看看ht和ct在哪里,请看下图:

    8961a113213621d2e11ec4b6ba4fdbc3.png

    output在哪里?请看下图:

    a7b64f4937bc972652778eaf5d87a10f.png

    05

    LSTM和其他网络组合

    还记得吗,output的维度等于隐藏层神经元的个数,即hidden_size,在一些时间序列的预测中,会在output后,接上一个全连接层,全连接层的输入维度等于LSTM的hidden_size,之后的网络处理就和BP网络相同了,如下图:
    4421943be9c59867f8e9168e8a435c44.png
    用pytorch实现上面的结构:
    import torchfrom torch import nnclass RegLSTM(nn.Module):    def __init__(self):        super(RegLSTM, self).__init__()        # 定义LSTM        self.rnn = nn.LSTM(input_size, hidden_size, hidden_num_layers)        # 定义回归层网络,输入的特征维度等于LSTM的输出,输出维度为1        self.reg = nn.Sequential(            nn.Linear(hidden_size, 1)        )    def forward(self, x):        x, (ht,ct) = self.rnn(x)        seq_len, batch_size, hidden_size= x.shape        x = y.view(-1, hidden_size)        x = self.reg(x)        x = x.view(seq_len, batch_size, -1)        return x
    当然,有些模型则是将输出当做另一个LSTM的输入,或者使用隐藏层ht,ct的信息进行建模,不一而足。 好了,以上就是我对LSTM的一些学习心得,看完记得关注点赞。 参考: https://zhuanlan.zhihu.com/p/94757947 https://zhuanlan.zhihu.com/p/59862381 https://zhuanlan.zhihu.com/p/36455374 https://www.zhihu.com/question/41949741/answer/318771336 https://blog.csdn.net/android_ruben/article/details/80206792

    本文目的在于学术交流,并不代表本公众号赞同其观点或对其内容真实性负责,版权归原作者所有,如有侵权请告知删除。

    96b2f3d8e027771de2520c7fe205aaa3.gif

    直播预告

    96b2f3d8e027771de2520c7fe205aaa3.gif 7483be98706695eac01bf5e226c0a008.png

    他山之石”历史文章

    • PointNet论文复现及代码详解

    • SCI写作常用句型之研究结果&发现

    • 白话生成对抗网络GAN及代码实现

    • pytorch的余弦退火学习率

    • Pytorch转ONNX-实战篇(tracing机制)

    • 联邦学习:FedAvg 的 Pytorch 实现

    • PyTorch实现ShuffleNet-v2亲身实践

    • 训练时显存优化技术——OP合并与gradient checkpoint

    • 浅谈数据标准化与Pytorch中NLLLoss和CrossEntropyLoss损失函数的区别

    • 在C++平台上部署PyTorch模型流程+踩坑实录

    • libtorch使用经验

    • 深度学习模型转换与部署那些事(含ONNX格式详细分析)

    • 如何支撑上亿类别的人脸训练?显存均衡的模型并行(PyTorch实现)

    • PyTorch trick 集锦

    d28285bad392010c6b22a045532bf127.png 6bc782e001ccfc061e148fd835420aa6.gif

    分享、点赞、在看,给个三连击呗!

    展开全文
  • 1.双向递归神经网络简介双向递归神经网络(Bidirectional Recurrent Neural Networks, Bi-RNN),是由Schuster和Paliwal于1997年首次提出的,和LSTM是在同一年被提出的。Bi-RNN的主要目标是增加RNN可利用的信息。RNN...

    1.双向递归神经网络简介

    双向递归神经网络(Bidirectional Recurrent Neural Networks, Bi-RNN),是由Schuster和Paliwal于1997年首次提出的,和LSTM是在同一年被提出的。Bi-RNN的主要目标是增加RNN可利用的信息。RNN无法利用某个历史输入的未来信息,Bi-RNN则正好相反,它可以同时使用时序数据中某个输入的历史及未来数据。
    Bi-RNN网络结构的核心是把一个普通的单项的RNN拆成两个方向,一个随时序正向的,一个逆着时序的反向的

    感觉上面的图就很直观了,看箭头就可以很容易的发现有正向的箭头和反向的箭头,也就代表时序的不同。注意一点就是,我们发现正向节点和反向节点是不共用的,作为输出的时候是两个节点输出一个结果。

    Bi-RNN中的每个RNN单元既可以是传统的RNN,也可以是LSTM单元或者GRU单元,同样也可以叠加多层Bi-RNN,进一步抽象的提炼出特征。如果最后使用作分类任务,我们可以将Bi-RNN的输出序列连接一个全连接层,或者连接全局平均池化Global Average Pooling,最后再接Softmax层,这部分和使用卷积神经网络部分一致,如果有不理解Softmax这些概念的建议看下cs231n系列的课程,里面的概念还是讲解的非常清晰的。

    2.Bidirectional LSTM Classifier的代码实现




    #coding:utf-8
    #代码主要是使用Bidirectional LSTM Classifier对MNIST数据集上进行测试
    #导入常用的数据库,并下载对应的数据集
    import tensorflow as tf
    import numpy as np
    from tensorflow.examples.tutorials.mnist import input_data
    mnist = input_data.read_data_sets("E:/Anaconda/DATA/sp504", one_hot = True)
    #设置对应的训练参数
    learning_rate = 0.01
    max_samples = 400000
    batch_size = 128
    display_step = 10
    n_input = 28
    n_steps = 28
    n_hidden = 256
    n_classes = 10
    #创建输入x和学习目标y的placeholder,这里我们的样本被理解为一个时间序列,第一个维度是时间点n_step,第二个维度是每个时间点的数据n_inpt。同时,在最后创建Softmax层的权重和偏差
    x = tf.placeholder("float", [None, n_steps, n_input])
    y = tf.placeholder("float", [None, n_classes])
    weights = tf.Variable(tf.random_normal([2 * n_hidden, n_classes]))
    biases = tf.Variable(tf.random_normal([n_classes]))
    #定义Bidirectional LSTM网络的生成函数
    def BiRNN(x, weights, biases):
        x = tf.transpose(x, [1, 0, 2])
        x = tf.reshape(x, [-1, n_input])
        x = tf.split(x, n_steps)
        lstm_fw_cell = tf.contrib.rnn.BasicLSTMCell(n_hidden, forget_bias = 1.0)
        lstm_bw_cell = tf.contrib.rnn.BasicLSTMCell(n_hidden, forget_bias = 1.0)
        outputs, _, _ = tf.contrib.rnn.static_bidirectional_rnn(lstm_fw_cell,
                                                                lstm_bw_cell, x,
                                                                dtype = tf.float32)
        return tf.matmul(outputs[-1], weights) + biases
    #使用tf.nn.softmax_cross_entropy_with_logits进行softmax处理并计算损失
    pred = BiRNN(x, weights, biases)
    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = pred, labels = y))
    optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(cost)
    correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
    init = tf.global_variables_initializer()
    #开始执行训练和测试操作
    with tf.Session() as sess:
        sess.run(init)
        step = 1
        while step * batch_size < max_samples:
            batch_x, batch_y = mnist.train.next_batch(batch_size)
            batch_x = batch_x.reshape((batch_size, n_steps, n_input))
            sess.run(optimizer, feed_dict = {x: batch_x, y: batch_y})
            if step % display_step == 0:
                acc = sess.run(accuracy, feed_dict = {x: batch_x, y: batch_y})
                loss = sess.run(cost, feed_dict = {x: batch_x, y: batch_y})
                print("Iter" + str(step * batch_size) + ", Minibatch Loss = " + \
                    "{:.6f}".format(loss) + ", Training Accuracy = " + \
                    "{:.5f}".format(acc))
            step += 1
        print("Optimization Finished!")
        test_len = 10000
        test_data = mnist.test.images[:test_len].reshape((-1, n_steps, n_input))
        test_label = mnist.test.labels[:test_len]
        print("Testing Accuracy:", sess.run(accuracy, feed_dict = {x: test_data, y: test_label}))

    展开全文
  • RNN结构双向LSTM,Transformer, BERT对比分析

    万次阅读 多人点赞 2019-07-19 10:01:56
    最近接到一些秋招面试,发现自己对于好多网络结构都模糊了,刚好最近在调研模型,就趁这个机会把之前的常见模型知识梳理一下。 主要参考文档: https://jalammar.github.io/illustrated-transformer/ ...
  • 多层双向和单向LSTM递归神经网络用于全网络交通速度预测 Stacked Bidirectional and Unidirectional LSTM Recurrent Neural Network for Network-wide Traffic Speed Prediction Short-term traffic forecasting ...
  • 【pytorch】双向LSTM实现文本情感分析

    千次阅读 2021-03-29 08:07:52
    output的拼接顺序: 正向第一个 <–> 方向最后一个 最后一个维度拼接 # 双向的LSTML中的最后一个时间步的output # 正向 last_output = output[:,-1,:18] # 反向 last_output = output[:,0,18:] # 获取双向LSTM中最后...
  • 二是构建双向RNN模型,这在自然语言处理中比较常见,比如Bi-LSTM+CRF做命名实体识别。 一、堆叠RNN、LSTM和GRU 1、堆叠RNN的结构和特性 RNN的一般性内容就不介绍了,如果不熟悉请看以上列出的笔记。我们先来看看堆叠...
  • 单层LSTM多层LSTM的输入与输出

    千次阅读 多人点赞 2020-06-10 11:44:09
    上图是单层LSTM的输入输出结构图。其实它是由一个LSTM单元的一个展开,如下图所示: 所以从左到右的每个LSTM Block只是对应一个时序中的不同的步。 在第一个图中,输入的时序特征有S个,长度记作:seq_len,每个...
  • RNN、LSTM、GRU、多层LSTM、Bi-LSTM

    千次阅读 2020-03-16 21:35:58
    有些时候,主要考虑的是哪些输入,有时候,考虑的是(输入,输出)之间的模型; 一、RNN f,g 就是普通的激活函数,可能是tanh...三、多层RNN/LSTM 多层RNN中,第一层的输入是Ht1~ (Xt, Ht-1),后面层的输入不再...
  • 关于双向LSTM,理解的思路是:双向LSTM是LSTM的改进版,LSTM是RNN的改进版。因此,首先需要理解RNN。 笔者曾在拙作 《从Boosting学习到神经网络:看山是山?》 说到过,模型的输出结果,事实上也是一种特征,也...
  • 文章目录一、词的表示二、LSTM概述2.1 标准RNN结构如下(单个tanh层)2.2 lstm 结构图如下2.3 lstm的4层交互结构说明:三、ELMO模型概述3.1 问题引入问题①:红框ELMO内部究竟是啥玩意?问题②:是直接将词输入到ELMO...
  • size], datasetX[train_size:len(datasetX), :], datasetY[train_size:len(datasetX)] ###################投入到 LSTM 的 X 需要有这样的结构: [samples, timesteps, features],所以做一下变换 trainX = trainX....
  • 文章目录前言第一课 论文导读机器翻译简介机器翻译相关方法前期知识储备第二课 论文精读 前言 本课程来自深度之眼deepshare.net,...使用多层LSTM的Seq2Seq模型 作者:llya Sutskever,Oriol Vinyals,Quoc V. Le 单...
  • 以最简单的网络结构为例,假如有三个隐藏层,每层的神经元个数都是1,且对应的非线性函数为 yi=σ(zi)=σ(wixi+bi)y_i=\sigma (z_i) = \sigma(w_ix_i+b_i)yi​=σ(zi​)=σ(wi​xi​+bi​), 如下: ​​ 引起梯度...
  • Pytorch实现的LSTM模型结构

    千次阅读 2021-03-27 19:25:40
    LSTM模型结构1、LSTM模型结构2、LSTM网络3、LSTM的输入结构4、Pytorch中的LSTM4.1、pytorch中定义的LSTM模型4.2、喂给LSTM的数据格式4.3、LSTM的output格式5、LSTM和其他网络组合 1、LSTM模型结构 BP网络和CNN网络...
  • RNN模型输出序列的长度只能和输入...将一个英文句子的每个token向量依次传入(即整个句子的矩阵表示,传进去他会依次进行)LSTM Encoder,然后得到最后时刻的 h,c ,将他们作为LSTM Decoder的初始 h,c。decoder的输入
  • “他山之石,可以攻玉”,站在巨人的肩膀才能看得更高,走得更远。在科研的道路上,更需借助...作者:知乎—master苏地址:https://www.zhihu.com/people/zhenyu22最近在学习LSTM应用在时间序列的预测上,但是遇到...
  • LSTM

    2019-06-12 17:09:56
    RNN内部通过σ(Wx+b)将输入x转成输出h。这里的参数W每一步都是一样的,即参数共享,其维度为[embed_dim, hidden_size]。...lstm 及变体https://www.cnblogs.com/wangduo/p/6773601.html?utm_source=itdadao&...
  • 双向LSTM 对航空乘客预测双向LSTM网络对其进行预测。 MLP多层感知器 对航空乘客预测 使用MLP 对航空乘客预测 本文采用的CNN + LSTM网络对其进行预测。 我喜欢直接代码+ 结果展示 先代码可以跑通,才值得深入研究每...
  • 双向LSTM 对航空乘客预测双向LSTM网络对其进行预测。 MLP多层感知器 对航空乘客预测简化版 使用MLP 对航空乘客预测 CNN + LSTM 航空乘客预测采用的CNN + LSTM网络对其进行预测。 ConvLSTM 航空乘客预测采用Co

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,237
精华内容 1,294
关键字:

多层双向lstm结构图