精华内容
下载资源
问答
  • 长短期记忆神经网络
    2020-12-05 11:24:57

    循环神经网络

    人类的思考并非每一秒都从零开始。例如当你读这篇文章的时候,你会根据对之前单词的理解来理解后面的每一个单词。你不会抛掉之前所知的一切而重新开始思考。你的思维是有持久性的。

    传统的神经网络无法做到这点,这似乎是一个很大的缺憾。然而循环网络解决了这个问题。其是具有循环的网络架构,可以使信息得以留存。

    在上图中,一块神经网络

    为输入,以

    为输出。而循环的架构允许信息从网络的一个步骤传递到下一个步骤。

    这类循环架构为循环神经网络蒙上了一层神秘的面纱。然而,其实只要稍作思索,即能发现它们和标准的神经网络并没有什么不同。一个循环神经网络可以被认为是同一个网络的多个副本,每个副本都向后传递一条消息。思考一下如果我们展开循环会怎样?

    这种链状的特质展现了循环神经网络与序列和列表之间的密切相关性。链状架构是神经网络用于序列和链表数据的最佳架构模式。

    并且这种架构名副其实,在过去的几年里,将 RNN 应用到各类问题上取得了令人难以置信的成功:语音识别、语言建模、翻译、图像字幕......它们的表现的确令人叹为观止。

    而这些成功的关键因素就是“长短期记忆神经网络(Long Short Time Memory,LSTM)”,这是一种非常特殊的循环神经网络,在许多任务上,它的表现要明显优于标准神经网络。几乎所有基于循环神经网络的振奋人心的成果都是通过 LSTM 实现的。而这篇文章将探讨的正是 LSTM。

    长期依赖的困扰

    RNN 的一个诱人之处在于,它们能够将之前的信息与当前的任务联系起来,例如我们可以通过之前的视频帧了解当前帧的内容。如果 RNN 能做到这一点,它们将大有用处。但它们能吗?这就得视情况而定了。

    有时,我们只需要查看最近的信息就可以执行当前的任务。例如,考虑一个语言模型,它试图根据前面的单词预测下一个单词。如果我们试图预测“the clouds are in the sky”中的最后一个单词,我们不需要任何更远的上下文。很明显,最后一个单词将是“sky”。在这种情况下,相关信息与所需要预测的单词位置之间的跨度很小,RNN 便可以学习使用之前的信息。

    但有些情况下,我们需要更多的上下文。考虑预测文本“I grew up in France… I speak fluent French.”的最后一个单词。从最靠近的信息中,能推断出最后一个单词可能是一种语言的名字,但如果我们想要缩小语言的范围,我们就需要更早的关于“France”的上下文。相关信息与我们寻求的预测点之间的跨度完全有可能十分巨大。

    不幸的是,随着跨度的增加,RNN 变得难以对信息之间的关联进行有效学习。

    理论上来说,RNN 是绝对能够处理这种“长期依赖关系”的。你可以谨小慎微地来为其选择参数来解决上述例子那种形式的问题。然而遗憾的是,在实践中,RNN 似乎无能为力。Hochreiter(1991[德国])对这一问题进行了深入探讨。

    令人欣慰的是,LSTM 不存在这种困扰。

    LSTM 网络

    长短期记忆网络,即 LSTM,是一种特殊类型的 RNN,具有对长期依赖进行学习的能力。

    LSTM 被明确地设计为避免长期依赖问题。与 RNN 相比,对信息的长期记忆实际上是 LSTM 与生俱来的能力。

    所有循环神经网络的构造都是将神经网络的模块以链式进行重复。这个重复的模块将会有一个非常简单的结构,例如单个

    层。

    LSTM 也有这种链状结构,但是重复模块的结构却不同。即并非单一的神经网络层,而是四个,并以一种非常特殊的方式相互作用。LSTM中的重复模块包含四个交互层

    不要担心细节。稍后,我们将逐步研究 LSTM 图。现在,让我们试着熟悉一下我们将要用到的符号。

    在上面的图中,每个黑色的单行箭头代表一个完整的向量,从一个节点的输出到其他节点的输入。粉色的圆圈表示点对点的操作,比如向量加法,黄色的方框表示神经网络层。箭头合并表示连接,而箭头分叉表示内容被复制,且副本被复制到不同的位置。

    LSTM的核心思想

    LSTM 的核心要素是细胞状态,即贯穿下图顶部的水平线。细胞状态有点像传送带。它沿着整个链直线贯通,只有一些微小的线性相互作用。信息很容易在没有大幅变化的情况下流动。在传递过程中,通过当前时刻输入

    、上一时刻隐藏层状态

    、上一时刻细胞状态

    以及门结构来增加或删除细胞状态中的信息。细胞状态随时间的信息传递

    门是指一种有选择性地让信息通过的方式,即控制增加或删除信息的程度。其由一个 sigmoid 神经网络层和一个点乘运算组成。

    sigmoid 层输出

    之间的数字,描述每个组件应该允许的通过量。

    的值表示“不让任何量通过”,而

    的值表示“让所有量通过”。

    LSTM 有三个这样的门,用来保护以及控制细胞的状态。

    逐步解析LSTM

    遗忘门:

    LSTM 的第一步是决定从上一个细胞状态中丢弃什么信息。这个决定是由一个叫做“遗忘门”的 sigmoid 层做出的。如下图所示,遗忘门的输入为

    ,输出为

    。即为细胞状态

    中的每个值输出一个相对应的介于

    之间的值。

    表示完全保留,而

    表示完全删除。

    让我们回到语言模型的例子,即试图根据前面的单词预测下一个单词。在这种情况下,细胞状态可能包含了当前主题的性别特征,以便正确使用代词。然而当我们看到一个新的主题时,我们通常需要忘掉旧主题的性别特征。遗忘门

    输入门:

    下一步是决定在细胞状态中存储哪些新信息。这分为两个部分。首先,

    层创建一个新的打算添加到细胞状态中的候选值向量。其次,一个名为“输入门层”的 sigmoid 层决定候选值中的哪些值应该被添加到细胞状态中。接下来,我们将二者结合来创建细胞状态的更新值。

    在我们语言模型的例子中,我们想要在细胞状态中添加新主题的性别特征,以取代我们打算遗忘的旧主题的性别特征。输入门

    更新细胞状态:

    现在是时候将旧的单元格状态

    更新为新的细胞状态

    了。前面的步骤已经定好了要做什么,接下来我们只需要实际去做就好了。

    我们将旧状态

    按元素乘上

    ,将打算遗忘的内容遗忘掉。同理,我们添加

    ,即添加新的信息到细胞状态中。更新细胞状态

    相对于语言模型,这样的操作所达到的目的正是删除旧主题的性别信息并添加新信息,正如我们之前所决定的那样。

    输出门:

    最后,我们将决定输出什么。此输出将基于细胞状态,但将是基于更新后的细胞状态。首先,我们运行一个 sigmoid 层,它决定输出细胞状态的哪些部分。然后,我们使细胞状态通过

    (将值的范围缩小在

    之间),并将其乘以 sigmoid 层的输出,这样我们只输出了我们想要输出的部分。输出门

    对于语言模型示例,由于它只看到了一个主语,所以它可能希望输出与动词相关的信息,以应对接下来发生的事情。例如,它可能输出主语是单数还是复数,这样我们就能知道后面跟着的与其相对应的动词的形式。

    穿越时间的反向传播

    以上所述是 LSTM 的前向计算过程,接下来我们要关注的是求解梯度的反向传播算法。

    结合上述,我们可以整理思路如下:前向计算各时刻遗忘门

    、输入门

    以及根据当前输入得到的新信息候选值

    、细胞状态

    、输出门

    、隐藏层状态

    、最终模型的输出

    反向传播计算误差

    ,即模型目标函数

    对加权输入

    的偏导;(注意:

    的传播沿两个方向,分别为从输出层传播至输入层,以及沿时间

    的反向传播);

    求解模型目标函数

    对权重

    的偏导数。

    传播至输入层更新参数:

    首先我们定义

    ,且由上述公式可知

    ,因此可得:

    同理可得:

    注意,由于

    记忆了所有时刻的细胞状态,故每个时间点迭代时,

    累加。

    由于

    ,因此可得 :

    由于:

    ;

    因此:

    最后,可以求得各个权重矩阵的偏导数(注:下述公式中的上标

    表示矩阵的转置):

    注意,以上权重参数在所有时刻共享,故每个时间点迭代时的梯度累加。

    穿越时间反向传播:

    沿时间反向传播,就是要计算出

    时刻的误差项

    我们可以得到:

    且已知:

    并且已知

    都是

    的函数,那么,利用全导数公式可得:

    接下来,我们把上式中的每个偏导数都求出来,

    根据:

    以及:

    可得:

    将上述所得公式代入到公式

    ,可以得到:

    其中:

    即为误差沿着时间传播一个时刻的公式。有了它,我们就可以写出将误差项反向传播到任意

    时刻的公式:

    代码实现

    现在,我们已经清楚了 LSTM 的算法原理。接下来,我们将上述过程通过 Python 代码实现出来。

    在下面的实现中,LSTMLayer 的参数包括输入维度、输出维度、隐藏层维度,单元状态维度等于隐藏层维度。gate 的激活函数为 sigmoid 函数,输出的激活函数为 tanh。

    激活函数的实现:

    我们先实现两个激活函数:sigmoid 和 tanh。

    class SigmoidActivator(object):

    def forward(self, weighted_input):

    return 1.0 / (1.0 + np.exp(-weighted_input))

    def backward(self, output):

    return output * (1 - output)

    class TanhActivator(object):

    def forward(self, weighted_input):

    return 2.0 / (1.0 + np.exp(-2 * weighted_input)) - 1.0

    def backward(self, output):

    return 1 - output * output

    LSTM初始化:

    我们把LSTM的实现放在 LstmLayer 类中。

    根据LSTM前向计算和方向传播算法,我们需要初始化一系列矩阵和向量。这些矩阵和向量有两类用途,一类是用于保存模型参数,例如:

    ;另一类是保存各种中间计算结果,以便于反向传播算法使用,它们包括:

    ,以及各个权重对应的梯度。

    在构造函数的初始化中,只初始化了与forward计算相关的变量,与 backward 相关的变量没有初始化。这是因为构造 LSTM 对象的时候,我们还不知道它未来是用于训练(既有 forward 又有 backward)还是推理(只有 forward)。

    class LstmLayer(object):

    def __init__(self, input_width, state_width,

    learning_rate):

    self.input_width = input_width

    self.state_width = state_width

    self.learning_rate = learning_rate

    # 门的激活函数

    self.gate_activator = SigmoidActivator()

    # 输出的激活函数

    self.output_activator = TanhActivator()

    # 当前时刻初始化为t0

    self.times = 0

    # 各个时刻的单元状态向量c

    self.c_list = self.init_state_vec()

    # 各个时刻的输出向量h

    self.h_list = self.init_state_vec()

    # 各个时刻的遗忘门f

    self.f_list = self.init_state_vec()

    # 各个时刻的输入门i

    self.i_list = self.init_state_vec()

    # 各个时刻的输出门o

    self.o_list = self.init_state_vec()

    # 各个时刻的即时状态c~

    self.ct_list = self.init_state_vec()

    # 遗忘门权重矩阵Wfh, Wfx, 偏置项bf

    self.Wfh, self.Wfx, self.bf = (

    self.init_weight_mat())

    # 输入门权重矩阵Wfh, Wfx, 偏置项bf

    self.Wih, self.Wix, self.bi = (

    self.init_weight_mat())

    # 输出门权重矩阵Wfh, Wfx, 偏置项bf

    self.Woh, self.Wox, self.bo = (

    self.init_weight_mat())

    # 单元状态权重矩阵Wfh, Wfx, 偏置项bf

    self.Wch, self.Wcx, self.bc = (

    self.init_weight_mat())

    def init_state_vec(self):

    '''初始化保存状态的向量'''

    state_vec_list = []

    state_vec_list.append(np.zeros(

    (self.state_width, 1)))

    return state_vec_list

    def init_weight_mat(self):

    '''初始化权重矩阵'''

    Wh = np.random.uniform(-1e-4, 1e-4,

    (self.state_width, self.state_width))

    Wx = np.random.uniform(-1e-4, 1e-4,

    (self.state_width, self.input_width))

    b = np.zeros((self.state_width, 1))

    return Wh, Wx, b

    前向计算的实现:

    forward方法实现了LSTM的前向计算:

    def forward(self, x):

    '''根据式1-式6进行前向计算'''

    self.times += 1

    # 遗忘门

    fg = self.calc_gate(x, self.Wfx, self.Wfh,

    self.bf, self.gate_activator)

    self.f_list.append(fg)

    # 输入门

    ig = self.calc_gate(x, self.Wix, self.Wih,

    self.bi, self.gate_activator)

    self.i_list.append(ig)

    # 输出门

    og = self.calc_gate(x, self.Wox, self.Woh,

    self.bo, self.gate_activator)

    self.o_list.append(og)

    # 即时状态

    ct = self.calc_gate(x, self.Wcx, self.Wch,

    self.bc, self.output_activator)

    self.ct_list.append(ct)

    # 单元状态

    c = fg * self.c_list[self.times - 1] + ig * ct

    self.c_list.append(c)

    # 输出

    h = og * self.output_activator.forward(c)

    self.h_list.append(h)

    def calc_gate(self, x, Wx, Wh, b, activator):

    '''计算门'''

    h = self.h_list[self.times - 1] # 上次的LSTM输出

    net = np.dot(Wh, h) + np.dot(Wx, x) + b

    gate = activator.forward(net)

    return gate

    从上面的代码我们可以看到,门的计算都是相同的算法,而门和

    的计算仅仅是激活函数不同。因此我们提出了calc_gate方法,这样减少了很多重复代码。

    反向传播算法的实现:

    backward 方法实现了 LSTM 的反向传播算法。需要注意的是,与 backword 相关的内部状态变量是在调用 backward 方法之后才初始化的。这种延迟初始化的一个好处是,如果 LSTM 只是用来推理,那么就不需要初始化这些变量,节省了很多内存。

    def backward(self, x, delta_h, activator):

    '''实现LSTM训练算法'''

    self.calc_delta(delta_h, activator)

    self.calc_gradient(x)

    算法主要分成两个部分,一部分是计算误差项:

    def calc_delta(self, delta_h, activator):

    # 初始化各个时刻的误差项

    self.delta_h_list = self.init_delta() # 输出误差项

    self.delta_o_list = self.init_delta() # 输出门误差项

    self.delta_i_list = self.init_delta() # 输入门误差项

    self.delta_f_list = self.init_delta() # 遗忘门误差项

    self.delta_ct_list = self.init_delta() # 即时输出误差项

    # 保存从上一层传递下来的当前时刻的误差项

    self.delta_h_list[-1] = delta_h

    # 迭代计算每个时刻的误差项

    for k in range(self.times, 0, -1):

    self.calc_delta_k(k)

    def init_delta(self):

    '''初始化误差项'''

    delta_list = []

    for i in range(self.times + 1):

    delta_list.append(np.zeros(

    (self.state_width, 1)))

    return delta_list

    def calc_delta_k(self, k):

    '''根据k时刻的delta_h,计算k时刻的delta_f、delta_i、delta_o、delta_ct,以及k-1时刻的delta_h'''

    # 获得k时刻前向计算的值

    ig = self.i_list[k]

    og = self.o_list[k]

    fg = self.f_list[k]

    ct = self.ct_list[k]

    c = self.c_list[k]

    c_prev = self.c_list[k-1]

    tanh_c = self.output_activator.forward(c)

    delta_k = self.delta_h_list[k]

    # 根据式9计算delta_o

    delta_o = (delta_k * tanh_c *

    self.gate_activator.backward(og))

    delta_f = (delta_k * og *

    (1 - tanh_c * tanh_c) * c_prev *

    self.gate_activator.backward(fg))

    delta_i = (delta_k * og *

    (1 - tanh_c * tanh_c) * ct *

    self.gate_activator.backward(ig))

    delta_ct = (delta_k * og *

    (1 - tanh_c * tanh_c) * ig *

    self.output_activator.backward(ct))

    delta_h_prev = (

    np.dot(delta_o.transpose(), self.Woh) +

    np.dot(delta_i.transpose(), self.Wih) +

    np.dot(delta_f.transpose(), self.Wfh) +

    np.dot(delta_ct.transpose(), self.Wch)

    ).transpose()

    # 保存全部delta值

    self.delta_h_list[k-1] = delta_h_prev

    self.delta_f_list[k] = delta_f

    self.delta_i_list[k] = delta_i

    self.delta_o_list[k] = delta_o

    self.delta_ct_list[k] = delta_ct

    另一部分是计算梯度:

    def calc_gradient(self, x):

    # 初始化遗忘门权重梯度矩阵和偏置项

    self.Wfh_grad, self.Wfx_grad, self.bf_grad = (

    self.init_weight_gradient_mat())

    # 初始化输入门权重梯度矩阵和偏置项

    self.Wih_grad, self.Wix_grad, self.bi_grad = (

    self.init_weight_gradient_mat())

    # 初始化输出门权重梯度矩阵和偏置项

    self.Woh_grad, self.Wox_grad, self.bo_grad = (

    self.init_weight_gradient_mat())

    # 初始化单元状态权重梯度矩阵和偏置项

    self.Wch_grad, self.Wcx_grad, self.bc_grad = (

    self.init_weight_gradient_mat())

    # 计算对上一次输出h的权重梯度

    for t in range(self.times, 0, -1):

    # 计算各个时刻的梯度

    (Wfh_grad, bf_grad,

    Wih_grad, bi_grad,

    Woh_grad, bo_grad,

    Wch_grad, bc_grad) = (

    self.calc_gradient_t(t))

    # 实际梯度是各时刻梯度之和

    self.Wfh_grad += Wfh_grad

    self.bf_grad += bf_grad

    self.Wih_grad += Wih_grad

    self.bi_grad += bi_grad

    self.Woh_grad += Woh_grad

    self.bo_grad += bo_grad

    self.Wch_grad += Wch_grad

    self.bc_grad += bc_grad

    print '-----%d-----' % t

    print Wfh_grad

    print self.Wfh_grad

    # 计算对本次输入x的权重梯度

    xt = x.transpose()

    self.Wfx_grad = np.dot(self.delta_f_list[-1], xt)

    self.Wix_grad = np.dot(self.delta_i_list[-1], xt)

    self.Wox_grad = np.dot(self.delta_o_list[-1], xt)

    self.Wcx_grad = np.dot(self.delta_ct_list[-1], xt)

    def init_weight_gradient_mat(self):

    '''初始化权重矩阵'''

    Wh_grad = np.zeros((self.state_width,

    self.state_width))

    Wx_grad = np.zeros((self.state_width,

    self.input_width))

    b_grad = np.zeros((self.state_width, 1))

    return Wh_grad, Wx_grad, b_grad

    def calc_gradient_t(self, t):

    '''计算每个时刻t权重的梯度'''

    h_prev = self.h_list[t-1].transpose()

    Wfh_grad = np.dot(self.delta_f_list[t], h_prev)

    bf_grad = self.delta_f_list[t]

    Wih_grad = np.dot(self.delta_i_list[t], h_prev)

    bi_grad = self.delta_f_list[t]

    Woh_grad = np.dot(self.delta_o_list[t], h_prev)

    bo_grad = self.delta_f_list[t]

    Wch_grad = np.dot(self.delta_ct_list[t], h_prev)

    bc_grad = self.delta_ct_list[t]

    return Wfh_grad, bf_grad, Wih_grad, bi_grad, \

    Woh_grad, bo_grad, Wch_grad, bc_grad

    梯度下降算法的实现:

    下面是用梯度下降算法来更新权重:

    def update(self):

    '''按照梯度下降,更新权重'''

    self.Wfh -= self.learning_rate * self.Whf_grad

    self.Wfx -= self.learning_rate * self.Whx_grad

    self.bf -= self.learning_rate * self.bf_grad

    self.Wih -= self.learning_rate * self.Whi_grad

    self.Wix -= self.learning_rate * self.Whi_grad

    self.bi -= self.learning_rate * self.bi_grad

    self.Woh -= self.learning_rate * self.Wof_grad

    self.Wox -= self.learning_rate * self.Wox_grad

    self.bo -= self.learning_rate * self.bo_grad

    self.Wch -= self.learning_rate * self.Wcf_grad

    self.Wcx -= self.learning_rate * self.Wcx_grad

    最后,是梯度检查的代码:

    def data_set():

    x = [np.array([[1], [2], [3]]),

    np.array([[2], [3], [4]])]

    d = np.array([[1], [2]])

    return x, d

    def gradient_check():

    '''梯度检查'''

    # 设计一个误差函数,取所有节点输出项之和

    error_function = lambda o: o.sum()

    lstm = LstmLayer(3, 2, 1e-3)

    # 计算forward值

    x, d = data_set()

    lstm.forward(x[0])

    lstm.forward(x[1])

    # 求取sensitivity map

    sensitivity_array = np.ones(lstm.h_list[-1].shape,

    dtype=np.float64)

    # 计算梯度

    lstm.backward(x[1], sensitivity_array, IdentityActivator())

    # 检查梯度

    epsilon = 10e-4

    for i in range(lstm.Wfh.shape[0]):

    for j in range(lstm.Wfh.shape[1]):

    lstm.Wfh[i,j] += epsilon

    lstm.reset_state()

    lstm.forward(x[0])

    lstm.forward(x[1])

    err1 = error_function(lstm.h_list[-1])

    lstm.Wfh[i,j] -= 2*epsilon

    lstm.reset_state()

    lstm.forward(x[0])

    lstm.forward(x[1])

    err2 = error_function(lstm.h_list[-1])

    expect_grad = (err1 - err2) / (2 * epsilon)

    lstm.Wfh[i,j] += epsilon

    print 'weights(%d,%d): expected - actural%.4e-%.4e' % (

    i, j, expect_grad, lstm.Wfh_grad[i,j])

    return lstm

    我们只对

    做了检查,我们也可以自行增加对其他梯度的检查。下面是某次梯度检查的结果:

    至此,对长短期记忆神经网络(LSTM)从算法原理到实现已经有了较为清晰的认识和深刻的理解。“锦瑟无端五十弦,一弦一柱思华年”,在学习的过程中,有许多艰难与坎坷,也有许多辛苦与汗水,然而“不经一番寒彻骨,哪得梅花扑鼻香”。

    更多相关内容
  • 时序预测 | MATLAB实现Bayes(贝叶斯)优化LSTM(长短期记忆神经网络)时间序列预测(完整源码和数据) 数据为一维时序列数据,运行环境MATLAB2018b及以上。
  • 基于海洋捕食者算法优化的长短期记忆神经网络径流预测.pdf
  • 《NLP汉语自然语言处理原理与实现》第九章LSTM的python的代码实现,使用python3实现。可运行。
  • 回归预测 | MATLAB实现TPA-LSTM(时间注意力注意力机制长短期记忆神经网络)多输入单输出(完整源码和数据) 多输入单输出,运行环境MATLAB2020b及以上,运行主文件TPAMain.m即可。
  • 提出了一种基于卷积神经网络长短期记忆(LSTM)神经网络的深度学习网络结构。采用特征融合的方法,通过卷积网络提取出浅层特征与深层特征并进行联接,对特征通过卷积进行融合,将获得的矢量信息输入LSTM单元。分别...
  • 本实验实现的是利用LSTM (长短期记忆神经网络) 进行股票预测,通过本次实验,你将了解股票预测的方法、股票预测的数据集处理技巧、LSTM模型搭建以及训练过程等等,除此之外,你还将看到Paddlepaddle框架实现深度学习...
  • 长短期记忆递归神经网络具有学习长的观察序列的潜力。 这对于时间序列预测似乎非常不错,并且事实的确可能是这样的。 在本教程中,你将了解,如何对于一个一步单变量时序预测问题开发一个LSTM预测模型。 完成本...
  • 人工智能-基于长短期记忆神经网络的收益率预测研究.pdf
  • 人工智能-基于长短期记忆神经网络的环渤海典型港口吞吐量预测.pdf
  • MATLAB实现LSTM(长短期记忆神经网络)多输入单输出数据集
  • 分类预测 | MATLAB实现LSTM(长短期记忆神经网络)分类预测(完整源码和数据) 多特征输入多标签输出,运行环境MATLAB2018b及以上。
  • 回归预测 | MATLAB实现LSTM(长短期记忆神经网络)多输入单输出(完整源码和数据) 多输入单输出,运行环境MATLAB2018b及以上。
  • 基于长短期记忆神经网络的短期负荷预测.pdf
  • MATLAB实现LSTM(长短期记忆神经网络)时间序列预测
  • 基于长短期记忆神经网络的短期负荷预测方法.pdf
  • 基于深度长短期记忆神经网络的短期负荷预测.pdf
  • 基于改进长短期记忆神经网络的短期负荷预测.pdf
  • MATLAB实现优化LSTM(长短期记忆神经网络)时间序列预测算法
  • 回归预测 | MATLAB实现BiLSTM(双向长短期记忆神经网络)多输入单输出(完整源码和数据) 多输入单输出,运行环境MATLAB2018b及以上。
  • 基于长短期记忆神经网络的海冰范围预测.pdf
  • 基于长短期记忆神经网络的手写数字识别.pdf
  • 基于长短期记忆神经网络的健康状态估算.pdf
  • 基于长短期记忆神经网络的可用停车位预测.pdf
  • 基于改进的长短期记忆神经网络方言辨识模型.pdf
  • 基于长短期记忆神经网络的燃气数据分析设计.pdf
  • 基于长短期记忆神经网络的刀具磨损状态监测.pdf
  • 基于长短期记忆神经网络模型的空气质量预测.pdf
  • 基于双向长短期记忆神经网络的岩相预测方法.pdf
  • 基于长短期记忆神经网络的光伏阵列故障诊断.pdf

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,243
精华内容 4,097
关键字:

长短期记忆神经网络

友情链接: 程序源代码.zip