李沐机器学习系列5---循环神经网络

1 Introduction

对于样本的分析,通过全连接层处理表格数据,通过卷积神经网络处理图像数据;第一种假设,所有数据都是独立同分布的RNN 处理序列信号
序列数据的更多场景
1)用户使用习惯具有时间的先后性
2)外推法和内插法

1.1 自回归模型

1)自回归模型,对自己执行回归
在这里插入图片描述
2)隐变量的自回归模型
在这里插入图片描述
生成训练数据,

在这里插入图片描述

1.2 马尔科夫模型

一个模型被称为马尔可夫模型,主要是因为它满足马尔可夫性质,也就是说,该模型中的未来状态仅依赖于当前状态,而不依赖于过去的历史状态。在数学上,这被表达为条件概率的形式: ( p ( x k ∣ x k − 1 , x k − 2 , … ) = p ( x k ∣ x k − 1 ) ( p(x_k|x_{k-1}, x_{k-2}, \ldots) = p(x_k|x_{k-1}) (p(xkxk1,xk2,)=p(xkxk1)。这意味着下一个状态( x_k )的概率分布只取决于紧邻的前一个状态( x_{k-1} ),而与之前的所有其他状态无关。

在这里插入图片描述

2 文本序列处理

将文本拆分成次元,将词源字符串映射成数字索引,并将文本数据转换成词元索引以供模型操作。

将文本作为字符串加载到内存中。
将字符串拆分为词元(如单词和字符)。
建立一个词表,将拆分的词元映射到数字索引。
将文本转换为数字索引序列,方便模型操作。

3 语言模型和数据集

语言模型的目标是估计序列的联合概率
P ( x 1 , x 2 , . . . , x T ) P(x_1, x_2, ..., x_T) P(x1,x2,...,xT)
在这里插入图片描述
用贝叶斯条件概率估计,这种贝叶斯估计,会因为样本的稀疏,并不好建立足够的联系。
在这里插入图片描述
在这里插入图片描述
可以用马尔科夫模型来近似,因为当前状态基本上只依赖于前几个词元。
在这里插入图片描述

单词出现的频率以非常快的速度进行衰减,齐普夫定律(Zipf’s law), 即第个最常用单词的频率为:
在这里插入图片描述
多元语法的频率
在这里插入图片描述

  • 除了一元语法词,单词序列似乎也遵循齐普夫定律, 尽管公式 (8.3.7)中的指数
    更小 (指数的大小受序列长度的影响);
  • 词表中元组的数量并没有那么大,这说明语言中存在相当多的结构, 这些结构给了我们应用模型的希望;
  • 很多元组很少出现,这使得拉普拉斯平滑非常不适合语言建模。 作为代替,我们将使用基于深度学习的模型

读取长序列数据,如果采用固定长度,效果不太好,采用随机偏移量划分序列,以获得覆盖性和随机性。
在这里插入图片描述

2.1 随机采样

def seq_data_iter_random(corpus, batch_size, num_steps):  #@save
    """使用随机抽样生成一个小批量子序列"""
    # 从随机偏移量开始对序列进行分区,随机范围包括num_steps-1
    corpus = corpus[random.randint(0, num_steps - 1):]
    # 减去1,是因为我们需要考虑标签
    num_subseqs = (len(corpus) - 1) // num_steps
    # 长度为num_steps的子序列的起始索引
    initial_indices = list(range(0, num_subseqs * num_steps, num_steps))
    # 在随机抽样的迭代过程中,
    # 来自两个相邻的、随机的、小批量中的子序列不一定在原始序列上相邻
    random.shuffle(initial_indices)

    def data(pos):
        # 返回从pos位置开始的长度为num_steps的序列
        return corpus[pos: pos + num_steps]

    num_batches = num_subseqs // batch_size
    for i in range(0, batch_size * num_batches, batch_size):
        # 在这里,initial_indices包含子序列的随机起始索引
        initial_indices_per_batch = initial_indices[i: i + batch_size]
        X = [data(j) for j in initial_indices_per_batch]
        Y = [data(j + 1) for j in initial_indices_per_batch]
        yield torch.tensor(X), torch.tensor(Y)

2.2 顺序分区

完全按照顺序进行分区,没有洗牌的操作。

def seq_data_iter_sequential(corpus, batch_size, num_steps):  #@save
    """使用顺序分区生成一个小批量子序列"""
    # 从随机偏移量开始划分序列
    offset = random.randint(0, num_steps)
    num_tokens = ((len(corpus) - offset - 1) // batch_size) * batch_size
    Xs = torch.tensor(corpus[offset: offset + num_tokens])
    Ys = torch.tensor(corpus[offset + 1: offset + 1 + num_tokens])
    Xs, Ys = Xs.reshape(batch_size, -1), Ys.reshape(batch_size, -1)
    num_batches = Xs.shape[1] // num_steps
    for i in range(0, num_steps * num_batches, num_steps):
        X = Xs[:, i: i + num_steps]
        Y = Ys[:, i: i + num_steps]
        yield X, Y

4 循环神经网络

循环圣经网络的核心思想
在这里插入图片描述

4.1 无隐状态的神经网络

在这里插入图片描述

4.2 有隐状态的神经网络

H t − 1 H_{t-1} Ht1捕获并保留序列知道当前时间步的历史信息
在这里插入图片描述
对于第一个输入,往往也会初始化一个隐变量
在这里插入图片描述
输出层,采用softmax的分类器;因为有很多个head,中间的输出层的结果如下图,会推断到下一个
在这里插入图片描述

4.3 困惑度

质量上,从人的评价来说,满足基本的结构,满足填充的内容正确,
在这里插入图片描述

似然概率来度量模型的质量,但是因序列的长度有差异,需要借用信息论中信息熵的概念来分析
类似调和平均数来判断,困惑度
在这里插入图片描述
在这里插入图片描述

5 RNN的从零实现

5.1 独热编码

在这里插入图片描述

独热编码(One-Hot Encoding)的好处主要包括:

  1. 清晰表示:独热编码通过将每个类别表示为一个唯一的二进制向量,为类别提供了明确的表示,这在处理类别数据时非常有用。

  2. 无序性:在独热编码中,不同类别之间没有数值上的关联,这避免了模型错误地解释类别间的数值关系,特别是在类别没有内在顺序的情况下。

  3. 适合距离计算:由于每个类别都被转换成相互正交的向量,它们在空间中的距离是相等的。这对于基于距离的算法(如K-近邻算法)非常有用。

在处理不同长度的序列样本时,RNN网络通常采用以下策略之一:

  1. 填充(Padding):将所有序列填充到相同的长度。较短的序列在末尾添加特殊的填充符号,以便所有序列具有相同的长度。这允许网络具有固定的结构。

  2. 动态计算图:某些深度学习框架支持动态计算图,它们可以处理可变长度的输入。在这种情况下,RNN可以在每个批次中处理不同长度的序列,而无需填充。

  3. 分批处理不同长度:将序列分组到不同长度的批次中。这种方法避免了过多的填充,但可能需要更复杂的批次管理。

5.2 梯度裁剪

梯度裁剪和Wolfe原则有一定的相似性,但也存在重要的区别:

  1. 梯度裁剪:主要关注梯度的大小。当梯度的范数超过一个预定的阈值时,会按比例缩减梯度,以防止梯度过大导致的训练不稳定问题。

  2. Wolfe原则:是一种在线搜索(Line Search)策略,用于选择步长。它包含两个条件:充分下降条件和曲率条件,旨在确保每一步优化都朝着目标函数下降的方向,并且步长既不太大也不太小。

共同之处在于它们都旨在通过控制优化步骤的大小来提高优化过程的稳定性。不同之处在于梯度裁剪是一种更直接的方法,用于控制梯度的大小,而Wolfe原则是一种更复杂的策略,用于在优化过程中选择合适的步长。
在这里插入图片描述
在这里插入图片描述

def grad_clipping(net, theta):  #@save
    """裁剪梯度"""
    if isinstance(net, nn.Module):
        params = [p for p in net.parameters() if p.requires_grad]
    else:
        params = net.params
    norm = torch.sqrt(sum(torch.sum((p.grad ** 2)) for p in params))
    if norm > theta:
        for param in params:
            param.grad[:] *= theta / norm

6 简洁实现

#@save
class RNNModel(nn.Module):
    """循环神经网络模型"""
    def __init__(self, rnn_layer, vocab_size, **kwargs):
        super(RNNModel, self).__init__(**kwargs)
        self.rnn = rnn_layer
        self.vocab_size = vocab_size
        self.num_hiddens = self.rnn.hidden_size
        # 如果RNN是双向的(之后将介绍),num_directions应该是2,否则应该是1
        if not self.rnn.bidirectional:
            self.num_directions = 1
            self.linear = nn.Linear(self.num_hiddens, self.vocab_size)
        else:
            self.num_directions = 2
            self.linear = nn.Linear(self.num_hiddens * 2, self.vocab_size)

    def forward(self, inputs, state):
        X = F.one_hot(inputs.T.long(), self.vocab_size)
        X = X.to(torch.float32)
        Y, state = self.rnn(X, state)
        # 全连接层首先将Y的形状改为(时间步数*批量大小,隐藏单元数)
        # 它的输出形状是(时间步数*批量大小,词表大小)。
        output = self.linear(Y.reshape((-1, Y.shape[-1])))
        return output, state

    def begin_state(self, device, batch_size=1):
        if not isinstance(self.rnn, nn.LSTM):
            # nn.GRU以张量作为隐状态
            return  torch.zeros((self.num_directions * self.rnn.num_layers,
                                 batch_size, self.num_hiddens),
                                device=device)
        else:
            # nn.LSTM以元组作为隐状态
            return (torch.zeros((
                self.num_directions * self.rnn.num_layers,
                batch_size, self.num_hiddens), device=device),
                    torch.zeros((
                        self.num_directions * self.rnn.num_layers,
                        batch_size, self.num_hiddens), device=device))

7 通过时间反向传播

7.1 梯度分析

通过链式法则回顾循环神经网络的梯度爆炸问题;类似控制中的乘积累加的问题,第一个词元对最后位置的词元产生重大的影响。
每个时间步的隐状态和输出,完整的RNN表示如下:
在这里插入图片描述

在这里插入图片描述
统计T个时间步内的总体的loss,
在这里插入图片描述
计算目标函数L关于参数 w h w_h wh的梯度时,
在这里插入图片描述
这里的因为链式法则比较复杂,
在这里插入图片描述
有以下几种策略:

  • 完全计算
    因为有循环结算,容易梯度爆炸
    在这里插入图片描述

  • 截断时间步
    截断到 ∂ h t − τ ∂ w h \frac{\partial h_{t-\tau}}{\partial w_h} whhtτ

  • 随机截断

  • 比较策略
    实践中,随机截断的效果不比常规截断更好,
    在这里插入图片描述

7.2 通过时间反向传播的细节

在这里插入图片描述
一套链式法则以后,类似于控制中的状态变量,初始的隐变量对应的参数的梯度是指数型的,导致数值上的不稳定;
在这里插入图片描述
解决方法:
1)截断时间不长,取近似的梯度;
2)LSTM

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

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

相关文章

【Path的使用】Node.js中的使用Path模块操作文件路径

😁 作者简介:一名大四的学生,致力学习前端开发技术 ⭐️个人主页:夜宵饽饽的主页 ❔ 系列专栏:Node.js 👐学习格言:成功不是终点,失败也并非末日,最重要的是继续前进的勇…

Leetcode算法系列| 12. 整数转罗马数字

目录 1.题目2.题解C# 解法一:模拟C# 解法二:硬编码数字 1.题目 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如&#xff0…

运算放大器(六):I-V 转换

1、跨阻放大器 放大器类型是根据其输入-输出信号的类型定义。假设放大器增益 (X:输入,Y:输出)。在电学范畴,由于用电压或电流表征一个信号,当输入信号为电流,输出信号为电压时&#…

MacOS14系统中Topaz Photo AI无法启动解决方法

MacOS14系统,在使用Topaz Photo AI是时无法启动,或者在 Mac电脑上导入图像后,Topaz Photo AI 应用程序窗口可能会冻结,怎么解决呢? 退出Topaz Photo AI for mac软件 回到电脑桌面,点击菜单栏前往-前往文件…

Prometheus 不能访问k8s的中的一些metrics的问题(controller-manager、scheduler、etcd)

主要有三个点 controller-manager、scheduler、etcd 参考: https://www.cnblogs.com/ltaodream/p/15448953.html kube-scheduler 在每台master节点执行 vim /etc/kubernetes/manifests/kube-scheduler.yaml 将 --bind-address127.0.0.1 改为 --bind-address…

Image - 体积最小的 base64 encode 1*1透明图片,透明背景图片base64编码

背景 前端开发时&#xff0c;有些<img>标签的src属性的值来源于接口&#xff0c;在接口获取结果之前&#xff0c;这个src应该设置为什么呢&#xff1f; 误区&#xff1a;设置为# 有人把src设置为<img src"#" />。 这是有问题的&#xff0c;浏览器解析…

理解UML中的依赖关系

理解UML中的依赖关系 在面向对象的设计中&#xff0c;理解各种类之间的关系对于构建一个清晰、可维护的系统至关重要。UML&#xff08;统一建模语言&#xff09;为我们提供了一种可视化这些关系的方式。今天&#xff0c;我们将深入探讨UML中的依赖关系&#xff08;Dependency&a…

脑电范式学习(一):Psychopy安装

脑电范式学习&#xff08;一&#xff09;&#xff1a;Psychopy安装 1 引言2 Psychopy软件3 安装教程4 花活儿5 总结 1 引言 可能有人会疑惑&#xff1a;为什么要去学Psychopy&#xff1f;Psychopy有什么好的&#xff1f; 首先&#xff0c;要告诉大家这么一个情况&#xff1a;现…

【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行环境搭建

【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 概述-CSDN博客 【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行环境搭建-CSDN博客 【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行模式-CSDN博客 1、模板虚拟机环境准备 1.1、 hadoop100 虚拟机配置要求如下 &…

拟杆菌在肠道感染中的矛盾作用

谷禾健康 拟杆菌门细菌是革兰氏阴性菌的代表&#xff0c;具有外膜、肽聚糖层和细胞质膜。它们无氧呼吸的主要副产物是乙酸、异戊酸和琥珀酸。是最耐氧的厌氧菌之一。 参与人体结肠中许多重要的代谢活动包括碳水化合物的发酵、含氮物质的利用以及胆汁酸和其他类固醇的生物转化。…

Python random模块(获取随机数)常用方法和使用例子

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 random.random random.random()用于生成一个0到1的随机符点数: 0 < n < 1.0 random.uniform random.uniform(a, b)&#xff0c;用于生成一个指定范围内的随机符点数&#xff0c;两个参数其中一个是上限&#xff0c;一…

【大数据】安装 Zookeeper 单机版

安装 Zookeeper 单机版 下面安装 Zookeeper&#xff0c;由于它是 Apache 的一个顶级项目&#xff0c;所以域名是 zookeeper.apache.org&#xff0c;所有 Apache 的顶级项目的官网都是以项目名 .apache.org 来命名的。 点击 Download 即可下载&#xff0c;这里我们选择的版本是 …

基于数据库和NER构建知识图谱流程记录

文章目录 环境准备拓扑设计构建流程设计文件流设计交互解析算法实现数据库交互NER解析相似度计算 基于数据库的文件生成从数据库中读取字段将字段后处理后保存为文件 基于文件的知识图谱构建bug修改与算法优化图数据库连接问题批量构建知识图谱问题批量删除边问题空值处理问题去…

使用pnnx将Torch模型转换为ncnn

1. 引言 以往我们将Torch模型转换为ncnn模型&#xff0c;通常需经过Torch–>onnx&#xff0c;onnx–>ncnn两个过程。但经常会出现某些算子不支持的问题。 ncnn作者针对该问题&#xff0c;直接开发一个Torch直接转换ncnn模型的工具 (PNNX)&#xff0c;以下为相关介绍及使…

【SpringBoot系列】springboot中拦截器Interceptor使用

🤵‍♂️ 个人主页:@香菜的个人主页,加 ischongxin ,备注csdn ✍🏻作者简介:csdn 认证博客专家,游戏开发领域优质创作者,华为云享专家,2021年度华为云年度十佳博主 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收…

目标检测中的常见指标

概念引入&#xff1a; TP&#xff1a;True Positive IoU > 阈值 检测框数量 FP: False Positive IoU < 阈值 检测框数量 FN: False Negative 漏检框数量 Precision:查准率 Recall:查全率&#xff08;召回率&#xff09; AP&am…

【EI会议征稿通知】2024年第九届智能计算与信号处理国际学术会议(ICSP 2024)

2024年第九届智能计算与信号处理国际学术会议&#xff08;ICSP 2024&#xff09; 2024年第八届智能计算与信号处理国际学术会议&#xff08;ICSP 2024&#xff09;将在西安举行&#xff0c; 会期是2024年4月19-21日&#xff0c; 为期三天, 会议由西安科技大学主办。 欢迎参会&…

浅谈有源滤波器在有色工业中的应用

贾丽丽 安科瑞电气股份有限公司 上海嘉定 201801 文摘:介绍了谐波的危害及类型&#xff0c;分析了有源滤波器的原理。 关键词:谐波&#xff1b;无源滤波器&#xff1b;有源滤波器 0引言 目前&#xff0c;许多变电所的负荷中含有大量的非线性负荷&#xff0c;如整流装置、交…

Python中User-Agent的重要作用及实际应用

摘要&#xff1a; User-Agent是HTTP协议中的一个重要字段&#xff0c;用于标识发送请求的客户端信息。在Python中&#xff0c;User-Agent的作用至关重要&#xff0c;它可以影响网络请求的结果和服务器端的响应。将介绍User-Agent在Python中的重要作用&#xff0c;并结合实际案…

【CMake】3.单项目单模块添加第三方依赖包示例工程

CMake 示例工程代码 https://github.com/LABELNET/cmake-simple 单项目单模块 - 添加第三方依赖示例工程 https://github.com/LABELNET/cmake-simple/tree/main/simple-deps 1. 单模块工程 第三方依赖 CMake 单模块工程&#xff0c;这是一个示例工程 simple-deps , 项目…
最新文章