Transformer 例子
据说很好用,先写一个例子看看:
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
# 构造简单的时间序列数据集
def generate_time_series():
time = np.arange(0, 100, 0.1)
amplitude = np.sin(time)
return amplitude
# 将时间序列数据转换为序列样本
def create_sequences(data, seq_length):
sequences = []
for i in range(len(data) - seq_length):
seq = data[i:i + seq_length]
label = data[i + seq_length]
sequences.append((seq, label))
return sequences
# 定义 Transformer 模型
class TransformerModel(nn.Module):
def __init__(self, input_size, output_size, num_layers, heads, hidden_size):
super(TransformerModel, self).__init__()
self.encoder_layer = nn.TransformerEncoderLayer(d_model=input_size, nhead=heads, dim_feedforward=hidden_size)
self.transformer_encoder = nn.TransformerEncoder(self.encoder_layer, num_layers=num_layers)
self.decoder = nn.Linear(input_size, output_size)
def forward(self, src):
src = src.unsqueeze(0) # 添加批次维度
output = self.transformer_encoder(src)
output = self.decoder(output[-1]) # 取最后一个时间步的输出
return output
# 定义训练函数
def train(model, criterion, optimizer, epochs, train_loader):
model.train()
for epoch in range(epochs):
running_loss = 0.0
for inputs, labels in train_loader:
optimizer.zero_grad()
outputs = model(inputs.float())
loss = criterion(outputs.squeeze(), labels.float())
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f"Epoch {epoch+1}/{epochs}, Loss: {running_loss}")
# 设置随机种子,保证实验的可复现性
torch.manual_seed(0)
np.random.seed(0)
# 生成时间序列数据并创建序列样本
data = generate_time_series()
seq_length = 10
sequences = create_sequences(data, seq_length)
# 将序列样本划分为训练集和测试集
train_size = int(len(sequences) * 0.8)
train_data = sequences[:train_size]
test_data = sequences[train_size:]
# 准备训练数据加载器
train_loader = torch.utils.data.DataLoader(train_data, batch_size=32, shuffle=True)
# 定义模型和优化器
model = TransformerModel(input_size=seq_length, output_size=1, num_layers=2, heads=2, hidden_size=128)
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
# 训练模型
train(model, criterion, optimizer, epochs=20, train_loader=train_loader)
# 测试模型
model.eval()
# 测试所有测试数据
test_inputs = torch.tensor([test_data[i][0] for i in range(len(test_data))]).float()
with torch.no_grad():
predicted = model(test_inputs).squeeze().numpy()
test_labels = [test_data[i][1] for i in range(len(test_data))]
# 可视化预测结果
plt.plot(predicted, label='predicted')
plt.plot(test_labels, label='test')
plt.legend()
plt.show()
浙公网安备 33010602011771号