您的位置:首页 > 娱乐 > 明星 > 福田网站建设龙岗网站建设罗湖网站建设_什么是软件的开发平台_百度竞价怎么做效果好_宁波谷歌seo

福田网站建设龙岗网站建设罗湖网站建设_什么是软件的开发平台_百度竞价怎么做效果好_宁波谷歌seo

2024/12/23 7:16:08 来源:https://blog.csdn.net/Zcymatics/article/details/143623850  浏览:    关键词:福田网站建设龙岗网站建设罗湖网站建设_什么是软件的开发平台_百度竞价怎么做效果好_宁波谷歌seo
福田网站建设龙岗网站建设罗湖网站建设_什么是软件的开发平台_百度竞价怎么做效果好_宁波谷歌seo

第二十周周报

  • 摘要
  • Abstract
  • 一、初步认识物理信息神经网络(PINN)
    • 1.PINN的基本概念
    • 2. PINN与传统机器学习的区别
    • 3.构建PINN的步骤
  • 二、代码实战——比较RNN、LSTM、Transformer在股市预测的表现
    • 1.RNN在股市预测中的表现
    • 2.LSTM在股市预测中的表现
    • 3.Transformer在股市预测中的表现
    • 4.结果分析与总结
  • 总结

摘要

本文主要探讨了物理信息神经网络(PINN)的基本概念、工作机制、训练过程,并与传统机器学习模型进行了比较。PINN通过将物理定律嵌入损失函数中,实现了对物理现象的精确模拟和预测,减少了对数据量的依赖,并提高了模型在数据稀缺情况下的预测能力。文章还详细介绍了构建PINN模型的步骤,包括确定问题域和物理定律、选择网络架构、准备数据集、定义损失函数、训练模型、验证和测试模型、调参与优化以及解释和应用。此外,文章通过代码实战比较了RNN、LSTM和Transformer在股市预测中的表现,发现LSTM在这种时序预测任务中表现最佳,而Transformer表现最差。最后,文章对结果进行了分析与总结,指出了LSTM的优势和Transformer在时序预测任务中的局限性。

Abstract

This paper primarily investigates the fundamental concepts, operating mechanisms, and training processes of Physics-Informed Neural Networks (PINNs), and compares them with traditional machine learning models. PINNs achieve precise simulation and prediction of physical phenomena by embedding physical laws into the loss function, thereby reducing the dependence on the volume of data and enhancing the model’s predictive capability in scenarios where data is scarce. The paper also provides a detailed exposition of the steps involved in constructing PINN models, which include identifying the problem domain and physical laws, selecting network architectures, preparing datasets, defining loss functions, training models, validating and testing models, adjusting parameters and optimizing, as well as interpreting and applying the models. Furthermore, the paper compares the performance of Recurrent Neural Networks (RNNs), Long Short-Term Memory (LSTM) networks, and Transformers in stock market forecasting through code implementation, finding that LSTM outperforms the others in such time-series prediction tasks, while Transformer performs the worst. Finally, the paper analyzes and summarizes the results, highlighting the advantages of LSTM and the limitations of Transformer in time-series forecasting tasks.

一、初步认识物理信息神经网络(PINN)

1.PINN的基本概念

1. PINN的基本原理
物理信息神经网络(PINN)是一种深度学习模型,它通过将物理定律嵌入到神经网络的损失函数中,实现了对物理现象的精确模拟和预测。这种模型不仅依赖于数据驱动的学习,还利用物理法则来指导模型的训练过程。

2.PINN模型的工作机制
PINN模型的核心在于其损失函数的设计,该函数不仅包括数据误差项,还特别加入了物理信息误差项。这种设计确保了模型在拟合数据的同时,还能够遵循物理定律。例如,在流体动力学问题中,PINN模型会将Navier-Stokes方程作为物理信息项纳入损失函数,以确保预测结果的物理一致性。

