논문 읽기/Image Processing

[논문 읽기] PyTorch 코드로 살펴보는 SRCNN(2014), Image Super-Resolution Using Deep Convolutional Networks

AI 꿈나무 2021. 6. 15. 14:45
반응형

 안녕하세요, 오늘 읽은 논문은 SRCNN, Image Super-Resolution Using Deep Convolutional Networks 입니다.

 

 해당 논문은 이미지의 해상도를 높이는 task인 super-resolution 분야에 CNN을 최초로 적용한 논문입니다. SRCNN은 CNN을 사용하여 low-resolution 이미지를 high-resolution 이미지로 mapping 합니다. 즉, 저해상도와 고해상도 사이의 관계를 학습하여 하나의 함수를 만드는 것으로 이해해볼 수 있습니다. SRCNN은 super resolution에서 사용하는 기존의 방법들을 제치고 SOTA 성능을 달성합니다. CNN은 정말 대단하네요 ㅎㅎ

 

 제가 SRCNN을 구현하고, 학습해서 성능을 test한 그림입니다. 화질이 엄청나게 개선되진 않았습니다 ㅎㅎ

 

 SRCNN을 PyTorch로 구현하고 학습하고 성능을 test해보는 포스팅은 아래에서 확인하실 수 있습니다.

 

[논문 구현] PyTorch로 SRCNN(2014) 구현하고 학습하기

 안녕하세요, 이번 포스팅에서는 SRCNN을 PyTorch로 구현하고 학습까지 진행한 후에 성능까지 test를 해보겠습니다. 작업 환경은 Google Colab에서 진행했습니다.  논문 리뷰는 아래 포스팅에서 확인하

deep-learning-study.tistory.com

 

SRCNN

 

 SRCNN은 3개의 Conv 연산으로 이루어져 있습니다. 위 그림에서 f1, f2, f3은 conv의 kernel_size를 의미합니다. n1, n2은 conv의 channel 수를 의미합니다. 해당 논문에서는 f1=9, f2=1, f3=5, n1=64, n2=32를 사용합니다. 활성화 함수는 ReLU를 사용하며, 3번째 conv에서는 활성화 함수를 사용하지 않습니다. 파이토치 코드로 한번 살펴보겠습니다.

 

 3번째 conv의 출력 채널은 입력 이미지의 채널과 동일해야 합니다. SRCNN은 이미지를 입력받아 이미지를 출력하도록 설계해야 하기 때문입니다. 어떻게보면 GAN의 generator과 같다고 생각해볼 수 있습니다.

 

class SRCNN(nn.Module):
    def __init__(self):
        super().__init__()

        # padding_mode='replicate'는 zero padding이 아닌, 주변 값을 복사해서 padding 합니다.
        self.conv1 = nn.Conv2d(1, 64, 9, padding=2, padding_mode='replicate')
        self.conv2 = nn.Conv2d(64, 32, 1, padding=2, padding_mode='replicate')
        self.conv3 = nn.Conv2d(32, 1, 5, padding=2, padding_mode='replicate')

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.relu(self.conv2(x))
        x = self.conv3(x)

        return x

 

 SRCNN의 loss function은 출력 이미지와 target 이미지 사이의 MSE를 사용합니다.

# 손실함수
loss_func = nn.MSELoss()

loss = loss_func(outputs, label)

 

 super resolution의 평가지표인 PSNR은 모델의 출력값과 high-resolution인 target과의 유사도를 측정합니다. PSNR 값이 클수록 좋습니다.

# PSNR function: 모델의 출력값과 high-resoultion의 유사도를 측정합니다.
# PSNR 값이 클수록 좋습니다.
def psnr(label, outputs, max_val=1.):
    label = label.cpu().detach().numpy()
    outputs = outputs.cpu().detach().numpy()
    img_diff = outputs - label
    rmse = math.sqrt(np.mean((img_diff)**2))
    if rmse == 0: # label과 output이 완전히 일치하는 경우
        return 100
    else:
        psnr = 20 * math.log10(max_val/rmse)
        return psnr

 

Experiment

 SRCNN의 kernel_size에 따른 성능비교 입니다.

 

 layer 수에따른 성능 비교입니다. 깊은 구조가 성능 향상으로 이어지지 않는 것으로 보아, 해당 신경망이 갖고 있는 파라미터 수로 dataset이 갖고 있는 정보를 포함하고 있다고 생각해볼 수 있습니다.

 

 다른 Super resolution 기법들과의 성능비교입니다.

 


참고자료

[1] https://arxiv.org/abs/1501.00092

반응형