大数跨境
0
0

通透!随机森林和 LSTM 对比 !!

通透!随机森林和 LSTM 对比 !! 机器学习和人工智能AI
2025-09-08
0

哈喽,大家好~

今儿咱们来聊聊Transformer 和 LSTM 的对比,序列建模方式、训练速度、任务适配性等等方面的比较~

首先,序列建模的核心问题,给定一个序列:

我们的目标是建模其条件分布:

即如何表示历史信息,并捕捉长程依赖。

LSTM:递归式记忆建模

LSTM 是 RNN 的改进型,通过引入门控机制,解决梯度消失/爆炸问题。

设输入为  ,隐藏状态为  ,细胞状态为 

  • 输入门
  • 遗忘门
  • 输出门
  • 候选记忆
  • 状态更新
  • 隐藏状态

LSTM 具有序列依赖,必须按时间步展开,训练不可并行。

记忆长度有限:虽然能比普通 RNN 更长,但仍难以捕捉远距离依赖。

适配性:适合中短期依赖任务(如语音、时间序列预测)。

Transformer:注意力驱动的全局建模

Transformer 直接通过 自注意力机制 (Self-Attention) 来建模全局依赖,不依赖递归。

自注意力机制,输入序列嵌入表示为 

映射到 Query, Key, Value:

其中 

注意力权重:

多头注意力:

其中

Transformer,并行训练,所有位置并行计算注意力,大幅提升训练速度。全局依赖方面,理论上一次即可捕获任意远距离的关系。

任务适配性上,在 NLP、CV、时间序列预测、强化学习等多模态任务上都表现优越。

训练速度与计算复杂度对比

模型
依赖性
并行性
单步复杂度
序列复杂度
长程依赖
LSTM
时间步递归
不可并行
较弱
Transformer
全局注意力
完全并行
极强
  • LSTM:复杂度随序列长度线性,但因无法并行,训练瓶颈严重。
  • Transformer:复杂度是二次方  ,但 GPU 并行使其更快,尤其在长序列上更高效。

完整案例

我们生成一段由正弦波 + 随机噪声构成的序列,让模型预测下一个时间步的值。

LSTM:经典循环神经网络,适合顺序依赖明确的序列。

Transformer:通过自注意力机制捕获全局依赖,训练速度快,适合长序列。

这里,比较四方面的数据:

  1. 训练速度(每个 epoch 时间)
  2. 预测精度(MSE)
  3. 模型收敛情况(loss 曲线)
  4. 实际预测效果可视化(预测序列 vs 原始序列)
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader, Subset
import numpy as np
import matplotlib.pyplot as plt
import time

# 1. 数据集
class SineDataset(Dataset):
    def __init__(self, seq_len=20, size=1000):
        x = np.linspace(050, size)
        y = np.sin(x) + 0.1*np.random.randn(size)
        self.seq_len = seq_len
        self.data = []
        for i in range(len(y)-seq_len):
            seq = y[i:i+seq_len].astype(np.float32)
            target = y[i+seq_len].astype(np.float32)
            self.data.append((seq, target))  # 确保是 tuple
    def __len__(self):
        return len(self.data)
    def __getitem__(self, idx):
        seq, target = self.data[idx]
        return torch.tensor(seq), torch.tensor(target)

seq_len = 20
dataset = SineDataset(seq_len)

# 切分训练集和测试集
train_dataset = Subset(dataset, range(800))
test_dataset = Subset(dataset, range(800, len(dataset)))

train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32)

# 2. 模型
class LSTMModel(nn.Module):
    def __init__(self, input_size=1, hidden_size=64, num_layers=2):
        super().__init__()
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size, 1)
    def forward(self, x):
        x = x.unsqueeze(-1)  # [B, seq_len, 1]
        out, _ = self.lstm(x)
        out = self.fc(out[:, -1, :])
        return out.squeeze()

class TransformerModel(nn.Module):
    def __init__(self, seq_len=20, d_model=64, nhead=4, num_layers=2):
        super().__init__()
        self.pos_emb = nn.Parameter(torch.randn(1, seq_len, d_model))
        self.input_fc = nn.Linear(1, d_model)
        encoder_layer = nn.TransformerEncoderLayer(d_model=d_model, nhead=nhead)
        self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=num_layers)
        self.fc_out = nn.Linear(d_model, 1)
    def forward(self, x):
        x = x.unsqueeze(-1)  # [B, seq_len, 1]
        x = self.input_fc(x) + self.pos_emb
        x = self.transformer(x)
        x = self.fc_out(x[:, -1, :])
        return x.squeeze()

