反卷积torch.nn.ConvTranspose2d详解(含转换成卷积运算的代码示例)

1.torch.nn.ConvTranspose2d参数介绍

官方文档:https://pytorch.org/docs/master/generated/torch.nn.ConvTranspose2d.html#torch.nn.ConvTranspose2d

torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, 
                         bias=True, dilation=1, padding_mode='zeros', device=None, dtype=None)

※反卷积可以认为先对feature map进行插值/padding操作得到新的feature map然后进行常规的卷积运算。实际转换过程中存在的细节问题下文会提及。

2.如何得到新的feature map
①s=1:不进行插值操作,只进行padding操作

H o u t = H i n + 2 ∗ p a d d i n g _ n e w s i z e     其 中 , p a d d i n g _ n e w s i z e = k e r n e l _ s i z e − p a d d i n g − 1 H_{out}=H_{in}+2*padding\_newsize \ \ \ 其中,padding\_newsize=kernel\_size-padding-1 Hout=Hin+2padding_newsize   ,padding_newsize=kernel_sizepadding1

②s>1:进行插值操作

1)在输入feature map的每2个像素之间增加(s-1)个0
2)在输入的底边和右边进行padding——(c+2p-k)mod(s),其中c的计算方式见下方。
3)最后根据公式进行外围的padding。

eg: i=3, k=3, p=1, s=2

普通卷积输出的计算方式: o u t p u t   f e a t u r e   m a p = ⌊ n + 2 p − f s + 1 ⌋ × ⌊ n + 2 p − f s + 1 ⌋ output\ feature\ map=\lfloor \frac{n+2p-f}{s}+ 1\rfloor×\lfloor \frac{n+2p-f}{s}+ 1\rfloor output feature map=sn+2pf+1×sn+2pf+1
同样地,计算反卷积的输出: 3 = ⌊ c + 2 ∗ 1 − 3 2 + 1 ⌋ → c = 5 , 6 3=\lfloor \frac{c+2*1-3}{2}+ 1\rfloor→c=5,6 3=2c+213+1c=5,6

  • 当c=5时,(5+2-3)mod(2)=0,∴第2)步无需填充
  • 而根据p’=k-p-1=1,则需要在feature map外围padding一圈,即可按照k’=3,s’=1进行卷积操作。
  • 上述操作依次如下图所示:

==============================================================

  • 当c=6时,(6+2-3)mod(2)=1,所以首先在底边和右边padding一行/列
  • 同样p’=1,再在上一步的基础上,在feature map外围padding一圈。
  • 上述操作依次如下图所示:

※torch.nn.ConvTranspose2d中的output_padding参数的设定为0或1就决定了c=5还是6。

3.执行卷积操作

整个过程满足: H i n = ( H o u t ∗ s − 2 ∗ p + k e r n e l _ s i z e ) , 其 中 H i n 为 目 标 尺 寸 , H o u t 为 原 始 尺 寸 H_{in}=(H_{out}*s - 2*p + kernel\_size),其中H_{in}为目标尺寸,H_{out}为原始尺寸 Hin=(Houts2p+kernel_size)HinHout

4.反卷积转换成卷积操作(代码示例)

1)插值操作

def interpolation(input, output_padding=0):    # padding use conv2d
    in_size = input.size()
    assert in_size[2]==in_size[3]
    inter_size = 2 * in_size[2] - 1
    output = torch.zeros(in_size[0], in_size[1], inter_size, inter_size)
    for i in range(in_size[0]):
        for j in range(in_size[1]):
            for m in range(in_size[2]):
                for n in range(in_size[3]):
                    output[i][j][2*m][2*n] = input[i][j][m][n]
    return output

2)卷积操作
※需要注意的是,torch.nn.ConvTranspose2d默认权重的排布方式和Conv2d是不同的,需要进行重新排布再进行常规的卷积操作。可以通过下方函数将反卷积操作转换为插值和卷积两步操作(这里的例子刚好没有底边和右边padding的情况)。

def compare_conv_deconv(input, weight, b, out):
    inter_input = interpolation(input)
    conv_wq = torch.flip(weight,dims=[2,3])
    conv_wq = conv_wq.transpose(0,1)
    test_out = torch.nn.functional.conv2d(inter_input, conv_wq, bias=b, stride=(1,1), padding=2, dilation=1, groups=1)  # kernel_size=4
    if out.equal(test_out):
        print("all results are correct!")
    return conv_wq, b

参考链接:https://blog.youkuaiyun.com/qq_41076797/article/details/114494990

torch.nn.ConvTranspose2dPyTorch中的一个函数,用于执行二维转置卷积操作。它具有多个参数,包括输入通道数(in_channels)、输出通道数(out_channels)、卷积核大小(kernel_size)、步长(stride)、填充(padding)、输出填充(output_padding)等等。你可以在官方文档中找到更详细的参数介绍和函数用法。 需要注意的是,torch.nn.ConvTranspose2dtorch.nn.Conv2d默认的权重排布方式是不同的。在进行反卷积操作之前,需要对权重进行重新排布,然后再进行常规的卷积操作。你可以通过一些函数来实现将反卷积操作转换为插值和卷积两步操作的方式。 具体操作流程如下: 1. 进行插值操作(根据需要进行插值,可以选择不进行插值操作) 2. 执行卷积操作(使用转置后的权重进行卷积) 3. 如果需要,可以将反卷积转换为卷积操作,重新排布权重,然后进行常规的卷积操作。 你可以参考上述代码示例来进行操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [反卷积torch.nn.ConvTranspose2d详解转换成卷积运算代码示例)](https://blog.csdn.net/cc__cc__/article/details/121444692)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值