《动手学深度学习(PyTorch版)》笔记8.4

注:书中对代码的讲解并不详细,本文对很多细节做了详细注释。另外,书上的源代码是在Jupyter Notebook上运行的,较为分散,本文将代码集中起来,并加以完善,全部用vscode在python 3.9.18下测试通过,同时对于书上部分章节也做了整合。

Chapter8 Recurrent Neural Networks

8.4 Recurrent Neural Networks

n n n元语法模型,单词 x t x_t xt在时间步 t t t的条件概率仅取决于前面 n − 1 n-1 n1个单词。对于时间步 t − ( n − 1 ) t-(n-1) t(n1)之前的单词,如果我们想将其可能产生的影响合并到 x t x_t xt上,需要增加 n n n,然而模型参数的数量也会随之呈指数增长,因为词表 V \mathcal{V} V需要存储 ∣ V ∣ n |\mathcal{V}|^n Vn个数字(每个可能的序列对应一个概率值),因此不如使用隐变量模型:

P ( x t ∣ x t − 1 , … , x 1 ) ≈ P ( x t ∣ h t − 1 ) , P(x_t \mid x_{t-1}, \ldots, x_1) \approx P(x_t \mid h_{t-1}), P(xtxt1,,x1)P(xtht1),

其中 h t − 1 h_{t-1} ht1隐状态(hidden state),也称为隐藏变量(hidden variable),它存储了到时间步 t − 1 t-1 t1的序列信息。通常,我们可以基于当前输入 x t x_{t} xt和先前隐状态 h t − 1 h_{t-1} ht1来计算时间步 t t t处的任何时间的隐状态:

h t = f ( x t , h t − 1 ) . h_t = f(x_{t}, h_{t-1}). ht=f(xt,ht1).

对于上式中的函数 f f f,隐变量模型可以不是近似值,因为 h t h_t ht可以存储到目前为止观察到的所有数据,然而这样的操作可能会使计算和存储的代价都变得昂贵。值得注意的是,隐藏层和隐状态是两个不同的概念,隐藏层是在从输入到输出的路径上(以观测角度来理解)的隐藏的层,而隐状态则是在给定步骤所做的任何事情(以技术角度来定义)的输入,并且这些状态只能通过先前时间步的数据来计算。

8.4.1 Neural Networks without Hidden States

对只有单隐藏层的多层感知机,设隐藏层的激活函数为 ϕ \phi ϕ,给定一个小批量样本 X ∈ R n × d \mathbf{X} \in \mathbb{R}^{n \times d} XRn×d,其中批量大小为 n n n,输入维度为 d d d,则隐藏层的输出 H ∈ R n × h \mathbf{H} \in \mathbb{R}^{n \times h} HRn×h通过下式计算:

H = ϕ ( X W x h + b h ) . \mathbf{H} = \phi(\mathbf{X} \mathbf{W}_{xh} + \mathbf{b}_h). H=ϕ(XWxh+bh).

输出层由下式给出:

O = H W h q + b q , \mathbf{O} = \mathbf{H} \mathbf{W}_{hq} + \mathbf{b}_q, O=HWhq+bq,

8.4.2 RNN with Hidden States

假设我们在时间步 t t t有小批量输入 X t ∈ R n × d \mathbf{X}_t \in \mathbb{R}^{n \times d} XtRn×d,换言之,对于 n n n个序列样本的小批量, X t \mathbf{X}_t Xt的每一行对应于来自该序列的时间步 t t t处的一个样本。用 H t ∈ R n × h \mathbf{H}_t \in \mathbb{R}^{n \times h} HtRn×h表示时间步 t t t的隐藏变量,计算公式如下:

H t = ϕ ( X t W x h + H t − 1 W h h + b h ) . (1) \mathbf{H}_t = \phi(\mathbf{X}_t \mathbf{W}_{xh} + \mathbf{H}_{t-1} \mathbf{W}_{hh} + \mathbf{b}_h).\tag{1} Ht=ϕ(XtWxh+Ht1Whh+bh).(1)

