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

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

Chapter8 Recurrent Neural Networks

8.1 Sequence Models

x t x_t xt表示在时间步(time step) t ∈ Z + t \in \mathbb{Z}^+ tZ+时观察到的股票价格 x t x_t xt。注意, t t t对于本文中的序列通常是离散的,并在整数或其子集上变化。假设一个交易员通过以下途径预测 x t x_t xt
x t ∼ P ( x t ∣ x t − 1 , … , x 1 ) . x_t \sim P(x_t \mid x_{t-1}, \ldots, x_1). xtP(xtxt1,,x1).

8.1.1 Autoregressive Models

为了实现这个预测,交易员可以使用回归模型,但输入数量以及 x t − 1 , … , x 1 x_{t-1}, \ldots, x_1 xt1,,x1本身因 t t t而异,有效估计 P ( x t ∣ x t − 1 , … , x 1 ) P(x_t \mid x_{t-1}, \ldots, x_1) P(xtxt1,,x1)展开归结为以下两种策略。
第一种策略是,假设在现实情况下相当长的序列 x t − 1 , … , x 1 x_{t-1}, \ldots, x_1 xt1,,x1可能是不必要的,因此我们只需要满足某个长度为 τ \tau τ的时间跨度,即使用观测序列 x t − 1 , … , x t − τ x_{t-1}, \ldots, x_{t-\tau} xt1,,xtτ,好处就是参数的数量总是不变的(至少在 t > τ t > \tau t>τ时如此),这种模型被称为自回归模型(autoregressive models),因为它们是对自己执行回归。

第二种策略如下图所示,指保留一些对过去观测的总结 h t h_t ht,并同时更新预测 x ^ t \hat{x}_t x^t和总结 h t h_t ht。这就产生了基于 x ^ t = P ( x t ∣ h t ) \hat{x}_t = P(x_t \mid h_{t}) x^t=P(xtht)估计 x t x_t xt,以及公式 h t = g ( h t − 1 , x t − 1 ) h_t = g(h_{t-1}, x_{t-1}) ht=g(ht1,xt1)更新的模型。由于 h t h_t ht从未被观测到,这类模型也被称为隐变量自回归模型(latent autoregressive models)。

在这里插入图片描述

一个常见的假设是虽然特定值 x t x_t xt可能会改变,但是序列本身的动力不会改变。这样的假设是合理的,因为新的动力一定受新的数据影响,而我们不可能用目前所掌握的数据来预测新的动力。称不变的动力学静止的(stationary),因此整个序列的估计值都将通过以下的方式获得:

P ( x 1 , … , x T ) = ∏ t = 1 T P ( x t ∣ x t − 1 , … , x 1 ) . P(x_1, \ldots, x_T) = \prod_{t=1}^T P(x_t \mid x_{t-1}, \ldots, x_1). P(x1,,xT)=t=1TP(xtxt1,,x1).

8.1.2 Markov Models

P ( x t ∣ x t − 1 , … , x 1 ) = P ( x t ∣ x t − τ , … , x t − 1 ) P(x_t \mid x_{t-1}, \ldots, x_1)=P(x_t \mid x_{t-\tau}, \ldots, x_{t-1}) P(xtxt1,,x1)=P(xtxtτ,,xt1)时,称序列满足马尔可夫条件(Markov condition)。特别地,如果 τ = 1 \tau = 1 τ=1,得到一阶马尔可夫模型(first-order Markov model),
P ( x 1 , … , x T ) = ∏ t = 1 T P ( x t ∣ x t − 1 ) ,  P ( x 1 ∣ x 0 ) = P ( x 1 ) . P(x_1, \ldots, x_T) = \prod_{t=1}^T P(x_t \mid x_{t-1}) \text{ , } P(x_1 \mid x_0) = P(x_1). P(x1,,xT)=t=1TP(xtxt1) , P(x1x0)=P(x1).

