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

PyTorch中自定义正则化逻辑回归(Module类)报错求解

问题分析与解决方案

错误直接原因

你遇到的Boolean value of Tensor with more than one value is ambiguous错误,是因为错误调用了nn.BCELoss类:nn.BCELoss(projected, actual)是把张量直接传给类的构造函数,而不是先实例化类再调用。BCELoss的构造函数会做参数合法性检查,触发了张量布尔值判断的歧义报错。正确做法是先实例化BCELoss(比如bce = nn.BCELoss()),再用bce(projected, actual)计算损失,或者用函数式的F.binary_cross_entropy。

隐藏的其他问题

除了直接报错的问题,你的代码还有几个破坏正则化逻辑的问题:

  • 把权重转成numpy(p.data.numpy())会断开PyTorch的计算图,导致正则化项无法参与反向传播,权重永远不会被正则化约束。
  • 惩罚项只在regularized_loss调用时计算一次,后续权重更新后不会重新计算,完全失去正则化效果。
  • 正则化项符号错误:应该加惩罚项(最小化总损失=分类损失+正则化惩罚),你写成减会鼓励权重变大,反而加剧过拟合。

修正方案(符合Module练习需求)

推荐把正则化逻辑整合到RegularizedLogistic模块中,这更符合PyTorch的设计范式,也能满足你练习Module类的目标:

import torch
import torch.nn as nn
import torch.nn.functional as F

class RegularizedLogistic(nn.Module):
    def __init__(self, num_features, lambda_=0.1):
        super().__init__()
        self.num_features = num_features
        self.lambda_ = lambda_
        self.linear = nn.Linear(num_features, 1)

    def forward(self, x):
        return torch.sigmoid(self.linear(x))
    
    def compute_loss(self, y_pred, y_true):
        # 计算二元交叉熵损失
        bce_loss = F.binary_cross_entropy(y_pred, y_true)
        # 计算L2正则化惩罚项(仅针对权重,不含偏置)
        l2_penalty = (self.lambda_ / self.num_features) * torch.sum(self.linear.weight ** 2)
        # 总损失=分类损失+正则化惩罚
        return bce_loss + l2_penalty

# 用法示例
model = RegularizedLogistic(num_features=10, lambda_=0.1)  # 替换成你的特征数
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

# 训练步骤
y_predicted = model(x_train)
loss = model.compute_loss(y_predicted, y_train)
loss.backward()
optimizer.step()
optimizer.zero_grad()

另一种修正:保留原Module结构,修复损失函数

如果你不想修改Module类,也可以修正regularized_loss函数的写法,确保计算图完整且动态更新惩罚项:

def regularized_loss(lambda_, model):
    bce_criterion = nn.BCELoss()  # 先实例化BCELoss类
    def compute_loss(projected, actual):
        # 直接使用模型的权重张量计算,避免转numpy
        w = model.linear.weight
        # 注意权重形状是(1, num_features),所以用shape[1]获取特征数
        punishment = (lambda_ / w.shape[1]) * torch.sum(w ** 2)
        return bce_criterion(projected, actual) + punishment
    return compute_loss

# 用法示例
model = RegularizedLogistic(num_features=10)
criterion = regularized_loss(0.1, model)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

y_predicted = model(x_train)
loss = criterion(y_predicted, y_train)
loss.backward()
optimizer.step()
optimizer.zero_grad()

总结

这个问题完全可以解决,和使用Module类无关,只是你的损失函数写法存在错误。把正则化逻辑整合到Module中是更优雅的实现方式,也完全符合你练习PyTorch Module类的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 04:27:14