2024/4/7周报

文章目录

  • 摘要
  • Abstract
  • 文献阅读
    • 题目
    • 引言
    • 创新点
    • Decoder-Encoder模型
    • 实验过程
    • 实验结果
  • 深度学习
    • LSTM变体
      • Bidirectional LSTM(双向LSTM)
      • GRU
      • GRU代码实现
  • 总结

摘要

用于统计机器翻译的RNN编码器-解码器学习短语表示
文中提出了一种新的神经网络模型称为RNN编码器-解码器,由两个递归神经网络(RNN)构成。一个RNN将符号序列编码为固定长度的向量表示,另一个将表示解码为另一个符号序列。通过使用由RNN编码器-解码器计算的短语对的条件概率作为现有对数线性模型中的附加特征,使得统计机器翻译系统的性能得到改善。

Abstract

文献阅读

题目

Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation

引言

在研究神经网络在SMT中的应用的基础上,提出了一种新的神经网络体系结构,可以作为传统基于短语的SMT系统的一部分。提出的神经网络结构,将其称为一个RNN Encoder–Decode,由两个递归神经网络(RNN)作为编码器和解码器对。实验结果表明,采用RNN Encoder–Decode对短语进行译码,提高了译码性能。定性分析表明,RNN Encoder–Decode能较好地捕捉短语表中的语言规律,间接解释了整体翻译性能的量化提升。

创新点

本文提出了GRU的结构:
在这里插入图片描述

先来看一下GRU各个状态是如何更新的:
在这里插入图片描述

其中,[.]j代表向量的第j个元素,也就是图中的公式都是以单个元素为例进行计算的。⨀表示将两个形状相同的矩阵对应元素相乘。[.]+[.]代表将两个向量进行拼接,不是对应元素相加。x和ht−1分别代表输入和上一层的隐藏状态。W∗和U∗代表权重矩阵,*代表r、z或空。σ代表sigmoid函数,图中z和r分别代表更新门和重置门。

如果重置门被设置为0,那么先前的隐藏层状态就会被强制遗忘,然后用当前的输入进行重置。这使得隐藏层状态可以有效的丢 弃跟未来没有任何关系的信息,从而使信息表达更为紧凑。而更新门则是用来控制先前的隐藏层状态会携带多少信息到当前状态。

Decoder-Encoder模型

编码器是一个RNN,它根据输入序列在每一时间步更新隐状态,最后输出编码向量c来表示整个输入序列。
解码器是一个条件RNN,它根据编码向量c以及前面生成的符号,通过计算隐状态和条件概率分布,生成输出序列。
在这里插入图片描述

编码器:
在这里插入图片描述

编码器部分标注出了隐藏层状态,用ht表示,其更新公式为:
在这里插入图片描述

其公式(1)说明当前时刻的隐藏层状态ht是由上一时刻的状态ht−1和当前时刻的输入xt共同决定的。f 是一个函数,可以是一个简单的逻辑函数,比如sigmoid函数,也可以是一个复杂的函数,比如LSTM。这篇论文中f用的是作者提出的一个新的结构,叫做GRU。

C是中间语义表示,可以是各个时刻隐藏输出的汇总:
在这里插入图片描述

也可以是最后一层隐层的输出:
C=hT

本篇论文中作者是将隐层的最后输出作为语义表示 C 。由于编码器用的是RNN的结构,每一个循环中的信息都会流到下一个循环中,因此中间语义表示 C 理论上包含了输入序列的所有信息。
在这里插入图片描述

解码器:
图中标注出了解码器的隐藏层状态,用st表示,从图中可以看出,隐藏层的状态更新,不仅跟上一时刻的输出st−1和当前时刻的输入c有关系,还跟上一时刻的输出yt−1有关:
在这里插入图片描述

实验过程

一、数据集
使用WMT2014数据集,其包含大量英法平行数据。双语语料库包括Europarl(6100万单词)、news commentary(550万单词)、UN(421万单词)和两个爬行语料库(9000万单词)。最后两个语料库比较吵。为了训练法语语言模型,除了bitext的目标侧外,还有大约7.12亿的爬行报纸材料。所有的单词计数都是经过标记的法语单词。
二、评估指标
提出使用RNN编码器-解码器模型来对短语进行分值,与传统的基于语言模型的方法进行对比BLEU分数。
三、超参数的设定
实验中使用的RNN Encoder–Decoder有1000个隐藏单元,标准差固定为0.01,h=10^-6,ρ=0.95。

