[PyTorch] 합성곱 신경망(Convolutional Neural Network, CNN)
Posted: Updated:
AI 스터디를 하며 ‘파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습’ 교재를 정리한 글입니다.
합성곱 신경망(Convolutional Neural Network, CNN)
합성곱(Convolution) 연산
이미지 특정 영역에서 입력값의 분포 또는 변화량을 계산해 출력 노드 생성
특정 영역 내에서 연산을 수행하므로 지역 특징(Local Features)을 효과적으로 추출
여러 영역의 지역 특징을 조합해 입력 데이터의 전반적인 전역 특징(Global Features)을 파악
합성곱 계층
입력 데이터와 필터를 합성곱해 출력 데이터 생성
이미지, 음성 데이터 등 고차원 이미지 처리에 사용
입력 데이터의 모든 위치에서 동일한 필터를 사용하여 모델 매개변수를 공유
모델이 학습해야 할 매개변수 수가 감소해 과대적합 방지
conv = torch.nn.Conv2d(
in_channels, # 입력 데이터 채널 크기
out_channels, # 출력 데이터 채널 크기
kernel_size, # 필터 크기
stride=1,
padding=0,
dilation=1,
groups=1, # 입력 채널, 출력 채널을 하나의 그룹으로 묶는 것
bias=True, # 편향 포함 여부
padding_mode="zeros" # zeros: 제로 패딩, reflect: 가장자리를 반사, replicate: 가장자리 값 복사
)
합성곱 계층 출력 크기 계산
\[L_{out} = \left\lfloor \frac{L_{in} + 2 \times \text{padding} - \text{dilation} \times (\text{kernel\_size} - 1) - 1}{\text{stride}} + 1 \right\rfloor\] \[L_{in} = 6, \quad \text{kernel\_size} = 3, \quad \text{stride} = 1, \quad \text{padding} = 0, \quad \text{dilation} = 1\] \[L_{out} = \left\lfloor \frac{6 + 2 \times 0 - 1 \times (3 - 1) - 1}{1} + 1 \right\rfloor = 4\]필터(Filter)
커널(Kernel), 윈도(Window)라고도 함
필터를 일정 간격으로 이동하면서 입력 데이터와 합성곱 연산을 수행해 특징 맵 생성
필터 영역마다 합성곱 연산을 수행하고 가중치 갱신
입력 이미지에서 필터와 대응하는 부분을 곱해서 모두 더한 값을 특징 맵 한 원소로 사용
특징 맵은 다음 합성곱 계층의 입력으로 사용돼 합성곱 연산 과정 반복
패딩(Padding)
합성곱 연산 수행 후 특징 맵 크기가 작아지므로, 특징 맵 가장자리에 특정 값을 덧붙이는 과정
가장자리에는 0으로 할당하고, 제로 패딩(Zero padding)이라고 함
간격(Stride)
필터가 한 번에 움직이는 크기
간격을 작게 설정하면 입력 데이터의 공간적인 정보 보존, 크게 설정하면 감소
채널(Channel)
입력 데이터와 필터가 3차원으로 구성되어 있을 때 같은 위치의 값끼리 연산
모델 구조나 목적에 따라 채널 개수 설정, 특징 맵 개수는 채널 개수만큼 존재
채널 개수가 많아지면 특징 다양성이 증가해 모델의 표현력(Representational) 증가
팽창(Dilation)
필터와 입력 사이에 간격을 두어 합성곱 연산 시 입력 데이터에 넓은 범위 영역을 고려할 수 있게 하는 기법
팽창 값은 일반적으로 1로 한 칸 간격으로 사용하지만, 2인 경우 입력 데이터를 한 칸씩 건너뛰면서 합성곱 연산을 수행할 수 있음
필터 크기를 키우지 않고 넓은 영역을 고려할 수 있지만, 인접한 픽셀을 고려하지 않아 공간적 정보가 보존되지 않음
활성화 맵(Activation Map)
합성곱 계층 특징 맵에 활성화 함수를 적용해 얻어진 출력값
모델이 비선형성을 가지게 해 추상적 특징 학습 가능
일반적으로 ReLU 함수 적용, 특징 맵 값이 0보다 크면 값 그대로 출력, 0 이하이면 0 출력
활성화 맵을 얻으면 다음 계층의 입력값으로 사용
풀링(Pooling)
특징 맵 크기를 줄이는 연산
연산량 감소, 입력 데이터 정보 압축
최댓값 풀링(Max Pooling)
특정 크기 필터 내 원솟값 중 가장 큰 값 선택
pool = torch.nn.MaxPool2d(
kernel_size,
stride=None,
padding=0,
dilation=1
)
평균값 풀링(Average Pooling)
특정 크기 필터 내 원솟값의 평균값 사용
pool = torch.nn.AvgPool2d(
kernel_size,
stride=None,
padding=0,
count_include_pad=True # 패딩 영역 값 평균 계산에 포함할지 여부 (제로 패딩 포함 여부)
)
평균값 풀링 출력 크기
\[L_{out} = \left\lfloor \frac{L_{in} + 2 \times \text{padding} - \text{kernel\_size}}{\text{stride}} + 1 \right\rfloor\]완전 연결 계층(Fully Connected Layer, FC)
입력 노드가 모든 출력 노드와 연결된 상태
입력과 출력 간 모든 가능한 관계 학습 가능
출력 노드 수를 조절할 수 있어 모델 복잡성과 용량 조절에 사용
import torch
from torch import nn
class CNN(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Sequential(
nn.Conv2d(
in_channels=3, out_channels=16, kernel_size=3, stride=2, padding=1
),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
)
self.conv2 = nn.Sequential(
nn.Conv2d(
in_channels=16, out_channels=32, kernel_size=3, stride=1, padding=1
),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
)
self.fc = nn.Linear(32 * 32 * 32, 10)
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = torch.flatten(x)
x = self.fc(x)
return x
댓글남기기