从0开始深度学习(28)——序列模型
序列模型是指一类特别设计来处理序列数据的神经网络模型。序列数据指的是数据中的每个元素都有先后顺序,比如时间序列数据(股票价格、天气变化等)、自然语言文本(句子中的单词顺序)、语音信号等。
1 统计工具
前面介绍了卷积神经网络架构,但是在处理序列数据时,需要新的神经网络架构,下面以股票价格为例:

我们用 x t x_{t} xt表示价格,其中 t t t表示时间步(time step),也就是在时间步 t t t时观察到的价格 x t x_{t} xt,我们通过下列公式来表示我们预测第 t t t日的价格:
x t ∼ P ( x t ∣ x t − 1 , … , x 1 ) . x_t \sim P(x_t \mid x_{t-1}, \ldots, x_1). xt∼P(xt∣xt−1,…,x1).
即,在已知 1 1 1 到 t − 1 t-1 t−1 的价格,求第 t t t 天的价格的概率分布。
1.1 自回归模型
为了实现这个预测,可以使用自回归模型:假设当前值 y t y_{t} yt 与过去的值 y t − 1 , y t − 2 , . . . y t − p y_{t-1} , y_{t-2} , ...y_{t-p} yt−1,yt−2,...yt−p 之间存在线性关系,一般形式为 :

其中:

大致分为两种策略:
①自回归模型: 假设在现实情况下相当长的序列 x t − 1 , … , x 1 x_{t-1}, \ldots, x_1 xt−1,…,x1可能是没价值的,因此我们只需要满足某个长度为 τ \tau τ的时间跨度, 即使用观测序列 x t − 1 , … , x t − τ x_{t-1}, \ldots, x_{t-\tau} xt−1,…,xt−τ。也就是说过长的历史序列可能并不必要,因此只需要关注较短的一段历史数据即可。因为只考虑观测值本身,所以叫自回归模型
②隐变量自回归模型: 即保留一些对过去观测的总结 h t h_{t} ht,这个“总结”是无法直观解释的,它是模型自助捕捉的内部关系依赖,然后同时更新预测值 x ^ t \hat{x}_t x^t和 h t h_t ht,即变为下列式子: x ^ t = P ( x t ∣ h t ) 和 h t = g ( h t − 1 , x t − 1 ) \hat{x}_t = P(x_t \mid h_{t}) 和h_t = g(h_{t-1}, x_{t-1}) x^t=P(xt∣ht)和ht=g(ht−1,xt−1)由于 h t h_{t} ht h t h_{t} ht从未被观测到,这类模型也被称为隐变量自回归模型,这里做出一个假设,即序列本身的动力学(数据随时间演变的方式)不会改变,意味着我们可以用过去的数据来推断未来的趋势,因为我们假定基本的动态规则是一致的。因此,整个序列的概率值可以表示为一系列条件概率的乘积:
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=1∏TP(xt∣xt−1,…,x1).
注意,如果我们处理的是离散的对象(如单词), 而不是连续的数字,则上述的考虑仍然有效。我们需要使用分类器而不是回归模型来估计
1.2 马尔可夫模型
马尔可夫条件: 在自回归模型中,如果 t t t 时刻的数值,只与 x t − 1 , … , x t − τ x_{t-1}, \ldots, x_{t-\tau} xt−1,…,xt−τ 有关,而不是整个过去的序列,则称其满足马尔可夫条件。
如果 τ = 1 \tau = 1 τ=1 ,则得到了一个一阶马尔可夫模型, P ( x ) P(x) P(x)由如下公式表示:
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=1∏TP(xt∣xt−1) 当 P(x1∣x0)=P(x1).
若当假设 x t x_t xt 仅是离散值时,可以使用动态规划可以沿着马尔可夫链精确地计算结果。
2 训练、预测
下面我们将用一个正弦函数和一些噪声生成1000个序列数据,并使用自回归模型进行训练和预测
2.1 生成数据
import torch
from torch import nn
import matplotlib.pyplot as plt
import numpy as np
from torch.utils.data import TensorDataset, DataLoaderT=1000
time=torch.arange(1,T+1,dtype=torch.float32)
x=torch.sin(0.01*time)+torch.normal(0,0.2,(T,))
# 绘制折线图
plt.plot(time, x)
plt.xlabel('Time')
plt.ylabel('Value')
plt.title('Time Series Data')
plt.show()
运行结果