实验结果

在这里插入图片描述

当我们同时使用CSLM和RNN Encoder–Decoder的短语评分时,可以获得最佳的性能。这说明CSLM和RNN Encoder–Decoder的贡献不太相关,单独改进这两种方法可以得到更好的结果。此外,我们尝试惩罚神经网络未知的单词数量(即不在候选列表中的单词)。我们通过简单地将未知单词的数量作为一个附加特性添加到式(9)中的对数线性模型中来实现这一点。然而,在这种情况下我们无法在测试集上获得更好的性能,而只能在开发集上获得更好的性能。

图4左边的图显示了使用RNN Encoder–Decoder学习的单词嵌入矩阵对单词进行二维嵌入。该预测是由最近提出的BarnesHut-SNE (van der Maaten, 2013)完成的。我们可以清楚地看到,语义上相似的单词彼此聚集在一起(参见图4中的放大图)。这种情况下的表示(图1中的c)是一个1000维的向量。与单词表示类似,我们使用图5中的bar - hut - sne可视化由四个或更多单词组成的短语的表示。
在这里插入图片描述

从可视化结果可以看出,RNN Encoder–Decoder同时捕获了短语的语义结构和句法结构。例如,在左下角的图中,大多数短语是关于持续时间的,而那些在语法上相似的短语则聚集在一起。右下角的图表显示了语义相似(国家或地区)的短语集群。另一方面,右上角的图表显示了语法上相似的短语。
在这里插入图片描述

深度学习

LSTM变体

Bidirectional LSTM(双向LSTM)

LSTM只能实现单向的传递,无法编码从后到前的信息。当我们语句是承前启后的情况时,自然能完成。但是当语句顺序倒过来,关键次在后面了,LSTM就无能为力了。在更细粒度的分类时,如对于强程度的褒义、弱程度的褒义、中性、弱程度的贬义、强程度的贬义的五分类任务需要注意情感词、程度词、否定词之间的交互。举一个例子,“这个餐厅脏得不行,没有隔壁好”,这里的“不行”是对“脏”的程度的一种修饰,通过BiLSTM可以更好的捕捉双向的语义依赖。
在这里插入图片描述

双向LSTM结构中有两个 LSTM 层,一个从前向后处理序列,另一个从后向前处理序列。这样,模型可以同时利用前面和后面的上下文信息。在处理序列时,每个时间步的输入会被分别传递给两个 LSTM 层,然后它们的输出会被合并。通过双向 LSTM,我们可以获得更全面的序列信息,有助于提高模型在序列任务中的性能。
双向神经网络的单元计算与单向的是相通的。但是双向神经网络隐藏层要保存两个值,一个参与正向计算,另一个值参与反向计算,处理完成后将两个LSTM的输出拼接起来。

Q:为什么LSTM中经常使用的是双向LSTM?
双向结构的设计可以提高模型的表示能力和性能,特别是好地捕捉序列中的信息、在处理复杂序列数据时。以下是为什么经常使用两层双向LSTM的一些原因:
更丰富的上下文信息: 两层LSTM可以提供更丰富的上下文信息。第一层LSTM将原始输入序列的信息进行初步处理,然后将其作为更丰富的输入提供给第二层LSTM。这有助于模型更好地捕捉输入序列中的特征和模式。
更强的特征表示: 两层LSTM可以逐步提取更抽象、更高级别的特征表示。第一层LSTM将原始数据进行编码,然后第二层LSTM在第一层的基础上进一步提取更有意义的特征。这有助于提高模型的表达能力,从而更好地建模序列数据
双向信息:双向LSTM可以从两个方向(正向和反向)分别获取序列数据的信息。

GRU

虽然LSTM能够抑制梯度消失问题,但需要以增加时间复杂度和空间复杂度作为代价。GRU在LSTM基础上将忘记门和输入门合并成一个新的门即更新门, GRU包含两个门:更新门与重置门
如果我们将重置门设置为 1,更新门设置为 0,那么我们将再次获得标准 RNN 模型。这两个门控向量决定了哪些信息最终能作为门控循环单元的输出,它们能够保存长期序列中的信息,使得重要信息可以跨越长时间步骤传递,且不会随时间而清除或因为与预测不相关而移除。