# 3. 训练函数
def train_model(model, train_loader, test_loader, epochs=20, lr=0.001):
    optimizer = torch.optim.Adam(model.parameters(), lr=lr)
    criterion = nn.MSELoss()
    train_loss = []
    start_time = time.time()
    
    for epoch in range(epochs):
        model.train()
        epoch_loss = 0
        for seq, target in train_loader:
            optimizer.zero_grad()
            pred = model(seq)
            loss = criterion(pred, target)
            loss.backward()
            optimizer.step()
            epoch_loss += loss.item()
        train_loss.append(epoch_loss / len(train_loader))
    
    train_time = time.time() - start_time
    
    # 测试预测
    model.eval()
    preds, targets = [], []
    with torch.no_grad():
        for seq, target in test_loader:
            pred = model(seq)
            preds.append(pred)
            targets.append(target)
    preds = torch.cat(preds).numpy()
    targets = torch.cat(targets).numpy()
    mse = np.mean((preds - targets)**2)
    
    return train_loss, train_time, preds, targets, mse

# 4. 实验
lstm_model = LSTMModel()
trans_model = TransformerModel(seq_len=seq_len)

lstm_loss, lstm_time, lstm_pred, lstm_true, lstm_mse = train_model(lstm_model, train_loader, test_loader)
trans_loss, trans_time, trans_pred, trans_true, trans_mse = train_model(trans_model, train_loader, test_loader)

print(f"LSTM MSE: {lstm_mse:.4f}, Time: {lstm_time:.2f}s")
print(f"Transformer MSE: {trans_mse:.4f}, Time: {trans_time:.2f}s")

# 5. 可视化
fig, axs = plt.subplots(2,2, figsize=(14,10))

# 1) 训练损失对比
axs[0,0].plot(lstm_loss, label='LSTM Loss', color='orange', linewidth=2)
axs[0,0].plot(trans_loss, label='Transformer Loss', color='deepskyblue', linewidth=2)
axs[0,0].set_title("训练损失对比", fontsize=14)
axs[0,0].set_xlabel("Epoch")
axs[0,0].set_ylabel("MSE Loss")
axs[0,0].legend()

# 2) 训练速度对比
axs[0,1].bar(['LSTM','Transformer'], [lstm_time, trans_time], color=['orange','deepskyblue'])
axs[0,1].set_title("训练时间对比", fontsize=14)
axs[0,1].set_ylabel("Seconds per 20 Epochs")

# 3) 测试集预测效果
axs[1,0].plot(lstm_true, label='True', color='black', linewidth=2)
axs[1,0].plot(lstm_pred, label='LSTM Pred', color='orange', linestyle='--')
axs[1,0].plot(trans_pred, label='Transformer Pred', color='deepskyblue', linestyle=':')
axs[1,0].set_title("测试集预测对比", fontsize=14)
axs[1,0].legend()

# 4) 误差随时间变化
axs[1,1].plot(lstm_pred - lstm_true, label='LSTM Error', color='orange')
axs[1,1].plot(trans_pred - trans_true, label='Transformer Error', color='deepskyblue')
axs[1,1].set_title("模型误差随时间变化", fontsize=14)
axs[1,1].legend()

plt.tight_layout()
plt.show()

-1.png)

  1. 训练损失对比:展示两种模型的收敛速度和最终损失值。可看出 LSTM 收敛更快或达到更低 loss(取决于数据)。
  2. 训练时间对比:对比训练速度,通常 LSTM 在长序列上更快(可通过 GPU 并行优化)。
  3. 测试集预测效果:实际预测曲线对比真实值,直观感受预测精度。
  4. 误差随时间变化:展示误差波动情况,观察哪个模型对序列波动捕捉更稳定。

通过这个可视化的结果,能够清晰说明 Transformer vs LSTM 在时序建模上的差异,包括收敛速度、预测精度和误差波动。

大家也可以基于此,继续通过调整数据量或者参数进行实验~

最后

最近准备了16大块的内容,124个算法问题的总结,完整的机器学习小册,免费领取~
领取:备注「算法小册」即可~
如有问题,记得微信号试试:xiaobai_ml012

【声明】内容源于网络
0
0
机器学习和人工智能AI
让我们一起期待 AI 带给我们的每一场变革!推送最新行业内最新最前沿人工智能技术!
内容 333
粉丝 0
机器学习和人工智能AI 让我们一起期待 AI 带给我们的每一场变革!推送最新行业内最新最前沿人工智能技术!
总阅读388
粉丝0
内容333