四、自然语言处理_04时序信号的预测思想

1、概述

时序信号在时间维度上存在先后顺序,要想对其做预测,则需要"用过去的自己"来预测"未来的自己"

画一个图来辅助理解:

复制代码
import numpy as np
from matplotlib import pyplot as plt
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"

x = np.linspace(start=0, stop=16* np.pi, num=1000)
y = np.sin(x)

plt.xlabel('x')
plt.ylabel('y')

plt.plot(x, y)
plt.show()

上面一个正弦信号【y=sin(x)】的示例图,将x轴视为时间维度,y轴视为数据值,其即可表示为时序信号

所以,"时序信号的预测问题"就可以转换为"根据过去的x1时间对应的y值,来预测未来x2时间的y值"

面对此问题,我们有两种建模思想:

  • 1、拟合:y = f(x)

    • 输入:x

    • 输出:y

    • 方法:全连接(Linear)

  • 2、拟合:y_n = f(y_1, y_2, ..., y_n-1)

    • 输入:过去的y

    • 输出:当前的y

    • 方法:循环神经网络(RNN、LSTM、GRU等)

2、拟合:y = f(x)

Step1: 构建模型、训练参数以及训练方法

复制代码
import torch
from torch import nn

# 构建模型1:拟合:y = f(x)
class Model1(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Sequential(
            nn.Linear(in_features=1, out_features=128),
            nn.ReLU(),
            nn.Linear(in_features=128, out_features=256),
            nn.ReLU(),
            nn.Linear(in_features=256, out_features=128),
            nn.ReLU(),
            nn.Linear(in_features=128, out_features=1)
        )
    def forward(self, x):
        x = self.linear(x)
        return x

# 设备检测
device = "cuda" if torch.cuda.is_available() else "cpu"

# 将[1, N]的数组,转换为[N, 1]的张量
X = torch.tensor(data=x.reshape(-1, 1), dtype=torch.float32).to(device=device)
Y = torch.tensor(data=y.reshape(-1, 1), dtype=torch.float32).to(device=device)

# 设置训练轮次为10000轮
epocs = 10000
# 实例化模型
model1 = Model1()
model1.to(device=device)
# 定义损失函数
loss_fn = nn.MSELoss()
# 定义优化器
optimizer = torch.optim.Adam(params=model1.parameters(), lr=1e-3)

# 构建训练方法
def train():
    for epoch in range(epocs):
        # 1、正向传播
        y_pred = model1(X)
        # 2、计算损失
        loss = loss_fn(y_pred, Y)
        # 3、反向传播
        loss.backward()
        # 4、优化一步
        optimizer.step()
        # 5、清空梯度
        optimizer.zero_grad()
        # 每100轮打印一次损失值
        if epoch % 100:
            print(loss.item())

Step2: 模型训练

复制代码
train()

Step3: 构建预测方法

复制代码
def predict(X):
    if not isinstance(X, torch.Tensor):
        X = torch.tensor(data=X.reshape(-1, 1), dtype=torch.float32).to(device=device)
    else:
        X = X.reshape(-1, 1).to(device=device)
    with torch.no_grad():
        y = model1(X).cpu().numpy().reshape(-1)
        return y

Step4: 模型预测

复制代码
y_pred = predict(x)

Step5: 展示预测效果

复制代码
plt.plot(x, y)
plt.plot(x, predict(x))

3、拟合:y_n = f(y_1, y_2, ..., y_n-1)

Step1: 构建模型、训练参数以及训练方法

复制代码
import torch
from torch import nn

# 构建模型2:y_n = f(y_1, y_2, ..., y_n-1)
class Model2(nn.Module):
    def __init__(self):
        super().__init__()
        self.gru = nn.GRU(input_size=1, hidden_size=256)
        self.linear = nn.Linear(in_features=256, out_features=1)
    def forward(self, x):
        out, hn = self.gru(x)
        x = hn.squeeze(dim=0)
        x = self.linear(x)
        return x

# 设备检测
device = "cuda" if torch.cuda.is_available() else "cpu"

# 设置序列长度为600
SEQ_LEN = 600

X = []
Y = []
# 使用前SEQ_LEN个y,预测下一个y
for idx in range(len(x)-SEQ_LEN):
    y_input = y[idx: idx + SEQ_LEN]
    y_output = y[idx + SEQ_LEN]
    X.append(y_input)
    Y.append(y_output)

X = np.array(X)
# 维度转换:[1, N] --> [N, 1]
Y = np.array(Y).reshape(-1, 1)

# 转张量
# permute(dims=(1, 0))将X的维度进行转换:[batch, seq_len] --> [seq_len, batch]
# unsqueeze(dim=-1)再次进行维度转换:[seq_len, batch] --> [seq_len, batch, input_size](并令input_size=1)
X = torch.tensor(data=X, dtype=torch.float32).permute(dims=(1, 0)).unsqueeze(dim=-1).to(device=device)
Y = torch.tensor(data=Y, dtype=torch.float32).to(device=device)


# 设置训练轮次为1000轮
epocs = 1000
# 实例化模型
model2 = Model2()
model2.to(device=device)
# 定义损失函数
loss_fn = nn.MSELoss()
# 定义优化器
optimizer = torch.optim.Adam(params=model2.parameters(), lr=1e-3)

# 构建训练方法
def train():
    for epoch in range(epocs):
        # 1、正向传播
        y_pred = model2(X)
        # 2、计算损失
        loss = loss_fn(y_pred, Y)
        # 3、反向传播
        loss.backward()
        # 4、优化一步
        optimizer.step()
        # 5、清空梯度
        optimizer.zero_grad()
        # 每100轮打印一次损失值
        if epoch % 100:
            print(loss.item())

Step2: 模型训练

复制代码
train()

Step3: 构建预测方法

复制代码
def predict(y, n=1):
    # 初始化一个空列表 results,用于存储每一步的预测结果
    results = []
    X = y
    for step in range(n):
        X_in = torch.tensor(data=[X], dtype=torch.float32).permute(dims=(1, 0)).unsqueeze(dim=-1).to(device=device)
        with torch.no_grad():
            # 获得预测结果
            y_pred = model2(X_in.to(device=device)).cpu().item()
            # 将预测结果保存至列表中
            results.append(y_pred)
            # 将预测结果 y_pred 添加到当前输入序列 X 的末尾
            X.append(y_pred)
            # 更新 X,移除其第一个元素,这样在下一次迭代中,模型将基于最新的序列进行预测
            X = X[1:]
    return results

Step4: 模型预测

复制代码
# 定义测试序列的起点,进行预测
SEQ_START = 88
# n=2000表示进行2000次连续的预测
y_pred = predict(y[SEQ_START:SEQ_START+SEQ_LEN].tolist(), n=2000)

Step5: 展示预测效果(整体上来看,比第一种方式预测的效果要更好一些)

复制代码
plt.plot(y)
plt.plot(y_pred)
相关推荐
何大春8 分钟前
【视频时刻检索】Text-Video Retrieval via Multi-Modal Hypergraph Networks 论文阅读
论文阅读·深度学习·神经网络·计算机视觉·视觉检测·论文笔记
mucheni9 分钟前
迅为iTOP-RK3576开发板/核心板6TOPS超强算力NPU适用于ARM PC、边缘计算、个人移动互联网设备及其他多媒体产品
arm开发·人工智能·边缘计算
Jamence10 分钟前
多模态大语言模型arxiv论文略读(三十六)
人工智能·语言模型·自然语言处理
www_pp_12 分钟前
# 构建词汇表:自然语言处理中的关键步骤
前端·javascript·自然语言处理·easyui
猿饵块22 分钟前
opencv--图像变换
人工智能·opencv·计算机视觉
LucianaiB30 分钟前
【金仓数据库征文】_AI 赋能数据库运维:金仓KES的智能化未来
运维·数据库·人工智能·金仓数据库 2025 征文·数据库平替用金仓
jndingxin44 分钟前
OpenCV 图形API(63)图像结构分析和形状描述符------计算图像中非零像素的边界框函数boundingRect()
人工智能·opencv·计算机视觉
旧故新长1 小时前
支持Function Call的本地ollama模型对比评测-》开发代理agent
人工智能·深度学习·机器学习
微学AI1 小时前
融合注意力机制和BiGRU的电力领域发电量预测项目研究,并给出相关代码
人工智能·深度学习·自然语言处理·注意力机制·bigru
知来者逆1 小时前
计算机视觉——速度与精度的完美结合的实时目标检测算法RF-DETR详解
图像处理·人工智能·深度学习·算法·目标检测·计算机视觉·rf-detr