GRU的优势:
参数更少:从而有效降低过拟合的风险,因此模型泛化能力较好,并且在反向传播的过程中,随着反向传播深度的加深,对应需要反向传播路径相比于LSTM大量减少,从而减小了时间、空间复杂度的负担。
训练速度较快: 由于GRU的参数较少,它通常比LSTM更快地训练。
对短序列有优势:GRU在某种程度上减少了梯度消失的问题,使其更容易捕捉到短序列中的相关信息。

GRU的缺点:
信息保存不如LSTM: GRU的门控机制相对简单,因此它不太适合捕捉长期依赖关系。在某些任务中,尤其是处理需要长期记忆的序列数据时,LSTM可能表现更好。
性能不稳定:GRU在某些任务中可能表现得不如LSTM稳定,因为它在不同数据集和问题上的性能差异较大。在一些情况下,LSTM可能更可靠。

GRU代码实现

d2l是李沐老师自己的一个包,可以从github上自行下载,之后我们就可以通过train_iter以mini-batch方式读取数据;并通过vocab把词转换成数字表示进行模型输入和输出。

import torch
from torch import nn
from d2l import torch as d2l
# 设置每个batch的大小和时间步数
batch_size, num_steps = 32, 35
# 加载时间机器数据集并获取词汇表
train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps)

先设置输入输出参数维度为词汇表大小,然后定义了两个函数normal和three,用于生成服从正态分布的随机权重张量。然后利用three函数初始化了GRU模型中更新门、重置门、候选隐状态等不同组件所需的权重和偏置参数。接着初始化了从隐状态到输出的权重和偏置。最后将所有参数放入列表中,设置requires_grad,并返回参数列表。这样就完成了GRU模型中不同门控机制的参数初始化,为后续建立GRU模型提供了参数准备。

# 初始化模型参数
def get_params(vocab_size, num_hiddens, device):
    # 设置输入和输出的维度为词汇表大小
    num_inputs = num_outputs = vocab_size
    
    # 定义一个函数,用于生成服从正态分布的随机张量,并乘以0.01进行缩放
    def normal(shape):
        return torch.randn(size=shape, device=device) * 0.01
    
    # 定义一个函数,生成三组权重和偏置张量,用于不同的门控机制
    def three():
        return (normal(
            (num_inputs, num_hiddens)), normal((num_hiddens, num_hiddens)),
                torch.zeros(num_hiddens, device=device))
    
    # 初始化GRU中的权重和偏置
    # 权重和偏置用于控制更新门
    W_xz, W_hz, b_z = three() # GRU多了这两行
    # 权重和偏置用于控制重置门
    W_xr, W_hr, b_r = three() # GRU多了这两行
    # 权重和偏置用于计算候选隐藏状态
    W_xh, W_hh, b_h = three()
    # 隐藏状态到输出的权重
    W_hq = normal((num_hiddens, num_outputs))
    # 输出的偏置
    b_q = torch.zeros(num_outputs, device=device)
    # 参数列表中各参数顺序
    params = [W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q]
    # 遍历参数列表中所有参数
    for param in params:
        # 设置参数的`requires_grad`属性为True,以便进行梯度计算
        param.requires_grad_(True)
    # 返回参数列表中所有参数
    return params

在这里插入图片描述
这个函数接收batch_size, num_hiddens和device作为参数。它返回一个只包含一个元素的元组,个元素是一个形状为(batch_size, num_hiddens)、设备为device、且值全为0的张量。这个全零的隐藏状态张量将作为GRU模型最初的隐藏状态使用。

# 定义隐藏状态的初始化函数
def init_gru_state(batch_size, num_hiddens, device):
    # 返回隐藏状态初始化为全零的元组
    return (torch.zeros((batch_size, num_hiddens), device=device),)

以下代码通过输入序列上的逐步计算,实现了GRU的基本前向计算流程,包括不同门控单元的计算以及隐藏状态的更新。

def gru(inputs, state, params):
    # 参数 params 解包为多个变量,分别表示模型中的权重和偏置
    W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q = params     
    # 传入的隐藏状态 state 解包为单个变量 H。
    H, = state
    # 创建一个空列表,用于存储每个时间步的输出
    outputs = []
    # 遍历输入序列中的每个时间步
    for X in inputs:
        # 更新门控机制 Z
        Z = torch.sigmoid((X @ W_xz) + (H @ W_hz) + b_z)
        # 重置门控机制 R
        R = torch.sigmoid((X @ W_xr) + (H @ W_hr) + b_r)
        # 计算候选隐藏状态 H_tilda
        H_tilda = torch.tanh((X @ W_xh) + ((R * H) @ W_hh) + b_h)
        # 更新隐藏状态 H
        H = Z * H + (1 - Z) * H_tilda
        # 计算输出 Y
        Y = H @ W_hq + b_q
        # 将输出添加到列表中
        outputs.append(Y)
    # 将所有输出拼接在一起,并返回拼接后的结果和最终的隐藏状态
    return torch.cat(outputs, dim=0), (H,)