当假设 x t x_t xt仅是离散值时,使用动态规划可以沿着马尔可夫链精确地计算结果。例如,利用 P ( x t + 1 ∣ x t , x t − 1 ) = P ( x t + 1 ∣ x t ) P(x_{t+1} \mid x_t, x_{t-1}) = P(x_{t+1} \mid x_t) P(xt+1xt,xt1)=P(xt+1xt)可以高效地计算 P ( x t + 1 ∣ x t − 1 ) P(x_{t+1} \mid x_{t-1}) P(xt+1xt1)

P ( x t + 1 ∣ x t − 1 ) = ∑ x t P ( x t + 1 , x t , x t − 1 ) P ( x t − 1 ) = ∑ x t P ( x t + 1 ∣ x t , x t − 1 ) P ( x t , x t − 1 ) P ( x t − 1 ) = ∑ x t P ( x t + 1 ∣ x t ) P ( x t ∣ x t − 1 ) \begin{aligned} P(x_{t+1} \mid x_{t-1}) &= \frac{\sum_{x_t} P(x_{t+1}, x_t, x_{t-1})}{P(x_{t-1})}\\ &= \frac{\sum_{x_t} P(x_{t+1} \mid x_t, x_{t-1}) P(x_t, x_{t-1})}{P(x_{t-1})}\\ &= \sum_{x_t} P(x_{t+1} \mid x_t) P(x_t \mid x_{t-1}) \end{aligned} P(xt+1xt1)=P(xt1)xtP(xt+1,xt,xt1)=P(xt1)xtP(xt+1xt,xt1)P(xt,xt1)=xtP(xt+1xt)P(xtxt1)

原则上,将 P ( x 1 , … , x T ) P(x_1, \ldots, x_T) P(x1,,xT)倒序展开也没什么问题,因为基于条件概率公式有:

P ( x 1 , … , x T ) = ∏ t = T 1 P ( x t ∣ x t + 1 , … , x T ) . P(x_1, \ldots, x_T) = \prod_{t=T}^1 P(x_t \mid x_{t+1}, \ldots, x_T). P(x1,,xT)=t=T1P(xtxt+1,,xT).
然而,在许多情况下,数据在时间上是前进的,显然未来的事件不能影响过去。在某些情况下,对于某些可加性噪声 ϵ \epsilon ϵ,我们可以找到 x t + 1 = f ( x t ) + ϵ x_{t+1} = f(x_t) + \epsilon xt+1=f(xt)+ϵ,反之则不行。

import torch
from torch import nn
from d2l import torch as d2l
import matplotlib.pyplot as pltT = 1000  # 总共产生1000个点
time = torch.arange(1, T + 1, dtype=torch.float32)
x = torch.sin(0.01 * time) + torch.normal(0, 0.2, (T,))
d2l.plot(time, [x], 'time', 'x', xlim=[1, 1000], figsize=(6, 3))
plt.show()

在这里插入图片描述

#将这个序列转换为模型的特征-标签(feature-label)对
tau = 4
features = torch.zeros((T - tau, tau))#这比提供的样本少了tau个,因为没有足够的历史记录来描述前tau个样本。
for i in range(tau):features[:, i] = x[i: T - tau + i]
labels = x[tau:].reshape((-1, 1))batch_size, n_train = 16, 600
# 只有前n_train个样本用于训练
train_iter = d2l.load_array((features[:n_train], labels[:n_train]),batch_size, is_train=True)# 初始化网络权重的函数
def init_weights(m):if type(m) == nn.Linear:nn.init.xavier_uniform_(m.weight)# 一个简单的多层感知机
def get_net():net = nn.Sequential(nn.Linear(4, 10),nn.ReLU(),nn.Linear(10, 1))net.apply(init_weights)return net# 平方损失。注意:MSELoss计算平方误差时不带系数1/2
loss = nn.MSELoss(reduction='none')def train(net, train_iter, loss, epochs, lr):trainer = torch.optim.Adam(net.parameters(), lr)for epoch in range(epochs):for X, y in train_iter:trainer.zero_grad()l = loss(net(X), y)l.sum().backward()trainer.step()print(f'epoch {epoch + 1}, 'f'loss: {d2l.evaluate_loss(net, train_iter, loss):f}')net = get_net()
train(net, train_iter, loss, 5, 0.01)#单步预测
onestep_preds = net(features)
d2l.plot([time, time[tau:]],[x.detach().numpy(), onestep_preds.detach().numpy()], 'time','x', legend=['data', '1-step preds'], xlim=[1, 1000],figsize=(6, 3))
plt.show()

