深度学习--------------序列模型

news2024/9/20 22:11:13

目录

  • 序列数据
  • 统计工具
    • (方案一)马尔可夫假设
    • (方案二)潜变量模型
    • 总结
  • 序列模型
    • 基于马尔可夫假设方式
      • 该部分总代码
    • 单步预测
    • 多步预测
    • k步预测
      • 该部分总代码

序列数据

实际中数据是有时序结构的。



统计工具

在时间t观察带 x t x_t xt,(假设有T个时间的话)那么得到T个不独立的随机变量。( x 1 x_1 x1,… x T x_T xT)~ p(x)

使用条件概率展开
在这里插入图片描述

在这里插入图片描述
先算p( x 1 x_1 x1),然后 x 2 x_2 x2是依赖于 x 1 x_1 x1的, x 2 x_2 x2出现的概率是需要知道 x 1 x_1 x1是多少的。依次类推 x 3 x_3 x3依赖于 x 1 x_1 x1 x 2 x_2 x2。…

对条件概率建模(正向)
在这里插入图片描述
训练f的话,其实就是训练一个模型,用 x t − 1 x_{t-1} xt1个数据训练一个模型来预测下一个模型。

所谓的自回归:就是给出一些数据,然后去预测这个数据的时候,不是用的另一些数据而是用这个数据前面的一些样本,所以叫自回归





(方案一)马尔可夫假设

在这里插入图片描述
例:
在这里插入图片描述
在原始的模型中,这个数据点与前面三个相关

在这里插入图片描述

当τ=2的时候:

在这里插入图片描述
这个数据点与前τ个相关,即该数据点前2个。

在这里插入图片描述




(方案二)潜变量模型

在这里插入图片描述
在这里插入图片描述

例:算x1的话,就是跟前面的x相关,也与潜变量h1相关

一旦引入了潜变量概念的话,那么可以不断更新h。h1是根据前一个时间的潜变量和前一个时间的x相关。
等价于是说:建立两个模型。

第一个模型:根据前面一个事件的h和前面时间的x来算新的潜变量。

第二个模型:给定新的潜变量的状态和前一个时间的x怎么算新的x(这里指x1)。
在这里插入图片描述





反过来写:

在这里插入图片描述




总结

  ①时序模型中,当前数据跟之前观察到的数据相关

  ②自回归模型使用自身过去数据来预测未来

  ③马尔可夫模型假设当前只跟最近少数数据相关,从而简化模型。

  ④潜变量模型使用潜变量来概括历史信息。




序列模型

使用正弦函数和一些可加性噪声来生成序列数据,时间步为1,2,3…1000

import torch
from d2l import torch as d2l

T = 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))
d2l.plt.tight_layout()
d2l.plt.show()

在这里插入图片描述
任务:给定任意一个时间点,预测接下来的时间的点长什么样子?



基于马尔可夫假设方式

使用马尔可夫假设:将数据映射为数据对在这里插入图片描述

y t y_t yt就表示预测第T个事件的数据。

解释:
①T - tau 为样本数,tau 为特征数,创建的是一个二维张量。

②表示有T-tau个元素(996),每个元素是一个长度为tau(即:向量中元素的数量为4)的向量,形状是[996,4]。

③这个矩阵的每一行将存储一个特征向量,每个特征向量包含tau个连续的时间点数据(即:每个特征向量的长度为4)。

④每个特征向量包含tau个连续的时间点数据。由于每个特征向量需要包含x中的前tau个时间点,所以最多只能构造出T - tau个这样的特征向量。

features = torch.zeros((T - tau, tau))

解释为什么这么设置:用一个例子举例推断说明

x = [x0, x1, x2, x3, x4, x5, x6, x7, x8, x9]

在这里插入图片描述




# 延迟时间步长
tau = 4
# 1000个点中最多构造出996个特征向量,且特征向量的长度为4
# 一个特征向量就是一个样本
features = torch.zeros((T - tau, tau))

