将卷积层的输出更改为张量元组

Changing the output of a convolutional layer to a tuple of tensors

为了处理视频帧,我使用压缩和激励块对卷积层的通道进行加权。 我想将(使用 torch.stack)卷积层的通道(特征图)与加权通道(通过使用提到的挤压和激励块)结合起来。但是我遇到了一个错误,当使用 torch.stack(x, weighted_channels) 与卷积层的通道相关的参数时 x,错误说 TypeError: stack(): argument 'tensors' (position 1) must be tuple of Tensors, not Tensor.

class conv(nn.Module):
def __init__(self, in_channel, out_channel, out_sigmoid=False):
    super(conv, self).__init__()
            
    self.deconv = self._deconv(in_channel=512, out_channel=256, num_conv=3)
    self.upsample = Upsample(scale_factor=2, mode='bilinear')
    self.SEBlock = SE_Block(c=256)


def _deconv(self, in_channel, out_channel, num_conv=2, kernel_size=3, stride=1, padding=1):
    layers=[]
    layers.append(BasicConv2d(in_channel, out_channel,kernel_size=kernel_size, stride=stride, padding=padding))
    for i in range(1, num_conv):
        layers.append(_SepConv2d(out_channel, out_channel,kernel_size=kernel_size, stride=stride, padding=padding))
    return nn.Sequential(*layers)

   def forward(self, x):
   
    x=self.deconv(x)
    x = self.upsample(x)
    stack = torch.stack(x, self.SEBlock(x,c=256))
    return x



    class BasicConv2d(nn.Module):
def __init__(self, in_planes, out_planes, kernel_size, stride, padding=0):
    super(BasicConv2d, self).__init__()
    self.conv = nn.Conv2d(in_planes, out_planes, kernel_size=kernel_size, stride=stride, padding=padding, bias=False)
    self.bn = nn.BatchNorm2d(out_planes, eps=1e-3, momentum=0.001, affine=True)
    self.relu = nn.ReLU()

def forward(self, x):
    x = self.conv(x)
    x = self.bn(x)
    x = self.relu(x)
    return x

 class _SepConv2d(nn.Module):
def __init__(self, in_planes, out_planes, kernel_size, stride, padding=0):
    super(_SepConv2d, self).__init__()
    self.conv_s = nn.Conv2d(in_planes, out_planes, kernel_size=kernel_size, stride=stride,       padding=padding, bias=False, groups=in_planes)
    self.bn_s = nn.BatchNorm2d(out_planes)
    self.relu_s = nn.ReLU()

    self.conv_t = nn.Conv2d(out_planes, out_planes, kernel_size=1, stride=1, padding=0, bias=False)
    self.bn_t = nn.BatchNorm2d(out_planes)
    self.relu_t = nn.ReLU()

def forward(self, x):
    x = self.conv_s(x)
    x = self.bn_s(x)
    x = self.relu_s(x)

    x = self.conv_t(x)
    x = self.bn_t(x)
    x = self.relu_t(x)
    return x 

class SE_Block(nn.Module):
"credits: https://github.com/moskomule/senet.pytorch/blob/master/senet/se_module.py#L4"
def __init__(self, c, r=16):
    super().__init__()
    self.squeeze = nn.AdaptiveAvgPool2d(1)
    self.excitation = nn.Sequential(
        nn.Linear(c, c // r, bias=False),
        nn.ReLU(inplace=True),
        nn.Linear(c // r, c, bias=False),
        nn.Sigmoid()
    )

def forward(self, x):
    bs, c, _, _ = x.shape
    y = self.squeeze(x).view(bs, c)
    y = self.excitation(y).view(bs, c, 1, 1)
    return x * y.expand_as(x)

我检查了 torch.stack 的两个参数,但它们的大小相同。

https://pytorch.org/docs/stable/generated/torch.stack.html

torch.stack(tensors, dim=0, *, out=None) → Tensor

  • tensors (sequence of Tensors) – sequence of tensors to concatenate

张量序列可以是元组,如 (tensor1, tensor2, tensor3) 或列表 [tensor1, tensor2, tensor3]。你所做的是输入 x 这是一个张量而不是张量序列,并且 weighted_channels 作为函数的 dim 参数。

正如评论中所述
torch.stack((x, weighted_channels))torch.stack([x, weighted_channels]) 应该有效。

请记住,这对于所有采用任意数量的张量并对其进行处理的函数都是相同的,例如torch.cat 和所有其他堆栈函数,如 vstackhstack-