在这里插入图片描述

即使预测的时间步超过了 600 + 4 600+4 600+4(n_train + tau),单步预测效果不错,但如果数据观察序列的时间步只到 604 604 604,我们需要一步一步地向前迈进:
x ^ 605 = f ( x 601 , x 602 , x 603 , x 604 ) , x ^ 606 = f ( x 602 , x 603 , x 604 , x ^ 605 ) , x ^ 607 = f ( x 603 , x 604 , x ^ 605 , x ^ 606 ) , x ^ 608 = f ( x 604 , x ^ 605 , x ^ 606 , x ^ 607 ) , x ^ 609 = f ( x ^ 605 , x ^ 606 , x ^ 607 , x ^ 608 ) , … \hat{x}_{605} = f(x_{601}, x_{602}, x_{603}, x_{604}), \\ \hat{x}_{606} = f(x_{602}, x_{603}, x_{604}, \hat{x}_{605}), \\ \hat{x}_{607} = f(x_{603}, x_{604}, \hat{x}_{605}, \hat{x}_{606}),\\ \hat{x}_{608} = f(x_{604}, \hat{x}_{605}, \hat{x}_{606}, \hat{x}_{607}),\\ \hat{x}_{609} = f(\hat{x}_{605}, \hat{x}_{606}, \hat{x}_{607}, \hat{x}_{608}),\\ \ldots x^605=f(x601,x602,x603,x604),x^606=f(x602,x603,x604,x^605),x^607=f(x603,x604,x^605,x^606),x^608=f(x604,x^605,x^606,x^607),x^609=f(x^605,x^606,x^607,x^608),
通常,对于直到 x t x_t xt的观测序列,其在时间步 t + k t+k t+k处的预测输出 x ^ t + k \hat{x}_{t+k} x^t+k称为 k k k步预测 k k k-step-ahead-prediction)。

#多步预测
multistep_preds = torch.zeros(T)
multistep_preds[: n_train + tau] = x[: n_train + tau]
for i in range(n_train + tau, T):multistep_preds[i] = net(multistep_preds[i - tau:i].reshape((1, -1)))d2l.plot([time, time[tau:], time[n_train + tau:]],[x.detach().numpy(), onestep_preds.detach().numpy(),multistep_preds[n_train + tau:].detach().numpy()], 'time','x', legend=['data', '1-step preds', 'multistep preds'],xlim=[1, 1000], figsize=(6, 3))
plt.show()

在这里插入图片描述

如上面例子所示,绿线的预测经过几个步骤之后就会衰减到一个常数,原因在于错误的累积:假设在步骤 1 1 1之后,我们积累了一些错误 ϵ 1 = ϵ ˉ \epsilon_1 = \bar\epsilon ϵ1=ϵˉ。于是,步骤 2 2 2的输入被扰动了 ϵ 1 \epsilon_1 ϵ1,结果积累的误差是 ϵ 2 = ϵ ˉ + c ϵ 1 \epsilon_2 = \bar\epsilon + c \epsilon_1 ϵ2=ϵˉ+cϵ1 c c c为常数),后面依此类推。基于 k = 1 , 4 , 16 , 64 k = 1, 4, 16, 64 k=1,4,16,64,通过对整个序列预测的计算,让我们更仔细地看一下 k k k步预测的困难。

