CNN의 기원
합성곱 신경망(Convolutional Neural Network, CNN)은 주로 이미지와 비디오 데이터의 분석에 사용되는 딥러닝 아키텍처로, 패턴 인식에 특화되어 있다. 1958년과 1959년에 David Huble과 Torsten Wiesel은 시각 피질에 대한 실험을 수행했는데, 시각 피질 안의 뉴런이 시야의 일부 범위 안에 있는 시각 자극에만 반응한다는 사실을 발견했다. 어떤 뉴런은 수직선의 이미지에만 반응하고, 다른 뉴런은 다른 각도의 선에 반응하기도 하며, 어떤 뉴런은 큰 수용 영역을 가져 저수준의 패턴이 조합되어 복잡한 패턴에 반응한다는 것을 알게 되었다. CNN은 고수준의 뉴런이 이웃한 저수준의 뉴런의 출력에 기반한다는 아이디어를 시작으로 진화되어 왔다.
CNN의 구성
CNN은 크게 컨볼루션 층(Convolution Layers)과 풀링 층(Pooling Layers)으로 구성되어 있다. 컨볼루션 층은 특성을 추출하는 층으로서 일련의 필터(Filter, Kernel, Feature Detector)로 구성된다. 필터는 뉴런의 수용 영역을 나타낸 것으로, 컨볼루션 층에서의 가중치 파라미터에 해당하며, 학습 단계에서 적절한 필터를 찾도록 학습된다.
0.25 | 0.17 | 0.9 |
0.89 | 0.36 | 0.63 |
0.7 | 0.24 | 0.82 |
위의 그림과 같이 필터는 랜덤 값으로 구성되어 있는 행렬이며, 이 값은 학습 과정에서 업데이트 된다. 필터의 동작 과정을 살펴보면, 아래 그림처럼 필터의 크기가 3x3이라고 할 때, 필터는 이미지의 모든 3x3 영역을 지나가면서 이미지 픽셀 행렬과 필터 행렬의 dot product를 구해 새로운 행렬에 저장한다. (필터가 이동할 때 이동 간격을 설정할 수도 있다. 이는 스트라이드(Stride)라고 하며, 출력 데이터의 크기를 조절하기 위해 사용한다. 보통 1과 같이 작은 값이 더 잘 작동한다.)

MNIST 데이터셋의 숫자 7로 필터의 동작 과정을 더 자세히 살펴보자. 그림과 같이 이미지 행렬과 필터가 있을 때, 필터는 이미지의 3x3 영역을 지나가면서 해당 영역과 자신의 dot product를 계산하고 그 값을 새로운 행렬에 저장한다. 이렇게 만들어진 행렬은 특성맵(Feature Map)이라고 하며, 해당 컨볼루션 층의 출력값(다음 층의 입력값)이 된다. (한 가지 주의해야 할 점은 입력 데이터의 채널 수와 필터의 채널 수는 동일해야 한다.)

패딩(Padding)은 합성곱 연산을 수행하기 전, 입력 데이터 주변을 특정값으로 채워 늘리는 것을 말한다. 주로 출력 데이터의 크기를 조절하기 위해 사용하며, 채울 값은 사용자가 설정할 수 있지만 주로 0(Zero-Paddding)을 사용한다.
풀링으로 인해 데이터의 크기는 컨볼루션 층을 지날 때마다 작아져 가장자리의 정보들이 사라지는 문제가 발생하기 때문에 패딩을 사용하며, 주로 합성곱 계층의 출력이 입력 데이터의 공간적 크기와 동일하게 맞춰주기 위해 사용한다.

풀링 층(Pooling Layers)은 컨볼루션 층의 출력(특성 맵)을 다운샘플링(Downsampling)하기 위해 사용한다. 입력의 공간적 차원을 줄이기 때문에 과적합을 제어하고 계산 비용을 줄이는 데 도움이 되기도 한다. 풀링에는 Max-Pooling과 Average pooling이 있는데 Max-Pooling은 해당 영역에서 최대값을 찾는 방법이고, Average-Pooling은 해당 영역의 평균값을 계산하는 방법이다. 이미지 인식 분야에서는 주로 Max-Pooling을 사용한다.

PyTorch 예제
import torch
import torch.nn as nn
import torch.nn.functional as F
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
# 컨볼루션 층
self.conv1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=3, stride=1, padding=0)
self.conv2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3, stride=1, padding=0)
self.conv3 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, stride=2, padding=0)
# 풀링 층
self.pool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0)
# 완전 연결층 정의
self.fc1 = nn.Linear(64 * 14 * 14, 128) # 입력 이미지가 28x28이라고 가정
self.fc2 = nn.Linear(128, 10) # 10개의 클래스를 위한 출력 레이어
def forward(self, x):
# 첫 번째 컨볼루션 층
x = F.relu(self.conv1(x))
x = self.pool(x)
# 두 번째 컨볼루션 층
x = F.relu(self.conv2(x))
x = self.pool(x)
# 세 번째 컨볼루션 층
x = F.relu(self.conv3(x))
# flattening
x = x.view(-1, 64 * 14 * 14) # 입력 크기와 풀링 레이어에 따라 조정된 값이다
# 완전 연결층
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
model = SimpleCNN()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
nn.Conv2d는 PyTorch에서 2차원 컨볼루션 연산을 수행하는 레이어를 정의하는 클래스로, 주로 이미지 처리 및 2D 데이터의 특징 추출에 사용된다. 주요 파라미터는 다음과 같다.
- in_channels: 입력 데이터의 채널 수. 예를 들어, RGB 이미지의 경우 3이다.
- out_channels: 컨볼루션 연산 후 생성되는 특성맵의 수를 나타낸다.
- kernel_size: 커널의 크기. 단일 정수값을 주면 커널의 높이와 너비가 같은 정사각형 커널을 사용하며, (높이, 너비) 형태의 튜플을 주면 비정사각형 커널을 사용할 수 있다.
- stride: 커널이 이동하는 간격. 기본값은 1이다.
- padding: 입력의 가장자리에 추가하는 픽셀 수. 기본값은 0이다.
- dilation: 필터 원소 사이의 간격으로 기본값은 1이다.
'AI' 카테고리의 다른 글
[AI] MediaPipe Hands: 손바닥 탐지 모델 분석 (0) | 2024.12.25 |
---|---|
3D Pose Estimation (0) | 2024.11.21 |
전이 학습 (Transfer Learning) (0) | 2024.08.26 |
Cross Entropy Loss (0) | 2024.08.20 |
선형 회귀 (Linear Regression) (0) | 2024.08.12 |