精华内容
下载资源
问答
  • 回顾下LSTM的几个及其计算公式,估计此时不用看那个九曲回肠的LSTM神经网络图,光看公式也能明白LSTM到底在干嘛了吧: 上面是LSTM的计算公式,首先找那几个,其实好找,那三个Sigmod作为非线性函数的就是...


    上面是LSTM的计算公式,首先找那几个门,其实好找,那三个Sigmod作为非线性函数的就是三个门,很明显其取值范围在0到1和门打开关闭的物理意义是很好对应起来的。

    所以含义很清楚,

    输入门是用来控制输入i’(t)进出多少或者是否允许进出的门控设备;

    输出门是用来控制t时刻状态值m(t)对外多少是可见的门控设备;

    遗忘门是控制RNN中历史状态m(t-1)流动到t时刻后允许多少进入t时刻的门控设备;

    结合常见的LSTM示意图,以下就是三个门的控制,上面罗列的公式中mt就是Ct

    遗忘门

    输入门 

     输出门

    LSTM是RNN模型,决定t时刻节点的除了当前输入值x(t)外,还有t-1时刻的隐层节点输出h(t-1),这代表了历史信息对当前的影响,所以决定门开关程度的除了当前输入 x(t)外,还有h(t-1),仅此区别而已。

    所以关键在LSTM的状态值更新函数和隐层节点输出值函数上。对于状态更新函数来说:

     

    f(t)是遗忘门门控,m(t-1)是历史状态信息,两者相乘代表t时刻允许多少历史信息进入来决定m(t)当前状态,如果遗忘门全关取值0,则历史对当前状态无影响,如果遗忘门全开取值1,则历史信息原封不动的传到t时刻,没有任何信息损失,当然更大可能是取值0到1之间,代表历史信息的部分流入;

     

    i(t)是输入门门控,i’(t)是当前t时刻输入值, 两者相乘代表t时刻允许多少当前输入信息进入来决定m(t)当前状态,如果输入门全关取值0,则LSTM忽略当前输入的影响,等于没看到这个输入直接跳过去了,如果输入门全开取值1,则当前输入最大化地决定当前状态m(t),没有任何信息损失,当然更大可能是取值0到1之间,代表输入信息的部分流入;

     

    经过上面两个门控控制历史信息的影响以及当前输入的影响,就形成了t时刻的隐层节点状态值m(t)。

     

    隐层节点输出值h(t)好理解,就是说通过输出门控制当前状态m(t)对外有多少是可见的,因为m(t)是内部隐藏的状态信息,除了往t+1时刻隐层传输外,外部其它地方是看不到的,但是它们可以看到h(t)。

     

    这就是LSTM是如何用三个门控以及抽离出的m状态存储器来表达运算逻辑的思路,其实可以看到它本质跟RNN一样,无非是体现历史影响及当前输入的影响,但是相对RNN来说,通过门控来自适应地根据历史和输入来控制信息的流动,当然其实更主要的是通过抽离出的m存储往后传递方式来解决梯度弥散问题的,因为今天主讲门控,所以这块不展开讲。

     

    很多其它深度学习的工作也引入了门函数,其思路和上面介绍的猪家的门控系统思路本质上是一样的,无非是用门函数来控制信息流动程度的。在计算模型上怎么理解“有门”和“没门”的模型呢?其实你可以缺省地认为所有的模型都是“有门”的,而“没门”只是有门的一种特例情况。为什么呢?因为“没门”等价于什么,等价于:“有门”但是那个门是永远全开的,永远不会关上或者半遮半掩。所以引入门其实在干什么呢,就是加入控制,在有些情况下让你进入,有些情况下不让你进入,比如看见x不让进,看见y则自由出入。

     

    |其它的类比

     

    上面为了方便理解门函数的作用,我们用现实生活中的门作为类比例子。其实生活中还有很多起到类似类比作用的设备,比如水龙头,打开水龙头那么水就可以流进来,如果关上水龙头,那么就切断了水源,水龙头打开的大点,那么水流量就大些,水龙头打开的小点,那么水流量就小些。DL中的门函数其实跟这个水龙头调节的作用是一样的,区别无非是控制的不是水流量,而是流入的信息流量。

     

    再比如,也可以把门函数类比为灯的光调节器,我们常见到带有光调节器的灯控设备,把设备调大,则照明强度增加,把设备调小,则照明强度减少。这个类比也能很形象地说明门函数的作用。

     

    其实归纳起来,所有这些生活中的门起的是什么作用呢?其实起的作用是个“调节阀”的作用,通过开关调节阀来控制物体的流入;通过开关调节阀大小来控制流入程度;所以,所有起到调节阀作用的生活设施都可以用来做门函数的类比。

    原文连接:https://blog.csdn.net/malefactor/article/details/51183989?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~first_rank_v2~rank_v25-3-51183989.nonecase&utm_term=%E9%97%A8%E4%B8%BB%E8%A6%81%E6%98%AF%E8%B5%B7%E4%BB%80%E4%B9%88%E4%BD%9C%E7%94%A8

    展开全文
  • 遗忘门 1.52.6.输入门 1.52.7.输出门 1.52.8.Intuitive Pipeline 1.52.9.LSTM变体GRU 1.52.10.LSTM变体FC-LSTM 1.52.11.Pytorch LSTM API介绍 1.52.11.1.nn.LSTM 1.52.11.2.nn.LSTMCell 1.52.12.案例1 1.52.13.

    1.52.LSTM
    1.52.1.LSTM简介
    1.52.2.RNN单元的内部结构
    1.52.3.LSTM单元的内部结构
    1.52.4.原理
    1.52.5.遗忘门
    1.52.6.输入门
    1.52.7.输出门
    1.52.8.Intuitive Pipeline
    1.52.9.LSTM变体GRU
    1.52.10.LSTM变体FC-LSTM
    1.52.11.Pytorch LSTM API介绍
    1.52.11.1.nn.LSTM
    1.52.11.2.nn.LSTMCell
    1.52.12.案例1
    1.52.13.演示实验代码2
    1.52.14.以MNIST分类为例实现LSTM分类
    1.52.15.词性标注案例(LSTM,jieba,Word2Vec)
    1.52.16.GRU
    1.52.17.参考博文

    1.52.LSTM

    为了解决传统RNN无法长时依赖问题,RNN的两个变体LSTM和GRU被引入。

    LSTM是一种特殊的RNN,其引入状态量来保留历史信息,同时引入门的概念来更新状态量。

    1.52.1.LSTM简介

    Long Short Term Memory,称为长短期记忆网络,意思就是长的短时记忆,其解决的仍然是短时记忆问题,这种短时记忆比较长,能一定程度上解决长时依赖。
    在这里插入图片描述
    上图为LSTM的抽象结构,LSTM由3个门来控制,分别是输入门、遗忘门和输出门。输入门控制网络的输入,遗忘门控制着记忆单元,输出门控制着网络的输出。最为重要的就是遗忘门,可以决定哪些记忆被保留,由于遗忘门的作用,使得LSTM具有长时记忆的功能。对于给定的任务,遗忘门能够自主学习保留多少之前的记忆,网络能够自主学习。

    1.52.2.RNN单元的内部结构

    在这里插入图片描述

    1.52.3.LSTM单元的内部结构

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    1.52.4.原理

    RNN网络中历史信息在每个RNN单元,都经过tanh/ReLu,信息在逐渐流失;而LSTM,采用信息更新的方式,更容易将有用的信息传递下去,传得更远。也就是下图中C随序列传递的过程。
    在这里插入图片描述
    为了实现状态量C的旧状态删除、新状态更新、当前结果有用状态信息的提取,分别引入”遗忘门”、”输出门”三个结构。

    :使用前一个输出,结合当前输入,通过sigmoid函数,得到输出值,在0~1之间,决定信息量各部分被遗忘/选择的程度。

    1.52.5.遗忘门

    在这里插入图片描述
    在这里插入图片描述

    1.52.6.输入门

    在这里插入图片描述
    输入门挑选信息来更新状态量C。
    在这里插入图片描述

    1.52.7.输出门

    在这里插入图片描述
    输出门挑选更新后的状态量C。

    1.52.8.Intuitive Pipeline

    在这里插入图片描述http://harinisuresh.com/2016/10/09/lstms/
    在这里插入图片描述
    http://www.cs.toronto.edu/~rgrosse/courses/csc321_2017/readings/L15%20Exploding%20and%20Vanishing%20Gradients.pdf
    在这里插入图片描述

    在这里插入图片描述
    https://weberna.github.io/blog/2017/11/15/LSTM-Vanishing-Gradients.html
    http://www.cs.toronto.edu/~rgrosse/courses/csc321_2017/readings/L15%20Exploding%20and%20Vanishing%20Gradients.pdf

    1.52.9.LSTM变体GRU

    在这里插入图片描述
    在这里插入图片描述

    1.52.10.LSTM变体FC-LSTM

    在这里插入图片描述

    1.52.11.Pytorch LSTM API介绍

    1.52.11.1.nn.LSTM

    __init__
    在这里插入图片描述
    LSTM.forward()
    在这里插入图片描述
    class torch.nn.LSTM(*args, **kwargs)
    参数列表:
    input_size: x的特征维度。
    hidden_size: 隐藏层的特征维度。
    num_layers: lstm隐层的层数,默认为1
    bias: False则bih=0和bhh=0,默认为True
    batch_first: True则输入输出的数据格式为(batch,seq,feature)
    dropout: 除最后一层,每一层的输出都进行dropout,默认为0
    bidirectional: True则为双向lstm默认为False。
    输入:input,(h_0, c_0)
    输出:output,(h_n, c_n)

    在Pytorch中使用nn.LSTM()可调用,参数和RNN的参数相同。具体介绍LSTM的输入和输出:
    输入: input, (h_0, c_0)
    input:输入数据with维度(seq_len,batch,input_size)
    h_0:维度为(num_layers*num_directions,batch,hidden_size),在batch中的初始的隐藏状态.
    c_0:初始的单元状态,维度与h_0相同
    Pytorch里的LSTM单元接受的输入都必须是3维的张量(Tensors).每一维代表的意思不能弄错。

    第一维体现的是序列(sequence)结构,也就是序列的个数,用文章来说,就是每个句子的长度,因为是喂给网络模型,一般都设定为确定的长度,也就是我们喂给LSTM神经元的每个句子的长度,当然,如果是其他的带有带有序列形式的数据,则表示一个明确分割单位长度,

    例如是如果是股票数据内,这表示特定时间单位内,有多少条数据。这个参数也就是明确这个层中有多少个确定的单元来处理输入的数据。

    第二维度体现的是batch_size,也就是一次性喂给网格多少条句子,或者股票数据中的,一次性喂给模型多少个时间单位的数据,具体到每个时刻,也就是一次性喂给特定时刻处理的单元的单词数或者该时刻应该喂给的股票数据的条数。

    第三位体现的是输入的元素(elements of input),也就是,每个具体的单词用多少维向量来表示,或者股票数据中 每一个具体的时刻的采集多少具体的值,比如最低价,最高价,均价,5日均价,10均价,等等

    输出:output, (h_n, c_n)
    output:维度为(seq_len, batch, num_directions * hidden_size)。
    h_n:最后时刻的输出隐藏状态,维度为 (num_layers * num_directions, batch, hidden_size)
    c_n:最后时刻的输出单元状态,维度与h_n相同。
    在这里插入图片描述
    nn.LSTM案例

    # -*- coding: UTF-8 -*-
    
    import torch
    import torch.nn as nn
    
    lstm = nn.LSTM(input_size=100, hidden_size=20, num_layers=4)
    print(lstm)
    x = torch.randn(10, 3, 100)
    out, (h, c) = lstm(x)
    print(out.shape, h.shape, c.shape)
    
    """
    输出结果:
    LSTM(100, 20, num_layers=4)
    torch.Size([10, 3, 20]) torch.Size([4, 3, 20]) torch.Size([4, 3, 20])
    """
    

    1.52.11.2.nn.LSTMCell

    在这里插入图片描述
    LSTMCell.forward()
    在这里插入图片描述
    Single layer

    # -*- coding: UTF-8 -*-
    
    import torch
    import torch.nn as nn
    
    x = torch.randn(10, 3, 100)
    print('one layer lstm')
    cell = nn.LSTMCell(input_size=100, hidden_size=20)
    h = torch.zeros(3, 20)
    c = torch.zeros(3, 20)
    for xt in x:
        h, c = cell(xt, [h, c])
    print(h.shape, c.shape)
    
    """
    输出结果:
    one layer lstm
    torch.Size([3, 20]) torch.Size([3, 20])
    """
    

    Two Layers

    # -*- coding: UTF-8 -*-
    
    import torch
    import torch.nn as nn
    
    x = torch.randn(10, 3, 100)
    print('two layer lstm')
    cell1 = nn.LSTMCell(input_size=100, hidden_size=30)
    cell2 = nn.LSTMCell(input_size=30, hidden_size=20)
    h1 = torch.zeros(3, 30)
    c1 = torch.zeros(3, 30)
    
    h2 = torch.zeros(3, 20)
    c2 = torch.zeros(3, 20)
    
    for xt in x:
        h1, c1 = cell1(xt, [h1, c1])
        h2, c2 = cell2(h1, [h2, c2])
    print(h2.shape, c2.shape)
    
    """
    输出结果:
    two layer lstm
    torch.Size([3, 20]) torch.Size([3, 20])
    """
    

    1.52.12.案例1

    # -*- coding: utf-8 -*-
    """lstm
    
    Automatically generated by Colaboratory.
    
    Original file is located at
        https://colab.research.google.com/drive/1GX0Rqur8T45MSYhLU9MYWAbycfLH4-Fu
    """
    
    !pip install torch
    !pip install torchtext
    !python -m spacy download en
    
    
    # K80 gpu for 12 hours
    import torch
    from torch import nn, optim
    from torchtext import data, datasets
    
    print('GPU:', torch.cuda.is_available())
    
    torch.manual_seed(123)
    
    TEXT = data.Field(tokenize='spacy')
    LABEL = data.LabelField(dtype=torch.float)
    train_data, test_data = datasets.IMDB.splits(TEXT, LABEL)
    
    print('len of train data:', len(train_data))
    print('len of test data:', len(test_data))
    
    print(train_data.examples[15].text)
    print(train_data.examples[15].label)
    
    # word2vec, glove
    TEXT.build_vocab(train_data, max_size=10000, vectors='glove.6B.100d')
    LABEL.build_vocab(train_data)
    
    
    batchsz = 30
    device = torch.device('cuda')
    train_iterator, test_iterator = data.BucketIterator.splits(
        (train_data, test_data),
        batch_size = batchsz,
        device=device
    )
    
    class RNN(nn.Module):
        
        def __init__(self, vocab_size, embedding_dim, hidden_dim):
            """
            """
            super(RNN, self).__init__()
            
            # [0-10001] => [100]
            self.embedding = nn.Embedding(vocab_size, embedding_dim)
            # [100] => [256]
            self.rnn = nn.LSTM(embedding_dim, hidden_dim, num_layers=2, 
                               bidirectional=True, dropout=0.5)
            # [256*2] => [1]
            self.fc = nn.Linear(hidden_dim*2, 1)
            self.dropout = nn.Dropout(0.5)
            
            
        def forward(self, x):
            """
            
            """
            # [seq, b, 1] => [seq, b, 100]
            embedding = self.dropout(self.embedding(x))
            
            # output: [seq, b, hid_dim*2]
            # hidden/h: [num_layers*2, b, hid_dim]
            # cell/c: [num_layers*2, b, hid_di]
            output, (hidden, cell) = self.rnn(embedding)
            
            # [num_layers*2, b, hid_dim] => 2 of [b, hid_dim] => [b, hid_dim*2]
            hidden = torch.cat([hidden[-2], hidden[-1]], dim=1)
            
            # [b, hid_dim*2] => [b, 1]
            hidden = self.dropout(hidden)
            out = self.fc(hidden)
            
            return out
    
    rnn = RNN(len(TEXT.vocab), 100, 256)
    
    pretrained_embedding = TEXT.vocab.vectors
    print('pretrained_embedding:', pretrained_embedding.shape)
    rnn.embedding.weight.data.copy_(pretrained_embedding)
    print('embedding layer inited.')
    
    optimizer = optim.Adam(rnn.parameters(), lr=1e-3)
    criteon = nn.BCEWithLogitsLoss().to(device)
    rnn.to(device)
    
    import numpy as np
    
    def binary_acc(preds, y):
        """
        get accuracy
        """
        preds = torch.round(torch.sigmoid(preds))
        correct = torch.eq(preds, y).float()
        acc = correct.sum() / len(correct)
        return acc
    
    def train(rnn, iterator, optimizer, criteon):
        
        avg_acc = []
        rnn.train()
        
        for i, batch in enumerate(iterator):
            
            # [seq, b] => [b, 1] => [b]
            pred = rnn(batch.text).squeeze(1)
            # 
            loss = criteon(pred, batch.label)
            acc = binary_acc(pred, batch.label).item()
            avg_acc.append(acc)
            
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            
            if i%10 == 0:
                print(i, acc)
            
        avg_acc = np.array(avg_acc).mean()
        print('avg acc:', avg_acc)
        
        
    def eval(rnn, iterator, criteon):
        
        avg_acc = []
        
        rnn.eval()
        
        with torch.no_grad():
            for batch in iterator:
    
                # [b, 1] => [b]
                pred = rnn(batch.text).squeeze(1)
    
                loss = criteon(pred, batch.label)
    
                acc = binary_acc(pred, batch.label).item()
                avg_acc.append(acc)
            
        avg_acc = np.array(avg_acc).mean()
        
        print('>>test:', avg_acc)
    
    for epoch in range(10):
        
        eval(rnn, test_iterator, criteon)
        train(rnn, train_iterator, optimizer, criteon)
    

    1.52.13.演示实验代码2

    # -*- coding: UTF-8 -*-
    
    import torch
    from torch import nn
    import numpy as np
    
    
    class Rnn(nn.Module):
        def __init__(self, INPUT_SIZE):
            super(Rnn, self).__init__()
    
            self.rnn = nn.LSTM(
                input_size=INPUT_SIZE,
                hidden_size=32,
                num_layers=2,
                bias=True,
                batch_first=True,
                dropout=0,
                bidirectional=False
            )
    
            self.out = nn.Linear(32, 1)
    
        def forward(self, x, hc_state):
            # input(x): batch, seq_len, input_size = 1, 10, 2
            # output(r_out): batch, seq_len, hidden_size * num_directions = 1, 10, 32*1
            r_out, hc_state = self.rnn(x, hc_state)
    
            outs = []
            for time in range(r_out.size(1)):
                outs.append(self.out(r_out[:, time, :]))
            return torch.stack(outs, dim=1), hc_state
    
    
    # 定义一些超参
    TIME_STEP = 10
    INPUT_SIZE = 2
    LR = 0.02
    # "看"数据
    # plt.plot(steps, y_np, 'r-', label='target(cos)')
    # plt.plot(steps, x_np, 'b-', label='input(sin)')
    # plt.legend(loc='best')
    # plt.show()
    
    # 选择模型
    model = Rnn(INPUT_SIZE)
    print(model)
    
    # 定义优化器和损失函数
    loss_func = nn.MSELoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=LR)
    
    h_state = torch.autograd.Variable(
        torch.zeros(2, 1, 32))  # h0/c0: num_layers * num_directions, batch, hidden_size = 2*1, 1, 32
    c_state = torch.autograd.Variable(torch.zeros(2, 1, 32))  # 第一次的时候,暂存为0
    for step in range(300):
        start, end = step * np.pi, (step + 1) * np.pi
    
        steps = np.linspace(start, end, TIME_STEP, dtype=np.float32)
        x_np = np.sin(steps)
        y_np = np.cos(steps)
    
        x = torch.from_numpy(x_np[np.newaxis, :, np.newaxis])
        y = torch.from_numpy(y_np[np.newaxis, :, np.newaxis])
    
        # 为了演示,重复x将输入数据特征扩展为两维
        prediction, (h_state, c_state) = model(torch.cat((x, x), 2), (h_state, c_state))
        h_state = h_state.data
        c_state = c_state.data
    
        loss = loss_func(prediction, y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    print("x:")
    print(x)
    print("y:")
    print(y)
    print("predict:")
    print(prediction)
    

    输出结果:

    Rnn(
      (rnn): LSTM(2, 32, num_layers=2, batch_first=True)
      (out): Linear(in_features=32, out_features=1, bias=True)
    )
    x:
    tensor([[[ 2.1783e-05],
             [-3.4199e-01],
             [-6.4281e-01],
             [-8.6604e-01],
             [-9.8481e-01],
             [-9.8481e-01],
             [-8.6602e-01],
             [-6.4279e-01],
             [-3.4203e-01],
             [-1.2874e-05]]])
    y:
    tensor([[[-1.0000],
             [-0.9397],
             [-0.7660],
             [-0.5000],
             [-0.1736],
             [ 0.1737],
             [ 0.5000],
             [ 0.7660],
             [ 0.9397],
             [ 1.0000]]])
    predict:
    tensor([[[-0.9952],
             [-0.9373],
             [-0.7687],
             [-0.4961],
             [-0.1764],
             [ 0.1734],
             [ 0.5018],
             [ 0.7659],
             [ 0.9358],
             [ 1.0058]]], grad_fn=<StackBackward>)
    

    1.52.14.以MNIST分类为例实现LSTM分类

    MNIST图片大小为28 * 28,可以将每张图片看做是长为28的序列,序列中每个元素的特征维度为28。将最后输出的隐藏状态ht作为抽象的隐藏特征输入到全连接层进行分类。最后输出的导入头文件:

    import torch
    import torch.nn as nn
    import torch.optim as optim
    import torchvision
    from torchvision import transforms
    
    class Rnn(nn.Module):
        def __init__(self, in_dim, hidden_dim, n_layer, n_classes):
            super(Rnn, self).__init__()
            self.n_layer = n_layer
            self.hidden_dim = hidden_dim
            self.lstm = nn.LSTM(in_dim, hidden_dim, n_layer, batch_first=True)
            self.classifier = nn.Linear(hidden_dim, n_classes)
    
        def forward(self, x):
            out, (h_n, c_n) = self.lstm(x)
            # 此时可以从out中获得最终输出的状态h
            # x = out[:, -1, :]
            x = h_n[-1, :, :]
            x = self.classifier(x)
            return x
    

    训练和测试代码:

    transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize([0.5], [0.5]),
    ])
    
    trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True)
    
    testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
    testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False)
    
    net = Rnn(28, 10, 2, 10)
    
    net = net.to('cpu')
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD(net.parameters(), lr=0.1, momentum=0.9)
    
    # Training
    def train(epoch):
        print('\nEpoch: %d' % epoch)
        net.train()
        train_loss = 0
        correct = 0
        total = 0
        for batch_idx, (inputs, targets) in enumerate(trainloader):
            inputs, targets = inputs.to('cpu'), targets.to('cpu')
            optimizer.zero_grad()
            outputs = net(torch.squeeze(inputs, 1))
            loss = criterion(outputs, targets)
            loss.backward()
            optimizer.step()
    
            train_loss += loss.item()
            _, predicted = outputs.max(1)
            total += targets.size(0)
            correct += predicted.eq(targets).sum().item()
    
            print(batch_idx, len(trainloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)'
                % (train_loss/(batch_idx+1), 100.*correct/total, correct, total))
    
    def test(epoch):
        global best_acc
        net.eval()
        test_loss = 0
        correct = 0
        total = 0
        with torch.no_grad():
            for batch_idx, (inputs, targets) in enumerate(testloader):
                inputs, targets = inputs.to('cpu'), targets.to('cpu')
                outputs = net(torch.squeeze(inputs, 1))
                loss = criterion(outputs, targets)
    
                test_loss += loss.item()
                _, predicted = outputs.max(1)
                total += targets.size(0)
                correct += predicted.eq(targets).sum().item()
    
                print(batch_idx, len(testloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)'
                    % (test_loss/(batch_idx+1), 100.*correct/total, correct, total))
    
    
    
    
    for epoch in range(200):
        train(epoch)
        test(epoch)
    

    输出结果:

    Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to ./data\MNIST\raw\train-images-idx3-ubyte.gz
     99%|█████████▉| 9846784/9912422 [00:20<00:00, 459422.31it/s]Extracting ./data\MNIST\raw\train-images-idx3-ubyte.gz to ./data\MNIST\raw
    Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz to ./data\MNIST\raw\train-labels-idx1-ubyte.gz
    0it [00:00, ?it/s]
      0%|          | 0/28881 [00:00<?, ?it/s]Extracting ./data\MNIST\raw\train-labels-idx1-ubyte.gz to ./data\MNIST\raw
    Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to ./data\MNIST\raw\t10k-images-idx3-ubyte.gz
    0it [00:00, ?it/s]
      0%|          | 0/1648877 [00:00<?, ?it/s]
      1%|          | 16384/1648877 [00:00<00:10, 157293.84it/s]
      4%|| 73728/1648877 [00:00<00:08, 190069.53it/s]
      9%|| 147456/1648877 [00:00<00:06, 243820.22it/s]
     14%|█▍        | 229376/1648877 [00:00<00:04, 308867.34it/s]
     18%|█▊        | 303104/1648877 [00:01<00:03, 371035.22it/s]
     25%|██▍       | 409600/1648877 [00:01<00:02, 455352.87it/s]
     38%|███▊      | 622592/1648877 [00:01<00:01, 595166.32it/s]
     53%|█████▎    | 876544/1648877 [00:01<00:01, 771295.72it/s]
     81%|████████  | 1335296/1648877 [00:01<00:00, 1026424.47it/s]Extracting ./data\MNIST\raw\t10k-images-idx3-ubyte.gz to ./data\MNIST\raw
    Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to ./data\MNIST\raw\t10k-labels-idx1-ubyte.gz
    0it [00:00, ?it/s]
      0%|          | 0/4542 [00:00<?, ?it/s]Extracting ./data\MNIST\raw\t10k-labels-idx1-ubyte.gz to ./data\MNIST\raw
    Processing...
    D:\installed\Anaconda3\lib\site-packages\torchvision\datasets\mnist.py:480: UserWarning: The given NumPy array is not writeable, and PyTorch does not support non-writeable tensors. This means you can write to the underlying (supposedly non-writeable) NumPy array using the tensor. You may want to copy the array to protect its data or make it writeable before converting it to a tensor. This type of warning will be suppressed for the rest of this program. (Triggered internally at  ..\torch\csrc\utils\tensor_numpy.cpp:141.)
      return torch.from_numpy(parsed.astype(m[2], copy=False)).view(*s)
    Done!
    32768it [00:03, 10112.94it/s]            
    1654784it [00:02, 615868.70it/s]                              
    8192it [00:01, 8065.27it/s]             
    Epoch: 0
    0 469 Loss: 2.333 | Acc: 4.688% (6/128)
    1 469 Loss: 2.313 | Acc: 6.250% (16/256)
    2 469 Loss: 2.307 | Acc: 7.292% (28/384)
    3 469 Loss: 2.310 | Acc: 9.180% (47/512)
    4 469 Loss: 2.310 | Acc: 9.375% (60/640)
    5 469 Loss: 2.313 | Acc: 9.896% (76/768)
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    239 469 Loss: 0.190 | Acc: 94.447% (29014/30720)
    240 469 Loss: 0.190 | Acc: 94.447% (29135/30848)
    241 469 Loss: 0.189 | Acc: 94.457% (29259/30976)
    242 469 Loss: 0.189 | Acc: 94.470% (29384/31104)
    243 469 Loss: 0.189 | Acc: 94.474% (29506/31232)
    244 469 Loss: 0.189 | Acc: 94.480% (29629/31360)
    245 469 Loss: 0.189 | Acc: 94.480% (29750/31488)
    246 469 Loss: 0.189 | Acc: 94.471% (29868/31616)
    247 469 Loss: 0.189 | Acc: 94.475% (29990/31744)
    248 469 Loss: 0.189 | Acc: 94.468% (30109/31872)
    249 469 Loss: 0.189 | Acc: 94.475% (30232/32000)
    250 469 Loss: 0.189 | Acc: 94.472% (30352/32128)
    251 469 Loss: 0.189 | Acc: 94.475% (30474/32256)
    252 469 Loss: 0.189 | Acc: 94.479% (30596/32384)
    

    1.52.15.词性标注案例(LSTM,jieba,Word2Vec)

    就是训练网络帮我们标注词性,当然实际的自然语言处理我们有很多成功的算法,但是应对新词总会有点麻烦,我们想啊,既然网络可以帮我们做了很多神奇的事,那么我们可不可以训练一个网络模型来帮我们自动的标注词性呢,显然这个思路靠谱,使用神经网络的套路:
    准备训练数据,这一步最是头大的,最好的办法就是找各大机构提供的标准的标注库,实在找不到,自己处理,国内外很多的分词标准库和工具可以用,jieba分词标注是一个不错的选择,使用起来也简单。
    读取数据文件
    分词
    把词语和标注分别放在两个数组里面
    构建词汇表、构建标注表
    把分词结果转换成对应词汇表和标签表中的序号。
    构建网络模型,这里使用Word2Vec预处理一下输入文本
    训练网络
    分析结果

    下面按照这个套路上源码:

    # -*- coding: UTF-8 -*-
    
    '''
    转自:https://zhuanlan.zhihu.com/p/41261640
    '''
    
    '''
    pip install jieba  | pip3 install jieba | easy_install jieba
    '''
    import jieba.posseg
    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    import torch.optim as optim
    
    # import sys
    
    '''
    处理语料
    pip install gensim
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple gensim
    '''
    import gensim
    
    torch.manual_seed(2)
    # sys.stdout = open('1.log', 'a')
    # sys.stdout = open('1.log', 'a')
    sent = '明天是荣耀运营十周年纪念日。' \
           '荣耀从两周年纪念日开始,' \
           '在每年的纪念日这天凌晨零点会开放一个新区。' \
           '第十版账号卡的销售从三个月前就已经开始。' \
           '在老区玩的不顺心的老玩家、准备进入荣耀的新手,都已经准备好了新区账号对这个日子翘首以盼。' \
           '陈果坐到了叶修旁边的机器,随手登录了她的逐烟霞。' \
           '其他九大区的玩家人气并没有因为第十区的新开而降低多少,' \
           '越老的区越是如此,实在是因为荣耀的一个账号想经营起来并不容易。' \
           '陈果的逐烟霞用了五年时间才在普通玩家中算是翘楚,哪舍得轻易抛弃。' \
           '更何况到最后大家都会冲着十大区的共同地图神之领域去。'
    words = jieba.posseg.cut(sent, HMM=True)  # 分词
    processword = []
    tagword = []
    for w in words:
        processword.append(w.word)
        tagword.append(w.flag)
    # 词语和对应的词性做一一对应
    texts = [(processword, tagword)]
    
    # 使用gensim构建本例的词汇表
    id2word = gensim.corpora.Dictionary([texts[0][0]])
    # 每个词分配一个独特的ID
    word2id = id2word.token2id
    
    # 使用gensim构建本例的词性表
    id2tag = gensim.corpora.Dictionary([texts[0][1]])
    # 为每个词性分配ID
    tag2id = id2tag.token2id
    
    
    def sen2id(inputs):
        return [word2id[word] for word in inputs]
    
    
    def tags2id(inputs):
        return [tag2id[word] for word in inputs]
    
    
    # 根据词汇表把文本输入转换成对应的词汇表的序号张量
    def formart_input(inputs):
        return torch.tensor(sen2id(inputs), dtype=torch.long)
    
    
    # 根据词性表把文本标注输入转换成对应的词汇标注的张量
    def formart_tag(inputs):
        return torch.tensor(tags2id(inputs), dtype=torch.long)
    
    
    # 定义网络结构
    class LSTMTagger(torch.nn.Module):
        def __init__(self, embedding_dim, hidden_dim, voacb_size, target_size):
            super(LSTMTagger, self).__init__()
            self.embedding_dim = embedding_dim
            self.hidden_dim = hidden_dim
            self.voacb_size = voacb_size
            self.target_size = target_size
            # 使用Word2Vec预处理一下输入文本
            self.embedding = nn.Embedding(self.voacb_size, self.embedding_dim)
            #  LSTM 以word_embeddings作为输入, 输出维度为 hidden_dim 的隐状态值
            self.lstm = nn.LSTM(self.embedding_dim, self.hidden_dim)
            # 线性层将隐状态空间映射到标注空间
            self.out2tag = nn.Linear(self.hidden_dim, self.target_size)
    
            self.hidden = self.init_hidden()
    
        def init_hidden(self):
            # 开始时刻, 没有隐状态
            # 关于维度设置的详情,请参考 Pytorch 文档
            # 各个维度的含义是 (Seguence, minibatch_size, hidden_dim)
            return (torch.zeros(1, 1, self.hidden_dim),
                    torch.zeros(1, 1, self.hidden_dim))
    
        def forward(self, inputs):
            # 预处理文本转成稠密向量
            embeds = self.embedding((inputs))
            # 根据文本的稠密向量训练网络
            out, self.hidden = self.lstm(embeds.view(len(inputs), 1, -1), self.hidden)
            # 做出预测
            tag_space = self.out2tag(out.view(len(inputs), -1))
            tags = F.log_softmax(tag_space, dim=1)
            return tags
    
    
    model = LSTMTagger(10, 10, len(word2id), len(tag2id))
    loss_function = nn.NLLLoss()
    optimizer = optim.SGD(model.parameters(), lr=0.1)
    # 看看随机初始化网络的分析结果
    with torch.no_grad():
        input_s = formart_input(texts[0][0])
        print(input_s)
        print(processword)
        tag_s = model(input_s)
        for i in range(tag_s.shape[0]):
            print(tag_s[i])
        # print(tag_s)
    for epoch in range(300):
        # 再说明下, 实际情况下你不会训练300个周期, 此例中我们只是构造了一些假数据
        for p, t in texts:
            # Step 1. 请记住 Pytorch 会累加梯度
            # 每次训练前需要清空梯度值
            model.zero_grad()
    
            # 此外还需要清空 LSTM 的隐状态
            # 将其从上个实例的历史中分离出来
            # 重新初始化隐藏层数据,避免受之前运行代码的干扰,如果不重新初始化,会有报错。
            model.hidden = model.init_hidden()
    
            # Step 2. 准备网络输入, 将其变为词索引的Tensor 类型数据
            sentence_in = formart_input(p)
            tags_in = formart_tag(t)
    
            # Step 3. 前向传播
            tag_s = model(sentence_in)
    
            # Step 4. 计算损失和梯度值, 通过调用 optimizer.step() 来更新梯度
            loss = loss_function(tag_s, tags_in)
            loss.backward()
            print('Loss:', loss.item())
            optimizer.step()
    
    # 看看训练后的结果
    with torch.no_grad():
        input_s = formart_input(texts[0][0])
        tag_s = model(input_s)
        for i in range(tag_s.shape[0]):
            print(tag_s[i])
    

    1.52.16.GRU

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    上述的过程的线性变换没有使用偏置。隐藏状态参数不再是标准RNN的4倍,而是3倍,也就是GRU的参数要比LSTM的参数量要少,但是性能差不多。

    1.52.17.参考博文

    http://blog.ziyouman.cn/?id=85
    https://blog.csdn.net/winycg/article/details/88937583
    https://zhuanlan.zhihu.com/p/144132609
    https://zhuanlan.zhihu.com/p/41261640
    https://cloud.tencent.com/developer/article/1072464?from=information.detail.pytorch%E5%AE%9E%E7%8E%B0lstm
    https://blog.csdn.net/qq_36652619/article/details/88085828
    http://t.zoukankan.com/jiangkejie-p-10600185.html

    展开全文
  • 由于遗忘门的控制,它可以保存很久很久之前的信息,由于输入门的控制,它又可以避免当前无关紧要的内容进入记忆。 当前时刻的单元状态c_t 输出门的计算: output LSTM 的反向传播训练算法 主要...

    文章简介:

    1. LSTM 思路
    2. LSTM 的前向计算
    3. LSTM 的反向传播

    LSTM

    长短时记忆网络(Long Short Term Memory Network, LSTM),是一种改进之后的循环神经网络,可以解决RNN无法处理长距离的依赖的问题,目前比较流行。

    长短时记忆网络的思路:

    原始 RNN 的隐藏层只有一个状态,即h,它对于短期的输入非常敏感。
    再增加一个状态,即c,让它来保存长期的状态,称为单元状态(cell state)。

    把上图按照时间维度展开:

    在 t 时刻,LSTM 的输入有三个:当前时刻网络的输入值 、上一时刻 LSTM 的输出值 、以及上一时刻的单元状态
    LSTM 的输出有两个:当前时刻 LSTM 输出值 、和当前时刻的单元状态.

    关键问题是:怎样控制长期状态 c ?

    方法是:使用三个控制开关

    第一个开关,负责控制继续保存长期状态c;
    第二个开关,负责控制把即时状态输入到长期状态c;
    第三个开关,负责控制是否把长期状态c作为当前的LSTM的输出。

    如何在算法中实现这三个开关?

    方法:用 门(gate)

    定义:gate 实际上就是一层全连接层,输入是一个向量,输出是一个 0到1 之间的实数向量。
    公式为:

     

    回忆一下它的样子:

     

    gate 如何进行控制?

    方法:用门的输出向量按元素乘以我们需要控制的那个向量
    原理:门的输出是 0到1 之间的实数向量,
    当门输出为 0 时,任何向量与之相乘都会得到 0 向量,这就相当于什么都不能通过;
    输出为 1 时,任何向量与之相乘都不会有任何改变,这就相当于什么都可以通过。


    LSTM 前向计算

    在 LSTM-1 中提到了,模型是通过使用三个控制开关来控制长期状态 c 的:

    这些开关就是用门(gate)来实现:

    接下来具体看这三重门


    LSTM 的前向计算:

    一共有 6 个公式

    遗忘门(forget gate)
    它决定了上一时刻的单元状态 c_t-1 有多少保留到当前时刻 c_t

    输入门(input gate)
    它决定了当前时刻网络的输入 x_t 有多少保存到单元状态 c_t

    输出门(output gate)
    控制单元状态 c_t 有多少输出到 LSTM 的当前输出值 h_t


    遗忘门的计算为:

    forget

    遗忘门的计算公式中:
    W_f 是遗忘门的权重矩阵,[h_t-1, x_t] 表示把两个向量连接成一个更长的向量,b_f 是遗忘门的偏置项,σ 是 sigmoid 函数。


    输入门的计算:

    input

    根据上一次的输出和本次输入来计算当前输入的单元状态:

    当前输入的单元状态c_t

    当前时刻的单元状态 c_t 的计算:由上一次的单元状态 c_t-1 按元素乘以遗忘门 f_t,再用当前输入的单元状态 c_t 按元素乘以输入门 i_t,再将两个积加和:
    这样,就可以把当前的记忆 c_t 和长期的记忆 c_t-1 组合在一起,形成了新的单元状态 c_t
    由于遗忘门的控制,它可以保存很久很久之前的信息,由于输入门的控制,它又可以避免当前无关紧要的内容进入记忆。

    当前时刻的单元状态c_t


    输出门的计算:

    output


    LSTM 的反向传播训练算法

    主要有三步:

    1. 前向计算每个神经元的输出值,一共有 5 个变量,计算方法就是前一部分:

    2. 反向计算每个神经元的误差项值。与 RNN 一样,LSTM 误差项的反向传播也是包括两个方向:
    一个是沿时间的反向传播,即从当前 t 时刻开始,计算每个时刻的误差项;
    一个是将误差项向上一层传播。

    3. 根据相应的误差项,计算每个权重的梯度。


    gate 的激活函数定义为 sigmoid 函数,输出的激活函数为 tanh 函数,导数分别为:

    具体推导公式为:

    具体推导公式为:


    目标是要学习 8 组参数,如下图所示:

    又权重矩阵 W 都是由两个矩阵拼接而成,这两部分在反向传播中使用不同的公式,因此在后续的推导中,权重矩阵也要被写为分开的两个矩阵。

    接着就来求两个方向的误差,和一个梯度计算。
    这个公式推导过程在本文的学习资料中有比较详细的介绍,大家可以去看原文:
    https://zybuluo.com/hanbingtao/note/581764


    1. 误差项沿时间的反向传递:

    定义 t 时刻的误差项:

    目的是要计算出 t-1 时刻的误差项:

    利用 h_t c_t 的定义,和全导数公式,可以得到 将误差项向前传递到任意k时刻的公式:


    2. 将误差项传递到上一层的公式:


    3. 权重梯度的计算:

    以上就是 LSTM 的训练算法的全部公式。



    链接:https://www.jianshu.com/p/dcec3f07d3b5
    来源:简书
     

    展开全文
  • 以往的研究表明,遗忘门是LSTM中最重要的门之一。在这里,我们展示了带有时间初始化偏差的仅忘记门版本的LSTM,不仅节省了计算量,而且优于标准LSTMONmultipleBenchMarkDatasets,并与一些最好的当代模型相竞争。...
  • 控制门单元又是由遗忘门单元和记忆门单元的加和组成。 1.控制门单元, 与最后的输出层做相乘操作,决定什么样的信息会被保留 2.遗忘门单元:上一层的控制门单元Ct-1直接与ft进行相乘操作,决定什么样的信息会...

    LSTM网络是有LSTM每个单元所串接而成的, 从下面可以看出RNN与LSTM网络的差异,

    LSTM主要有控制门单元和输出门单元组成

    控制门单元又是由遗忘门单元和记忆门单元的加和组成。

    1.控制门单元, 与最后的输出层做相乘操作,决定什么样的信息会被保留

    2.遗忘门单元:上一层的控制门单元Ct-1直接与ft进行相乘操作,决定什么样的信息会被遗弃

    3.记忆门单元: 将输入的结果it 与 新数据形成的控制参数,进行相乘操作,决定什么样的数据会被保留

    4.控制门单元的更新操作Ct, 即将记忆门单元和遗忘门单元进行加和,组成了控制门单元传入到下一个阶段

    5.输出门单元: 将输出ot与控制门单元进行结合,获得当前隐藏层的输出结果,也可以用来做当前层的预测结果

     

    6.最后LSTM的展示结构,是由多个LSTM单元所组成的

     

    转载于:https://www.cnblogs.com/my-love-is-python/p/10516682.html

    展开全文
  • 遗忘门一文中仅 的Python 3.5 Tensorflow 1.4 开始上手 安装Tensorflow 1.4 跑步: pip install -r requirements.txt 添加和复制实验可以通过 python main.py --data add --name my_add_exp --log_every 20 --...
  • 通常在一个LSTM中包含三个门来控制细胞状态 3、一个一个门的打开LSTM(遗忘门、输入门、输出门) (1)遗忘门 LSTM的第一件事情是需要决定我们的细胞状态需要丢弃哪些信息。所以我们通过遗忘门来进行这项操作,这个...
  • 转载于:https://www.cnblogs.com/rongye/p/10013258.html
  • 遗忘门2. 输入门3. 刷新Memory4. 输出门5. 小结  循环神经网络除了训练困难,还有一个更严重的问题,那就是短时记忆(Short-term memory)。考虑一个长句子: 今天天气太美好了,尽管路上发生了一件不愉快的事,…...
  • 遗忘门中,来自先前隐状态的信息和来自当前输入的信息传递到sigmoid函数,并将值压缩到0和1之间。越接近0,意味着丢弃,越接近1意味着保留 输入门(input gate) 为了更新单元状态,LSTM需要输入门。首先,...
  • GRU控循环单元简述

    2020-07-02 22:11:53
    GRU控循环单元简述 By:Yang Liu 1.什么是控循环单元GRU 在循环神经⽹络中的梯度计算⽅法中,我们发现,当时间步数较⼤或者时间步较小时,循环神经⽹络的梯度较容易出现衰减或爆炸。虽然裁剪梯度可以应对梯度爆炸...
  • 一:控循环神经网络简介 控循环神经网络是在经典RNN基础之上调整而出的网络结构,通过加入控机制(非线性激活函数,通常是sigmoid), 用来控制神经网络中的信息传递。控机制可以用来控制记忆单元中哪些信息...
  • 图2 LSTM结构图 1.1 LSTM--遗忘门 图3 遗忘门 LSTM 的第一步要决定从细胞状态中舍弃哪些信息。这一决定由所谓“遗忘门层”的 S 形网络层做出。它接收 和 ,并且对细胞状态 中的每一个数来说输出值都介于 0 和 1 ...
  • 1. 具体在看看几个门的位置和作用 lstm理解与使用(pytorch为例) 遗忘门的构成和参数 输入门 输出门 2. 参数量计算 如何计算 LSTM 的参数量
  • 同时网络不再额外给出记忆状态Ct,而是将输出结果ht作为记忆状态不断向后传递 其他关键区别: GRU 有两个门(重置门与更新门),而 LSTM 有三个门(输入门、遗忘门和输出门)。 GRU 并不会控制并保留内部记忆(c...
  • 遗忘门 顾名思义,遗忘门的作用就是用来“忘记”信息的。在LSTM的使用过程中,有一些信息不是必要的,因此遗忘门的作用就是用来选择这些信息并“忘记”它们。遗忘门决定了细胞状态Ct-1中的哪些信息将被遗忘。那么...
  • LSTM及其激活函数理解

    千次阅读 2020-11-25 18:37:44
    LSTM及其激活函数理解 -------本文仅为学习笔记,不做任何商业用途------- ...相比于传统的RNN,LSTM的参数会随着输入序列而改变,同时会选择记住和遗忘输入序列里的相关信息。LSTM可以用于不分段的连续手写识别上
  • 文章目录零、前置知识一、LSTM目标二、LSTM的结构解析门结构的介绍遗忘门(forget gate)输入门(input gate)输出门(output gate)总结一下前馈结构流程三、LSTM变种四、解决问题的思路(从循环神经网络到LSTM)...
  • 文章目录一、长短期记忆网络(LSTM)1.1 门控记忆单元1.2 输入门、遗忘门与输出门1.3候选记忆单元1.4 记忆单元1.5 隐藏状态二、从零实现LSTM2.1 初始化模型参数2.2 定义网络模型2.3 训练和预测2.4 简洁实现小结练习 ...
  • 文章目录LSTM结构遗忘门输入门决定给细胞状态C添加哪些新的信息更新旧的细胞信息输出门LSTM小结如何实现长期依赖?如何避免梯度消失/爆炸?双向LSTM(Bi-LSTM)GRU 上一篇文章中,提到RNN难以学习到长期依赖关系,后来...
  • AI学习笔记(十九)循环神经网络

    千次阅读 2021-01-02 14:36:51
    2、将先前隐藏状态和遗忘门输出的向量进行点乘,相当于趋于0的时候,前一个时刻的状态信息会被忘掉,隐藏状态会被重置为当前输入的信息; 3、得到了新的隐藏状态,但是还不能直接输出,而是通过更新门来控制最后的...
  • RNN-GRU-LSTM详解

    2021-03-04 21:49:52
    7、对于现在常用的带遗忘门的 LSTM 来说,6 中的分析依然成立,而 5 分为两种情况:其一是遗忘门接近 1(例如模型初始化时会把 forget bias 设置成较大的正数,让遗忘门饱和),这时候远距离梯度不消失;其二是遗忘...
  • 同时作为输入输入到遗忘门中,经过遗忘门会得到0和1的向量,和上一个隐含状态做点积,物理意义可以理解为:当输入一些新的东西之后,模型会考虑遗忘之前的那些东西。   输入门 输入仍是上一个单元的...
  • LSTM

    2019-05-04 07:14:29
    这个决策由一个称为“遗忘门(forget gate)”的sigmoid层决定。输入 和 ,输出一个0和1之间的数。1代表“完全保留这个值”,而0代表“完全扔掉这个值”。 比如对于一个基于上文预测最后一个...
  • 循环神经网络2--LSTM

    2018-03-15 16:37:37
    ), 则遗忘门的权重矩阵 W f W f \mathbf{W}_{f} 维度是 d c × ( d h + d x ) d c × ( d h + d x ) d_{c}×(d_{h}+d_{x}) . 事实上, 权重矩阵 W f W f \mathbf{W}_{f} 都是两个矩阵拼接而成的: 一个是 W f h W f ...
  • LSTM公式及理解

    万次阅读 多人点赞 2019-01-25 22:34:22
    LSTM最重要的概念就是三个门:输入、输出、遗忘门;以及两个记忆:长记忆C、短记忆h。只要弄懂了这三个门两种记忆就可以弄明白LSTM了。这里先留个印象就行,接下来我们展开来讲。 从RNN、长时记忆说起 接下来...
  • LSTM这一篇就够了

    万次阅读 多人点赞 2019-09-16 15:02:25
    LSTM 有三种类型的门结构:遗忘门、输入门和输出门。 遗忘门   遗忘门的功能是决定应丢弃或保留哪些信息。来自前一个隐藏状态的信息和当前输入的信息同时传递到 sigmoid 函数中去,输出值介于 0 和 1 之间...
  • 深入理解LSTM,全网最详细讲解~~

    千次阅读 多人点赞 2020-03-19 16:42:24
    遗忘门】 图 3 LSTM 神经单元“遗忘门” 部分 首先将上一时刻( t−1t-1t−1时刻)的 隐藏状态的信息 St−1S_{t-1}St−1​ 与本时刻( ttt时刻)的数据共同输入Sigmoid 函数,输出的值介于0 ~ 1之间,代表该不该...
  • 下面我们就来研究上图中LSTM的遗忘门,输入门和输出门以及细胞状态。 2.1 LSTM之遗忘门 遗忘门(forget gate)顾名思义,是控制是否遗忘的,在LSTM中即以 一定的概率控制是否遗忘上一层的隐藏细胞状态 。遗忘...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,475
精华内容 4,590
关键字:

遗忘门