pytorch Python:对象不可调用-在Notebook中运行,但不在PyCharm中运行

fslejnso  于 2024-01-09  发布在  Python
关注(0)|答案(1)|浏览(193)

编辑:我可以解决它(希望它能做我想做的)。但我不明白为什么它现在工作。我把我的变通办法放在底部。如果有人能启发我,为什么它工作(或者为什么notebook没有它工作),那就太好了。
我使用本教程中的代码:
https://amaarora.github.io/posts/2020-09-13-unet.html#understanding-input-and-output-shapes-in-u-net
它在我的笔记本代码中运行。
现在,我尝试为我的模型修改这段代码。因此,我将其复制到我的model.py中,它只有一个类AENet并相应地修改它。但PyCharm已经发出警告,
对象“Encoder "不可调用对象”Decoder“不可调用
当我从终端调用时程序中断。
使用前:

  1. class AENet(nn.Module):
  2. def __init__(self,input_dim, block_size):
  3. super(AENet,self).__init__()
  4. self.input_dim = input_dim
  5. self.cov_source = nn.Parameter(torch.zeros(block_size, block_size), requires_grad=False)
  6. self.cov_target = nn.Parameter(torch.zeros(block_size, block_size), requires_grad=False)
  7. self.encoder = nn.Sequential(
  8. nn.Linear(self.input_dim,128),
  9. nn.BatchNorm1d(128,momentum=0.01, eps=1e-03),
  10. nn.ReLU(),
  11. nn.Linear(128,8),
  12. nn.BatchNorm1d(8,momentum=0.01, eps=1e-03),
  13. nn.ReLU(),
  14. )
  15. self.decoder = nn.Sequential(
  16. nn.Linear(8,128),
  17. nn.BatchNorm1d(128,momentum=0.01, eps=1e-03),
  18. nn.ReLU(),
  19. nn.Linear(128,self.input_dim)
  20. )
  21. def forward(self, x):
  22. z = self.encoder(x.view(-1,self.input_dim))
  23. return self.decoder(z), z

字符串
在我复制、粘贴和修改AENet类之后,它看起来像这样:

  1. class Block(nn.Module):
  2. def __init__(self, in_ch, out_ch):
  3. super().__init__()
  4. self.conv1 = nn.Conv2d(in_ch, out_ch, 3)
  5. self.relu = nn.ReLU()
  6. self.conv2 = nn.Conv2d(out_ch, out_ch, 3)
  7. def forward(self, x):
  8. return self.conv2(self.relu(self.conv1(x)))
  9. class Encoder(nn.Module):
  10. def __init__(self, chs=(1, 64, 128, 256, 512, 1024)):
  11. super().__init__()
  12. self.enc_blocks = nn.ModuleList([Block(chs[i], chs[i + 1]) for i in range(len(chs) - 1)])
  13. self.pool = nn.MaxPool2d(2)
  14. def forward(self, x):
  15. ftrs = []
  16. for block in self.enc_blocks:
  17. x = block(x)
  18. ftrs.append(x)
  19. x = self.pool(x)
  20. return ftrs
  21. class Decoder(nn.Module):
  22. def __init__(self, chs=(1024, 512, 256, 128, 64)):
  23. super().__init__()
  24. self.chs = chs
  25. self.upconvs = nn.ModuleList([nn.ConvTranspose2d(chs[i], chs[i + 1], 2, 2) for i in range(len(chs) - 1)])
  26. self.dec_blocks = nn.ModuleList([Block(chs[i], chs[i + 1]) for i in range(len(chs) - 1)])
  27. def forward(self, x, encoder_features):
  28. for i in range(len(self.chs) - 1):
  29. x = self.upconvs[i](x)
  30. enc_ftrs = self.crop(encoder_features[i], x)
  31. x = torch.cat([x, enc_ftrs], dim=1)
  32. x = self.dec_blocks[i](x)
  33. return x
  34. def crop(self, enc_ftrs, x):
  35. _, _, H, W = x.shape
  36. enc_ftrs = torchvision.transforms.CenterCrop([H, W])(enc_ftrs)
  37. return enc_ftrs
  38. class AENet(nn.Module):
  39. def __init__(self, input_dim, block_size, enc_chs=(1, 64, 128, 256, 512, 1024), dec_chs=(1024, 512, 256, 128, 64), num_class=1,
  40. retain_dim=True, out_sz=(256, 640)):
  41. super(AENet,self).__init__()
  42. self.input_dim = input_dim
  43. self.cov_source = nn.Parameter(torch.zeros(block_size, block_size), requires_grad=False)
  44. self.cov_target = nn.Parameter(torch.zeros(block_size, block_size), requires_grad=False)
  45. self.encoder = Encoder(enc_chs)
  46. self.decoder = Decoder(dec_chs)
  47. self.head = nn.Conv2d(dec_chs[-1], num_class, 1)
  48. self.retain_dim = retain_dim
  49. self.out_sz = out_sz
  50. def forward(self, x):
  51. print(f'FOR X: we have the dimensions {x.shape}')
  52. z = self.encoder(x[None, None, :])
  53. print(f'FOR Z: we have the dimensions {z.shape}')
  54. out = self.decoder(z[::-1][0], z[::-1][1:])
  55. out = self.head(out)
  56. if self.retain_dim:
  57. out = F.interpolate(out, self.out_sz)
  58. print(f'FOR O: we have the dimensions {out.shape}')
  59. return out, z


我的解决方法:

  1. z = self.encoder.forward(x[None, None, :])
  2. out = self.decoder.forward(z[::-1][0], z[::-1][1:])


为什么我需要直接调用类的方法,而它在jupyter notebook中直接工作?

xzlaal3s

xzlaal3s1#

不知道你是否解决了这个问题,但是当我遇到同样的问题时,我发现我的python interpreter没有为pycharm配置。一旦设置正确,它就会发现nn.Module子类是可调用的。

相关问题