You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在样本总数非批量整数倍时实现神经网络批量训练?

问题分析与解决方案

核心错误修正

你当前模型的致命问题是:最后一层nn.Linear(356, batch_size)把输出维度固定成了批量大小,这完全违背了任务逻辑。模型的输出维度只和你的任务目标(标签)维度相关,和batch_size没有任何关系:

  • 若为回归任务,输出维度是1(单变量回归)或目标变量的数量;
  • 若为分类任务,输出维度是类别总数(比如10分类就设为10)。

举个回归任务的示例,正确的模型结构如下:

batch_size = 30
n_inputs = X.size[1]  # 2377
n_outputs = 1  # 根据任务调整,分类任务改成对应类别数

# 2 hidden layers
model = nn.Sequential(
    nn.Linear(n_inputs, 1024),
    nn.ReLU(),
    nn.Linear(1024, 512),
    nn.ReLU(),
    nn.Linear(512, 356),
    nn.ReLU(),
    nn.Linear(356, n_outputs),
    # 分类任务可按需添加nn.Softmax(dim=1),需配合对应损失函数
)

通用批量训练方案

手动编写批量循环容易出错,推荐直接使用PyTorch内置的Dataset和DataLoader,它们会自动处理样本打乱、批量划分,包括最后一批样本数量不足的情况。

步骤1:定义自定义数据集

import torch
from torch.utils.data import Dataset, DataLoader

class CustomDataset(Dataset):
    def __init__(self, x_data, y_data):
        self.x = x_data
        self.y = y_data
        
    def __len__(self):
        return len(self.x)
    
    def __getitem__(self, idx):
        return self.x[idx], self.y[idx]

步骤2:构建数据加载器

# 实例化数据集
dataset = CustomDataset(X, y)

# 构建DataLoader,shuffle=True表示每个epoch打乱样本顺序
# drop_last=False(默认)保留最后一批不足batch_size的样本,设为True则丢弃
dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)

步骤3:简化训练循环

optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
criterion = torch.nn.MSELoss()  # 回归用MSELoss,分类用CrossEntropyLoss等

for epoch in range(5):
    totalloss = 0.0
    model.train()  # 切换到训练模式
    for batch_x, batch_y in dataloader:
        optimizer.zero_grad()
        
        ypred = model(batch_x)
        # 确保输出与标签维度匹配:若标签是(N,)而输出是(N,1),用unsqueeze(1)调整
        loss = criterion(ypred, batch_y.unsqueeze(1) if len(batch_y.shape)==1 else batch_y)
        # 累计总损失时乘以当前batch样本数,避免最后一批权重偏低
        totalloss += loss.item() * batch_x.size(0)
        
        loss.backward()
        optimizer.step()
    
    # 打印每个epoch的平均损失
    avg_loss = totalloss / len(dataset)
    print(f"Epoch {epoch+1}, Average Loss: {avg_loss:.4f}")

额外注意事项

  • 确保X和y都是PyTorch张量类型,若为numpy数组,用torch.from_numpy()转换;
  • 若标签维度与模型输出不匹配,可在Dataset中提前调整,或在训练循环中用unsqueeze/squeeze修正;
  • 若不需要保留最后一批不足批量的样本,在DataLoader中设置drop_last=True即可。

内容的提问来源于stack exchange,提问作者Mirk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 09:35:24