3. PINN模型的训练过程
PINN模型的训练过程涉及以下几个关键步骤:

  • 定义物理问题和相应的物理定律:明确模型的目标和对应的物理定律,如流体力学中的Navier-Stokes方程:
    ρ ( ∂ u ∂ t + u ⋅ ∇ u ) = − ∇ p + μ ∇ 2 u + f \rho \left( \frac{\partial \mathbf{u}}{\partial t} + \mathbf{u} \cdot \nabla \mathbf{u} \right) = -\nabla p + \mu \nabla^2 \mathbf{u} + \mathbf{f} ρ(tu+uu)=p+μ2u+f
    其中,ρ 是流体密度,u 是速度向量,p 是压力,μ 是动力粘度,f 是外力。

  • 构建神经网络:设计适合问题复杂性的神经网络结构,输入参数通常包括位置、时间等,输出为物理量的预测值。

  • 定义损失函数:损失函数由数据误差项和物理信息误差项组成,后者确保模型预测结果满足物理定律。例如,对于一维热传导方程:
    ∂ u ∂ t − α ∂ 2 u ∂ x 2 = 0 \frac{\partial u}{\partial t} - \alpha \frac{\partial^2 u}{\partial x^2} = 0 tuαx22u=0
    其中,u(x,t) 是温度分布,α 是热扩散系数。物理信息误差项可以表示为:
    L P D E = [ ∂ u ^ ∂ t − α ∂ 2 u ^ ∂ x 2 ] 2 \mathcal{L}_{PDE} = \left[ \frac{\partial \hat{u}}{\partial t} - \alpha \frac{\partial^2 \hat{u}}{\partial x^2} \right]^2 LPDE=[tu^αx22u^]2
    数据误差项(如果有实际观测数据uobs)可以表示为:
    L d a t a = ∣ ∣ u ^ − u o b s ∣ ∣ 2 \mathcal{L}_{data} = || \hat{u} - u_{obs} ||^2 Ldata=∣∣u^uobs2

  • 训练网络:使用梯度下降等优化算法调整网络权重,最小化整体损失函数:
    L = λ P D E L P D E + λ d a t a L d a t a \mathcal{L} = \lambda_{PDE} \mathcal{L}_{PDE} + \lambda_{data} \mathcal{L}_{data} L=λPDELPDE+λdataLdata
    其中,λPDE 和 λdata 是权衡两个误差项重要性的超参数。

  • 模型验证与测试:在训练集以外的数据上验证模型的准确性和物理定律的遵循情况。

2. PINN与传统机器学习的区别

PINN与传统机器学习的主要区别在于其对物理知识的集成。传统机器学习方法主要依赖于大量数据,而,PINN通过引入物理定律作为先验知识,减少了对数据量的依赖,提高了模型在数据稀缺情况下的预测能力。
比较如下:
1. 物理约束的融合

  • PINN:将物理定律直接融入模型训练,通过损失函数中的额外项确保模型遵循物理规律。
  • 传统机器学习:通常不考虑物理约束,侧重于从数据中学习模式和关系。

2. 数据依赖性

  • PINN:对数据质量和数量的依赖较小,物理约束提供了额外的指导信息。
  • 传统机器学习:需要大量的标记数据,数据稀缺或标注成本高昂时性能可能受影响。

3. 泛化能力

  • PINN:整合物理法则,即使在数据稀缺环境中也能保持合理的预测。
  • 传统机器学习:可能在数据密集区域内泛化良好,但对于新数据或极端情况可能难以提供准确预测。

4. 问题适用性

  • PINN:适用于可以被明确物理定律描述的科学计算和工程问题。
  • 传统机器学习:适用于各类问题,特别是在物理定律未知或难以描述的情况下。

3.构建PINN的步骤

构建一个PINN模型通常需要以下步骤:

  1. 确定问题域和物理定律
    明确研究问题和相应的物理定律,如偏微分方程。
  2. 选择网络架构
    根据问题的复杂性选择合适的神经网络架构,如全连接网络或卷积神经网络。
  3. 准备数据集
    收集相关的观测数据,用于校准模型预测。
  4. 定义损失函数
    构建包含数据驱动损失和物理驱动损失的损失函数。
  5. 训练模型
    使用优化算法调整网络参数,最小化总损失。
  6. 对模型进行验证和测试
    使用独立数据集测试模型的泛化能力。
  7. 调参与优化
    调整网络架构、超参数或损失函数中的权重,以改善模型表现。
  8. 解释和应用
    解释模型预测与物理过程的关系,并将其应用于实际问题。

通过这些步骤,可以构建一个适用于特定物理学问题的PINN模型。