训练与预测:
训练和预测的工作方式与RNN中的实现完全相同。训练结束后,我们分别打印输出训练集的困惑度和前缀“time traveler”和“traveler”的预测序列上的困惑度。

# 训练
vocab_size, num_hiddens, device = len(vocab), 256, d2l.try_gpu()
# 设置训练的总轮数和学习率
num_epochs, lr = 500, 1
# 创建 GRU 模型实例
model = d2l.RNNModelScratch(len(vocab), num_hiddens, device, get_params,
                           init_gru_state, gru)
# 调用 D2L 库中的训练函数,传入模型实例、训练数据迭代器、词汇表、学习率和训练的总轮数
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)

在这里插入图片描述
简单实现:高级API包含了前文介绍地全部配置细节,所以可以直接实例化GRU。其使用编译好的运算符来进行计算,而非python处理其中的许多细节。

# 简洁实现
# 设置输入特征的维度为词汇表大小
num_inputs = vocab_size
# 创建一个 GRU 层,指定输入特征的维度和隐藏单元的数量
gru_layer = nn.GRU(num_inputs, num_hiddens)
# 创建一个 RNNModel 实例,传入 GRU 层和词汇表的大小
model = d2l.RNNModel(gru_layer, len(vocab))
# 将模型移动到指定的设备上(可能是 GPU)
model = model.to(device)
# 调用 D2L 库中的 train_ch8 函数进行训练,传入模型实例、训练数据迭代器、词汇表、学习率和训练的总轮数
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)

总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/522172.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

博客评论回复03

接着之前写的,之前返回的数据集按道理来说渲染出来还是丑丑的,因此这次我看着抖音的评论样子,自己瞎写了一通,不过也算是模仿出来了虽然肯定没有抖音写的好。 类似与前面几章写的表结构 首先看看抖音评论区是怎么样的&#xff1f…

消息队列之RabbitMQ的安装配置

一,前言 RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。点击跳转RabbitM…

前端开发学习笔记 3 (Chrome浏览器调试工具、Emmet语法、CSS复合选择器、CSS元素选择模式、CSS背景)

文章目录 Chrome浏览器调试工具Emmet语法CSS复合选择器后代选择器子选择器并集选择器伪类选择器 CSS元素选择模式元素选择模式概述CSS块标签CSS行内标签CSS行内块标签CSS元素显示模式转换 CSS背景CSS背景颜色CSS背景图片CSS背景图片平铺CSS背景图片位置CSS背景图片固定CSS背景复…

HIS系统是什么?一套前后端分离云HIS系统源码 接口技术RESTful API + WebSocket + WebService

HIS系统是什么?一套前后端分离云HIS系统源码 接口技术RESTful API WebSocket WebService 医院管理信息系统(全称为Hospital Information System)即HIS系统。 常规模版包括门诊管理、住院管理、药房管理、药库管理、院长查询、电子处方、物资管理、媒体管理等&…

275. 传纸条(DP)

题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排坐成一个 m 行 n 列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸运的是&…

CMU15/445 2023 Spring-project1 LRU-K 替换策略

在写个demo之前,专门学习了LRU:【LeetCode刷题】146. LRU 缓存-CSDN博客 使用哈希表 双向链表可以满足删除/增加的时间复杂度为O(1)。 在通读完15/445这块的说明之后,发现和LRU还是有些差别的。 官方文档中对LRU-K的解释是:LRU-K算法根据所…

Spring boot框架Rouyi Cloud入门之token

🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄 🌹简历模板、学习资料、面试题库、技术互助 🌹文末获取联系方式 📝 往期热门专栏回顾 专栏…

【Gluten】Spark 的向量化执行引擎框架 Gluten

Gluten 项目主要用于“粘合” Apache Spark 和作为 Backend 的 Native Vectorized Engine。Backend 的选项有很多,目前在 Gluten 项目中已经明确开始支持的有 Velox、Clickhouse 和 Apache Arrow。通过使用Native backend 执行计算,加速 Spark 执行速度&…

