Transpose Convolution

김명섭·2024년 11월 10일

다음은 Transpose Convolution의 size를 구하는 공식이다.
output_size = (input_size - 1) * stride - 2 * padding + dilation * (kernel_size - 1) + output_padding + 1

Pytorch의 Transpose Convolution이 실제로 어떻게 적용되는지 결과를 보고 각 hyper parameter로 이해해보자.

input size는 batch_size를 제외하고 (1, 256, 256)이다.

이때, in_channels는 3이고, out_channels는 1이고, kernel_size를 2로 했기 때문에 (3, 1, 2, 2) shape의 필터가 생긴다. 하나의 원소(픽셀값 크기가 3인 1차원 텐서)에서 (1,2,2) 텐서를 만들고 256x256개의 원소에 대해서 진행한다. 이 때, kernel_size가 2이고 stride가 1이기 때문에 한 칸씩 이동하며 겹치게 더하면 최종적으로 1칸이 늘어나게 된다. kernel_size를 3으로 바꾸면 (1, 258, 258)이 나오는 것을 알 수 있다.

stride를 2로 바꾸면, (1, 512, 512)로 나온다. (3으로 바꾸면 (1, 767, 767)로 나오는 것을 확인하였다.) stride가 2를 하게 되면, (1, 256, 256) 이미지에서 1칸씩 이동하는 것이 아니고 2칸씩 이동하는데 그 전에 사이 사이 값에 0을 채워 넣고 진행한다. 즉, (1, 256, 256) -> (1, 256+255, 256+255) 으로 바뀌고 여기서 앞에서와 같이 kernel_size를 2로 하여 모든 픽셀에 대해서 가로 세로 2배를 하고 겹치는 부분은 더하는 방식이다. 그렇게 되면 256+255에 겹치지 못한 kernel_size - 1 만큼의 값이 더해지게 된다. stride가 3이면, 256개의 픽셀 사이(255개)에 2개씩 0을 추가하는 것이고, 256+255+255=766이 되는 것이고, 여기에 kernel_size가 2이므로 767이 되는 것이다.

padding을 1을 한다는 얘기는 ConvTranspose2d에서는 반대로 최종 출력에서 양 끝에서 1씩 제거한다는 의미이다.
이는, ConvTranspose2d 자체도 Transpose 하고 연산하는 방식이기 때문이다.

dilation을 2로 한다는 얘기는 2배로 확장한다는 얘기이고, kernel_size가 2인 경우 filter가 (2,2)에서 (3,3)이 되면서 빈 칸이 0으로 채워진다. 따라서, 예시의 경우 (2,2) 필터에서 (3,3) 필터가 된다. 따라서 결과가 (1,1,6,6)에서 (1,1,7,7)로 바뀐 것이다.
stride를 2로 바꾸면 (2,2)를 하나 씩 겹치게 더하면 6이 되지만, 이번엔 2칸씩 움직이므로 10개가 된다.
여기에 dilation을 2로 적용하면, filter가 (2,2)에서 (3,3)이 되고, stride가 2칸씩 움직이면 5개의 (3,3)이 2칸씩 움직이면서 더해져서 4칸이 겹치고 최종적으로 (11,11)이 된다.

output_padding은 padding과 다르게 양쪽에 추가하는 것이 아니고 우측 하단부터 추가한다. 그리고, padding과 다르게 최종 출력이 커지게된다.

profile
ML Engineer

0개의 댓글