二、代码实战——比较RNN、LSTM、Transformer在股市预测的表现

1. 环境如下

  • 系统:windows11
  • anaconda3:10.8
  • pytorch:11.8
  • pycharm
  • python:3.8

2.数据集的收集与预处理:
数据集是上海证券交易所(代码:sh)在2000年1月4日至2007年10月22日期间的部分交易日的股票市场数据。数据包括每个交易日的日期、开盘价(open)、收盘价(close)、最高价(high)、最低价(low)、成交量(volume)等信息。
在这里插入图片描述
我们通过一个dataset类来对数据集进行预处理:

# 这个类的主要作用是将股票数据集加载并预处理,然后提供给PyTorch模型进行训练或测试。
# 它首先读取CSV文件中的股票价格数据,然后根据train_flag参数决定是创建训练集还是测试集。
# 数据被标准化处理后,通过__getitem__方法,
# 可以获取到用于模型训练或测试的样本序列。每个样本包含T个时间步长的数据点和一个目标值(即下一个时间点的值)。
import pandas as pd  # 导入pandas库,用于数据处理
import numpy as np  # 导入numpy库,用于数值计算
import torch  # 导入PyTorch库,用于深度学习模型
import math  # 导入math库,用于数学运算
from torch.utils.data import DataLoader, Dataset  # 从PyTorch中导入DataLoader和Dataset类# 定义一个名为StockDataset的类,它继承自PyTorch的Dataset类
class StockDataset(Dataset):def __init__(self, file_path, time_step=10, train_flag=True):# 读取数据with open(file_path, "r", encoding="GB2312") as fp:  # 以只读模式打开文件,使用GB2312编码data_pd = pd.read_csv(fp)  # 使用pandas读取CSV文件self.train_flag = train_flag  # 标记数据集是用于训练还是测试self.data_train_ratio = 0.9  # 训练数据占总数据的比例self.T = time_step  # 时间步长,即用于预测的过去数据点的数量if train_flag:  # 如果是训练数据集self.data_len = int(self.data_train_ratio * len(data_pd))  # 计算训练数据的长度data_all = np.array(data_pd['close'])  # 将'close'列转换为numpy数组data_all = (data_all - np.mean(data_all)) / np.std(data_all)  # 对数据进行标准化处理self.data = data_all[:self.data_len]  # 截取训练数据else:  # 如果是测试数据集self.data_len = int((1 - self.data_train_ratio) * len(data_pd))  # 计算测试数据的长度data_all = np.array(data_pd['close'])  # 将'close'列转换为numpy数组data_all = (data_all - np.mean(data_all)) / np.std(data_all)  # 对数据进行标准化处理self.data = data_all[-self.data_len:]  # 截取测试数据print("data len:{}".format(self.data_len))  # 打印数据长度def __len__(self):  # 定义数据集的长度return self.data_len - self.T  # 返回数据长度减去时间步长def __getitem__(self, idx):  # 定义如何获取单个样本# Transformer、RNN用这个return self.data[idx:idx + self.T], self.data[idx + self.T]  # 返回从idx开始的T个数据点和下一个时间点的值# LSTM用这个# seq = self.data[idx:idx + self.T]# target = self.data[idx + self.T]# return torch.tensor(seq, dtype=torch.float).view(-1, 1), torch.tensor(target, dtype=torch.float)

1.RNN在股市预测中的表现

RNN的模型如下:

# 定义一个循环神经网络(RNN)模型
class RNN(nn.Module):def __init__(self, rnn_layer=2, input_size=1, hidden_size=4):super(RNN, self).__init__()self.rnn_layer = rnn_layer  # RNN层数self.input_size = input_size  # 输入层维度self.hidden_size = hidden_size  # 隐藏层维度self.rnn = nn.RNN(  # 定义RNN层input_size=self.input_size,  # 输入层维度hidden_size=self.hidden_size,  # 隐藏层维度num_layers=self.rnn_layer,  # RNN层数batch_first=True  # 批处理优先)self.fc = nn.Linear(self.hidden_size, self.input_size)  # 全连接层# 初始化隐藏状态def init_hidden(self, x):batch_size = x.shape[0]  # 批处理大小init_h = torch.zeros(self.rnn_layer, batch_size, self.hidden_size, device=x.device).requires_grad_()return init_h# 前向传播函数def forward(self, x, h=None):x = x.unsqueeze(2)  # 增加一个维度h = h if h else self.init_hidden(x)  # 如果没有提供隐藏状态,则初始化out, h = self.rnn(x, h)  # RNN层out = self.fc(out[:, -1, :]).squeeze(1)  # 全连接层并去除维度为1的维度return out