# 每四个数据作为特征,第五个作为标签,不断构造这样的数据形成数据集
for i in range(tau):

    # x[i:T - tau + i]是切片操作,确保了每次都能从x中取出长度为tau的连续片段。
    # 当i=0时,x[0:996]右边不包含
    # 当i=1时,x[1:997]
    # 当i=2时,x[2:998]
    # 当i=3时,x[3:999]
    # features[:, i]是996行,4列,然而x是一个向量,且长度是996

    # 0   1   2   3
    # 1   2   3   4
    # 2   3   4   5
    # ...
    # 995 996 997 998
    features[:, i] = x[i:T - tau + i]

# 提取标签数据并进行形状变换,从1行996列变成了996行1列 (即:从一维变成二维)
# x[tau:]从第五列开始到最后一列,转变为1列996行
labels = x[tau:].reshape((-1, 1))

# # 批量大小和训练样本数量
batch_size, n_train = 16, 600
# 使用 features 和 labels 的前 n_train 个样本创建一个可迭代的训练集
# 第一个参数(features[:n_train], labels[:n_train])是一个元组
# 这行代码的作用是从完整的数据集(features和labels)中分割出训练集(前n_train个样本)
train_iter = d2l.load_array((features[:n_train], labels[:n_train]), batch_size, is_train=True)


为什么写这句代码?

    features[:, i] = x[i:T - tau + i]

在循环中的形状数据是这样的。(是不是很迷?这到底是在干什么?这里就是巧妙之处。)
在这里插入图片描述

这句代码设置的原因:
这是将i=0、1、2、3时,对应的1维的x的向量,填入features矩阵的第一列、第二列、第三列、第四列。
在这里插入图片描述
这里四个数据,也就是每一行作为数据特征。

在这里插入图片描述
第五个作为标签,第五个与前四个数据相关。

labels = x[tau:].reshape((-1, 1))



使用一个相当简单的结构:只是一个拥有两个全连接层的多层感知机。

# 初始化网络权重的函数
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.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)



该部分总代码

import torch
from torch import nn
from d2l import torch as d2l


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


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.backward()
            # 更新模型参数
            trainer.step()
        # 打印当前轮次的损失
        print(f'epoch {epoch + 1}, '
              f'loss: {d2l.evaluate_loss(net, train_iter, loss):f}')


T = 1000
time = torch.arange(1, T + 1, dtype=torch.float32)
x = torch.sin(0.01 * time) + torch.normal(0, 0.2, (T,))

