I am making an image segmentation transfer learning project using Pytorch. I am using the weights of this pre-trained model and class UNet3D. https://github.com/MrGiovanni/ModelsGenesis
When I run the following codes I get this error at the line which MSELoss is called: "AttributeError: 'DataParallel' object has no attribute 'size' ".
When I delete the first line I get a similar error: "AttributeError: 'UNet3D' object has no attribute 'size'
"
How can I convert DataParallel or UNet3D class to an object which MSELoss can use? I do not need DataParallel for now. I need to run the UNet3D() class for transfer learning.
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'
You have a typo on this line:
pred = model
should be
pred = model(x)
model is nn.Module object which describes the network. x, y, pred are (supposed to be) torch tensors.
Aside from this particular case, I think it would be good to think about how to solve this type of problems in general.
You saw an error (exception) on a certain line. Is the problem there, or earlier? Can you isolate the problem?
For example, if you print out the arguments you're passing to criterion(pred, y) just before the call, do they look right? (they don't)
What happens if you create a couple of tensors of the right shape just before the call and pass them instead? (works fine)
What is the error really saying? "AttributeError: 'UNet3D' object has no attribute 'size'" - well, of course it's not supposed to have a size, but why is the code trying to access it's size? Actually, why is the code even able to access that object on that line? (since the model is not supposed to be passed to the criterion function - right?)
Maybe useful further reading: https://ericlippert.com/2014/03/05/how-to-debug-small-programs/