[Python] What's the relationship between the weight of transposeconv and its corresponding...

Discussão em 'Python' iniciado por Stack, Dezembro 18, 2024.

  1. Stack

    Stack Membro Participativo

    I'm simulating the workflow of convtranspose function in pytorch, thus I'm thinking of setting the weight of grouped convtranspose to its corresponding grouped conv, and I have tested like this:

    import torch
    import torch.nn as nn
    class SimulatedTransposeConv2d(nn.Module):
    def __init__(self, input_channel, output_channel, k_h, k_w, s_w, p_w,groups, weight, bias) -> None:
    super().__init__()
    self.conv1 = nn.Conv2d(input_channel, output_channel ,kernel_size = (k_h, k_w), stride = (1, 1), groups=groups)
    self.output_channel = output_channel
    self.input_channel = input_channel
    self.pad_insert = s_w - 1
    self.pad_sides = k_w - p_w - 1
    with torch.no_grad():
    weight = weight.flip([-1, -2]).permute(1,0,2,3).reshape(output_channel, input_channel // groups, k_h, k_w)
    self.conv1.weight.copy_(weight)
    self.conv1.bias.copy_(bias)
    def forward(self, x):
    x = self.pad(x, self.pad_insert, self.pad_sides)
    return self.conv1(x)
    def pad(self, x, pad_insert, pad_sides):
    '''It's written in C style'''
    b = x.shape[0]
    c = x.shape[1]
    h = x.shape[2]
    w = x.shape[3]
    pad_w_size = pad_sides * 2 + pad_insert* (w - 1) + w
    res = torch.zeros(pad_w_size * b * h * c)
    x = x.flatten()
    for k in range(c):
    for i in range(h):
    for j in range(w):
    res[k * h * pad_w_size + i * pad_w_size + j * (pad_insert + 1)+ pad_sides] = x[k * h * w + i * w + j]
    return res.reshape(b ,c ,h, pad_w_size)

    if __name__ == "__main__":
    k_h = 3
    k_w = 3
    p_w = 0
    s_w = 1
    groups = 8
    tranpose2d = nn.ConvTranspose2d(in_channels = 8, out_channels = 8, kernel_size = (k_h, k_w), stride = (1, s_w), padding = (k_h - 1, p_w), groups=groups)
    simulated_transpose2d = SimulatedTransposeConv2d(8, 8, k_h, k_w, s_w, p_w, groups, tranpose2d.state_dict()['weight'], tranpose2d.state_dict()['bias'])
    x = torch.rand((1 ,8 ,8, 8)).type(torch.float32)
    print((tranpose2d(x) - simulated_transpose2d(x)).abs().mean())



    according to my code, If the groups=1 or the groups = input_channel, the result will be right, but if the groups parameter is not in the situations above(eg input_channel = 8 and groups = 4), the result will be wrong, I think it's probably because the weight relationship between convtranspose and conv is not correct weight_conv=weight_transpose.flip([-1,-2]).permute(1,0,2,3).reshape(output_channel, input_channel // groups, k_h, k_w),is the way of thinking right? If it is correct, so what's the relationship between them? Thanks!

    Continue reading...

Compartilhe esta Página