max_steps = 64
features = torch.zeros((T - tau - max_steps + 1, tau + max_steps))
# 列i(i<tau)是来自x的观测,其时间步从(i)到(i+T-tau-max_steps+1)
for i in range(tau):features[:, i] = x[i: i + T - tau - max_steps + 1]# 列i(i>=tau)是来自(i-tau+1)步的预测,其时间步从(i)到(i+T-tau-max_steps+1)
for i in range(tau, tau + max_steps):features[:, i] = net(features[:, i - tau:i]).reshape(-1)steps = (1, 4, 16, 64)
d2l.plot([time[tau + i - 1: T - max_steps + i] for i in steps],[features[:, tau + i - 1].detach().numpy() for i in steps], 'time', 'x',legend=[f'{i}-step preds' for i in steps], xlim=[5, 1000],figsize=(6, 3))
plt.show()

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kmeans聚类选择最优K值python实现

Kmeans算法中K值的确定是很重要的。 下面利用python中sklearn模块进行数据聚类的K值选择 数据集自制数据集&#xff0c;格式如下&#xff1a; 维度为3。 ①手肘法 手肘法的核心指标是SSE(sum of the squared errors&#xff0c;误差平方和)&#xff0c; 其中&#xff0c;Ci是第…

【玩转408数据结构】线性表——定义和基本操作

考点剖析 线性表是算法题命题的重点&#xff0c;该类题目实现相对容易且代码量不高&#xff0c;但需要最优的性能&#xff08;也就是其时间复杂度以及空间复杂度最优&#xff09;&#xff0c;这样才可以获得满分。所以在考研复习中&#xff0c;我们需要掌握线性表的基本操作&am…

Linux探秘:如何用 find 命令发现隐藏的宝藏

&#x1f31f;&#x1f30c; 欢迎来到知识与创意的殿堂 — 远见阁小民的世界&#xff01;&#x1f680; &#x1f31f;&#x1f9ed; 在这里&#xff0c;我们一起探索技术的奥秘&#xff0c;一起在知识的海洋中遨游。 &#x1f31f;&#x1f9ed; 在这里&#xff0c;每个错误都…

无心剑汉英双语诗《龙年大吉》

七绝龙年大吉 Great Luck in the Dragon Year 龙腾五岳九州圆 年吼佳音万里传 大漠苍鹰华夏梦 吉人天相铸奇缘 Dragon flies over five peaks watching the divine land so great and round, New Year’s call sends joyous tidal waves far across the world’s bound. The…

教师如何找答案? #知识分享#职场发展

当今社会&#xff0c;随着信息技术的迅猛发展&#xff0c;大学生们在学习过程中面临着各种各样的困难和挑战。而在这些挑战中&#xff0c;面对繁重的作业和复杂的题目&#xff0c;大学生搜题软件应运而生 1.快解题 这是一个网站 是一款服务于职业考证的考试搜题软件,拥有几千…

echarts的title标题属性

echarts的title标题属性 title 标题组件&#xff0c;包含主标题和副标题。 位于 option对象第一层. title.text 设置主标题内容title.subtext 设置副标题内容 在 ECharts 2.x 中单个 ECharts 实例最多只能拥有一个标题组件。但是在 ECharts 3 中可以存在任意多个标题组件&am…

【k8s系列】(202402) 证书apiserver_client_certificate_expiration_seconds

apiserver_client_certificate_expiration_second证书定义的位置&#xff1a;kubernetes/staging/src/k8s.io/apiserver/pkg/authentication/request/x509/x509.go at 244fbf94fd736e94071a77a8b7c91d81163249d4 kubernetes/kubernetes (github.com) apiserver_client_certi…

【Python】读写文件r,w,a六种模式简单认识

r模式&#xff0c;只读&#xff0c;不存在该文件时报错 r模式&#xff0c;读写&#xff0c;不存在该文件时报错,覆盖写 w模式&#xff0c;只写&#xff0c;不存在该文件时创建&#xff0c;会将文件内容清空再写 w模式&#xff0c;读写&#xff0c;不存在该文件时创建&#xff0…

代码随想录 Leetcode455. 分发饼干

题目&#xff1a; 代码(首刷看解析 2024年2月8日&#xff09;&#xff1a; class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int res 0;int index s.size() - 1…

Oracle中sql怎么判断联合索引是否生效

