PyTorch AttributeError: 'UNet3D' object has no attribute 'size'

PyTorch AttributeError: 'UNet3D' object has no attribute 'size'

我正在使用 Pytorch 进行图像分割迁移学习项目。我正在使用这个预训练模型和 class UNet3D 的权重。 https://github.com/MrGiovanni/ModelsGenesis

当我 运行 以下代码时,我在调用 MSELoss 的行收到此错误:“AttributeError: 'DataParallel' object has no attribute 'size'”.

当我删除第一行时,出现类似的错误:“AttributeError: 'UNet3D' object has no attribute 'size'

如何将 DataParallel 或 UNet3D class 转换为 MSELoss 可以使用的对象?我现在不需要 DataParallel。我需要 运行 UNet3D() class 进行迁移学习。

model = nn.DataParallel(model, device_ids = [i for i in range(torch.cuda.device_count())])
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), conf.lr, momentum=0.9, weight_decay=0.0, nesterov=False)
scheduler = lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)
initial_epoch=10
for epoch in range(initial_epoch, conf.nb_epoch):
    scheduler.step(epoch)
    model.train()
    for batch_ndx, (x,y) in enumerate(train_loader):
        x, y = x.float().to(device), y.float().to(device)
        pred = model
        loss = criterion(pred, y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-46-20d1943b3498> in <module>
     25         x, y = x.float().to(device), y.float().to(device)
     26         pred = model
---> 27         loss = criterion(pred, y)
     28         optimizer.zero_grad()
     29         loss.backward()

/opt/anaconda3/lib/python3.7/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    548             result = self._slow_forward(*input, **kwargs)
    549         else:
--> 550             result = self.forward(*input, **kwargs)
    551         for hook in self._forward_hooks.values():
    552             hook_result = hook(self, input, result)

/opt/anaconda3/lib/python3.7/site-packages/torch/nn/modules/loss.py in forward(self, input, target)
    430 
    431     def forward(self, input, target):
--> 432         return F.mse_loss(input, target, reduction=self.reduction)
    433 
    434 

/opt/anaconda3/lib/python3.7/site-packages/torch/nn/functional.py in mse_loss(input, target, size_average, reduce, reduction)
   2528                 mse_loss, tens_ops, input, target, size_average=size_average, reduce=reduce,
   2529                 reduction=reduction)
-> 2530     if not (target.size() == input.size()):
   2531         warnings.warn("Using a target size ({}) that is different to the input size ({}). "
   2532                       "This will likely lead to incorrect results due to broadcasting. "

/opt/anaconda3/lib/python3.7/site-packages/torch/nn/modules/module.py in __getattr__(self, name)
    592                 return modules[name]
    593         raise AttributeError("'{}' object has no attribute '{}'".format(
--> 594             type(self).__name__, name))
    595 
    596     def __setattr__(self, name, value):

AttributeError: 'UNet3D' object has no attribute 'size'

你在这行有错别字:

pred = model

应该是

pred = model(x)

model 是描述网络的 nn.Module 对象。 x、y、pred 是(应该是)火炬张量。

抛开这个特殊情况,我想想想一般如何解决这类问题。

您在某行看到错误(异常)。问题出在那里,还是更早?你能隔离问题吗?

例如,如果您在调用之前打印出传递给 criterion(pred, y) 的参数,它们看起来正确吗? (他们没有)

如果您在调用之前创建了几个正确形状的张量并传递它们,会发生什么情况? (工作正常)

错误 真的 说的是什么? “AttributeError: 'UNet3D' object has no attribute 'size'” - 嗯,当然它不应该有一个大小,但为什么代码试图访问它的大小?实际上,为什么代码甚至能够访问该行上的那个对象? (因为模型不应该传递给标准函数 - 对吧?)

进一步阅读可能有用:https://ericlippert.com/2014/03/05/how-to-debug-small-programs/