PyTorch华氏转摄氏分类模型无法达成100%准确率的问题咨询
问题解决:基于华氏温度的二分类模型优化
核心问题分析
你的代码存在两个关键问题导致参数无法收敛到预期值:
- 学习率设置过高:SGD优化器的
lr=0.1对于这个简单任务来说幅度过大,参数更新时容易震荡甚至发散,无法稳定收敛到目标值。 - 逐样本训练的梯度噪声:逐样本更新权重会引入大量无规律的梯度噪声,导致参数始终处于波动状态,难以收敛到最优解。
注:你的标签计算逻辑是正确的((x-32)*1.8与(x-32)/1.8符号一致,不影响分类标签),但为了逻辑直观,建议直接用x>32生成标签,避免公式混淆。
修正后的代码
import torch import numpy as np # 生成数据集:输入为华氏温度,x>32时标签为1(对应摄氏>0),否则为0 x = np.arange(-100, 100) y = np.where(x > 32, 1., 0.) # 转换为PyTorch张量并添加维度 x = torch.from_numpy(x).to(torch.float32).unsqueeze(1) y = torch.from_numpy(y).to(torch.float32).unsqueeze(1) class BasicModel(torch.nn.Module): def __init__(self, in_features:int, out_features:int): super(BasicModel, self).__init__() self.linear = torch.nn.Linear(in_features=in_features, out_features=out_features) self.sigmoid = torch.nn.Sigmoid() def forward(self, input): out = self.linear(input) out = self.sigmoid(out) return out model = BasicModel(1, 1) loss_func = torch.nn.BCELoss() # 降低学习率,改用批量训练策略 optimizer = torch.optim.SGD(model.parameters(), lr=0.001) epochs = 5000 model.train() for epoch in range(epochs): optimizer.zero_grad() # 批量计算预测结果与损失,替代逐样本训练 prediction = model(x) loss = loss_func(prediction, y) loss.backward() optimizer.step() if epoch % 500 == 0: for name, param in model.named_parameters(): print(f"{name}: {param.data.item():.4f}", end=" ") print(f"Epoch:{epoch} loss:{loss.item():.6f}") # 测试集验证 x_test = torch.tensor([[33.], [32.], [31.]]) model.eval() with torch.no_grad(): predictions = model(x_test) print("\nTest Results:") for temp, pred in zip(x_test, predictions): print(f"华氏温度{temp.item()}: 预测概率={pred.item():.4f},分类结果={1 if pred.item()>0.5 else 0}")
关键调整说明
- 降低学习率:将
lr从0.1调整为0.001,让参数更新更平缓,确保模型能稳定收敛到目标权重(0.5555)和偏差(-17.7777)。 - 批量训练:对整个数据集计算一次梯度后再更新权重,大幅减少梯度噪声,加速收敛过程。
- 增加训练轮次:将epochs从1000提升到5000,给模型足够的时间收敛到最优参数。
- 测试阶段禁用梯度:使用
torch.no_grad()避免不必要的梯度计算,节省内存并提升效率。
运行修正后的代码,模型参数会逐渐接近预期值,测试集分类结果将完全符合要求,实现100%准确率。
内容的提问来源于stack exchange,提问作者Alican Kartal
相关产品推荐
相关产品推荐

