You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PyTorch构建逻辑回归模型时遇"optimizer got an empty parameter list"错误求助

PyTorch构建逻辑回归模型时遇"optimizer got an empty parameter list"错误求助

嗨,我来帮你排查这个问题~ 这个报错的核心原因和你模型的初始化逻辑、代码缩进都有关系,咱们一步步来解决:

1. 报错的根本原因

当你创建LogisticRegressionModel实例时如果没传input_dim__init__里会把self.linear设为None。这时候你去创建SGD优化器,调用model.parameters()会返回空列表——因为PyTorch此时还没识别到任何可训练的层(self.linear要等到第一次调用forward才会被实例化),优化器自然就报错了。

另外我注意到你代码里的缩进有严重问题forward方法被错误地嵌套在__init__else代码块里了!这会导致forward不是类的方法,模型实例根本无法正常执行前向传播,这也是必须先修正的问题。

2. 完整的修正方案

第一步:先修正模型的代码缩进

forward方法的缩进调整到和__init__同一级别,确保它是类的成员方法:

import torch
import torch.nn as nn
import torch.optim as optim
from torch import Tensor

class LogisticRegressionModel(nn.Module):
    def __init__(self, input_dim=None) -> None:
        super().__init__()
        if input_dim is not None:
            torch.manual_seed(9)
            self.linear = nn.Linear(in_features=input_dim, out_features=1)
        else:
            self.linear = None
            self.input_dim = None  # 这里的缩进要正确,属于else块
    
    # 注意这里的缩进,和__init__平级
    def forward(self, X: Tensor):
        if self.linear is None:
            input_dim = X.shape[1]
            torch.manual_seed(9)
            self.linear = nn.Linear(in_features=input_dim, out_features=1)
        return torch.sigmoid(self.linear(X))

第二步:解决优化器空参数列表的问题

这里给你两种可选方案:

方案A:提前指定输入维度(推荐,更直观)

初始化模型时直接传入input_dim,这样self.linear__init__阶段就被创建,优化器能直接拿到可训练参数:

# 假设你的输入数据维度是10,根据实际情况替换
model = LogisticRegressionModel(input_dim=10)
# 现在创建优化器就不会报错了
optimizer = optim.SGD(params=model.parameters(), lr=0.001)

方案B:支持延迟初始化(适合不想提前指定维度的场景)

如果确实想让模型自动从输入数据中识别维度,那需要在创建优化器之前,先给模型喂一个dummy数据触发forward,提前初始化self.linear层:

model = LogisticRegressionModel()
# 生成一个和训练数据同维度的虚拟输入(比如batch_size=1,输入维度=10)
dummy_X = torch.randn(1, 10)
# 执行一次前向传播,让模型初始化linear层
model(dummy_X)
# 现在再创建优化器就能获取到参数了
optimizer = optim.SGD(params=model.parameters(), lr=0.001)

3. 额外的优化建议

你当前用的是BCEWithLogitsLoss,这个损失函数本身已经包含了sigmoid的计算逻辑,而你的模型forward里又手动加了torch.sigmoid(),这样会导致两次sigmoid计算,不仅冗余还可能引发数值不稳定的问题。建议修改forward的返回值,去掉手动的sigmoid:

def forward(self, X: Tensor):
    if self.linear is None:
        input_dim = X.shape[1]
        torch.manual_seed(9)
        self.linear = nn.Linear(in_features=input_dim, out_features=1)
    return self.linear(X)  # 直接返回线性层的输出,交给BCEWithLogitsLoss处理

这样调整后,你的模型不仅能解决报错,训练效率和数值稳定性也会更好~

火山引擎 最新活动