然后我们对RNN模型进行训练,代码如下:

import tqdm  # 导入tqdm库,用于显示进度条
from models import *  # 从models模块导入所有模型
from dataset.dataset_rnn_transformer import StockDataset  # 从dataset模块导入StockDataset类
from torch.utils.data import DataLoader  # 从PyTorch中导入DataLoader类
from tensorboardX import SummaryWriter  # 导入tensorboardX的SummaryWriter,用于记录训练过程checkpointdir = '../checkpoints/RNN'  # 设置模型检查点目录
stock_file = '../stocks/shangzheng.csv'  # 设置股票数据文件路径
logger = SummaryWriter(checkpointdir)  # 创建SummaryWriter实例,用于记录训练日志# 引入设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")def l2_loss(pred, label):  # 定义L2损失函数loss = torch.nn.functional.mse_loss(pred, label, size_average=True)  # 使用均方误差作为损失函数loss.to(device)return lossdef train(model, dataloader, optimizer):  # 定义训练函数model.train()  # 将模型设置为训练模式loader = tqdm.tqdm(dataloader)  # 创建进度条loss_epoch = 0  # 初始化损失值for idx, (data, label) in enumerate(loader):  # 遍历数据集data, label = data.float(), label.float()  # 将数据和标签转换为浮点数data, label = data.to(device), label.to(device)  # 使用GPUoutput = model(data)  # 模型前向传播optimizer.zero_grad()  # 清零梯度loss = l2_loss(output, label)  # 计算损失loss.backward()  # 反向传播optimizer.step()  # 更新模型参数loss_epoch += loss.detach().item()  # 累加损失loss_epoch /= len(loader)  # 计算平均损失return loss_epoch  # 返回平均损失def eval(model, dataloader):  # 定义评估函数model.eval()  # 将模型设置为评估模式loader = tqdm.tqdm(dataloader)  # 创建进度条loss_epoch = 0  # 初始化损失值for idx, (data, label) in enumerate(loader):  # 遍历数据集data, label = data.float(), label.float()  # 将数据和标签转换为浮点数data, label = data.to(device), label.to(device)  # 引入GPUoutput = model(data)  # 模型前向传播loss = l2_loss(output, label)  # 计算损失loss_epoch += loss.detach().item()  # 累加损失loss_epoch /= len(loader)  # 计算平均损失return loss_epoch  # 返回平均损失def main():  # 定义主函数dataset_train = StockDataset(file_path=stock_file, time_step=10)  # 创建训练数据集dataset_test = StockDataset(file_path=stock_file, time_step=10, train_flag=False)  # 创建测试数据集train_loader = DataLoader(dataset_train, batch_size=64, shuffle=True)  # 创建训练数据加载器test_loader = DataLoader(dataset_test, batch_size=64, shuffle=False)  # 创建测试数据加载器model = RNN(rnn_layer=2, input_size=1, hidden_size=4)  # 实例化RNN模型model = model.to(device)  # 引入GPUoptimizer = torch.optim.Adam(model.parameters(), lr=1e-3)  # 创建Adam优化器total_epoch = 3000  # 设置训练轮数for epoch_idx in range(total_epoch):  # 训练循环if epoch_idx % 50 == 0:  # 每50轮打印一次训练结果train_loss = train(model, train_loader, optimizer)  # 训练模型print("stage: train, epoch:{:5d}, loss:{}".format(epoch_idx, train_loss))  # 打印训练损失logger.add_scalar('Train/Loss', train_loss, epoch_idx)  # 记录训练损失if epoch_idx % 100 == 0:  # 每100轮评估一次模型eval_loss = eval(model, test_loader)  # 评估模型print("stage: test, epoch:{:5d}, loss:{}".format(epoch_idx, eval_loss))  # 打印测试损失torch.save(model.state_dict(), "{}/checkpoint_{:0>3}.ckpt".format(checkpointdir, epoch_idx))  # 保存模型检查点logger.add_scalar('Test/Loss', eval_loss, epoch_idx)  # 记录测试损失if __name__ == '__main__':main()  # 运行主函数

