SR ResNet 구축

 

한요섭박사님 강의 링크

GIT 링크

paper 링크

 

Model 추가하기

class SRResNet(nn.Module)


#model.py
class ResNet(nn.Module):
    def __init__(self, in_channels, out_channels, nker=64, learning_type="plain", norm="bnorm", nblk=16):  # Nblk(NumberOfBlock) = resblock가 몇번 반복되는지 정의하는 parameter

    super(ResNet, self).__init__()

    self.learning_type = learning_type

    self.enc = CBR2d(in_channels, nker, kernel_size=3, stride=1, padding=1, bias=True, norm=None, relu=0.0)  # padding은 int(kernel_size/2) = 9/2 =4.5 -> 4

 

layer 추가하기

class ResBlock(nn.Module)


#layer.py
    def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=True, norm="bnorm", relu=0.0):
        super().__init__()

        layers = []

        # 1st conv
        layers += [CBR2d(in_channels=in_channels, out_channels=out_channels,
                         kernel_size=kernel_size, stride=stride, padding=padding,
                         bias=bias, norm=norm, relu=relu)]

        # 2nd conv
        layers += [CBR2d(in_channels=out_channels, out_channels=out_channels,
                         kernel_size=kernel_size, stride=stride, padding=padding,
                         bias=bias, norm=norm, relu=None)] # 그림엔 Relu가 없음 None으로 함

        self.resblk = nn.Sequential(*layers)

    def forward(self, x):
        return x + self.resblk(x)  # Elementwise Sum이 적용된 output 도출

 

Model 추가하기

class SRResNet(nn.Module)


#model.py
        res = []
        for i in range(nblk):
            res += [ResBlock(nker, nker, kernel_size=3, stride=1, padding=1, bias=True, norm=norm, relu=0.0)]
        self.res = nn.Sequential(*res)
        self.dec = CBR2d(nker, nker, kernel_size=3, stride=1, padding=1, bias=True, norm=norm, relu=None)

 

layer 추가하기

class PixelUnshuffle(nn.Module) 역방향

class PixelShuffle(nn.Module) 정방향

https://arxiv.org/pdf/1609.05158.pdf 참조해서 구현


#layer.py
class PixelUnshuffle(nn.Module):# channel 방향으로 stack 되어있는 resolution을 
                                # hight-resolution image로 변경해줌
    def __init__(self, ry=2, rx=2):
        super().__init__()
        self.ry = ry
        self.rx = rx

    def forward(self, x):
        ry = self.ry
        rx = self.rx
        # Batchsize, ChannelSize, Height, Width
        [B, C, H, W] = list(x.shape)

        x = x.reshape(B, C, H // ry, ry, W // rx, rx)   # B,C는 그대로 두고 downsampling한 axis
        x = x.permute(0, 1, 3, 5, 2, 4)
        x = x.reshape(B, C * (ry * rx), H // ry, W // rx)
        return x

class PixelShuffle(nn.Module):# High-resolution image -> low resolution image
    def __init__(self, ry=2, rx=2):
        super().__init__()
        self.ry = ry
        self.rx = rx

    def forward(self, x):
        ry = self.ry
        rx = self.rx

        [B, C, H, W] = list(x.shape)

        x = x.reshape(B, C // (ry * rx), ry, rx, H, W)
        # axis 수정
        x = x.permute(0, 1, 4, 2, 5, 3)
        # 원본의 형태로 다시 만들어줌
        x = x.reshape(B, C // (ry * rx), H * ry, W * rx)

        return x

 

Model 추가하기

class SRResNet(nn.Module)


#model.py
        ps1 = []
        ps1 += [nn.Conv2d(in_channels=nker, out_channels=4 * nker, kernel_size=3, stride=1, padding=1)]  # 64->256 = 4* nker(64)
        ps1 += [PixelShuffle(ry=2, rx=2)]
        ps1 += [nn.ReLU()]
        self.ps1 = nn.Sequential(*ps1)  # subfixcel이 정의되어있는 첫번째 block

        ps2 = []
        ps2 += [nn.Conv2d(in_channels=nker, out_channels=4 * nker, kernel_size=3, stride=1, padding=1)]
        ps2 += [PixelShuffle(ry=2, rx=2)]
        ps2 += [nn.ReLU()]
        self.ps2 = nn.Sequential(*ps2)

        self.fc = CBR2d(nker, out_channels, kernel_size=9, stride=1, padding=4, bias=True, norm=None, relu=None)  # 마지막 colvolution layer


    def forward(self, x):
        x = self.enc(x)  # 첫번째 block 수행
        x0 = x  # skip connection 으로 건너띄어진 Elementwise Sum output으로 정의

        x = self.res(x)  # B residual blcoks 수행

        x = self.dec(x)  # Conv, BN 수행
        x = x + x0

        x = self.ps1(x)  # subfixcel 1 수행
        x = self.ps2(x)  # subfixcel 1 수행

        x = self.fc(x)  # 마지막 colvolution 수행

        return x

 

Train para 추가하기

-


#train.py
# resnet, srresnet 추가
parser.add_argument("--network", default="srresnet", choices=["unet", "hourglass", "resnet", "srresnet"], type=str, dest="network") 

# option에 0을 추가해서 keepdim에 값을 할당하여 down dimension을 수행
parser.add_argument('--opts', nargs='+', default=['bilinear', 4.0, 0], dest='opts')

 

network 추가하기

-


#train.py
# resnet, srresnet 추가
elif network == "resnet":
    net = ResNet(in_channels=nch, out_channels=nch, nker=nker, learning_type=learning_type).to(device)
elif network == "srresnet":
    net = SRResNet(in_channels=nch, out_channels=nch, nker=nker, learning_type=learning_type).to(device)

 

 

 

 

Comments