超市商品管理系统的设计与实现(全套资料)

一、系统架构 前端:vue | view-design 后端:springboot | mybatis-plus 环境:jdk17 | mysql8 | maven | nodejs | redis 二、代码及数据库 三、功能介绍 01. web端-首页 02. web端-超市概况 03. web端-超市区域 04. …

【Web】纯萌新的BUUCTF刷题日记Day1

目录 [RoarCTF 2019]Easy Java [网鼎杯 2018]Fakebook [CISCN2019 华北赛区 Day2 Web1]Hack World [BJDCTF2020]The mystery of ip [网鼎杯 2020 朱雀组]phpweb [BSidesCF 2020]Had a bad day [BJDCTF2020]ZJCTF,不过如此 [BUUCTF 2018]Online Tool [GXYCTF…

并发 ---- 多线程原理及底层实现

并发现象遍布日常生活,我们时常接触:我们可以边走路边说话;或者,左右手同时做出不一样的动作。在计算机应用程序中也有很好的例子: 浏览器 - 浏览器可以同时下载任意数量的文件和打开多个网页,下载时仍允许…

观测线程的工具——jconsole

joconsole的简单使用 joncole位置在jdk/bin路径中,在进入路径后可以查找到jconsole.exe的应用程序。如图: 双击创建jconsole进程,可以在里面选择所要观测的java文件。 以我的代码为例: class MyThread extends Thread {Overrid…

用户侧终端表计--预付费电表/费控/时间控制/负载控制/远程充值/远程抄表/分时计量/定量电能表/多回路预付费电表

预付费电表(先付费后用电)又叫做定量电能表,除了具有普通电能表的计量功能外,特别的是用户先买电,买电后才能用电,若用完电后用户不继续买电,则自动切断电源停止供电。 安科瑞薛瑶瑶1870170908…

Spark编程基础

一、RDD入门 1.RDD是什么? RDD是一个容错的、只读的、可进行并行操作的数据结构,是一个分布在集群各个节点中的存放元素的集合,即弹性分布式数据集。 2.RDD的三种创建方式 第一种是将程序中已存在的集合(如集合、列表、数组&a…

【JavaSE零基础】00-基础语法(1-12章)

1 第一章 Java开发环境搭建 1.1 章节目标与知识框架 1.1.1 章节目标 掌握Java的开发环境搭建,会编写HelloWorld程序,并能够准确的进行编译和运行;理解path和classpath环境变量并可以自行配置。 1.1.2 知识框架 1.2 Java语言概述(了解) J…

Uniapp/HTML5 上传文件到腾讯云Cos图片存储(Demo)

Uniapp引入方式 npm install cos-js-sdk-v5 HTML引入方式 <script type"text/javascript" src"js/cos-js-sdk-v5.min.js"></script> 在腾讯官网中找到cosJs放到本地项目中引入在项目中util工具类目录下封装一个upload.js用于公共上传Js impo…

操作系统②——内存管理

1. 栈、堆 1.1 程序的内存分配 栈区&#xff08;stack&#xff09;&#xff1a;由编译器自动分配释放 &#xff0c;存放函数的参数值&#xff0c;局部变量的值等。其操作方式类似于数据结构中的栈。堆区&#xff08;heap&#xff09;&#xff1a;一般由程序员分配释放&#x…

C++:stack类和queue类

stack的介绍和使用 1. stack 是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。 2. stack 是作为容器适配器被实现的&#xff0c;容器适配器即是对特定类封装作为其底层的容器&#xff0c;并…

H265码率控制(一)之HM代码R-λ model介绍

前言 在HM中R-λ的码率控制引入是在k0103提案中开始引入的&#xff0c;代码是HM-8.0以后的版本出现的&#xff0c;后面经过多个提案不断的修改&#xff0c;如M0257提案&#xff0c;M0036提案等&#xff1b;笔者建议研究HM代码的R-λ码率控制从HM10.0版本开始这个版本的R-λ已经…

1.基础乐理-唱名与记住唱名的方法

首先有 0、1、2、3、4、5、6、7&#xff0c;这八个数字 在音乐中要用笔来记录音乐就要用到 0、1、2、3、4、5、6、7&#xff0c;这八个数字&#xff0c;如果我们要唱出来 或 说出来&#xff0c;只要用嘴巴说出来就不是用 0、1、2、3、4、5、6、7&#xff0c;这八个数字了&…