PyTorch中D-Linear模型训练时输出与目标形状不匹配报错
问题分析
你的报错核心是模型输出包含了所有输入特征的预测值,但你只需要目标变量的n步预测。示例代码用5列输入时,模型输出维度为[batch_size, seq_len, 5],而目标仅对应1列,维度是[batch_size, seq_len],两者自然无法对齐。
解决方案
1. 数据集预处理:明确拆分特征与目标序列
构造时序样本时,要严格区分输入(历史特征+目标)和标签(未来目标):
def create_dataset(data, seq_len, n_step): X, y = [], [] # 遍历生成样本,确保输入包含所有16列,标签仅取目标列(第16列,索引为15) for i in range(len(data) - seq_len - n_step + 1): X.append(data[i:i+seq_len, :]) # 输入:历史seq_len步的16列数据 y.append(data[i+seq_len:i+seq_len+n_step, 15]) # 标签:未来n_step步的目标变量 return torch.tensor(X, dtype=torch.float32), torch.tensor(y, dtype=torch.float32)
2. 修改D-Linear模型:只输出目标变量的预测值
原D-Linear默认对每一列特征做预测,你需要调整模型结构,只针对目标列输出n步结果:
方案一:仅用目标列历史数据做预测
如果不需要其他特征辅助,直接提取目标列的历史序列训练:
class DLinear(nn.Module): def __init__(self, seq_len, pred_len, input_dim=16, target_idx=15): super().__init__() self.seq_len = seq_len self.pred_len = pred_len self.target_idx = target_idx # 仅针对目标列的时序序列做线性变换 self.linear_trend = nn.Linear(seq_len, pred_len) self.linear_seasonal = nn.Linear(seq_len, pred_len) def forward(self, x): # 提取目标列的历史序列:[batch, seq_len] target_seq = x[:, :, self.target_idx] trend = self.linear_trend(target_seq) # [batch, pred_len] seasonal = self.linear_seasonal(target_seq) # [batch, pred_len] return trend + seasonal # 输出形状:[batch, pred_len]
方案二:利用所有特征辅助目标预测
如果需要结合15个特征提升精度,可先对所有特征做时序分解,再融合结果输出目标预测:
class DLinearMultiFeat(nn.Module): def __init__(self, seq_len, pred_len, input_dim=16): super().__init__() self.seq_len = seq_len self.pred_len = pred_len # 为每个特征列定义时序分解层 self.trend_layers = nn.ModuleList([nn.Linear(seq_len, pred_len) for _ in range(input_dim)]) self.seasonal_layers = nn.ModuleList([nn.Linear(seq_len, pred_len) for _ in range(input_dim)]) # 融合所有特征的分解结果,输出目标预测 self.fusion = nn.Linear(input_dim, 1) def forward(self, x): trend_outputs, seasonal_outputs = [], [] # 对每个特征列做时序分解 for i in range(x.shape[2]): feat_seq = x[:, :, i] trend_outputs.append(self.trend_layers[i](feat_seq).unsqueeze(-1)) seasonal_outputs.append(self.seasonal_layers[i](feat_seq).unsqueeze(-1)) # 合并所有特征的分解结果:[batch, pred_len, input_dim] trend_all = torch.cat(trend_outputs, dim=-1) seasonal_all = torch.cat(seasonal_outputs, dim=-1) # 融合后得到目标预测,压缩维度至[batch, pred_len] output = self.fusion(trend_all + seasonal_all).squeeze(-1) return output
3. 训练循环:确认维度匹配
训练时打印关键张量的形状,确保模型输出和目标的维度一致:
criterion = nn.MSELoss() for epoch in range(epochs): model.train() pred = model(x_train) # 打印形状验证:pred.shape应为[batch_size, n_step],y_train.shape同理 # print(pred.shape, y_train.shape) loss = criterion(pred, y_train) # 后续优化步骤(反向传播、更新参数)...
内容的提问来源于stack exchange,提问作者ianux22
相关产品推荐
相关产品推荐

