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

如何将Optimizer定义为PyTorch类的属性?解决AttributeError报错

问题解决:AttributeError: 'PneumoniaModel' object has no attribute 'optimizer'

错误原因分析

  1. 构造函数名称错误:Python类的构造函数必须是__init__(前后各两个下划线),你代码里写的是_init_(单下划线),导致构造函数完全没执行,self.optimizer等属性根本没被创建。
  2. Lightning使用规范问题:即使构造函数正确,也不应该在__init__里初始化优化器——PyTorch Lightning需要通过configure_optimizers方法管理优化器的创建与返回,这样才能正确处理设备迁移、分布式训练等场景。

修正后的完整代码

import torch
import torchvision
import pytorch_lightning as pl
from torchmetrics import Accuracy

class PneumoniaModel(pl.LightningModule):
    def __init__(self):
        super().__init__()
        self.model = torchvision.models.resnet18()
        # 修正Conv2d的大写C
        self.model.conv1 = torch.nn.Conv2d(1, 64, kernel_size=(7,7), stride=(2,2), padding=(3,3), bias=False)
        self.model.fc = torch.nn.Linear(in_features=512, out_features=1, bias=True)

        # 修正BCEWithLogitsLoss的大写L
        self.loss_fn = torch.nn.BCEWithLogitsLoss(pos_weight=torch.tensor([3]))

        self.train_acc = Accuracy(task="binary")
        self.val_acc = Accuracy(task="binary")

        # 初始化训练/验证步骤的输出列表,避免后续报错
        self.training_step_outputs = []
        self.validation_step_outputs = []

    def forward(self, data):
        pred = self.model(data)
        return pred

    def training_step(self, batch, batch_idx):
        x_ray, label = batch
        label = label.float()
        pred = self(x_ray)[:,0]
        loss = self.loss_fn(pred, label)

        # 保存loss用于epoch平均计算
        self.training_step_outputs.append(loss)
        
        self.log("Train_Loss", loss)
        self.log("Step Train ACC", self.train_acc(torch.sigmoid(pred), label.int()))

        return loss

    def on_train_epoch_end(self):
        epoch_average = torch.stack(self.training_step_outputs).mean()
        self.log("training_epoch_average", epoch_average)
        self.training_step_outputs.clear()  # 释放内存

    def validation_step(self, batch, batch_idx):
        x_ray, label = batch
        label = label.float()
        pred = self(x_ray)[:,0]
        loss = self.loss_fn(pred, label)

        # 保存loss用于epoch平均计算
        self.validation_step_outputs.append(loss)
        
        self.log("Val Loss", loss)
        self.log("Step Val ACC", self.val_acc(torch.sigmoid(pred), label.int()))

    def on_validation_epoch_end(self):
        epoch_average = torch.stack(self.validation_step_outputs).mean()
        self.log("validation_epoch_average", epoch_average)
        self.validation_step_outputs.clear()  # 释放内存

    def configure_optimizers(self):   
        # 直接在该方法内创建并返回优化器
        return torch.optim.Adam(self.model.parameters(), lr=1e-4)

额外修正说明

  • 修正了torch.nn.conv2d为torch.nn.Conv2d(类名首字母大写)
  • 修正了BCEWithlogitsLoss为BCEWithLogitsLoss(类名首字母大写)
  • 初始化了training_step_outputs和validation_step_outputs列表,避免on_train_epoch_end和on_validation_epoch_end中调用stack时出错
  • 更新了Accuracy的初始化方式,添加task="binary"适配二分类场景(torchmetrics v0.10+版本要求)

内容的提问来源于stack exchange,提问作者ashrafghani afrah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:07:07