2.2 构造数据集
我们是准备用 y t = F ( X t ) y_t=F(X_t) yt=F(Xt),其中 X t = [ x t − τ , … , x t − 1 ] X_t= [x_{t-\tau}, \ldots, x_{t-1}] Xt=[xt−τ,…,xt−1],我们这里假设 τ = 4 \tau=4 τ=4,即用前四个数据来预测下一个数据,但是这样的话,前 4 4 4 个数据就没有历史样本去描述了,一般的做法是直接舍弃,或者用零序列去填充。
这里我们用600个数据进行训练,剩余的用于预测。
构建数据集时,使用滑动窗口去构建:

# 构造数据集
tau=4# 初始化特征矩阵,因为前四个值就是当前值的特征
features = torch.zeros((T - tau, tau))
for i in range(T - tau): # 用滑动窗口进行构建features[i,:]=x[i:tau+i]
print('features:',features.shape)
print(features[:5])labels = x[tau:].reshape((-1, 1))
print('labels:',labels.shape)
print(labels[:5])batch_size = 16
n = 600 # 只有前600个样本用于训练
dataset = TensorDataset(features[:n], labels[:n])
train_iter = DataLoader(dataset, batch_size=batch_size, shuffle=False)
运行结果

2.3 构造模型进行训练
# 构造模型
def init_weights(m):if type(m)==nn.Linear:nn.init.xavier_uniform_(m.weight)def net():net=nn.Sequential(nn.Linear(4,10),nn.ReLU(),nn.Linear(10,1))net.apply(init_weights)return net# 评估模型在给定数据集上的损失
def evaluate_loss(net, data_iter, loss):"""评估模型在给定数据集上的损失"""net.eval() # 设置模型为评估模式total_loss = 0.0with torch.no_grad(): # 不计算梯度for X, y in data_iter:y_hat = net(X)l = loss(y_hat, y)total_loss += l.sum().item() # 计算总损失net.train() # 恢复模型为训练模式return total_loss / len(data_iter.dataset)loss=nn.MSELoss(reduction='none')
lr=0.01
net=net()
optimzer=torch.optim.Adam(net.parameters(),lr)
loss_sum=[]
num_epoch=20
def train(net,num_epoch,train_iter,loss,optimzer,loss_sum):for epoch in range(num_epoch):for x,y in train_iter:optimzer.zero_grad()l=loss(net(x),y)l.sum().backward()optimzer.step()temp=evaluate_loss(net,train_iter,loss)loss_sum.append(temp)print("epoch ",epoch+1,": loss:",temp)train(net,num_epoch,train_iter,loss,optimzer,loss_sum)# 绘制折线图
plt.plot(range(num_epoch), loss_sum)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
运行结果

2.4 预测
# 使用模型进行预测
def predict(net, data_iter):net.eval() # 设置模型为评估模式predictions = []with torch.no_grad(): # 不计算梯度for X, y in data_iter:y_hat = net(X)predictions.extend(y_hat.numpy())net.train() # 恢复模型为训练模式return predictions# 获取测试集的预测结果
predictions = predict(net, test_iter)# 绘制预测结果与真实值的对比图
true_values = labels[n:].numpy()
plt.plot(true_values, label='True Values')
plt.plot(predictions, label='Predictions')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()
运行结果

