Python/Pytorch

[Pytorch] 파이토치 Conv1d, Conv2d 원리 비교

jimmy_AI 2022. 11. 22. 15:28
반응형

Python torch Conv1d vs Conv2d

파이썬 파이토치에서 convolution을 수행하는 layer 종류인 Conv1d, Conv2d에 대하여

두 종류의 원리와 사용법 차이를 비교해보도록 하겠습니다.

 

 

Conv1d 예제 및 원리

Conv1d는 1차원 벡터 여러개에 대하여 한 방향으로 움직이며 컨볼루션 합을 진행하는 layer로

대표적인 예시로 자연어 처리에서의 단어 토큰 임베딩의 컨볼루션을 들 수 있습니다.

 

이해를 돕기 위하여 아래의 상황을 가정한 예시를 그림으로 나타내보겠습니다.

sequence length = 5(한 문장은 5개의 단어 토큰으로 구성됩니다.)

input dimension = 7(각 토큰을 7차원 임베딩으로 표현합니다.)

kernel size = 2(이웃한 2개 토큰의 임베딩을 하나의 컨볼루션 합으로 표현합니다.)

output dimension = 3(각 컨볼루션 결과는 3차원 임베딩으로 나타냅니다.)

stride = 1(컨볼루션 한 번에 1칸씩 전진합니다.)

stride = 1이므로 1-2번, 2-3번, 3-4번, 4-5번 토큰이 하나의 단위가 되어

총 4개의 3차원 임베딩 결과를 반환한 것을 살펴볼 수 있습니다.

 

Conv1d에서의 1d의 의미는 한 가지 축의 방향으로 이동하면서 컨볼루션 합을

계산한다는 의미라고 생각해주시면 됩니다.

(위의 예시에서는 단어 토큰의 순서 방향으로 이동하였습니다.)

 

이제 Conv1d가 파이토치 코드로 구현된 nn.Conv1d 메소드의 사용법을 살펴보겠습니다.

위의 예시에서 batch size = 2로 확장한 경우 예제는 다음과 같습니다.

import torch
import torch.nn as nn

x = torch.randn(2, 7, 5) # batch size = 2, dimension = 7, sequence length = 5

Net = nn.Conv1d(in_channels = 7, out_channels = 3, kernel_size = 2, stride = 1)

output = Net(x)

print(output.shape) # torch.Size([2, 3, 4])

in_channels와 out_channels 인자에 input과 output의 임베딩 차원 수를 각각 적어주면

각 batch마다 3 x 4 형태의 output이 출력된 결과를 살펴볼 수 있었습니다.

 

반응형

 

Conv2d 예제 및 원리

Conv2d는 Conv1d와 다르게 두 가지 축의 방향으로 이동하여 컨볼루션 합

얻는 형태로 이미지에서 height 및 width 방향으로 이동하는 컨볼루션이 대표적인

예시로 볼 수 있습니다.

 

이번에는 다음과 같은 상황 예시를 그림으로 표현해보겠습니다.

input dimension = 8 x 8(8 x 8 픽셀의 이미지를 생각해주시면 됩니다.)

input channels = 3(각 픽셀의 값이 R, G, B의 3개의 채널로 표현된 상황입니다.)

kernel size = 3(3 x 3 단위를 하나의 컨볼루션 단위로 봅니다.)

stride = 1(한 번에 height 방향 혹은 width 방향으로 1칸씩 움직입니다.)

# of filters = 5(각 컨볼루션 단위를 5가지 output 종류를 나타내는 채널로 학습합니다.)

여기서 padding은 진행하지 않는다고 가정하면

8 x 8 이미지를 3 x 3 kernel로 stride = 1로 이동 시 6 x 6 shape의 output이

각 채널에서 출력되는 것을 확인할 수 있습니다.

 

마찬가지로 위 상황을 파이토치의 nn.Conv2d 메소드를 활용하여 나타내면

다음과 같습니다.(여기서도 batch size = 2로 확장하였습니다.)

x = torch.randn(2, 3, 8, 8) # batch size = 2, channels = 3, dimension = (8, 8)

Net = nn.Conv2d(in_channels = 3, out_channels = 5, kernel_size = 3, stride = 1)

output = Net(x)

print(output.shape) # torch.Size([2, 5, 6, 6])

in_channels에 input의 채널 개수, out_channels에 출력 filter의 개수를 각각 적어주면

각 batch마다 5 x 6 x 6의 output이 출력된 결과를 확인할 수 있습니다.

 

참고로, 파이토치에서는 해당 원리를 확장하여 3차원 텐서에 대해서도 컨볼루션

진행할 수 있는 nn.Conv3d 메소드도 제공하고 있습니다.