Python从0到100(一百):基于Transformer的时序数据建模与实现详解
在深度学习领域,Transformer 已经成为一种重要的模型架构,广泛应用于自然语言处理(NLP)、计算机视觉、时序数据建模等多个领域。Transformer 具有强大的建模能力,特别是在处理时序数据(如股票价格、气象数据、传感器数据等)时,展示了非常出色的性能。
本教程将从 0 到 100,基于 Transformer 架构,带你完整实现一个时序数据建模项目,最终构建一个时序数据预测模型。我们将使用 Python 和 PyTorch 完成这一过程。
一、Transformer 简介
Transformer 是一种 自注意力机制(Self-Attention Mechanism)为核心的神经网络架构,最早在 2017 年由 Vaswani 等人提出。与传统的 RNN 和 LSTM 模型相比,Transformer 完全不依赖序列顺序,而是通过自注意力机制并行处理整个序列。
Transformer 的关键组件:
- 自注意力机制(Self-Attention):衡量一个序列中的每个元素与其他元素之间的依赖关系。
- 位置编码(Positional Encoding):由于 Transformer 无法处理序列顺序信息,需要通过位置编码来传递顺序信息。
- 编码器(Encoder)与解码器(Decoder):分别用于编码输入序列和生成输出序列。
在本教程中,我们将使用 Transformer 的编码器 部分来处理时序数据。
二、任务概述
我们将使用 PyTorch 来实现基于 Transformer 的时序数据建模。我们选择一个简单的任务:时间序列预测。
假设我们有某个领域的时间序列数据(例如气象数据、股市数据等),我们的目标是根据过去的数据来预测未来的值。具体步骤如下:
- 数据预处理:加载并处理时序数据。
- 构建 Transformer 模型:基于 Transformer 的编码器实现时序数据建模。
- 训练与评估:训练模型并评估预测效果。
- 预测与结果可视化:对未来的数据进行预测,并展示结果。
三、环境准备
- 安装 PyTorch:
pip install torch torchvision torchaudio
- 安装其它依赖:
pip install numpy matplotlib pandas scikit-learn
四、数据集选择
在本教程中,我们以 股票价格数据 为例进行时序数据建模。可以从多个渠道获取数据,例如 Yahoo Finance。这里我们使用 yfinance
库来下载数据。
pip install yfinance
五、数据预处理
首先,我们需要下载并处理股票数据,选取一个具体的股票(例如 Apple, 股票代码 AAPL)。
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 下载 Apple 股票数据
stock_data = yf.download('AAPL', start='2010-01-01', end='2023-01-01')
# 选择收盘价格作为时序数据
stock_data = stock_data['Close']
# 绘制股票数据
plt.figure(figsize=(10,6))
plt.plot(stock_data)
plt.title("Apple Stock Price (2010-2023)")
plt.xlabel("Date")
plt.ylabel("Price")
plt.show()
数据标准化
由于神经网络对输入数据的范围敏感,我们需要对数据进行标准化处理,使其范围保持一致。
from sklearn.preprocessing import MinMaxScaler
# 将股票数据转换为 numpy 数组
stock_prices = stock_data.values.reshape(-1, 1)
# 使用 MinMaxScaler 进行标准化
scaler = MinMaxScaler(feature_range=(0, 1))
stock_prices_scaled = scaler.fit_transform(stock_prices)
# 将数据转换回 pandas DataFrame 便于操作
stock_prices_scaled = pd.DataFrame(stock_prices_scaled, columns=['Price'])
# 查看前几行数据
stock_prices_scaled.head()
六、创建训练和测试集
为了训练模型,我们需要将时间序列数据分成输入和输出(标签)。我们会根据过去 n
天的股票价格来预测未来的一天价格。
def create_dataset(data, time_step=60):
X, y = [], []
for i in range(len(data) - time_step - 1):
X.append(data[i:(i + time_step), 0])
y.append(data[i + time_step, 0])
return np.array(X), np.array(y)
# 设置时间步长
time_step = 60
# 创建训练集和测试集
X, y = create_dataset(stock_prices_scaled.values, time_step)
# 分割为训练集和测试集(80% 用于训练,20% 用于测试)
train_size = int(len(X) * 0.8)
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]
# 将输入数据调整为适合 LSTM 模型的形状
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)
X_test = X_test.reshape(X_test.shape[0], X_test.shape[1], 1)
七、构建 Transformer 模型
接下来,我们将使用 PyTorch 构建 Transformer 模型。我们的模型将包括:
- 输入层:接收过去的时间步长(
time_step
)。 - Transformer 编码器:进行时序数据建模。
- 输出层:输出预测结果。
import torch
import torch.nn as nn
class TransformerModel(nn.Module):
def __init__(self, input_size=1, hidden_size=64, num_layers=2, num_heads=8, output_size=1):
super(TransformerModel, self).__init__()
# 定义 Transformer 编码器
self.encoder_layer = nn.TransformerEncoderLayer(
d_model=hidden_size, nhead=num_heads, batch_first=True
)
self.transformer_encoder = nn.TransformerEncoder(self.encoder_layer, num_layers=num_layers)
# 全连接层
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
# 通过 Transformer 编码器
x = self.transformer_encoder(x)
# 取最后时间步的输出进行预测
x = self.fc(x[:, -1, :])
return x
# 初始化模型
model = TransformerModel(input_size=1, hidden_size=64, num_layers=2, num_heads=8, output_size=1)
八、训练模型
训练模型时,我们使用 均方误差损失函数(MSELoss)和 Adam 优化器。
# 损失函数和优化器
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
# 转换数据为 torch 张量
X_train_tensor = torch.tensor(X_train, dtype=torch.float32)
y_train_tensor = torch.tensor(y_train, dtype=torch.float32)
# 训练模型
num_epochs = 100
for epoch in range(num_epochs):
model.train()
# 前向传播
outputs = model(X_train_tensor)
loss = criterion(outputs.squeeze(), y_train_tensor)
# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch+1) % 10 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
九、评估模型与预测
训练完成后,我们使用测试集对模型进行评估。
# 测试数据
X_test_tensor = torch.tensor(X_test, dtype=torch.float32)
y_test_tensor = torch.tensor(y_test, dtype=torch.float32)
# 预测
model.eval()
with torch.no_grad():
predicted = model(X_test_tensor).squeeze().numpy()
# 反向标准化预测数据
predicted = scaler.inverse_transform(predicted.reshape(-1, 1))
# 绘制预测结果
plt.figure(figsize=(10, 6))
plt.plot(stock_data.index[train_size+time_step:], stock_data.values[train_size+time_step:], color='blue', label='Actual Price')
plt.plot(stock_data.index[train_size+time_step:], predicted, color='red', label='Predicted Price')
plt.title("Stock Price Prediction (Transformer)")
plt.xlabel("Date")
plt.ylabel("Price")
plt.legend()
plt.show()
十、总结
通过本教程,你已经学习了如何使用 Transformer 模型 来进行时序数据建模与预测。我们涵盖了数据的加载、处理、模型构建、训练和预测等多个步骤。Transformer 模型凭借其强大的建模能力,能够有效地处理时序数据,并为预测任务提供强大的支持。
如果你有进一步的优化需求,可以尝试:
- 调整模型的超参数,如隐藏层维度、层数、头数等。
- 使用不同类型的时序数据
,如气象数据、销售数据等。
3. 结合其它技术(如长短期记忆网络LSTM、GRU等)进行模型融合。
希望本教程对你有所帮助!
发表回复