同形状张量仍触发TypeError:'int'对象不可调用问题求助
解决PyTorch MSELoss报错:TypeError: 'int' object is not callable
我最近在训练模型时碰到了一个让人困惑的问题:明明打印出来的predicted和target形状完全一致(都是torch.Size([6890, 3])),但使用nn.MSELoss()计算损失时却抛出了类型错误。以下是我的错误信息、代码片段和最终的解决思路:
错误信息
报错堆栈如下:
Traceback (most recent call last): File "train.py", line 251, in <module> main() File "train.py", line 230, in main train(net, training_dataset, targets, device, criterion, optimizer, epoch, args.epochs) File "train.py", line 101, in train loss = criterion(predicted, target.detach().cpu().numpy()) File "/home/hb119056/.local/lib/python3.6/site-packages/torch/nn/modules/module.py", line 493, in __call__ result = self.forward(*input, **kwargs) File "/home/hb119056/.local/lib/python3.6/site-packages/torch/nn/modules/loss.py", line 443, in forward return F.mse_loss(input, target, reduction=self.reduction) File "/home/hb119056/.local/lib/python3.6/site-packages/torch/nn/functional.py", line 2244, in mse_loss if not (target.size() == input.size()): TypeError: 'int' object is not callable
相关代码片段
错误发生在损失计算的这一行:
target = torch.from_numpy(np.load(file_dir + '/points/points{:03}.npy'.format(i))).to(device) rv = torch.zeros(12 * outputs.shape[0]) for j in [x for x in range(10) if x != i]: source = torch.from_numpy(np.load(file_dir + '/points/points{:03}.npy'.format(j))).to(device) rv = factor.ransac(source, target, prob, n_iter, tol, device) # 自定义类RANSAC方法 predicted = factor.predict(source, rv, outputs) print(target.shape, predicted.shape) loss = criterion(predicted, target.detach().cpu().numpy()) ## 错误发生处
其中criterion是nn.MSELoss()实例。
问题分析与解决方法
仔细看报错的核心行:if not (target.size() == input.size()):,这里的target.size()抛出了“int对象不可调用”的错误——这是因为我把target转换成了numpy数组!
PyTorch的损失函数(包括MSELoss)期望输入是PyTorch Tensor,而不是numpy数组。numpy数组的size是一个属性(直接访问target.size就能得到元素个数),但PyTorch内部代码试图调用target.size()(把它当成方法),自然就会报错。
解决方法很简单:不要把target转成numpy数组,直接使用Tensor计算损失:
# 替换原来的错误行,根据需求选择其中一种即可 loss = criterion(predicted, target) # 如果需要将target从计算图中分离(比如不需要计算target的梯度),可以用detach() loss = criterion(predicted, target.detach())
另外还要确保predicted和target在同一个设备上(比如都是CPU或者GPU),从代码看target已经通过.to(device)放到了对应设备,predicted应该也在同一设备,所以不需要额外处理设备问题。
内容的提问来源于stack exchange,提问作者Rani
相关产品推荐
相关产品推荐

