Pytorch 'Tensor' 对象不可调用
Pytorch 'Tensor' object is not callable
我正在尝试将 sobel 过滤器应用于我的网络。我收到此错误:“'Tensor' 对象不可调用 ”
这是我的代码:
class SobelFilter(nn.Module):
def __init__(self):
super(SobelFilter, self).__init__()
kernel1=torch.Tensor([[1, 0, -1],[2,0,-2],[1,0,-1]])
kernela=kernel1.expand((1,1,3,3))
kernel2=torch.Tensor([[1, 2, 1],[0,0,0],[-1,-2,-1]])
kernelb=kernel2.expand((1,1,3,3))
inputs = torch.randn(1,1,64,128)
self.conv1 = F.conv2d(inputs,kernela,stride=1,padding=1)
self.conv2 = F.conv2d(inputs,kernelb,stride=1,padding=1)
def forward(self, x ):
print(x.shape)
G_x = self.conv1(x) %GIVES ERROR AT THIS LINE
G_y = self.conv2(x)
out = torch.sqrt(torch.pow(G_x,2)+ torch.pow(G_y,2))
return out
class EXP(nn.Module):
def __init__(self, maxdisp):
super(EXP, self).__init__()
self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
self.SobelFilter = SobelFilter()
def forward(self, im):
% just think "im" to be [1,32,64,128]
for i in range(im.shape[1]):
out1= im[:,i,:,:].unsqueeze(1)
im[:,i,:,:] = self.SobelFilter(out1)
什么会导致问题?
谢谢!
我认为您的问题是您使用的是 torch.nn.functional
而不是 torch
。
函数 API 的目的是直接执行操作(在本例中为 conv2d),而不创建 class 实例然后调用其 forward 方法。
因此,语句 self.conv1 = F.conv2d(inputs,kernela,stride=1,padding=1)
已经在 input
和 kernela
之间进行卷积,而您在 self.conv1
中得到的就是这种卷积的结果。
这里有两种方法可以解决这个问题。在 __init__
中使用 torch.Conv2d
,其中 inputs
是输入的通道,而不是与实际输入具有相同形状的张量。
第二种方法是坚持使用功能 API 但将其移至 forward()
方法。你想实现的可以通过将 forward 更改为:
def forward(self, x ):
print(x.shape)
G_x = F.conv2d(x,self.kernela,stride=1,padding=1)
G_y = F.conv2d(x,self.kernelb,stride=1,padding=1)
out = torch.sqrt(torch.pow(G_x,2)+ torch.pow(G_y,2))
return out
请注意,我制作了 kernela
和 kernelb
class 属性。因此,您还应该将 __init__()
更改为
def __init__(self):
super(SobelFilter, self).__init__()
kernel1=torch.Tensor([[1, 0, -1],[2,0,-2],[1,0,-1]])
self.kernela=kernel1.expand((1,1,3,3))
kernel2=torch.Tensor([[1, 2, 1],[0,0,0],[-1,-2,-1]])
self.kernelb=kernel2.expand((1,1,3,3))
我正在尝试将 sobel 过滤器应用于我的网络。我收到此错误:“'Tensor' 对象不可调用 ” 这是我的代码:
class SobelFilter(nn.Module):
def __init__(self):
super(SobelFilter, self).__init__()
kernel1=torch.Tensor([[1, 0, -1],[2,0,-2],[1,0,-1]])
kernela=kernel1.expand((1,1,3,3))
kernel2=torch.Tensor([[1, 2, 1],[0,0,0],[-1,-2,-1]])
kernelb=kernel2.expand((1,1,3,3))
inputs = torch.randn(1,1,64,128)
self.conv1 = F.conv2d(inputs,kernela,stride=1,padding=1)
self.conv2 = F.conv2d(inputs,kernelb,stride=1,padding=1)
def forward(self, x ):
print(x.shape)
G_x = self.conv1(x) %GIVES ERROR AT THIS LINE
G_y = self.conv2(x)
out = torch.sqrt(torch.pow(G_x,2)+ torch.pow(G_y,2))
return out
class EXP(nn.Module):
def __init__(self, maxdisp):
super(EXP, self).__init__()
self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
self.SobelFilter = SobelFilter()
def forward(self, im):
% just think "im" to be [1,32,64,128]
for i in range(im.shape[1]):
out1= im[:,i,:,:].unsqueeze(1)
im[:,i,:,:] = self.SobelFilter(out1)
什么会导致问题? 谢谢!
我认为您的问题是您使用的是 torch.nn.functional
而不是 torch
。
函数 API 的目的是直接执行操作(在本例中为 conv2d),而不创建 class 实例然后调用其 forward 方法。
因此,语句 self.conv1 = F.conv2d(inputs,kernela,stride=1,padding=1)
已经在 input
和 kernela
之间进行卷积,而您在 self.conv1
中得到的就是这种卷积的结果。
这里有两种方法可以解决这个问题。在 __init__
中使用 torch.Conv2d
,其中 inputs
是输入的通道,而不是与实际输入具有相同形状的张量。
第二种方法是坚持使用功能 API 但将其移至 forward()
方法。你想实现的可以通过将 forward 更改为:
def forward(self, x ):
print(x.shape)
G_x = F.conv2d(x,self.kernela,stride=1,padding=1)
G_y = F.conv2d(x,self.kernelb,stride=1,padding=1)
out = torch.sqrt(torch.pow(G_x,2)+ torch.pow(G_y,2))
return out
请注意,我制作了 kernela
和 kernelb
class 属性。因此,您还应该将 __init__()
更改为
def __init__(self):
super(SobelFilter, self).__init__()
kernel1=torch.Tensor([[1, 0, -1],[2,0,-2],[1,0,-1]])
self.kernela=kernel1.expand((1,1,3,3))
kernel2=torch.Tensor([[1, 2, 1],[0,0,0],[-1,-2,-1]])
self.kernelb=kernel2.expand((1,1,3,3))