0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

PyTorch教程-10.4. 双向递归神经网络

jf_pJlTbmA9 来源:PyTorch 作者:PyTorch 2023-06-05 15:44 次阅读

到目前为止,我们的序列学习任务的工作示例是语言建模,我们的目标是在给定序列中所有先前标记的情况下预测下一个标记。在这种情况下,我们只希望以左向上下文为条件,因此标准 RNN 的单向链接似乎是合适的。然而,还有许多其他序列学习任务上下文,在这些上下文中,在向左和向右上下文的每个时间步调整预测是非常好的。例如,考虑词性检测。在评估与给定词相关的词性时,为什么我们不应该考虑两个方向的上下文?

另一项常见任务(通常在针对感兴趣的实际任务微调模型之前用作预训练练习)是屏蔽文本文档中的随机标记,然后训练序列模型以预测缺失标记的值。请注意,根据空白后面的内容,缺失标记的可能值会发生显着变化:

我是___。

我___饿了。

我___饿了,我能吃半头猪。

在第一句话中,“快乐”似乎是一个可能的候选者。“不”和“非常”这两个词在第二句中似乎说得通,但“不”与第三句似乎格格不入。

幸运的是,一种简单的技术可以将任何单向 RNN 转换为双向 RNN (Schuster 和 Paliwal,1997)。我们简单地实现两个单向 RNN 层,它们以相反的方向链接在一起并作用于相同的输入(图 10.4.1)。对于第一个 RNN 层,第一个输入是x1最后的输入是 xT,但是对于第二个 RNN 层,第一个输入是 xT最后的输入是x1. 为了产生这个双向 RNN 层的输出,我们只需将两个底层单向 RNN 层的相应输出连接在一起。

pYYBAGR9N2OAGJ96AADWxnNwvHE433.svg

图 10.4.1双向 RNN 的架构。

正式地为任何时间步长t,我们考虑一个小批量输入 Xt∈Rn×d(示例数量: n,每个示例中的输入数量:d) 并令隐藏层激活函数为ϕ. 在双向架构中,这个时间步长的前向和后向隐藏状态是H→t∈Rn×h 和H←t∈Rn×h,分别在哪里h是隐藏单元的数量。前向和后向隐藏状态更新如下:

(10.4.1)H→t=ϕ(XtWxh(f)+H→t−1Whh(f)+bh(f)),H←t=ϕ(XtWxh(b)+H←t+1Whh(b)+bh(b)),

权重在哪里 Wxh(f)∈Rd×h,Whh(f)∈Rh×h,Wxh(b)∈Rd×h,andWhh(b)∈Rh×h, 和偏见bh(f)∈R1×h和 bh(b)∈R1×h都是模型参数

接下来,我们连接前向和后向隐藏状态 H→t和 H←t获得隐藏状态 Ht∈Rn×2h送入输出层。在具有多个隐藏层的深度双向 RNN 中,此类信息作为输入传递到下一个双向层。最后,输出层计算输出 Ot∈Rn×q(输出数量: q):

(10.4.2)Ot=HtWhq+bq.

这里,权重矩阵 Whq∈R2h×q和偏见 bq∈R1×q是输出层的模型参数。虽然从技术上讲,两个方向可以有不同数量的隐藏单元,但在实践中很少做出这种设计选择。我们现在演示双向 RNN 的简单实现。

import torch
from torch import nn
from d2l import torch as d2l

from mxnet import np, npx
from mxnet.gluon import rnn
from d2l import mxnet as d2l

npx.set_np()

from jax import numpy as jnp
from d2l import jax as d2l

No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)

import tensorflow as tf
from d2l import tensorflow as d2l

10.4.1。从零开始实施

要从头开始实现双向 RNN,我们可以包含两个RNNScratch具有独立可学习参数的单向实例。

class BiRNNScratch(d2l.Module):
  def __init__(self, num_inputs, num_hiddens, sigma=0.01):
    super().__init__()
    self.save_hyperparameters()
    self.f_rnn = d2l.RNNScratch(num_inputs, num_hiddens, sigma)
    self.b_rnn = d2l.RNNScratch(num_inputs, num_hiddens, sigma)
    self.num_hiddens *= 2 # The output dimension will be doubled

class BiRNNScratch(d2l.Module):
  def __init__(self, num_inputs, num_hiddens, sigma=0.01):
    super().__init__()
    self.save_hyperparameters()
    self.f_rnn = d2l.RNNScratch(num_inputs, num_hiddens, sigma)
    self.b_rnn = d2l.RNNScratch(num_inputs, num_hiddens, sigma)
    self.num_hiddens *= 2 # The output dimension will be doubled

class BiRNNScratch(d2l.Module):
  num_inputs: int
  num_hiddens: int
  sigma: float = 0.01

  def setup(self):
    self.f_rnn = d2l.RNNScratch(num_inputs, num_hiddens, sigma)
    self.b_rnn = d2l.RNNScratch(num_inputs, num_hiddens, sigma)
    self.num_hiddens *= 2 # The output dimension will be doubled