训练3000轮,每100轮记录一次训练参数:
训练结果如下:
在这里插入图片描述
然后我们对训练结果进行预测
选择2900这个最后训练的最优参数

代码如下:

# 导入所需的库
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import torch
import tqdm
from dataset.dataset_rnn_transformer import StockDataset
from torch.utils.data import DataLoader
from models import RNN# 定义股票数据文件的路径和模型检查点的路径
stock_file = '../stocks/shangzheng.csv'
loadckpt = '../checkpoints/RNN/checkpoint_2900.ckpt'def plot():# 加载测试数据集dataset_test = StockDataset(file_path=stock_file, time_step=10, train_flag=False)# 创建数据加载器,设置批量大小为64,不打乱数据顺序test_loader = DataLoader(dataset_test, batch_size=64, shuffle=False)# 使用tqdm库包装测试数据加载器,以显示进度条loader = tqdm.tqdm(test_loader)model = RNN()# 确定是否有可用的GPU,如果有,则使用GPU,否则使用CPUdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 使用weights_only=True来加载权重weights = torch.load(loadckpt, map_location=device, weights_only=True)# 加载模型权重到模型中model.load_state_dict(weights, strict=False)# 初始化预测结果和标签的列表preds = []labels = []# 遍历测试数据加载器中的所有数据for idx, (data, label) in enumerate(loader):# 将数据和标签转换为浮点数类型data, label = data.float(), label.float()# 使用模型进行预测output = model(data)# 将预测结果添加到列表中preds += (output.detach().tolist())# 将标签添加到列表中labels += (label.detach().tolist())# 创建绘图fig, ax = plt.subplots()# 生成x轴的数据,即预测结果的索引data_x = list(range(len(preds)))# 在图表上绘制预测结果,使用红色线条ax.plot(data_x[-60:], preds[-60:], label='RNN模型预测的股票收盘价', color='red')# 在图表上绘制实际标签,使用蓝色线条ax.plot(data_x[-60:], labels[-60:], label='实际的股票收盘价', color='blue')# 设置X轴标签ax.set_xlabel('索引号', fontsize=15)# 设置Y轴标签ax.set_ylabel('股票价格', fontsize=15)# 显示图例plt.legend()# 加入标题plt.title("RNN", fontsize=30, loc='center', color='red')# 显示图表plt.show()# 指定保存图表的路径save_path = 'plot_figure'base_filename = 'RNN_stock_prediction_plot'filename = os.path.join(save_path, f"{base_filename}.png")if os.path.exists(filename):counter = 1while os.path.exists(os.path.join(save_path, f"{base_filename}_{counter}.png")):counter += 1filename = os.path.join(save_path, f"{base_filename}_{counter}.png")plt.savefig(filename)plt.close()print(f"Plot saved as {filename}")# 如果这是主程序,则运行绘图函数
if __name__ == '__main__':plot()

于是就得到了预测结果:
在这里插入图片描述

2.LSTM在股市预测中的表现

模型:

class LSTM(nn.Module):def __init__(self, lstm_layer=2, input_dim=1, hidden_size=8):super(LSTM, self).__init__()self.hidden_size = hidden_sizeself.lstm_layer = lstm_layerself.lstm = nn.LSTM(input_size=input_dim,hidden_size=hidden_size,num_layers=self.lstm_layer,batch_first=True)self.out_layer = nn.Linear(hidden_size, input_dim)def init_hidden(self, x):batch_size = x.shape[0]init_h = (torch.zeros(self.lstm_layer, batch_size, self.hidden_size, device=x.device),torch.zeros(self.lstm_layer, batch_size, self.hidden_size, device=x.device))return init_hdef forward(self, x, h=None):h = h if h else self.init_hidden(x)output, hidden = self.lstm(x, h)out = self.out_layer(output[:, -1, :]).squeeze(1)return out

