精华内容
下载资源
问答
  • 长短时神经网络
    千次阅读
    2018-07-15 10:33:45

    点击查看完整代码http://www.daimapi.com/neuralnetwork3_1/


    LSTM(Long Short-Term Memory)是长短期记忆网络,是一种时间递归神经网络,适合于处理和预测时间序列中间隔和延迟相对较长的重要事件。LSTM 已经在科技领域有了多种应用。基于LSTM的系统可以学习翻译语言、控制机器人、图像分析、文档摘要、语音识别图像识别、手写识别、控制聊天机器人、预测疾病、点击率和股票、合成音乐等等任务。

    该代码不使用任何第三方深度学习工具包实现,利用Python3实现。

    # -*- coding: utf-8 -*-
    import copy, numpy as np
    np.random.seed(0)
    
    # 计算sigmoid函数的值
    def sigmoid(x):
        output = 1/(1+np.exp(-x))
        return output
    
    # 利用sigmoid函数计算误差
    def sigmoid_output_to_derivative(output):
        return output*(1-output)
    
    # 训练数据集并进行迭代
    int2binary = {}
    binary_dim = 8
    
    largest_number = pow(2,binary_dim)
    binary = np.unpackbits(np.array([range(largest_number)],dtype=np.uint8).T,axis=1)
    for i in range(largest_number):
        int2binary[i] = binary[i]
    
    # 设置LSTM的参数
    alpha = 0.1
    input_dim = 2
    hidden_dim = 16
    output_dim = 1
    
    # 初始化神经网络的权重
    synapse_0 = 2*np.random.random((input_dim,hidden_dim)) - 1
    synapse_1 = 2*np.random.random((hidden_dim,output_dim)) - 1
    synapse_h = 2*np.random.random((hidden_dim,hidden_dim)) - 1
    
    synapse_0_update = np.zeros_like(synapse_0)
    synapse_1_update = np.zeros_like(synapse_1)
    synapse_h_update = np.zeros_like(synapse_h)
    
    # 进行训练
    for j in range(10000):

    更多相关内容
  • 长短时记忆网络(Long Short Term Memory Network, LSTM),它有效地解决了原始循环神经网络(RNN)的缺陷,在语音识别、图片描述、自然语言处理等许多领域中成功应用。本文讲解由三个Gate(input、forget、output)和一...
  • 基于神经网络(堆栈自编码SAEs、长短时神经网络LSTM、门循环单元GRU)的交通流预测 Python 3.6 Tensorflow-gpu 1.5.0 Keras 2.1.3 scikit-learn 0.19 交通流预测
  • 基于双向长短时神经网络的水量预测方法研究.pdf
  • 基于深度卷积长短时神经网络的视频帧预测.pdf
  • 基于长短时神经网络的城市需水量预测应用.pdf
  • 基于多因素长短时神经网络的日用水量预测方法研究.pdf
  • 长短时记忆神经网络(LSTM)

    万次阅读 多人点赞 2020-09-24 20:27:36
    下面为翻译文章,会稍有增删: ...循环神经网络 人类不会每秒都从头开始思考。 阅读本文,您会根据对先前单词的理解来理解每个单词。 您不会丢掉一切,重新从头开始思考。 传统的神经网络无法做到这一

    下面为翻译文章,会稍有增删:

    原文:http://colah.github.io/posts/2015-08-Understanding-LSTMs/

    其他人的翻译:https://www.xiemingzhao.com/posts/eff2088e.html

    类似的文章:https://www.jianshu.com/p/8219ca28925e

    循环神经网络

    人类不会每秒都从头开始思考。 阅读本文时,您会根据对先前单词的理解来理解每个单词。 您不会丢掉一切,重新从头开始思考。 传统的神经网络无法做到这一点,这似乎是一个重大缺陷。 例如,假设您想对电影中每个点发生的事件进行分类。 尚不清楚传统的神经网络如何利用电影中先前事件的推理来告知后期事件。循环神经网络解决了这个问题。 它是具有循环的网络,可以使信息持久存在。

    图1 循环神经网络

    上面的循环神经网络,以 x t x_t xt 作为网络的输入,然后输出 h t h_t ht ,循环使得信息可以从当前步流动到下一步。

    这些循环使这个神经网络显得有些神秘。 但是,如果您再想一想,就会发现它们与普通的神经网络并没有什么不同。 循环神经网络可以看作是同一网络的多个副本,每个副本都将消息传递给后继者。 考虑一下如果展开循环会发生什么:

    在这里插入图片描述

    图2 展开的循环神经网络

    这种类似链的性质表明,循环神经网络与序列和列表密切相关。 它们是用于此类数据的神经网络的自然架构。

    在过去的几年中,将RNN应用到各种问题上已经取得了令人难以置信的成功:语音识别,语言建模,翻译,图像字幕…清单还在继续。 我将在Andrej Karpathy的出色博客文章 “The Unreasonable Effectiveness of Recurrent Neural Networks” 中讨论使用RNN可以实现的惊人成就。 但是它们确实非常惊人。

    这些成功的关键是使用“ LSTM”,这是一种非常特殊的循环神经网络,在许多任务上都能比标准版本好得多。 几乎所有令人兴奋的结果都是利用循环神经网络实现的。 本文将探讨的是这些LSTM

    长时依赖问题

    RNNs有吸引力的一个地方是它可以将先前的信息连接到当前的任务上,例如使用先前的视频帧可能会有助于对当前帧的理解。如果RNNs可以做到这一点,将变得十分有用,但是可以做到吗?

    有时,我们只需要查看最近的信息即可执行当前任务。 例如,考虑一种语言模型,该模型试图根据先前的单词预测下一个单词。 如果我们试图预测 “the clouds are in the sky” 的最后一个词,那么我们不需要任何进一步的上下文——很明显,下一个词将是“sky”。 在这种情况下,相关信息与所需信息之间的距离很小,RNN可以学习使用过去的信息。

    在这里插入图片描述

    图3

    但是这里也存在一些需要更多上下文信息的情况。想一下如果我们想要预测最后一个单词 “I grew up in France… I speak fluent French.” 从最近的信息来看,要预测的单词应该是一种语言的名字,但是要确定是那种语言,我们需要更前面单词 “France” 的上下文信息。这说明相关信息与当前任务的距离可能非常远。

    在这里插入图片描述

    图4

    从理论上来说,RNNs完全有能力处理这样的长时依赖,人类可以仔细的选择参数以解决这类简单问题。不幸的是,在实践中,RNNs看起来并没有能力处理他们。Hochreiter(1991)[German]Bengio, et al. (1994)等人对此问题进行了深入探讨,发现了处理这类问题变困难的根本原因。

    谢天谢地,LSTMs没有这个问题。

    LSTM网络

    长短时记忆神经网络(Long Short Term networks),通常叫做LSTMs,是一种能够捕捉长时依赖的特殊循环神经网络。它们由Hochreiter & Schmidhuber (1997) 提出,然后被许多人在后来的工作中进行精炼和推广。他们的工作在各种问题上表现都非常好,现在也被广泛使用。

    LSTMs是专门设计用来避免长时依赖问题的。长时间的记住信息已经成为了它的默认行为,不需要专门去学习。

    所有的LSTMs都有重复神经网络模块的链式形式。在标准的RNNs中,这个重复的模块可以是非常简单的结构,例如单个tanh层。

    在这里插入图片描述

    图5 包含单个tanh层的标准RNN重复模块

    LSTMs同样也有类似的链式结构,但是重复的模块有不同的结构。不是只有一个神经网络层,而是四个,以一种非常特殊的方式进行交互。

    在这里插入图片描述

    图6 包含四个交互层的LSTM重复模块

    不需要担心在模型中计算的细节。我们之后将一步步浏览整个LSTM网络。现在先来熟悉一下将要使用到的符号表示。

    在这里插入图片描述

    图7 网络中的符号含义
    1. 神经网络层(用于学习)
    2. 逐点操作(逐点相乘、逐点相加)
    3. 向量转移(向量沿箭头方向移动)
    4. 连接(将两个向量连接在一起)
    5. 复制(将向量复制为两份)
    LSTMs背后的核心思想

    LSTMs的关键是细胞状态(cell state),水平的线贯穿图的顶部。细胞状态就像一个传送带,它沿整个链条一直沿直线延伸,只有一些较小的线性相互作用。 信息不加改变地流动非常容易。

    在这里插入图片描述

    图8

    LSTM有能力向细胞状态添加或者移除信息,这些操作由门(gate)结构来精细调控。门结构是一种让信息有选择通过的方式。他们由一个sigmoid神经网络层和一个点乘操作构成。

    在这里插入图片描述

    图9

    sigmoid层输出的数据在0-1之间,表示每一个组件应该通过多少信息。如果为0则表示任何信息都无法通过,如果为1则表示所有信息都可以通过。

    一个LSTM有三个这样的门来保护和控制细胞状态。

    一步步看LSTM

    LSTM的第一个步骤是决定需要从细胞状态中丢弃哪些信息。这个是由一个sigmoid层也叫做遗忘门(forget gate)来决定的。它输入 h t − 1 h_{t-1} ht1 x t x_t xt ,然后经过sigmoid层后,得到0-1之间的输出 f t f_t ft 。之后跟细胞状态 C t − 1 C_{t-1} Ct1 逐点相乘。如果 f t f_t ft 对应的值为0,则丢弃对应的信息,反之,则保留对应的信息。

    在这里插入图片描述

    图10

    解释一下:

    C t − 1 C_{t-1} Ct1 是上一时刻的细胞状态

    h t − 1 h_{t-1} ht1 是上一时刻的模块输出

    σ \sigma σ 代表sigmoid层,每一个数据都需要经过sigmoid函数

    f t f_t ft 代表遗忘门的输出

    W f W_f Wf 代表权重矩阵

    b f b_f bf 代表偏置

    [ h t − 1 , x t ] [h_{t-1},x_t] [ht1,xt] 代表将两个矩阵拼接在一起

    LSTM的下一个步骤是要决定将哪些信息存储在细胞状态中,这包含两个部分:

    1.首先有一个sigmoid层叫做“输入门层”,它决定我们将更新哪些信息。

    2.下一步,一个tanh层创建候选值的向量, C ~ t \tilde{C}_t C~t ,决定哪些信息能够被加到细胞状态中

    接下来,我们将结合着两个部分对细胞状态进行更新。

    在这里插入图片描述

    图11

    现在我们来将细胞状态 C t − 1 C_{t-1} Ct1 更新为 C t C_t Ct

    我们先用旧的状态 C t − 1 C_{t-1} Ct1 对应点乘 f t f_t ft ,即 C t − 1 ∗ f t C_{t-1} * f_t Ct1ft ,用来丢弃我们已经决定要遗忘的信息,然后再加上 i t ∗ C ~ t i_t * \tilde{C}_t itC~t ,最终构成细胞状态 C t C_t Ct 。这是新的候选值,根据我们决定更新每个状态值的大小来缩放。

    在这里插入图片描述

    图12

    最后我们需要决定我们的输出,输出取决于我们的细胞状态,但是应当是一个过滤的版本。首先,首先我们要运行一个sigmoid层来决定要输出细胞状态的哪些信息。然后将细胞状态通过tanh层然后乘以sigmoid层的输出,最后我们就可以输出我们想要输出的部分。

    在这里插入图片描述

    图12
    长短时记忆神经网络的变体

    我们到目前为止讨论的都是普通的长短时记忆神经网络。但是并不是所有的LSTMs都跟上面的一样。事实上,几乎每一个涉及到LSTMs的文章都使用了一些不同的版本。这些版本的区别很小,但是值得一提。

    其中一个受欢迎的LSTM变体,由Gers & Schmidhuber (2000)提出,添加了窥视孔连接,这意味着可以让门层看到细胞状态。

    在这里插入图片描述

    图13

    上面的图对每一个门都添加了窥视孔,但是很多文章都仅仅给一部分门窥视孔。

    另一个变体使用了双输入和输出门。与单独决定要遗忘或者添加一些信息不同,这个网络同时决定这两件事情。当我们要添加一些信息的时候,才会遗忘这个地方的信息;当我们要遗忘更旧信息的时候,才会在这个地方添加新值。这两句话看起来是在表述一个意思,但是仔细品品,又有些不一样的意味。

    在这里插入图片描述

    图14

    一个有些戏剧性的LSTM变体是门控循环单元(Gate Recurrent Unit,GRU)Cho, et al. (2014)。它结合了遗忘和输入门成为一个单一的“更新门”,它还结合了细胞状态和隐藏状态,并且做了一些其他的改变。最终的模型比标准的LSTM模型更简单,而且越来越受欢迎。

    在这里插入图片描述

    图15

    这里仅仅只有一些值得注意的LSTM变体。还有许多其他的例如:Depth Gated RNNs by Yao, et al. (2015) 。同样也有完全不同的方法去解决长时依赖,像Clockwork RNNs by Koutnik, et al. (2014)

    这些LSTM变体中那个是最好的?差异重要吗?Greff, et al. (2015) 对受欢迎的变体做了一个比较,发现他们都是一样的。Jozefowicz, et al. (2015) 测试了超过一万个RNN结构,发现一些RNN在特定任务上表现要比LSTMs更好。

    总结

    之前,我提到了人们使用RNN所取得的非凡成就。基本上所有这些都是使用LSTM实现的。对于大多数任务,它们确实工作得更好!

    写成一组方程式,LSTM看起来很吓人。希望本文逐步介绍它们,使他们变得更加平易近人。

    LSTM是我们可以使用RNN完成的重要一步。很自然地想:还有另外一个大步吗?研究人员普遍认为:“是的!有下一步,Attention!”这个想法是让RNN的每一步都从更大的信息集合中选择信息。例如,如果您使用RNN创建描述图像的标题,则它可能会选择图像的一部分以查看其输出的每个单词。实际上,Xu, et al. (2015) 正是这样做的-如果您想探索Attention,这可能是一个有趣的起点!Attention取得了许多令人振奋的结果,而且似乎还有很多其他的任务……

    Attention不仅仅是RNN研究中唯一令人兴奋的话题。例如,Grid LSTMs by Kalchbrenner, et al. (2015) 看起来更具有前途。将RNNs用于生成模型中也十分有趣,例如: Gregor, et al. (2015), Chung, et al. (2015), 以及 Bayer & Osendorfer (2015) 。最近几年对于递归神经网络来说是一个令人振奋的时刻,而即将到来的几年有望如此!

    致谢

    展开全文
  • 长短时记忆神经网络(Long Short-term Memory Networks,简称LSTM)是特殊的RNN,尤其适合顺序序列数据的处理,LSTM 由 Hochreiter & Schmidhuber (1997) 提出,并在近期被 Alex Graves 进行了改良和推广,LSTM...
    • 本文收录于《深入浅出讲解自然语言处理》专栏,此专栏聚焦于自然语言处理领域的各大经典算法,将持续更新,欢迎大家订阅!
    • ​个人主页:有梦想的程序星空
    • ​个人介绍:小编是人工智能领域硕士,全栈工程师,深耕Flask后端开发、数据挖掘、NLP、Android开发、自动化等领域,有较丰富的软件系统、人工智能算法服务的研究和开发经验。
    • ​如果文章对你有帮助,欢迎关注点赞收藏订阅。

    1、LSTM的背景介绍

            长短时记忆神经网络(Long Short-term Memory Networks,简称LSTM)是特殊的RNN,尤其适合顺序序列数据的处理,LSTM 由 Hochreiter & Schmidhuber (1997) 提出,并在近期被 Alex Graves 进行了改良和推广,LSTM明确旨在避免长期依赖性问题,成功地解决了原始循环神经网络的缺陷,成为当前最流行的RNN,在语音识别、图片描述、自然语言处理等许多领域中成功应用。

    2、RNN的不足

    图1 RNN的网络结构图 

            循环神经网络处理时间序列数据具有先天优势,通过反向传播和梯度下降算法达到了纠正错误的能力,但是在进行反向传播时也面临梯度消失或者梯度爆炸问题,这种问题表现在时间轴上。如果输入序列的长度很长,人们很难进行有效的参数更新。通常来说梯度爆炸更容易处理一些。梯度爆炸时我们可以设置一个梯度阈值,当梯度超过这个阈值的时候可以直接截取。

            有三种方法应对梯度消失问题:

            (1)合理的初始化权重值。初始化权重,使每个神经元尽可能不要取极大或极小值,以躲开梯度消失的区域。

            (2)使用 ReLu 代替 sigmoid 和 tanh 作为激活函数。

            (3)使用其他结构的RNNs,比如长短时记忆网络(LSTM)和 门控循环单元 (GRU),这是最流行的做法。

    3、LSTM的结构和原理

    图2 LSTM的结构图 

    上图中使用的各个元素的图标的含义如下图所示:

    其中:

    Neural Network Layer:神经网络层,用于学习;

    Pointwise Operation:逐点运算操作,如逐点相乘、逐点相加、向量和等;

    Vector Transfer:向量转移,向量沿箭头方向移动;

    Concatenate:连接,将两个向量连接在一起;

    Copy:复制,将向量复制为两份。

            LSTM核心是细胞状态,穿过图的顶部的长横线,长直线称之为细胞状态(Cell State),决定什么样的信息会被保留,什么样的信息会被遗忘,记为{C_t}

            细胞状态像传送带一样,它贯穿整个细胞却只有很少的分支,这样能保证信息不变的流过整个RNN,细胞状态如下图所示:

    图3 细胞状态图

            LSTM网络能通过一种被称为门的结构对细胞状态进行删除或者添加信息。门能够有选择性的决定让哪些信息通过。门的结构为一个sigmoid层和一个点乘操作的组合,sigmoid层输出0到1之间的数,描述每个部分有多少量可以通过,0代表不允许任何量通过,1表示允许任何量通过,结构如下图所示:

    图4 门结构单元

             LSTM实现了三个门计算,即遗忘门、输入门和输出门,用来保护和控制细胞状态。

            遗忘门负责决定保留多少上一时刻的单元状态到当前时刻的单元状态,即决定从细胞状态中丢弃什么信息。该门读取{h_{t - 1}}{x_t},然后经过sigmoid层后,输出一个0-1之间的数{f_t}给每个在细胞状态{C_{t - 1}}中的数字逐点相乘。{f_t}的值为0表示完全丢弃,1表示完全保留。结构如下图所示:

    图5 遗忘门结构图 

            输入门负责决定保留多少当前时刻的输入到当前时刻的单元状态,包含两个部分,第一部分为sigmoid层,该层决定要更新什么值,第二部分为tanh层,该层把需要更新的信息更新到细胞状态里。tanh层创建一个新的细胞状态值向量{\tilde C_t}{\tilde C_t}会被加入到状态中。结构如下图:

    图6 输入门结构图 

            然后就到了更新旧细胞状态的时间了,将{C_{t - 1}}更新为{C_t},把旧状态与{f_t}相乘,丢弃确定需要丢弃的信息,再加上{i_t}*{\tilde C_t} ,这样就完成了细胞状态的更新,结构如下图所示:

     图7 更新旧细胞状态

            输出门负责决定当前时刻的单元状态有多少输出,通过一个sigmoid层来确定细胞状态的哪个部分将输出出去。把细胞状态通过tanh进行处理,得到一个-1到1之间的值,并将它和sigmoid门的输出相乘,最终仅仅输出确定输出的部分。结构如下图所示:

    图8 输出门的结构

    4、LSTM的训练过程

            LSTM的参数训练算法,依然是反向传播算法。主要有如下三个步骤:

            第一步:前向计算每个神经元的输出值。对于LSTM而言,依据前面介绍的算法,分别进行计算。

            第二步:确定优化目标函数。在训练早期,输出值和预期值会不一致,于是计算每个神经元的误差项值,构造出损失函数。

            第三步:根据损失函数的梯度指引,更新网络权值参数。与传统RNN类似,LSTM误差项的反向传播包括两个层面:一个是空间上层面的,将误差项向网络的上一层传播。另一个是时间层面上的,沿时间反向传播,即从当前t时刻开始,计算每个时刻的误差。

            然后跳转第一步,重复做第一、二和三步,直至网络误差小于给定值。

    关注微信公众号【有梦想的程序星空】,了解软件系统和人工智能算法领域的前沿知识,让我们一起学习、一起进步吧!

    展开全文
  • 基于长短时神经网络(LSTM)+word2vec的情感分析

    千次阅读 多人点赞 2020-01-19 16:51:18
    前言: 毕业前的项目,最近终于有时间整理个博客出来。使用的keras+gensim完成,也...当特征小于max_len,根据max_len填充其余位数为0。 当特征大于max_len,则进行截断。 在本项目中,我定义的max_len为150,...

    前言:
    毕业前的项目,最近终于有时间整理个博客出来。使用的keras+gensim完成,也参考了互联网很多相关资料。最终效果只有88%左右,不过优化空间很大,只用作学习demo

    数据集使用的是谭松波酒店评论数据集 停用词我自己整理了一个停用词词典 分享给大家
    链接:https://pan.baidu.com/s/1ZkMGAUH7VSxJALWBs41iKQ
    提取码:2c1e

    1.数据处理

    这一步主要是对评论文本做清洗,在这里只做简单的去停用词
    首先写一个去停用词的方法

    import jieba
    
    f = open('./stop_words.txt', encoding='utf-8')         # 加载停用词
    stopwords = [i.replace("\n", "") for i in f.readlines()]    # 停用词表
    
    def del_stop_words(text):
    	"""
    	删除每个文本中的停用词
    	:param text:
    	:return:
    	"""
    	word_ls = jieba.lcut(text)
    	word_ls = [i for i in word_ls if i not in stopwords]
    	return word_ls
    

    然后读取正面评论与负面评论的语料 并进行清洗

    with open("./test_data/neg.txt", "r", encoding='UTF-8') as e:     # 加载负面语料
        neg_data1 = e.readlines()
    
    with open("./test_data/pos.txt", "r", encoding='UTF-8') as s:     # 加载正面语料
        pos_data1 = s.readlines()
    
    neg_data = sorted(set(neg_data1), key=neg_data1.index)  #列表去重 保持原来的顺序
    pos_data = sorted(set(pos_data1), key=pos_data1.index)
    
    neg_data = [del_stop_words(data.replace("\n", "")) for data in neg_data]   # 处理负面语料
    pos_data = [del_stop_words(data.replace("\n", "")) for data in pos_data]
    all_sentences= neg_data + pos_data  # 全部语料 用于训练word2vec
    

    2. 文本向量化

    对于文本的向量化其实有很多方式,包括独热(one-hot),词袋模型(bag of words),逆文本特征频率(tf-idf)和word2vec等。

    本项目我们使用word2vec(据说效果很好)进行词向量的提取,word2vec是使用深度学习的方式将词映射为一个多维向量。

    首先顶级模型结构 并进行训练及保存

    from gensim.models.word2vec import Word2Vec
    from gensim.corpora.dictionary import Dictionary
    import pockle
    import logging
    
    logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)  # 将日志输出到控制台
    
    model = Word2Vec(all_sentences,     # 上文处理过的全部语料
                     size=150,  # 词向量维度 默认100维
                     min_count=1,  # 词频阈值 词出现的频率 小于这个频率的词 将不予保存
                     window=5  # 窗口大小 表示当前词与预测词在一个句子中的最大距离是多少
                     )
    model.save('./models/Word2vec_v1')  # 保存模型
    

    然后加载模型 提取出词的索引与向量

    def create_dictionaries(model):
    	"""
    	创建词语字典,并返回word2vec模型中词语的索引,词向量
    	"""
        gensim_dict = Dictionary()    # 创建词语词典
        gensim_dict.doc2bow(model.wv.vocab.keys(), allow_update=True)
    
        w2indx = {v: k + 1 for k, v in gensim_dict.items()}  # 词语的索引,从1开始编号
        w2vec = {word: model[word] for word in w2indx.keys()}  # 词语的词向量
        return w2indx, w2vec
    
    
    model = Word2Vec.load('./models/Word2vec_v1')         # 加载模型
    index_dict, word_vectors= create_dictionaries(model)  # 索引字典、词向量字典
    

    使用 pickle 存储序列化数据 pickle是一个非常方便的库 可以将py的字典 列表等等程序运行过程中的对象存储为实体数据

    output = open(pkl_name + ".pkl", 'wb')      
    pickle.dump(index_dict, output)  # 索引字典
    pickle.dump(word_vectors, output)  # 词向量字典
    output.close()
    

    3. LSTM训练

    接下来 使用keas库搭建LSTM模型 来进行训练
    首先我们定义几个必要参数

    # 参数设置
    vocab_dim = 150 # 向量维度
    maxlen = 150 # 文本保留的最大长度
    batch_size = 100 # 训练过程中 每次传入模型的特征数量
    n_epoch = 4   # 迭代次数
    
    

    加载词向量数据 并填充词向量矩阵

    f = open("./model/评价语料索引及词向量2.pkl", 'rb')  # 预先训练好的
    index_dict = pickle.load(f)    # 索引字典,{单词: 索引数字}
    word_vectors = pickle.load(f)  # 词向量, {单词: 词向量(100维长的数组)}
    
    n_symbols = len(index_dict) + 1  # 索引数字的个数,因为有的词语索引为0,所以+1
    embedding_weights = np.zeros((n_symbols, 150))  # 创建一个n_symbols * 1000矩阵
    
    for w, index in index_dict.items():  # 从索引为1的词语开始,用词向量填充矩阵
        embedding_weights[index, :] = word_vectors[w]  # 词向量矩阵,第一行是0向量(没有索引为0的词语,未被填充)
    

    接下来将所有的评论数据映射成为数字
    因为之前通过加载词向量 已经拥有了一个索引字典
    只要将出现在的索引字典中的单词转换为其索引数字 未出现的转换为0即可

    def text_to_index_array(p_new_dic, p_sen): 
        """
        文本或列表转换为索引数字
        :param p_new_dic:
        :param p_sen:
        :return:
        """
        if type(p_sen) == list:
            new_sentences = []
            for sen in p_sen:
                new_sen = []
                for word in sen:
                    try:
                        new_sen.append(p_new_dic[word])  # 单词转索引数字
                    except:
                        new_sen.append(0)  # 索引字典里没有的词转为数字0
                new_sentences.append(new_sen)
            return np.array(new_sentences)   # 转numpy数组
        else:
            new_sentences = []
            sentences = []
            p_sen = p_sen.split(" ")
            for word in p_sen:
                try:
                    sentences.append(p_new_dic[word])  # 单词转索引数字
                except:
                    sentences.append(0)  # 索引字典里没有的词转为数字0
            new_sentences.append(sentences)
            return new_sentences
    

    加载特征与标签 将特征全部映射成数字 并且分割验证集和测试集

    with open("./原始语料/neg.txt", "r", encoding='UTF-8') as f:
                neg_data1 = f.readlines()
    
    with open("./原始语料/pos.txt", "r", encoding='UTF-8') as g:
        pos_data1 = g.readlines()
    
    neg_data = sorted(set(neg_data1), key=neg_data1.index)  #列表去重 保持原来的顺序
    pos_data = sorted(set(pos_data1), key=pos_data1.index)
    
    neg_data = [process_txt(data) for data in neg_data]
    pos_data = [process_txt(data) for data in pos_data]
    data = neg_data + pos_data
    
    
    # 读取语料类别标签
    label_list = ([0] * len(neg_data) + [1] * len(pos_data))
    
    
    # 划分训练集和测试集,此时都是list列表
    X_train_l, X_test_l, y_train_l, y_test_l = train_test_split(data, label_list, test_size=0.2)
    
    # 转为数字索引形式
    
    # token = Tokenizer(num_words=3000)   #字典数量
    # token.fit_on_texts(train_text)
    
    X_train = text_to_index_array(index_dict, X_train_l)
    X_test = text_to_index_array(index_dict, X_test_l)
    
    y_train = np.array(y_train_l)  # 转numpy数组
    y_test = np.array(y_test_l)
    
    print("训练集shape: ", X_train.shape)
    print("测试集shape: ", X_test.shape)
    

    因为模型输入的每一个特征长度需要相同,所以我们需要定义一个最大的长度max_len。
    当特征小于max_len时,根据max_len填充其余位数为0。
    当特征大于max_len,则进行截断。
    在本项目中,我定义的max_len为150,是一个平均长度。有时候为了保证不丢失信息,可以打印出所有特征中最大的长度,并将其设置为max_len

    X_train = sequence.pad_sequences(X_train, maxlen=maxlen)
    X_test = sequence.pad_sequences(X_test, maxlen=maxlen)
    

    定义模型 训练模型 验证模型

    ef train_lstm(p_n_symbols, p_embedding_weights, p_X_train, p_y_train, p_X_test, p_y_test, X_test_l):
        print('创建模型...')
        model = Sequential()
        model.add(Embedding(output_dim=vocab_dim,  # 输出向量维度
                            input_dim=p_n_symbols,  # 输入向量维度
                            mask_zero=True,         # 使我们填补的0值在后续训练中不产生影响(屏蔽0值)
                            weights=[p_embedding_weights],   # 对数据加权
                            input_length=maxlen ))      # 每个特征的长度
    
        model.add(LSTM(output_dim=100,
                       activation='sigmoid',
                       inner_activation='hard_sigmoid'))
        model.add(Dropout(0.5))   # 每次迭代丢弃50神经元 防止过拟合
        model.add(Dense(units=512,
                        activation='relu'))
        model.add(Dropout(0.5))
        model.add(Dense(units=1,  # 输出层1个神经元 1代表正面 0代表负面
                        activation='sigmoid'))
        model.summary()
    
        print('编译模型...')
        model.compile(loss='binary_crossentropy',
                      optimizer='adam',
                      metrics=['accuracy'])
    
        print("训练...")
        train_history = model.fit(p_X_train, p_y_train, batch_size=batch_size, nb_epoch=n_epoch,
                  validation_data=(p_X_test, p_y_test))
    
        print("评估...")
        score, acc = model.evaluate(p_X_test, p_y_test, batch_size=batch_size)
        label = model.predict(p_X_test)
        print('Test score:', score)
        print('Test accuracy:', acc)
        for (a, b, c) in zip(p_y_test, X_test_l, label):
            print("原文为:"+ "".join(b))
            print("预测倾向为", a)
            print("真实倾向为", c)
    
        show_train_history(train_history, 'acc', 'val_acc')    # 训练集准确率与验证集准确率 折线图
        show_train_history(train_history, 'loss', 'val_loss')  # 训练集误差率与验证集误差率 折线图
    
        """保存模型"""
        model.save('./model/emotion_model_LSTM.h5')
        print("模型保存成功")
    

    可以通过show_train_history函数打印的训练集曲线 来判断模型是否过拟合。
    方便确定迭代次数 进行调参 函数如下

    def show_train_history(train_history,train, velidation):
        """
        可视化训练过程 对比
        :param train_history:
        :param train:
        :param velidation:
        :return:
        """
        plt.plot(train_history.history[train])
        plt.plot(train_history.history[velidation])
        plt.title("Train History")   #标题
        plt.xlabel('Epoch')    #x轴标题
        plt.ylabel(train)  #y轴标题
        plt.legend(['train', 'test'], loc='upper left')  #图例 左上角
        plt.show()
    

    项目github:https://github.com/sph116/lstm_emotion
    没仔细检查,可能会有些小问题,望海涵,欢迎交流。
    在这里插入图片描述

    后续优化:
    1.增大训练word2vec 语料数量
    2.数据清洗不止进行简单的去停用词
    3.增加模型结构及复杂度

    展开全文
  • 基于python3、tensorflow库的bilstm程序。双向长短时记忆网络。python文件。
  • 基于长短时记忆神经网络的鄱阳湖水位预测.pdf
  • 深度学习-43:长短时记忆神经网络(LSTM)

    万次阅读 多人点赞 2018-10-14 00:31:09
    深度学习-43:长短时记忆神经网络(LSTM) 深度学习原理与实践(开源图书)-总目录 长短时记忆神经网络(Long Short-term Memory Networks,LSTM)是一种 RNN 特殊的类型,可以学习长期依赖信息。LSTM 由 Hochreiter &...
  • 基于卷积神经网络与双向长短时记忆网络组合模型的短交通流预测.pdf
  • 提出一种考虑温度模糊化的多层长短时记忆神经网络(ML-LSTM)短期负荷预测方法。利用隶属度函数将预测时刻的温度和当日的平均温度进行模糊化处理,减小夏季温度波动性对负荷预测的影响;建立含3层隐藏层的长短时记忆...
  • 长短时记忆神经网路简介
  • 长短时记忆神经网络(LSTM)预测股票价格,附带例子和完整代码
  • 深度学习之循环神经网络(8)长短时记忆网络(LSTM)0. LSTM原理1. 遗忘门2. 输入门3. 刷新Memory4. 输出门5. 小结  循环神经网络除了训练困难,还有一个更严重的问题,那就是短记忆(Short-term memory)。考虑...
  • 主要介绍了循环神经网络RNN和长短时记忆网络LSTM,并对其中的原理和网络结构进行了详细的推导和解释。
  • 对lstm长短时记忆神经网络的简单介绍,包括循环神经网络的基础知识,lstm的简介和用lstm预测正弦图像的实验。
  • #资源达人分享计划#
  • 长短时记忆网络(Long Short Term Memory Network, LSTM),它有效地解决了原始循环神经网络(RNN)的缺陷,在语音识别、图片描述、自然语言处理等许多领域中成功应用。(LSTM-2)型引入了Ct,Ct-1记忆对神经网络的影响...
  • 长短时记忆神经网络模型改进.pdf
  • 长短时记忆网络(LSTM)

    2021-07-07 06:56:10
    本文将介绍改进后的循环神经网络长短时记忆网络(LongShortTermMemoryNetwork,LSTM),   原始RNN的隐藏层只有一个状态,即h,它对于短期的输入非常敏感。那么如果我们再增加一个状态,即c,让它来保存长期...
  • 数据是单维一例的,基于时间节点的预测,matlab出图,程序包含LSTM程序单独运行、SSA-LSTM程序运行、两种程序对比。前70%训练,后面30%预测,大约有2000个数据,代码有详细说明,可供调整学习。
  • 这个应该也是能跑的,不过需要改动一些数据,就是在根据自己的需要对代码进行改动,改动之后是能够运行的,之前朋友做的这个,是用温度预测负荷的,用的长短时记忆神经网络(LSTM)来做的,我这里将他进行了改动,...
  • 基于卷积神经网络长短时记忆神经网络的非特定人语音情感识别算法.pdf
  • 基于长短记忆神经网络的短期光伏发电预测技术研究.pdf
  • 基于双向长短时记忆神经网络的句子分类.pdf
  • 基于长短时记忆神经网络的硬件木马检测.pdf

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,926
精华内容 3,170
关键字:

长短时神经网络

友情链接: state_machine.rar