class BiRNNScratch(d2l.Module):
  def __init__(self, num_inputs, num_hiddens, sigma=0.01):
    super().__init__()
    self.save_hyperparameters()
    self.f_rnn = d2l.RNNScratch(num_inputs, num_hiddens, sigma)
    self.b_rnn = d2l.RNNScratch(num_inputs, num_hiddens, sigma)
    self.num_hiddens *= 2 # The output dimension will be doubled

前向和后向 RNN 的状态分别更新,而这两个 RNN 的输出被连接起来。

@d2l.add_to_class(BiRNNScratch)
def forward(self, inputs, Hs=None):
  f_H, b_H = Hs if Hs is not None else (None, None)
  f_outputs, f_H = self.f_rnn(inputs, f_H)
  b_outputs, b_H = self.b_rnn(reversed(inputs), b_H)
  outputs = [torch.cat((f, b), -1) for f, b in zip(
    f_outputs, reversed(b_outputs))]
  return outputs, (f_H, b_H)

@d2l.add_to_class(BiRNNScratch)
def forward(self, inputs, Hs=None):
  f_H, b_H = Hs if Hs is not None else (None, None)
  f_outputs, f_H = self.f_rnn(inputs, f_H)
  b_outputs, b_H = self.b_rnn(reversed(inputs), b_H)
  outputs = [np.concatenate((f, b), -1) for f, b in zip(
    f_outputs, reversed(b_outputs))]
  return outputs, (f_H, b_H)

@d2l.add_to_class(BiRNNScratch)
def forward(self, inputs, Hs=None):
  f_H, b_H = Hs if Hs is not None else (None, None)
  f_outputs, f_H = self.f_rnn(inputs, f_H)
  b_outputs, b_H = self.b_rnn(reversed(inputs), b_H)
  outputs = [jnp.concatenate((f, b), -1) for f, b in zip(
    f_outputs, reversed(b_outputs))]
  return outputs, (f_H, b_H)

@d2l.add_to_class(BiRNNScratch)
def forward(self, inputs, Hs=None):
  f_H, b_H = Hs if Hs is not None else (None, None)
  f_outputs, f_H = self.f_rnn(inputs, f_H)
  b_outputs, b_H = self.b_rnn(reversed(inputs), b_H)
  outputs = [tf.concat((f, b), -1) for f, b in zip(
    f_outputs, reversed(b_outputs))]
  return outputs, (f_H, b_H)

10.4.2。简洁的实现

使用高级 API,我们可以更简洁地实现双向 RNN。这里我们以一个 GRU 模型为例。

class BiGRU(d2l.RNN):
  def __init__(self, num_inputs, num_hiddens):
    d2l.Module.__init__(self)
    self.save_hyperparameters()
    self.rnn = nn.GRU(num_inputs, num_hiddens, bidirectional=True)
    self.num_hiddens *= 2

Using the high-level APIs, we can implement bidirectional RNNs more concisely. Here we take a GRU model as an example.

class BiGRU(d2l.RNN):
  def __init__(self, num_inputs, num_hiddens):
    d2l.Module.__init__(self)
    self.save_hyperparameters()
    self.rnn = rnn.GRU(num_hiddens, bidirectional=True)
    self.num_hiddens *= 2

Flax API does not offer RNN layers and hence there is no notion of any bidirectional argument. One needs to manually reverse the inputs as shown in the scratch implementation, if a bidirectional layer is needed.

Using the high-level APIs, we can implement bidirectional RNNs more concisely. Here we take a GRU model as an example.

10.4.3。概括

在双向 RNN 中,每个时间步的隐藏状态同时由当前时间步之前和之后的数据确定。双向 RNN 主要用于序列编码和给定双向上下文的观察估计。由于长梯度链,双向 RNN 的训练成本非常高。

10.4.4。练习

如果不同方向使用不同数量的隐藏单元,形状将如何Ht改变?

设计具有多个隐藏层的双向 RNN。

多义现象在自然语言中很常见。例如,“银行”一词在“我去银行存款”和“我去银行坐下”的语境中有不同的含义。我们如何设计一个神经网络模型,以便在给定上下文序列和一个词的情况下,返回该词在上下文中的向量表示?哪种类型的神经架构更适合处理多义词?

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 神经网络
    +关注

    关注

    42

    文章

    4771

    浏览量

    100739
  • pytorch
    +关注

    关注

    2

    文章

    808

    浏览量

    13218