训练的代码类似于上面,就不赘述了
训练的参数如下:
在这里插入图片描述
同样制作图表,结果如下:
在这里插入图片描述
下面记录一下在处理LSTM模型时候,遇到的问题:

  1. 错误: RuntimeError: input.size(-1) must be equal to input_size. Expected 1, got 8 表明您的 LSTM 层期望的输入特征维度是 1,但是实际上接收到的输入特征维度是 8。
    这个问题通常是由于以下几个原因造成的:
  2. 数据预处理:StockDataset 类返回的数据形状可能不正确。您的 getitem 方法应该返回一个形状为 (time_step, input_dim) 的张量,其中 input_dim 是 1,因为您的 LSTM 模型的 input_dim 参数设置为 1。
  3. 模型定义:在 LSTM 类中,您定义了 self.emb_layer 来将输入特征维度从 input_dim(1)映射到 hidden_size(8)。然后,您将这个输出传递给 LSTM 层。但是,LSTM 层期望的输入特征维度仍然是 1。

为了解决这个问题,我们需要确保数据的形状与模型的期望输入相匹配。以下是解决方案:

  1. 步骤 1: 检查 StockDataset 的 getitem 方法
def __getitem__(self, idx):# 返回从idx开始的T个数据点和下一个时间点的值# 确保返回的数据形状是 (time_step, 1) seq = self.data[idx:idx + self.T]target = self.data[idx + self.T]return torch.tensor(seq, dtype=torch.float).view(-1, 1), torch.tensor(target, dtype=torch.float)
  1. 步骤 2: 调整 LSTM 类的定义
    由于您的 LSTM 层期望的输入特征维度是 1,您不需要 self.emb_layer 来改变输入特征维度。您可以直接将输入传递给 LSTM 层。
class LSTM(nn.Module):def __init__(self, lstm_layer=2, input_dim=1, hidden_size=8):super(LSTM, self).__init__()self.hidden_size = hidden_sizeself.lstm_layer = lstm_layerself.lstm = nn.LSTM(input_size=input_dim,hidden_size=hidden_size,num_layers=self.lstm_layer,batch_first=True)self.out_layer = nn.Linear(hidden_size, input_dim)def init_hidden(self, x):batch_size = x.shape[0]init_h = (torch.zeros(self.lstm_layer, batch_size, self.hidden_size, device=x.device),torch.zeros(self.lstm_layer, batch_size, self.hidden_size, device=x.device))return init_hdef forward(self, x, h=None):h = h if h else self.init_hidden(x)output, hidden = self.lstm(x, h)out = self.out_layer(output[:, -1, :]).squeeze(1)return out

3.Transformer在股市预测中的表现

模型:

class PositionalEncoding(nn.Module):def __init__(self, d_model, max_len=5000):  # 增加 max_len 的默认值,以适应更长的序列super(PositionalEncoding, self).__init__()pe = torch.zeros(max_len, d_model)position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))pe[:, 0::2] = torch.sin(position * div_term)pe[:, 1::2] = torch.cos(position * div_term)pe = pe.unsqueeze(0).transpose(0, 1)self.register_buffer('pe', pe)def forward(self, x):# 动态调整位置编码的长度以匹配输入张量 x 的长度pe = self.pe[:x.size(0), :]return x + pe# 定义一个函数,用于生成Transformer模型中的遮罩,以防止未来信息的泄露
def _generate_square_subsequent_mask(sz):# 创建一个上三角矩阵,用于遮罩未来信息mask = (torch.triu(torch.ones(sz, sz)) == 1).transpose(0, 1)# 将0值替换为负无穷,1值替换为0,以便于后续的计算mask = mask.float().masked_fill(mask == 0, float('-inf')).masked_fill(mask == 1, float(0.0))return mask# 定义Transformer模型
class Transformer(nn.Module):def __init__(self, feature_size=1, num_layers=4, dropout=0.1):super(Transformer, self).__init__()self.pos_encoder = PositionalEncoding(feature_size)self.encoder_layer = nn.TransformerEncoderLayer(d_model=feature_size,nhead=8,dropout=dropout,batch_first=True)self.transformer_encoder = nn.TransformerEncoder(self.encoder_layer, num_layers=num_layers)self.decoder = nn.Linear(feature_size, 1)  # 确保输出层的输出尺寸为 1self.init_weights()def init_weights(self):initrange = 0.1self.decoder.bias.data.zero_()self.decoder.weight.data.uniform_(-initrange, initrange)def forward(self, src):src = src.unsqueeze(2)src = self.pos_encoder(src)output = self.transformer_encoder(src)# 确保输出的尺寸与输入的批量大小一致output = self.decoder(output[:, -1, :])  # 只取序列的最后一个输出return output.squeeze(1)  # 压缩输出,移除多余的维度,以匹配最终的标签形状