由于在当前时间步中,隐状态使用的定义与前一个时间步中使用的定义相同,因此称式(1)的计算是循环的(recurrent),基于循环计算的隐状态神经网络称为循环神经网络(recurrent neural network),在循环神经网络中执行循环计算的层称为循环层(recurrent layer)。对于时间步 t t t,输出层的输出类似于多层感知机中的计算:

O t = H t W h q + b q . \mathbf{O}_t = \mathbf{H}_t \mathbf{W}_{hq} + \mathbf{b}_q. Ot=HtWhq+bq.
循环神经网络的参数包括隐藏层的权重 W x h ∈ R d × h , W h h ∈ R h × h \mathbf{W}_{xh} \in \mathbb{R}^{d \times h}, \mathbf{W}_{hh} \in \mathbb{R}^{h \times h} WxhRd×h,WhhRh×h和偏置 b h ∈ R 1 × h \mathbf{b}_h \in \mathbb{R}^{1 \times h} bhR1×h,以及输出层的权重 W h q ∈ R h × q \mathbf{W}_{hq} \in \mathbb{R}^{h \times q} WhqRh×q和偏置 b q ∈ R 1 × q \mathbf{b}_q \in \mathbb{R}^{1 \times q} bqR1×q。值得一提的是,即使在不同的时间步,循环神经网络也总是使用这些模型参数,因此循环神经网络的参数开销不会随着时间步的增加而增加。

下图展示了循环神经网络在三个相邻时间步的计算逻辑。

在这里插入图片描述

import torch
from d2l import torch as d2l

#循环计算(部分)的两种计算方法
X, W_xh = torch.normal(0, 1, (3, 1)), torch.normal(0, 1, (1, 4))
H, W_hh = torch.normal(0, 1, (3, 4)), torch.normal(0, 1, (4, 4))
torch.matmul(X, W_xh) + torch.matmul(H, W_hh)
torch.matmul(torch.cat((X, H), 1), torch.cat((W_xh, W_hh), 0))

8.4.3 Character-Level Language Models Based on RNN

接下来介绍如何使用循环神经网络来构建语言模型。设小批量大小为1,批量中的文本序列为"machine"。为了简化后续部分的训练,考虑使用字符级语言模型(character-level language model),将文本词元化为字符而不是单词。下图演示了如何通过基于字符级语言建模的循环神经网络,使用当前的和先前的字符预测下一个字符。

在这里插入图片描述

在实践中,我们使用的批量大小为 n > 1 n>1 n>1,每个词元都由一个 d d d维向量表示。因此,在时间步 t t t输入 X t \mathbf X_t Xt将是一个 n × d n\times d n×d矩阵。

8.4.4 Perplexity

我们可以通过计算序列的似然概率来度量模型的质量,然而这难以理解、难以比较,因为较短的序列比较长的序列更有可能出现。为了解决这个问题,我们可以运用信息论。如果想要压缩文本,我们可以根据当前词元集预测的下一个词元。一个更好的语言模型应该能让我们更准确地预测下一个词元,即它应该允许我们在压缩序列时花费更少的比特,所以我们可以通过一个序列中所有的 n n n个词元的交叉熵损失的平均值来衡量模型的质量:

1 n ∑ t = 1 n − log ⁡ P ( x t ∣ x t − 1 , … , x 1 ) \frac{1}{n} \sum_{t=1}^n -\log P(x_t \mid x_{t-1}, \ldots, x_1) n1t=1nlogP(xtxt1,,x1)

其中 P P P由语言模型给出, x t x_t xt是在时间步 t t t从该序列中观察到的实际词元。这使得不同长度的文档的性能具有了可比性。困惑度(perplexity)是上式的指数:

exp ⁡ ( − 1 n ∑ t = 1 n log ⁡ P ( x t ∣ x t − 1 , … , x 1 ) ) . \exp\left(-\frac{1}{n} \sum_{t=1}^n \log P(x_t \mid x_{t-1}, \ldots, x_1)\right). exp(n1t=1nlogP(xtxt1,,x1)).

困惑度的最好的理解是“下一个词元的实际选择数的调和平均数”。

  • 在最好的情况下,模型总是完美地估计标签词元的概率为1。在这种情况下,模型的困惑度为1。
  • 在最坏的情况下,模型总是预测标签词元的概率为0。在这种情况下,困惑度是正无穷大。
  • 在基线上,该模型的预测是词表的所有可用词元上的均匀分布。在这种情况下,困惑度等于词表中唯一词元的数量。事实上,如果我们在没有任何压缩的情况下存储序列,这将是我们能做的最好的编码方式。因此,这种方式提供了一个重要的上限,而任何实际模型都必须超越这个上限。

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

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

相关文章

JSP页面模型

1. JSP页面模型 JSP页面模型描述如何为所提供的协议通过请求对象创建响应对象。JSP容器将Web客户端发送的请求下发给JSP页面实现对象,并向Web客户端返回响应。JSP页面实现对象时一个servlet,运行时表示JSP页面,由JSP容器执行。 在JSP页面作者和JSP容器之间定义合同的方法 …

Android:Cordova,JavaScript操作设备功能

Cordova学习 Cordova提供了一组设备相关的API,通过这组API,移动应用能够以JavaScript访问原生的设备功能,如摄像头、麦克风等。 Cordova还提供了一组统一的JavaScript类库,以及为这些类库所用的设备相关的原生后台代码。 Cordova是PhoneGap贡献给Apache后的开源项目,是从…

OpenCV-35 查找轮廓

一、 什么是图像轮廓 图像轮廓是具有相同颜色或灰度的连续点的曲线,轮廓在形状分析和物体的检测识别中很有用。 用于图形分析物体的识别和检测 注意点: 为了检测的准确性,需要先对图像进行二值化或Canny操作。画轮廓时会修改输入的图像&a…

C++ dfs 的状态表示(五十一)【第十一篇】

今天我们接着学习dfs(状态表示)。 1.抽象形式的dfs 前面用到的 DFS 算法都是比较容易想象出搜索过程的,接下来我们看一些不那么容易想象搜索过程的 DFS 过程,这些问题我们称为抽象形式的 DFS。 来回顾一下上节课遇到的一个问题&a…

Kubernetes实战(二十六)-K8S 部署Dashboard UI

Kubernetes Dashboard是Kubernetes集群的通用、基于Web的UI。它允许用户管理集群中运行的应用程序并对其进行故障排除,以及管理集群本身。 访问到DashBoard有两种方式: 通过KubernetesAPI访问:Dashboard是Kubernetes的内置的UI插件&#xff…

JavaEE作业-实验二

目录 1 实验内容 2 实验要求 3 思路 4 核心代码 5 实验结果 1 实验内容 实现两个整数求和的WEB程序 2 实验要求 ①采用SpringMVC框架实现 ②数据传送到WEB界面采用JSON方式 3 思路 ①创建一个SpringMVC项目,配置好相关的依赖和配置文件。 ②创建一个Con…

Python __pycache__文件

pycharm配置位置 几个基本概念 源代码(source code) 我们每天编写的Python、Java、C等代码通常指的就是源代码,源代码的特点是人类可读。但是CPU只能读懂二进制,看不懂我们写的源代码,因此还需要进行编译&#xff08…

【EAI 014】Gato: A Generalist Agent

论文标题:A Generalist Agent 论文作者:Scott Reed, Konrad Zolna, Emilio Parisotto, Sergio Gomez Colmenarejo, Alexander Novikov, Gabriel Barth-Maron, Mai Gimenez, Yury Sulsky, Jackie Kay, Jost Tobias Springenberg, Tom Eccles, Jake Bruce,…