在Oracle中&#xff0c;判断联合索引是否生效可以通过以下几种方法&#xff1a; 执行计划&#xff08;Execution Plan&#xff09;: 当你执行一个SQL查询时&#xff0c;Oracle会生成一个执行计划&#xff0c;显示如何最有效地执行该查询。你可以使用EXPLAIN PLAN命令来查看这…

Kafka 入门介绍

目录 一. 前言 二. 使用场景 三. 分布式的流平台 四. Kafka 的基本术语 4.1. 主题和日志 &#xff08;Topic 和 Log&#xff09; 4.2. 分布式&#xff08;Distribution&#xff09; 4.3. 异地数据同步技术&#xff08;Geo-Replication&#xff09; 4.4. 生产者&#xf…

Vulnhub靶机:hacksudo-Thor

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;hacksudo-Thor&#xff08;10.0.2.49&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://download.vulnhub.com/…

【JAVA WEB】 css背景属性 圆角矩形的绘制

目录 背景属性设置 圆角矩形 背景属性设置 背景颜色,在style中 background-color:颜色&#xff1b; 背景图片 background-image:url(……) 背景图片的平铺方式 background-repeat: 平铺方式 repeat 平铺&#xff08;默认&#xff09;no-repeat 不平铺repeat-x 水平平铺repea…

推荐一款开源的跨平台划词翻译和OCR翻译软件:Pot

Pot简介 一款开源的跨平台划词翻译和OCR翻译软件 下载安装指南 根据你的机器型号下载对应版本&#xff0c;下载完成后双击安装即可。 使用教程 Pot具体功能如下&#xff1a; 划词翻译输入翻译外部调用鼠标选中需要翻译的文本&#xff0c;按下设置的划词翻译快捷键即可按下输…

跨域--浏览器与服务器通信过程中出现跨域问题

一、跨域产生的原因 浏览器和服务器的协议、域名、端口号只要有一个不一致&#xff0c;就会产生跨域错误。 服务器和服务器进行数据通信时&#xff0c;如果三要素不一致&#xff0c;也不会产生跨域错误。 跨域的限制是浏览器的限制&#xff0c;与服务器无关。 跨域是一个安全策…

HiveSQL——共同使用ip的用户检测问题【自关联问题】

注&#xff1a;参考文章&#xff1a; SQL 之共同使用ip用户检测问题【自关联问题】-HQL面试题48【拼多多面试题】_hive sql 自关联-CSDN博客文章浏览阅读810次。0 问题描述create table log( uid char(10), ip char(15), time timestamp);insert into log valuesinsert into l…

Gradle IDEA 乱码

文章目录 环境代码测试结果配置 JAVA_TOOL_OPTIONS配置 build.gradle.kts配置 idea64.exe.vmoptions无配置 总结问题链接 环境 Java 环境 java version "21.0.2" 2024-01-16 LTS Java(TM) SE Runtime Environment (build 21.0.213-LTS-58) Java HotSpot(TM) 64-Bit…

MySQL进阶查询篇(7)-触发器的创建和使用

MySQL数据库触发器的创建和使用 触发器(Trigger)是MySQL数据库中非常强大且有用的功能&#xff0c;它可以在特定的数据库事件发生时自动执行一段预定义的代码。触发器可以用于实现数据完整性约束、自动化业务逻辑、审计日志等功能。本文将介绍MySQL数据库中触发器的创建和使用…

秒杀相关问题解决

秒杀 超卖问题 如下,我们先来复现问题,抢购秒杀券的代码逻辑也是很简单, 先判断优惠券是否开始了,是的化,判断库存是否充足,如果是的化,扣减库存,最后创建订单 如下是代码 Override Transactional public Result seckillVoucher(Long voucherId) {//1.查询优惠券SeckillVo…

平台工程是 FinOps 的“黄金路径”

云成本催生出了各种工具集。这些工具集目前主要用于现代 IT 堆栈&#xff0c;以加强资源、减少浪费、优化已确定的效率&#xff0c;并在最高、最广和最广泛的层面上监控系统的运行状况。 在云计算环境中&#xff0c;MLOps 实践的兴起旨在使软件工程与运维工程保持一致&#xff…