用PyTorch拟合7×1小数据集时Loss不收敛,求3层感知机代码调整建议
3层感知机拟合小数据集Loss不收敛的调优思路
我尝试用3层感知机模型拟合一个7×1规模的小数据集,但Loss始终无法收敛,尝试过扩大或缩小模型规模都没有效果,恳请提供代码调整的思路提示。以下是我的代码:
import torch import torch.nn as nn import torch.nn.functional as F vec_shape = [7, 1] x_0 = [500, 1000, 2000, 4000, 5000, 8000, 10000] y_0 = [1.171467, 1.486507, 11.7738, 34.448421, 75.402871, 225.319848, 492.262426] # x = torch.tensor(x_0).reshape(vec_shape).float() x = torch.log(torch.tensor(x_0).reshape(vec_shape).float()) y = torch.tensor(y_0).reshape(vec_shape).float() class Net(nn.Module): def __init__(self,n_input,n_hidden,n_output): super(Net,self).__init__() self.hidden1 = nn.Linear(n_input,n_hidden) self.hidden2 = nn.Linear(n_hidden,n_hidden) self.predict = nn.Linear(n_hidden,n_output) def forward(self,input): out = self.hidden1(input) out = F.relu(out) out = self.hidden2(out) out = torch.sigmoid(out) out =self.predict(out) return out def weight_init(self): for op in self.modules(): if isinstance(op, nn.Linear): nn.init.normal_(op.weight.data) nn.init.normal_(op.bias.data) net = Net(1,10,1) net.weight_init() # print(net) optimizer = torch.optim.SGD(net.parameters(),lr = 0.1) loss_func = torch.nn.MSELoss() for t in range(500): prediction = net(x) loss = loss_func(prediction, y) optimizer.zero_grad() loss.backward() optimizer.step() if(t%50 == 0): print('Loss = %.4f' % loss.data)
代码调整思路:
- 修正激活函数组合:第二隐藏层后的
sigmoid激活函数会把输出限制在(0,1)区间,而标签y最大值超过400,这会导致最后一层线性层难以将小范围映射到目标数值,极易引发梯度消失。建议将sigmoid替换为ReLU/LeakyReLU,或直接去掉该激活函数。 - 对标签y做归一化处理:y的数值跨度从1到492,MSE损失会对大数值样本的误差给予更高权重,导致模型拟合失衡。可以用MinMax缩放将y缩至(0,1)区间,或标准化为均值0、方差1的分布,训练完成后再反变换还原数值。
- 更换优化器或调整学习率:SGD优化器对学习率敏感,0.1的学习率在小数据集上可能过大,导致参数震荡无法收敛。建议换成Adam优化器(自适应学习率能力更强),或把SGD的学习率降至0.01/0.001尝试。
- 优化权重初始化方式:当前的正态分布初始化不匹配ReLU激活函数的特性,对于ReLU应使用He初始化(
nn.init.kaiming_normal_),错误的初始化容易导致梯度消失或爆炸。 - 增加训练轮次:500轮的训练次数对于小数据集可能不足,可尝试将轮次提升至2000或5000轮,观察Loss变化趋势。
- 简化模型结构:3层感知机对于仅7个样本的数据集可能过于复杂,可先尝试简化为2层结构(去掉一个隐藏层),确认模型能否收敛后再逐步调整复杂度。
内容的提问来源于stack exchange,提问作者bin Pang
相关产品推荐
相关产品推荐