ChatGpt报错:We ran into an issue while authenticating you解决办法

在登录ChatGpt时报错:Oops!,We ran into an issue while authenticating you.(我们在验证您时遇到问题),记录一下解决过程。 完整报错: We ran into an issue while authenticating you. If this issue persists, please contact…

MATLAB环境下用于提取冲击信号的几种解卷积方法

卷积混合考虑了信号的时延,每一个单独源信号的时延信号都会和传递路径发生一 次线性瞬时混合;解卷积的过程就是找一个合适的滤波器,进行反卷积运算,得到源信号的近似解。 声音不可避免的会发生衍射、反射等现象,所以&…

上线GPT应用的流程

上线一个应用是一个逐步迭代的过程,不断根据用户反馈和市场需求进行改进和优化。上线一个基于GPT的应用通常需要以下步骤,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1.明确目标和用途…

【数据结构】双向链表(链表实现+测试+原码)

前言 在双向链表之前,如果需要查看单链表来复习一下,链接在这里: http://t.csdnimg.cn/Ib5qS 1.双向链表 1.1 链表的分类 实际中链表的结构非常多样,以下情况组合起来就有8种链表结构: 1.1.1 单向或者双向 1.1.2 …

【Linux】学习-深入了解文件的读与写

深入了解语言级别(C语言)文件操作的"读"与"写" 在学习前,我们先要知道在Linux下的一个原则:一切皆是文件 如何理解呢?举个外设的例子,比如键盘和显示器,这两个外设也可以其实本质上也是文件&…

Java并发基础:LinkedBlockingDeque全面解析!

内容概要 LinkedBlockingDeque提供了线程安全的双端队列实现,它支持在队列两端高效地进行插入和移除操作,同时具备阻塞功能,能够很好地协调生产者与消费者之间的速度差异,其内部基于链表结构,使得并发性能优异&#x…

c语言游戏实战(7):扫雷

前言: 扫雷是一款经典的单人益智游戏,它的目标是在一个方格矩阵中找出所有的地雷,而不触碰到任何一颗地雷。在计算机编程领域,扫雷也是一个非常受欢迎的项目,因为它涉及到许多重要的编程概念,如数组、循环…

Java:Arrays类、Lambda表达式、JDK新特性(方法引用) --黑马笔记

一、Arrays类 1.1 Arrays基本使用 Arrays是操作数组的工具类,它可以很方便的对数组中的元素进行遍历、拷贝、排序等操作。 下面我们用代码来演示一下:遍历、拷贝、排序等操作。需要用到的方法如下: public class ArraysTest1 {public stat…

网络编程..

1.互联网 有了互联网的出现 我们就可以足不出户的实现看电影、购物等等操作 我们认知中可能的互联网模型 较为真实的互联网模型 那么数据是如何从一个设备传递到另外一个设备的呢? 2.网络互联模型 统共有三种: 3.TCP/IP协议 TCP/IP是一群协议 里面…

[韩顺平]python笔记

AI工程师、运维工程师 python排名逐年上升,为什么? python对大数据分析、人工智能中关键的机器学习、深度学习都提供有力的支持Python支持最庞大的 代码库 ,功能超强 数据分析:numpy/pandas/os 机器学习:tensorflow/…

【实习】深信服防火墙网络安全生产实习

一、实习概况 1.1实习目的 1.掌握防火墙规则的作用2.掌握代理上网功能的作用3.掌握端口映射功能的作用 1.2实习任务 1.防火墙的WEB控制台 2.需要在防火墙上配置dnat …

.NET命令行(CLI)常用命令

本文用于记录了.NET软件开发全生命周期各阶段常用的一些CLI命令,用于开发速查。 .NET命令行(CLI)常用命令 项目创建(1)查看本机SDK(2)查看本机可以使用的.NET版本(3)生成…