收藏 人收藏

    评论

    相关推荐

    基于递归神经网络和前馈神经网络的深度学习预测算法

    蛋白质二级结构预测是结构生物学中的一个重要问题。针对八类蛋白质二级结构预测,提出了一种基于递归神经网络和前馈神经网络的深度学习预测算法。该算法通过双向
    发表于 12-03 09:41 9次下载

    PyTorch教程之循环神经网络

    电子发烧友网站提供《PyTorch教程之循环神经网络.pdf》资料免费下载
    发表于 06-05 09:52 0次下载
    <b class='flag-5'>PyTorch</b>教程之循环<b class='flag-5'>神经网络</b>

    PyTorch教程之从零开始的递归神经网络实现

    电子发烧友网站提供《PyTorch教程之从零开始的递归神经网络实现.pdf》资料免费下载
    发表于 06-05 09:55 0次下载
    <b class='flag-5'>PyTorch</b>教程之从零开始的<b class='flag-5'>递归</b><b class='flag-5'>神经网络</b>实现

    PyTorch教程9.6之递归神经网络的简洁实现

    电子发烧友网站提供《PyTorch教程9.6之递归神经网络的简洁实现.pdf》资料免费下载
    发表于 06-05 09:56 0次下载
    <b class='flag-5'>PyTorch</b>教程9.6之<b class='flag-5'>递归</b><b class='flag-5'>神经网络</b>的简洁实现

    PyTorch教程10.3之深度递归神经网络

    电子发烧友网站提供《PyTorch教程10.3之深度递归神经网络.pdf》资料免费下载
    发表于 06-05 15:12 0次下载
    <b class='flag-5'>PyTorch</b>教程10.3之深度<b class='flag-5'>递归</b><b class='flag-5'>神经网络</b>

    PyTorch教程10.4双向递归神经网络

    电子发烧友网站提供《PyTorch教程10.4双向递归神经网络.pdf》资料免费下载
    发表于 06-05 15:13 0次下载
    <b class='flag-5'>PyTorch</b>教程<b class='flag-5'>10.4</b>之<b class='flag-5'>双向</b><b class='flag-5'>递归</b><b class='flag-5'>神经网络</b>

    PyTorch教程16.2之情感分析:使用递归神经网络

    电子发烧友网站提供《PyTorch教程16.2之情感分析:使用递归神经网络.pdf》资料免费下载
    发表于 06-05 10:55 0次下载
    <b class='flag-5'>PyTorch</b>教程16.2之情感分析:使用<b class='flag-5'>递归</b><b class='flag-5'>神经网络</b>

    使用PyTorch构建神经网络

    PyTorch是一个流行的深度学习框架,它以其简洁的API和强大的灵活性在学术界和工业界得到了广泛应用。在本文中,我们将深入探讨如何使用PyTorch构建神经网络,包括从基础概念到高级特性的全面解析。本文旨在为读者提供一个完整的
    的头像 发表于 07-02 11:31 707次阅读

    递归神经网络是循环神经网络

    递归神经网络(Recurrent Neural Network,简称RNN)和循环神经网络(Recurrent Neural Network,简称RNN)实际上是同一个概念,只是不同的翻译方式
    的头像 发表于 07-04 14:54 744次阅读

    递归神经网络与循环神经网络一样吗

    递归神经网络(Recursive Neural Network,RvNN)和循环神经网络(Recurrent Neural Network,RNN)是两种不同类型的神经网络结构,它们在
    的头像 发表于 07-05 09:28 841次阅读

    rnn是递归神经网络还是循环神经网络

    RNN(Recurrent Neural Network)是循环神经网络,而非递归神经网络。循环神经网络是一种具有时间序列特性的神经网络,能
    的头像 发表于 07-05 09:52 567次阅读

    PyTorch神经网络模型构建过程

    PyTorch,作为一个广泛使用的开源深度学习库,提供了丰富的工具和模块,帮助开发者构建、训练和部署神经网络模型。在神经网络模型中,输出层是尤为关键的部分,它负责将模型的预测结果以合适的形式输出。以下将详细解析
    的头像 发表于 07-10 14:57 495次阅读

    递归神经网络的实现方法

    递归神经网络(Recursive Neural Network,简称RNN)是一种特殊类型的神经网络,其特点在于能够处理具有层次或树状结构的数据,并通过递归的方式对这些数据进行建模。与
    的头像 发表于 07-10 17:02 316次阅读

    递归神经网络和循环神经网络的模型结构

    递归神经网络是一种旨在处理分层结构的神经网络,使其特别适合涉及树状或嵌套数据的任务。这些网络明确地模拟了层次结构中的关系和依赖关系,例如语言中的句法结构或图像中的层次表示。它使用
    的头像 发表于 07-10 17:21 648次阅读
    <b class='flag-5'>递归</b><b class='flag-5'>神经网络</b>和循环<b class='flag-5'>神经网络</b>的模型结构

    pytorch中有神经网络模型吗

    当然,PyTorch是一个广泛使用的深度学习框架,它提供了许多预训练的神经网络模型。 PyTorch中的神经网络模型 1. 引言 深度学习是一种基于人工
    的头像 发表于 07-11 09:59 696次阅读