tau = 4
features = torch.zeros((T - 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
train_iter = d2l.load_array((features[:n_train], labels[:n_train]), batch_size, is_train=True)

loss = nn.MSELoss()
# 创建神经网络模型
net = get_net()
# 训练模型
train(net, train_iter, loss, 5, 0.01)

在这里插入图片描述



单步预测

模型预测下一个时间步的能力(即:单步预测)

import torch
from torch import nn
from d2l import torch as d2l


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


# net(要训练的神经网络模型)、train_iter(训练数据的迭代器,用于批量地提供训练数据)、loss(损失函数,用于评估模型的预测与实际值之间的差异)
def train(net, train_iter, loss, epochs, lr):
    # 定义优化器,目标是调整模型的参数,以最小化损失函数。Adam是一种基于梯度下降的优化算法,具有自适应学习率的特点。
    trainer = torch.optim.Adam(net.parameters(), lr)
    # 迭代训练指定的轮数
    for epoch in range(epochs):
        # 遍历训练集中的每个批次
        # 下面的y相当于合并元组中的labels[:n_train]
        for X, y in train_iter:
            # 梯度清零,PyTorch 会累积梯度,而我们需要的是每个批次独立计算的梯度
            trainer.zero_grad()
            # 通过模型 net 进行前向传播,计算模型对于当前批次数据的预测,然后使用损失函数 loss 计算预测值与真实值之间的损失。
            l = loss(net(X), y)
            # 反向传播求梯度
            l.backward()
            # 更新模型参数
            trainer.step()
        # 打印当前轮次的损失
        print(f'epoch {epoch + 1}, '
              f'loss: {d2l.evaluate_loss(net, train_iter, loss):f}')


T = 1000
time = torch.arange(1, T + 1, dtype=torch.float32)
x = torch.sin(0.01 * time) + torch.normal(0, 0.2, (T,))

tau = 4
features = torch.zeros((T - 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
# features[:n_train] 并不是取一维的,而是取 features 张量的前 n_train(这里是 600)行。
# 表示从整个特征集中选择了前 600 个特征向量作为训练集。
# 合并成一个元组是为了将数据分为特征和标签,并将它们作为训练数据集传递给数据加载器
train_iter = d2l.load_array((features[:n_train], labels[:n_train]), batch_size, is_train=True)

# 只是定义还没使用
loss = nn.MSELoss()
# 创建神经网络模型
net = get_net()
# 训练模型,使用 features 和 labels 的前 n_train(即:600) 个样本进行训练。总共996个特征向量(features)
train(net, train_iter, loss, 5, 0.01)

# 将特征数据输入到模型net中,并获取模型的一步预测结果onestep_preds。net是一个已经训练好的神经网络,用于根据给定的特征预测未来的某个值。
# 使用训练好的模型,对所有特征向量进行一个预测
# onestep_preds形状为(T - tau, 1),对应于features中每个特征向量的预测结果。每个预测值都是基于其对应的特征向量通过整个模型的前向传播过程计算得到的。
onestep_preds = net(features)

# 进行数据可视化,将真实数据和一步预测结果绘制在同一个图中进行比较
d2l.plot(
    # 是两个x轴的数据系列,下面x.detach().numpy() 表示模型在原始时间轴 time 上的观测数据
    # onestep_preds.detach().numpy() 表示的是模型的预测数据。
    [time, time[tau:]],
    # x是在时间序列中真实观测到的数据。detach()用于从计算图中分离变量,防止其梯度被追踪
    # 将模型预测的一步结果从PyTorch张量转换为NumPy数组,以便绘图。
    [x.detach().numpy(), onestep_preds.detach().numpy()], 'time', 'x',
    legend=['data', 'l-step preds'], xlim=[1, 1000], figsize=(6, 3))
d2l.plt.show()


前向传播:

当net(features)被调用时,features中的每个特征向量(即每一行)都将被逐一传递给模型的第一个线性层。线性层会这些特征向量进行线性变换(即矩阵乘法加上偏置),产生新的特征表示。然后,这些新的特征表示会经过ReLU激活函数,进行非线性变换。最后,它们被传递给第二个线性层,该层将输出最终的预测结果。由于第二个线性层的输出维度为1,因此每个特征向量都会得到一个单一的预测值。
在这里插入图片描述

正如我们所料,单步预测效果不错。 即使这些预测的时间步超过了600+4(n_train + tau), 其结果看起来仍然是可信的。 然而有一个小问题:如果数据观察序列的时间步只到604, 我们需要一步一步地向前迈进:
在这里插入图片描述



多步预测

tau是每个特征向量包含的数量
为了进行多步预测,我们需要从当前点回溯 tau 个点来获取输入特征。

初始化多步预测:
开始多步预测时,您希望从训练数据的最后一个时间点之后立即开始,最后一个特征向量的最后一个时间点实际上与下一个时间点(即第一个未用于训练的时间点)是连续的,因此您只需要额外考虑 tau - 1 个时间点来确保时间窗口的连续性。然而,由于我们实际上想要包括训练数据中的最后一个完整特征向量,所以我们需要包括这个特征向量的所有 tau 个时间点。



    通常,对于直到 x t x_t xt的观测序列,其在时间步t+k处的预测输出在这里插入图片描述称为k步预测(k-step-ahead-prediction)。由于我们的观察已经到了 x 604 x_{604} x604,它的k步预测是在这里插入图片描述。换句话说,我们必须使用我们自己的预测(而不是原始数据)来进行多步预测。让我们看看效果如何。

import torch
from torch import nn
from d2l import torch as d2l


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


# net(要训练的神经网络模型)、train_iter(训练数据的迭代器,用于批量地提供训练数据)、loss(损失函数,用于评估模型的预测与实际值之间的差异)
def train(net, train_iter, loss, epochs, lr):
    # 定义优化器,目标是调整模型的参数,以最小化损失函数。Adam是一种基于梯度下降的优化算法,具有自适应学习率的特点。
    trainer = torch.optim.Adam(net.parameters(), lr)
    # 迭代训练指定的轮数
    for epoch in range(epochs):
        # 遍历训练集中的每个批次
        # 下面的y相当于合并元组中的labels[:n_train]
        for X, y in train_iter:
            # 梯度清零,PyTorch 会累积梯度,而我们需要的是每个批次独立计算的梯度
            trainer.zero_grad()
            # 通过模型 net 进行前向传播,计算模型对于当前批次数据的预测,然后使用损失函数 loss 计算预测值与真实值之间的损失。
            l = loss(net(X), y)
            # 反向传播求梯度
            l.backward()
            # 更新模型参数
            trainer.step()
        # 打印当前轮次的损失
        print(f'epoch {epoch + 1}, '
              f'loss: {d2l.evaluate_loss(net, train_iter, loss):f}')


T = 1000
time = torch.arange(1, T + 1, dtype=torch.float32)
x = torch.sin(0.01 * time) + torch.normal(0, 0.2, (T,))

tau = 4
features = torch.zeros((T - 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
# features[:n_train] 并不是取一维的,而是取 features 张量的前 n_train(这里是 600)行。
# 表示从整个特征集中选择了前 600 个特征向量作为训练集。
# 合并成一个元组是为了将数据分为特征和标签,并将它们作为训练数据集传递给数据加载器
train_iter = d2l.load_array((features[:n_train], labels[:n_train]), batch_size, is_train=True)

# 只是定义还没使用
loss = nn.MSELoss()
# 创建神经网络模型
net = get_net()
# 训练模型,使用 features 和 labels 的前 n_train(即:600) 个样本进行训练。总共996个特征向量(features)
train(net, train_iter, loss, 5, 0.01)

# 将特征数据输入到模型net中,并获取模型的一步预测结果onestep_preds。net是一个已经训练好的神经网络,用于根据给定的特征预测未来的某个值。
# 使用训练好的模型,对所有特征向量进行一个预测
# onestep_preds形状为(T - tau, 1),对应于features中每个特征向量的预测结果。每个预测值都是基于其对应的特征向量通过整个模型的前向传播过程计算得到的。
onestep_preds = net(features)

# 初始化多步预测结果的张量
multistep_preds = torch.zeros(T)
# 将已知的真实数据赋值给多步预测结果,0到604(604不包含)
# x[:n_train + tau]为已经拥有的真实的历史数据,可以直接使用这些数据作为多步预测的起点。
# 实际上是在告诉模型:“对于前 n_train + tau 个时间点,我们已经知道了真实的值,因此不需要预测它们。”
# 为什么是n_train + tau个呢?额外包含了 tau 个时间点确保在多步预测开始时有一个完整的时间窗口可用
multistep_preds[:n_train + tau] = x[:n_train + tau]


# 对剩余时间步进行多步预测
for i in range(n_train + tau, T):
    # 获得多步预测结果
    # multistep_preds[i - tau:i]是从n_train到n_train+3四个,然后n_train+1,...n_train+tau+1四个,依次类推
    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))

d2l.plt.show()


前600个数据点做训练,后面600-1000做预测
所以从这个600开始就往后预测400个点,也就是那个绿色,发现相差很离谱。

绿色的上面的紫红色线是每一次去预测下一个点,然后在下一个数据点用真正观测到的数据给你。而绿色则是从600这里,蓝色的点就不在给出了,然后需要用自己的预测的值去预测,然后一直下去。
所以为什么会相差这么多呢?因为每一次预测的时候都有一点误差,然后误差不断叠加。就是说预测有误差,然后误差进入到数据,然后误差又会增加,然后就会不断累积误差。

在这里插入图片描述
如上面的例子所示,绿线的预测显然并不理想。 经过几个预测步骤之后,预测的结果很快就会衰减到一个常数。为什么这个算法效果这么差呢?事实是由于错误的累积:假设在步骤1之后,我们积累了一些错误在这里插入图片描述。 于是,步骤2的输入被扰动了在这里插入图片描述,结果积累的误差是依照次序的在这里插入图片描述,其中 c 为某个常数,后面的预测误差依此类推。因此误差可能会相当快地偏离真实的观测结果。

例如,未来24小时的天气预报往往相当准确,但超过这一点,精度就会迅速下降。




k步预测

基于k = 1, 4, 16, 64,通过对整个序列预测的计算,让我们更仔细地看一下k步预测的困难。

# 最大步长
max_steps = 64
# 初始化特征张量
features = torch.zeros((T - tau - max_steps + 1, tau + max_steps))
# 从 0 到 tau-1进行遍历
for i in range(tau):
    # 构造特征矩阵
    features[:, i] = x[i:i + T - tau - max_steps + 1]
    
# 从 tau 到 tau + max_steps - 1,通过 net(features[:, i - tau:i]) 进行多步预测
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) )



该部分总代码

import torch
from torch import nn
from d2l import torch as d2l


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


# net(要训练的神经网络模型)、train_iter(训练数据的迭代器,用于批量地提供训练数据)、loss(损失函数,用于评估模型的预测与实际值之间的差异)
def train(net, train_iter, loss, epochs, lr):
    # 定义优化器,目标是调整模型的参数,以最小化损失函数。Adam是一种基于梯度下降的优化算法,具有自适应学习率的特点。
    trainer = torch.optim.Adam(net.parameters(), lr)
    # 迭代训练指定的轮数
    for epoch in range(epochs):
        # 遍历训练集中的每个批次
        # 下面的y相当于合并元组中的labels[:n_train]
        for X, y in train_iter:
            # 梯度清零,PyTorch 会累积梯度,而我们需要的是每个批次独立计算的梯度
            trainer.zero_grad()
            # 通过模型 net 进行前向传播,计算模型对于当前批次数据的预测,然后使用损失函数 loss 计算预测值与真实值之间的损失。
            l = loss(net(X), y)
            # 反向传播求梯度
            l.backward()
            # 更新模型参数
            trainer.step()
        # 打印当前轮次的损失
        print(f'epoch {epoch + 1}, '
              f'loss: {d2l.evaluate_loss(net, train_iter, loss):f}')


T = 1000
time = torch.arange(1, T + 1, dtype=torch.float32)
x = torch.sin(0.01 * time) + torch.normal(0, 0.2, (T,))

tau = 4
features = torch.zeros((T - 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
# features[:n_train] 并不是取一维的,而是取 features 张量的前 n_train(这里是 600)行。
# 表示从整个特征集中选择了前 600 个特征向量作为训练集。
# 合并成一个元组是为了将数据分为特征和标签,并将它们作为训练数据集传递给数据加载器
train_iter = d2l.load_array((features[:n_train], labels[:n_train]), batch_size, is_train=True)
# 只是定义还没使用
loss = nn.MSELoss()
# 创建神经网络模型
net = get_net()
# 训练模型,使用 features 和 labels 的前 n_train(即:600) 个样本进行训练。总共996个特征向量(features)
train(net, train_iter, loss, 5, 0.01)

max_steps = 64
# 933行68列
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矩阵的前tau列
    # i的取值0、1、2、3
    # 所有行的前四列,使用原始时间序列x的前tau个时间步的数据复制到features矩阵的前tau列中。
    # 0到933、1到934、2到935、3到936,x是一维的
    # 0   1   2   3
    # 1   2   3   4
    # 2   3   4   5
    # ...
    # 933 934 935 936
    # 每列代表一个时间步的观测数据,时间范围从i到i + T - tau - max_steps + 1。
    features[:, i] = x[i: i + T - tau - max_steps + 1]

# 列i(i>=tau)是来自(i-tau+1)步的预测,其时间步从(i)到(i+T-tau-max_steps+1)
# 从4开始(第五个点)到67列
for i in range(tau, tau + max_steps):
    # 所有行的4到68列,features的所有行,0到4列
    #                               1到5列
    #                               2到6列
    #                                ...
    #                               63列到67列

    # 对于每一列(从tau(4列)到tau + max_steps - 1(67列)),它使用前tau(4)个时间步的观测数据(即features[:, i - tau:i])作为输入,
    # 通过前tau(4)个时间步(即观测数据)来预测第i个时间步的值。
    # 例如前4列预测第5列
    # 通过.reshape(-1)调整为与输入数据相同的形状,并存储在features矩阵的相应列中。
    features[:, i] = net(features[:, i - tau:i]).reshape(-1)
steps = (1, 4, 16, 64)

# steps=1时,time从4到937(937不包含)
# steps=4时,time从7到940(940不包含)
# steps=16时,time从19到952(952不包含)
# steps=64时,time从67到1000(1000不包含)
d2l.plot([time[tau + i - 1: T - max_steps + i] for i in steps],
         # 从features矩阵中提取了每个预测步长对应的预测结果列
         # 所有行的4(标号)列,所有行的7(标号)列,所有行的19(标号)列,所有行的67(标号)列
         [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))
d2l.plt.show()


蓝色点:
每次给出4个真实的数据点预测下一个

紫红色:
每次给出4个真实的数据点预测接下来4个(这4个不会给出真实数据)

绿色:
每次给出4个真实的数据点预测接下来16个(这16个不会给出真实数据)

红色:
每次给出4个真实的数据点预测接下来64个(这64个不会给出真实数据)
在这里插入图片描述

其中:

[time[tau + i - 1: T - max_steps + i] for i in steps]

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

二叉搜索树(Java实现)

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多数据结构知识 1.概念 二叉搜索树又称二叉排序树,或者它是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都…

【kafka-01】kafka安装和基本核心概念

Kafka系列整体栏目 内容链接地址【一】afka安装和基本核心概念https://zhenghuisheng.blog.csdn.net/article/details/142213307【二】kafka集群搭建https://zhenghuisheng.blog.csdn.net/article/details/142253288 kafka安装和基本核心概念 一&#xff0c;kafka安装和基本核心…

MoneyPrinterTurbo 安装使用流程

项目地址&#xff1a; https://github.com/harry0703/MoneyPrinterTurbo 开发环境&#xff1a;mac 1 git 下载 # 下载代码到本地 git clone https://github.com/harry0703/MoneyPrinterTurbo.git cd MoneyPrinterTurbo2 docker 配源 在 docker 安装目录执行以下命令显示隐藏…

Spring模块详解Ⅳ(Spring ORM和Spring Transaction)

目录 Spring ORM&#xff08;Object-Relational Mapping&#xff09;作用核心组件使用步骤事务管理代码演示优点挑战总结 Spring Transaction&#xff08;Spring事务管理&#xff09;事务的基本概念Spring事务管理的类型声明式事务管理事务的传播行为&#xff08;Propagation&a…

【LabVIEW学习篇 - 25】:JKI状态机

文章目录 JKI状态机JKI状态机安装JKI状态机的基本了解状态机的运行原理示例 JKI状态机 JKI状态机的核心就是队列消息状态机用户事件处理器模式&#xff0c;JKI状态机采用指定格式的字符串来描述状态。 JKI状态机并没有采用队列而是采用指定的字符串进行存储&#xff0c;它封装…

【论文阅读】PERCEIVER-ACTOR: A Multi-Task Transformer for Robotic Manipulation

Abstract transformers凭借其对大型数据集的扩展能力&#xff0c;彻底改变了视觉和自然语言处理。但在机器人操作中&#xff0c;数据既有限又昂贵。通过正确的问题表述&#xff0c;操纵仍然可以从变形金刚中受益吗&#xff1f;我们使用peract来研究这个问题&#xff0c;peract…

图解Redis 02 | String数据类型的原理及应用场景

介绍 在 Redis 中&#xff0c;String 是一种重要的数据类型&#xff0c;是最基本的 key-value 结构&#xff0c;在这个结构中&#xff0c; value 是一个字符串。value 所能容纳的数据最大长度为512M。 需要注意的是&#xff0c;这里的字符串不只指文本数据&#xff0c;它还可…

Https AK--(ssl 安全感满满)

免责声明&#xff1a;本文仅做分享&#xff01; 目录 https探测 openssl Openssl连接服务器获取基本信息 连接命令&#xff1a; 指定算法连接: 测试弱协议连接是否可以连接: 得到的内容包括&#xff1a; sslscan 在线查询证书 https AK type 中间人AK sslsplit 工具…

【C++题解】1997. 孤独的素数

欢迎关注本专栏《C从零基础到信奥赛入门级&#xff08;CSP-J&#xff09;》 问题&#xff1a;1997. 孤独的素数 类型&#xff1a;二维数组 题目描述&#xff1a; 在一个 n 行 m 列的矩阵王国中&#xff0c;生活着一些整数&#xff0c;其中一些是素数&#xff0c;一些不是素数…

数据中心一体化智能运维方案

数据中心基础运维概述 在当今这个信息化的时代&#xff0c;数据中心作为支撑企业信息化建设的核心枢纽&#xff0c;其运维工作的重要性不言而喻。某数据中心深知运维工作的关键性&#xff0c;因此&#xff0c;从基础环境到网络、服务器存储以及基础软件&#xff0c;每一环节都力…

openeuler 22.03 lts sp4 使用 kubeadm 部署 k8s-v1.28.2 高可用集群

文章目录 [toc]废话篇这篇文章什么时候写的为什么是 openeuler为什么是 22.03 lts sp4高可用架构题外话 干活篇环境介绍系统初始化相关关闭防火墙关闭 selinux关闭 swap开启内核模块开启模块自动加载服务 sysctl 内核参数调整清空 iptables 规则安装各种依赖和工具修改 .bashrc…

R语言的基础知识R语言函数总结

R语言与数据挖掘&#xff1a;公式&#xff1b;数据&#xff1b;方法 R语言特征 对大小写敏感通常&#xff0c;数字&#xff0c;字母&#xff0c;. 和 _都是允许的(在一些国家还包括重音字母)。不过&#xff0c;一个命名必须以 . 或者字母开头&#xff0c;并且如果以 . 开头&…

Python数据分析案例60——扩展变量后的神经网络风速预测(tsfresh)

案例背景 时间序列的预测一直是经久不衰的实际应用和学术研究的对象&#xff0c;但是绝大多数的时间序列可能就没有太多的其他的变量&#xff0c;例如一个股票的股价&#xff0c;还有一个企业的用电量&#xff0c;人的血糖浓度等等&#xff0c;空气的质量&#xff0c;温度这些…

【工具推荐】Agently:一款灵活易用的 AI 应用开发框架

本文内容均来自个人笔记并重新梳理&#xff0c;如有错误欢迎指正&#xff01; 如果对您有帮助&#xff0c;烦请点赞、关注、转发、订阅专栏&#xff01; 专栏订阅入口 | 精选文章 | Kubernetes | Docker | Linux | 羊毛资源 | 工具推荐 | 往期精彩文章 【Docker】&#xff08;全…

LAMP环境搭建记录:基于VM的Ubuntu虚拟机

LAMP环境搭建记录&#xff1a;基于VM的Ubuntu虚拟机 我们从这样的角度出发&#xff1a; 一、简述LAMP环境 二、搭建LAMP环境 一、什么是LAMP环境 首先&#xff0c;该词是复合&#xff1a; ​ LAMP Linux Apache MySQL PHP 其中&#xff0c;逐项简述为&#xff1a; …

基于STM32的温度、电流、电压检测proteus仿真系统(OLED、DHT11、继电器、电机)

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于STM32F103C8T6 采用DHT11读取温度、滑动变阻器模拟读取电流、电压。 通过OLED屏幕显示&#xff0c;设置电流阈值为80&#xff0c;电流小阈值为50&#xff0c;电压阈值为60&#xff0c;温度阈值…

幼儿与非幼儿识别系统源码分享

幼儿与非幼儿识别检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer…

跨域训练评估BEVal:自动驾驶 BEV 的跨数据集评估框架

跨域训练评估BEVal&#xff1a;自动驾驶 BEV 的跨数据集评估框架 Abstract 当前在自动驾驶中的鸟瞰图语义分割研究主要集中在使用单个数据集&#xff08;通常是nuScenes数据集&#xff09;优化神经网络模型。这种做法导致了高度专业化的模型&#xff0c;可能在面对不同环境或…

苹果手机怎么清理照片内存

在使用苹果手机的过程中&#xff0c;照片往往是占用大量存储空间的主要元凶。随着时间的推移&#xff0c;无论是拍照、截图还是通过应用下载的图片&#xff0c;都会逐渐堆积&#xff0c;消耗宝贵的内存资源。合理清理照片内存不仅可以帮助你释放空间&#xff0c;还能优化设备的…

【算法】动态规划—最长回文子序列

思路分析 关于”回文串“的问题&#xff0c;是面试中常见的&#xff0c;本文提升难度&#xff0c;讲一讲”最长回文子序列“问题&#xff0c;题目很好理解&#xff1a; 输入一个字符串 s&#xff0c;请找出 s 中的最长回文子序列长度。 比如输入 s"aecda"&#xff0c…