투명한 기부를 하고싶다면 이 링크로 와보세요! 🥰 (클릭!)
바이낸스(₿) 수수료 평생 20% 할인받는 링크로 가입하기! 🔥 (클릭!)
Depthwise Convolution
우선 Depth-wise Seperable Convolution에 대한 설명을 하기에 앞서 Depth-wise Convolution에 대한 설명을 먼저 할까 한다.
기본적인 개념은 쉽다. 위 처럼 H*W*C의 conv output을 C단위로 분리하여 각각 conv filter을 적용하여 output을 만들고 그 결과를 다시 합치면 conv filter가 훨씬 적은 파라미터를 가지고서 동일한 크기의 아웃풋을 낼 수 있다. 또한 각 필터에 대한 연산 결과가 다른 필터로부터 독립적일 필요가 있을 경우에 특히 장점이 된다.
이를 파이토치에서 구현하려면 다음과 같이 하면 된다.
class depthwise_conv(nn.Module):
def __init__(self, nin, kernels_per_layer):
super(depthwise_separable_conv, self).__init__()
self.depthwise = nn.Conv2d(nin, nin * kernels_per_layer, kernel_size=3, padding=1, groups=nin)
def forward(self, x):
out = self.depthwise(x)
return out
첫 칸은 in_channels 이고, 두번째 칸은 out_channels이다.
직관적으로 알 수 있듯, 하나의 레이어에서 몇개의 아웃풋을 만들 것이냐는 말로 귀결된다.
여기에서의 구현의 핵심은 groups = nin 부분인데, 입력 레이어를 nin개의 서로 다른 group으로 만들어서 해당 연산을 수행하겠다는 뜻이 된다. (반대로 생각해보면, group의 default 값이 1이라는 소리이다.)
Pointwise Convolution
흔히 1x1 Conv라고 불리는 필터이다. 많이 볼 수 있는 트릭이고 주로 기존의 matrix의 결과를 논리적으로 다시 shuffle해서 뽑아내는 것을 목적으로 한다. 위 방법을 통해 총 channel수를 줄이거나 늘리는 목적으로도 많이 쓴다.
pytorch로 구현하면 아래와 같이 구현할 수 있다.
class pointwise_conv(nn.Module):
def __init__(self, nin, nout):
super(depthwise_separable_conv, self).__init__()
self.pointwise = nn.Conv2d(nin, nout, kernel_size=1)
def forward(self, x):
out = self.pointwise(x)
return out
Depthwise Separable Convolution
Depthwise convolution을 먼저 수행한 후 Pointwise convolution을 수행한다.
이를 통해서 3x3의 필터를 통해 conv 연산도 진행하고, 서로 다른 channel들의 정보도 공유하면서 동시에 파라미터 수도 줄일 수 있다.
아래와 같이 구현된다.
class depthwise_separable_conv(nn.Module):
def __init__(self, nin, kernels_per_layer, nout):
super(depthwise_separable_conv, self).__init__()
self.depthwise = nn.Conv2d(nin, nin * kernels_per_layer, kernel_size=3, padding=1, groups=nin)
self.pointwise = nn.Conv2d(nin * kernels_per_layer, nout, kernel_size=1)
def forward(self, x):
out = self.depthwise(x)
out = self.pointwise(out)
return out
코드 출처 : https://discuss.pytorch.org/t/how-to-modify-a-conv2d-to-depthwise-separable-convolution/15843/7