2.5 多步预测
# 多步预测
def multistep_predict(net, data_iter, steps):net.eval() multistep_predictions = []with torch.no_grad(): for X, y in data_iter:current_features = X.clone()for _ in range(steps):'''在每一步中,模型用 current_features 作为输入,并预测出 y_hat。然后将 y_hat 拼接到 current_features 的末尾,同时移除 current_features 的第一个时间步,保持输入长度不变。这样,y_hat 成为下一步的输入'''y_hat = net(current_features)current_features = torch.cat([current_features[:, 1:], y_hat], dim=1)multistep_predictions.extend(y_hat.numpy())net.train() return multistep_predictions# 获取测试集的不同步数的多步预测结果
steps = [4, 16, 32]
multistep_predictions = {step: multistep_predict(net, test_iter, step) for step in steps}# 绘制结果
plt.figure(figsize=(12, 6)) # 设置图像的宽度为12英寸,高度为6英寸
plt.plot(true_values, label='True Values')
plt.plot(ones_predictions, label='1-step Predictions')
for step, preds in multistep_predictions.items():plt.plot(preds, label=f'{step}-step Predictions')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()

上述的多步预测是迭代预测法,即用自己预测数据再去预测下一个数据,另一种方法是seq2seq,后面在介绍,迭代预测法如下图所示:

相关文章:
从0开始深度学习(28)——序列模型
序列模型是指一类特别设计来处理序列数据的神经网络模型。序列数据指的是数据中的每个元素都有先后顺序,比如时间序列数据(股票价格、天气变化等)、自然语言文本(句子中的单词顺序)、语音信号等。 1 统计工具 前面介绍…...
vue2使用 <component> 标签动态渲染不同的表单组件
在后台管理系统中,涉及到大量表单信息的修改和新增。现在想对模板中代码做一些简单的优化。 1. 使用 v-for 循环简化表单项 可以将表单项的定义提取到一个数组中,然后使用 v-for 循环来生成这些表单项。这将减少重复代码,提高可维护性。 2…...
C#实现在windows上实现指定句柄窗口的指定窗口坐标点击鼠标左键和右键的详细情况
在Windows编程中,有时我们需要对特定窗口进行操作,比如模拟鼠标点击。这在自动化测试、脚本编写或某些特定应用程序的开发中尤为常见。本文将深入探讨如何在C#中实现对指定句柄窗口进行鼠标点击操作,包括左键和右键点击。我们会从理论背景开始…...
探索Python自动化新境界:Invoke库的神秘面纱
文章目录 **探索Python自动化新境界:Invoke库的神秘面纱**第一部分:背景介绍第二部分:Invoke库是什么?第三部分:如何安装Invoke库?第四部分:Invoke库函数使用方法1. 定义任务2. 执行任务3. 任务…...
CSS样式实现3D效果
CSS 3D效果是通过CSS3中的transform和perspective等属性来实现的。这些属性允许你创建具有深度感和三维外观的网页元素。以下是一些常见的CSS 3D效果及其实现方法: 1. 3D旋转(Rotate) 使用transform: rotateX(), rotateY(), rotateZ()来分别…...
华为eNSP:MSTP
一、什么是MSTP? 1、MSTP是IEEE 802.1S中定义的生成树协议,MSTP兼容STP和RSTP,既可以快速收敛,也提供了数据转发的多个冗余路径,在数据转发过程中实现VLAN数据的负载均衡。 2、MSTP可以将一个或多个VLAN映射到一个Inst…...
modbus协议 Mthings模拟器使用
进制转换 HEX 16进制 (0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F表示0-15) dec 10进制 n(16进制) -> 10 abcd.efg(n) d*n^0 c*n^1 b*n^2 a*n^3 e*n^-1 f*n^-2 g*n^-3(10) 10 -> n(16进制) Modbus基础概念 高位为NUM_H&…...
内网安全-代理技术-socket协议
小迪安全网络架构图: 背景:当前获取window7 出网主机的shell。 1.使用msf上线,查看路由 run autoroute -p 添加路由: run post/multi/manage/autoroute 使用socks模块开启节点,作为流量跳板 msf6 exploit(multi/ha…...
选择排序(C语言)
一、步骤 选择排序的基本思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。 1.首先,我们先建立一个乱序数组,如࿱…...
✍Qt自定义带图标按钮
✍Qt自定义带图标按钮 📝问题引入 近段时间的工作中,有遇到这样一个需求 📝: 一个按钮,有normal、hover、pressed三种状态的样式,并且normal和hover样式下,字体颜色和按钮图标不一样。 分析…...
【Git】如何在 Git 项目中引用另一个 Git 项目:子模块与子树合并
如何在 Git 项目中引用另一个 Git 项目:子模块与子树合并 在进行软件开发时,我们经常会遇到需要将一个 Git 项目(B 项目)引用到另一个 Git 项目(A 项目)的情况。这种需求通常出现在以下场景: …...
webstorm 打开prettier的项目代码后面会出现红色的波浪线
效果如图所有代码后面都有红色的波浪线。 解决File-Settings 找到Editor下面的inspections ...按照图示取消勾选ESLint再点Apply ok...
用 Python 从零开始创建神经网络(二):第一个神经元的进阶
第一个神经元的进阶 引言1. Tensors, Arrays and Vectors:2. Dot Product and Vector Additiona. Dot Product (点积)b. Vector Addition (向量加法) 3. A Single Neuron with NumPy4. A Layer of Neurons with NumPy5…...
一、文心一言问答系统为什么要分对话,是否回学习上下文?二、文心一言是知识检索还是大模型检索?三、文心一言的词向量、词语种类及多头数量
目录 一、文心一言问答系统为什么要分对话,是否回学习上下文? 二、文心一言是知识检索还是大模型检索? 三、文心一言的词向量、词语种类及多头数量 一、文心一言问答系统为什么要分对话,是否回学习上下文? 文心一言问答系统分对话的原因在于其设计初衷就是提供一个交互…...
C++ 的协程
现代C中的协程(coroutines)是C20引入的一项重大语言特性,它们允许函数在执行过程中可以暂停并稍后从暂停点恢复执行。协程提供了一种控制流机制,使得函数可以包含多个入口点和出口点,这与传统的单入口、单出口的函数模…...
D3的竞品有哪些,D3的优势,D3和echarts的对比
D3 的竞品 ECharts: 简介: ECharts 是由百度公司开发的一款开源的 JavaScript 图表库,提供了丰富的图表类型和高度定制化的配置选项。特点: 易于使用,文档详尽,社区活跃,支持多种图表类型(如折线图、柱状图、饼图、散点…...
大厂计算机网络高频八股文面试题及参考答案(面试必问,持续更新)
目录 请简述 TCP 和 UDP 的区别? TCP 和 UDP 分别对应的常见应用层协议有哪些? UDP 的优缺点是什么?它适用于哪些场景? UDP 如何实现可靠传输? 请简述 HTTP 和 HTTPS 的区别? HTTP 协议的工作原理是什么? HTTP 状态码有哪些常见的类型及其含义? HTTP 哪些常用的…...
【bayes-Transformer-GRU多维时序预测】多变量输入模型。matlab代码,2023b及其以上
% 1. 数据准备 X_train 训练数据输入; Y_train 训练数据输出; X_test 测试数据输入; % 2. 模型构建 inputSize size(X_train, 2); numHiddenUnits 100; numResponses 1; layers [ … sequenceInputLayer(inputSize) biLSTMLayer(numHiddenUnits, ‘OutputMode’, ‘se…...
动手学深度学习69 BERT预训练
1. BERT 3亿参数 30亿个词 在输入和loss上有创新 两个句子拼起来放到encoder–句子对 cls-class分类 sep-seperate 分隔符 分开每个句子 告诉是哪个句子 两个句子给不同的向量 位置编码不用sin cos, 让网络自己学习 bert–通用任务 encoder 是双向的,…...
【2024软考架构案例题】你知道 Es 的几种分词器吗?Standard、Simple、WhiteSpace、Keyword 四种分词器你知道吗?
👉博主介绍: 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主 ⛪️ 个人社区&#x…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...
