PyTorch搭建二分类模型报错Optimizer got an empty parameter list
PyTorch二分类模型报错
optimizer got an empty parameter list排查 核心报错原因
报错的直接诱因是自定义神经网络类的构造函数书写错误:Python中类的初始化方法是前后各带两个下划线的__init__,你的代码里写的是单下划线包裹的_init_,这个方法不会在类实例化时自动执行。
这就导致你在方法里定义的全连接层、激活层根本没有被注册到PyTorch的模型体系中,调用model.parameters()时拿不到任何可训练参数,优化器初始化时收到空的参数列表就直接抛出错误。
代码中其他会阻断运行的隐藏问题
修完上面的构造函数错误后,还有几处写法错误会导致后续运行失败,一并修正即可:
- 批数据切片逻辑写反:训练循环里取批次的代码
x_train[i:min(x_train.shape[0]),i+batch_size]维度完全错误,正确写法是按样本维度切分,即x_train[i:i+batch_size],标签同理。 - 存储训练损失误用
nn.ModuleList:ModuleList是用来注册网络子模块的容器,存损失数值用普通Python列表[]即可。 - 预测环节张量转numpy缺失处理:模型输出的是带梯度记录的PyTorch张量,直接传给
np.where会报错,需要先调用.detach().numpy()截断梯度、转为numpy数组再做阈值判断。
修正后关键代码片段
网络类定义
class neuralnetwork(nn.Module): # 注意构造方法是双下划线前后包裹 def __init__(self): super().__init__() torch.manual_seed(2020) self.fc1 = nn.Linear(64, 256) self.relu1 = nn.ReLU() self.fc2 = nn.Linear(256, 1024) self.relu2 = nn.ReLU() self.out = nn.Linear(1024, 1) self.final = nn.Sigmoid() def forward(self, x): op = self.fc1(x) op = self.relu1(op) op = self.fc2(op) op = self.relu2(op) op = self.out(op) y = self.final(op) return y
训练循环批处理部分
# 损失存储改用普通列表 loss_for_every_epoch=[] for epoch in range(num_epochs): train_loss=0.0 for i in range(0,x_train.shape[0],batch_size): # 修正切片逻辑 input_data=x_train[i:i+batch_size] labels=y_train[i:i+batch_size] optimizer.zero_grad() output_data=model(input_data) loss=loss_function(output_data,labels) loss.backward() optimizer.step() train_loss+=loss.item()*batch_size print("Epoch: {} - Loss:{:.4f}".format(epoch+1,train_loss )) loss_for_every_epoch.append(train_loss)
预测部分
# 先截断梯度再转numpy数组 y_test_prediction=model(x_test).detach().numpy() a=np.where(y_test_prediction>0.5,1,0)
内容的提问来源于stack exchange,提问作者David manga
相关产品推荐
相关产品推荐

