🐍 Python & library/PyTorch

[PyTorch] nn.Conv의 padding과 padding_mode

복만 2022. 3. 24. 14:16

PyTorch 에서 제공하는 convolution 함수에 설정 가능한 parameter 중paddingpadding_mode라는 것이 있다.

 

 

padding의 경우 padding의 크기를 지정할 수 있는 parameter인데 (int 혹은 tuple), PyTorch 1.9.0부터 string으로 지정할 수 있는 옵션이 추가되었다.

이는 Tensorflow에서는 원래 있던 옵션인데, padding의 크기를 직접 지정하는 대신 same 혹은 valid 옵션을 주면 input size에 맞게 자동으로 padding 크기가 설정된다.

  • valid는 padding을 따로 주지 않고 input image 자체만을 이용해 convolution 연산을 수행한다.
  • same은 output size가 input size와 동일하게 되도록 padding을 조절한다. 만약 stride=1, dilation=1인 경우 padding=(kernel_size-1)/2로 설정된다.

 


 

padding_mode는 padding을 뭘로 채울 지 설정할 수 있다. zeros, reflect, replicate, circular이 있으며, 기본 값은 zeros로, padding을 모두 0으로 채운다. 대부분 zero-filling을 사용하지만 다양한 선택지가 있어 소개해 보고자 한다.

 

* 예시를 위해 [1, 2, 3, 4, 5] 모양의 1D tensor와 padding을 4로 설정한 1D identity Conv 연산을 이용했다.

 

  • zeros: zero-filling을 이용한다.
x = torch.tensor([[[1, 2, 3, 4, 5]]]).float()

conv = nn.Conv1d(1, 1, 3, padding=4, padding_mode='zeros', bias=False)
conv.weight = torch.nn.Parameter(torch.tensor([[[0., 1., 0.]]]))

y = conv(x)
print(y)
>> tensor([[[0., 0., 0., 1., 2., 3., 4., 5., 0., 0., 0.]]])

 

  • reflect: 양 끝에 거울처럼 반사된 값을 사용한다. 단, 이 경우 input 크기보다 더 큰 값의 padding을 사용할 수 없다.
x = torch.tensor([[[1, 2, 3, 4, 5]]]).float()

conv = nn.Conv1d(1, 1, 3, padding=4, padding_mode='reflect', bias=False)
conv.weight = torch.nn.Parameter(torch.tensor([[[0., 1., 0.]]]))

y = conv(x)
print(y)
>> tensor([[[4., 3., 2., 1., 2., 3., 4., 5., 4., 3., 2.]]])

 

  • replicate: 양 끝단의 값을 padding 값으로 이용한다.
import torch
import torch.nn as nn

x = torch.tensor([[[1, 2, 3, 4, 5]]]).float()

conv = nn.Conv1d(1, 1, 3, padding=4, padding_mode='replicate', bias=False)
conv.weight = torch.nn.Parameter(torch.tensor([[[0., 1., 0.]]]))

y = conv(x)
print(y)
>> tensor([[[1., 1., 1., 1., 2., 3., 4., 5., 5., 5., 5.]]])

 

  • circular: input 값을 순환하여 사용한다.
import torch
import torch.nn as nn

x = torch.tensor([[[1, 2, 3, 4, 5]]]).float()

conv = nn.Conv1d(1, 1, 3, padding=4, padding_mode='circular', bias=False)
conv.weight = torch.nn.Parameter(torch.tensor([[[0., 1., 0.]]]))

y = conv(x)
print(y)
>> tensor([[[3., 4., 5., 1., 2., 3., 4., 5., 1., 2., 3.]]])

 

반응형