【问题标题】:ModuleAttributeError: 'Model' object has no attribute 'predict'ModuleAttributeError:“模型”对象没有属性“预测”
【发布时间】:2021-12-14 17:04:00
【问题描述】:

我正在解决我使用 pytorch-lightning 和 swin Transformer 的问题,但是当我尝试在新数据上测试我的模型时,我收到了一个错误:

model = Model(config) 
model.load_state_dict(torch.load(f'{config.model.name}/default/version_0/checkpoints/best_loss.ckpt')['state_dict'])
model = model.cuda().eval()
test_dataset = PetfinderDataModule(test, test)
test_predictions = model.predict(test_dataset)

这是模型类,它继承自 LightningModule:

class Model(pl.LightningModule):
   def __init__(self, cfg):
       super().__init__()
       self.cfg = cfg
       self.__build_model()
       self._criterion = eval(self.cfg.loss)()
       self.transform = get_default_transforms()
       self.save_hyperparameters(cfg)

   def __build_model(self):
       self.backbone = create_model(
           self.cfg.model.name, pretrained=True, num_classes=0, in_chans=3
       )
       num_features = self.backbone.num_features
       self.fc = nn.Sequential(
           nn.Dropout(0.5), nn.Linear(num_features, self.cfg.model.output_dim)
       )
   def forward(self, x):
       f = self.backbone(x)
       out = self.fc(f)
       return out

   def training_step(self, batch, batch_idx):
       loss, pred, labels = self.__share_step(batch, 'train')
       return {'loss': loss, 'pred': pred, 'labels': labels}
       
   def validation_step(self, batch, batch_idx):
       loss, pred, labels = self.__share_step(batch, 'val')
       return {'pred': pred, 'labels': labels}

   def __share_step(self, batch, mode):
       images, labels = batch
       labels = labels.float() / 100.0
       images = self.transform(images)
       
       logits = self.forward(images).squeeze(1)
       loss = self._criterion(logits, labels)
       
       pred = logits.sigmoid().detach().cpu() * 100.
       labels = labels.detach().cpu() * 100.
       return loss, pred, labels
       
   def training_epoch_end(self, outputs):
       self.__share_epoch_end(outputs, 'train')

   def validation_epoch_end(self, outputs):
       self.__share_epoch_end(outputs, 'val')
   def __share_epoch_end(self, outputs, mode):
       preds = []
       labels = []
       for out in outputs:
           pred, label = out['pred'], out['labels']
           preds.append(pred)
           labels.append(label)
       preds = torch.cat(preds)
       labels = torch.cat(labels)
       metrics = torch.sqrt(((labels - preds) ** 2).mean())
       self.log(f'{mode}_loss', metrics)

   def configure_optimizers(self):
       optimizer = eval(self.cfg.optimizer.name)(
           self.parameters(), **self.cfg.optimizer.params
       )
       scheduler = eval(self.cfg.scheduler.name)(
           optimizer,
           **self.cfg.scheduler.params
       )
       return [optimizer], [scheduler]

然后它给了我以下错误:

ModuleAttributeError:“模型”对象没有属性“预测”

我也试过了:

test_predictions = model(test_dataset)

但是出现了一个新的错误:

AttributeError: 'PetfinderDataModule' 对象没有属性 'shape'

【问题讨论】:

    标签: python pytorch predict pytorch-lightning


    【解决方案1】:

    PyTorch (nn.Module.forward)PyTorchLightning (LightningModule) 中(基本上只抽象了文档中说明的训练和推理细节:

    注意一些事情。

    1. 代码相同。
    2. PyTorch 代码不是抽象的 - 只是有组织的。
    3. LightningModule 中未包含的所有其他代码均已由培训师自动为您完成。

    ) 没有 predict 函数。当您调用模型对象时,即model(...),它会调用模型的__call__,而后者又会返回forward 函数。

    因此,model.predict(test_dataset) 应该是 model(test_dataset)。但是,我不知道PetfinderDataModule 是什么,在搜索引擎上查询它不会返回任何有用的结果。

    话虽如此,正如@Ivan 所说,如果您/可以使用Trainer,则有Trainer.predict(返回模型的forward 输出)

    【讨论】:

    • 虽然有Trainer.predict
    • 感谢您提及此@Ivan;我会更新我的答案。它也恰好调用了forward
    猜你喜欢
    • 2022-06-16
    • 2019-10-05
    • 2021-04-15
    • 1970-01-01
    • 2021-04-11
    • 2012-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多