对模型进行训练,同上
在这里插入图片描述
最后是结果:
在这里插入图片描述

4.结果分析与总结

以下是对结果的分析与探讨:

在这里插入图片描述
Total loss如下:

模型total Loss(损失函数:均方误差)
RNN0.0036613855459918716
LSTM0.0032446914311013604
Transformer0.017887676032642796

结果是显而易见的,RNN与LSTM在这种时序预测中的表现是比较好的,LSTM更优一些。Transformer是最差的。

1.为什么LSTM表现最好?

  1. 长期依赖问题:LSTM(长短期记忆网络)是为了解决RNN(循环神经网络)在处理长序列数据时遇到的梯度消失或梯度爆炸问题而设计的。LSTM通过引入门控机制(输入门、遗忘门、输出门)来控制信息的流动,有效地捕捉长期依赖关系。
  2. 参数共享:LSTM在时间序列的不同位置共享相同的参数,这使得模型能够学习到时间序列中不同位置的相同模式,提高了模型的泛化能力。
  3. 更好的梯度流:LSTM的设计允许梯度更有效地流动,减少了梯度消失或爆炸的问题,使得模型在训练过程中更加稳定。

2.Transformer表现差的原因包括:

  1. 对时序数据的适应性:Transformer最初是为处理自然语言处理任务设计的,它依赖于自注意力机制来捕捉序列中任意两个位置之间的关系。然而,这种机制可能不如RNN和LSTM那样自然地适应时序数据,特别是在股票价格预测这类具有明显时间序列特性的任务中。
  2. 缺乏时间序列特性的建模:Transformer没有像RNN和LSTM那样的循环结构,它不直接建模时间序列数据的顺序性,这可能导致它在捕捉时间序列数据的动态变化和趋势方面不如RNN和LSTM有效。
  3. 超参数调整和模型结构:Transformer模型的表现可能受到超参数设置和模型结构的影响。例如,如果Transformer的层数、头数或隐藏层大小没有针对特定的时序预测任务进行优化,可能会导致性能不佳。

3.RNN表现比LSTM差的原因:

  1. 梯度问题:传统的RNN由于其简单的循环结构,在处理长序列时容易出现梯度消失或爆炸的问题,导致模型难以学习到长期依赖关系。
  2. 参数更新问题:RNN在每个时间步更新参数时,是独立更新的,这可能导致模型难以捕捉到时间序列中的长期模式。

LSTM之所以比RNN表现好,主要是因为它通过门控机制有效地解决了长期依赖问题,并且能够更稳定地处理长序列数据,防止梯度爆炸和梯度消失。
而Transformer在股票价格预测这类时序预测任务中表现不佳,可能是因为它最初是为处理自然语言数据设计的,缺乏对时序数据的自然适应性,以及可能需要针对时序数据进行特定的结构和超参数调整。
因此,在实际应用中,选择合适的模型需要考虑任务的特性和数据的特点,以及模型的适应性和泛化能力。

总结

本周因为要准备考试和课程论文,进度缓慢,之后需要加快进度。
本周的工作主要集中在对物理信息神经网络(PINN)的理解和应用上,以及比较不同深度学习模型在股市预测任务中的表现。通过深入研究PINN,我们了解到其在物理现象模拟中的优势,尤其是在数据稀缺的情况下。在代码实战部分,我们通过比较RNN、LSTM和Transformer在股市预测中的表现,发现LSTM因其长短期记忆能力在时序预测任务中表现最佳。相反,Transformer由于其原始设计并非针对时序数据,因此在这类任务中表现不佳。此外,我们还讨论了RNN和LSTM在处理长序列数据时的梯度问题,以及LSTM如何通过门控机制解决这些问题。最后,文章指出了在实际应用中选择合适模型的重要性,需要考虑任务特性、数据特点以及模型的适应性和泛化能力。
下一周计划继续跑模型和深入的理解PINN。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com