CNN(합성곱 신경망)이란?
- 이미지나 영상 데이터를 처리하는 데 특화된 딥러닝 모델
- 인간의 시신경 구조에서 영감을 받아 만들어졌으며, 이미지를 단순한 숫자의 나열이 아닌 '공간적인 구조'를 유지한 채로 분석하는 것입니다.
CNN의 핵심 레이어 4가지
1. 합성곱 층 (Convolutional Layer)
- 역할: 이미지에서 특징(Feature)을 찾아내는 가장 핵심적인 레이어
- 동작 방식: 필터(Filter) 또는 커널(Kernel)이라고 불리는 작은 행렬이 이미지 위를 돋보기처럼 훑으며(Sliding) 겹치는 부분의 픽셀 값들과 수학적인 곱셈/덧셈(합성곱 연산)을 수행
- 효과: 네트워크의 얕은 부분(초기 레이어)에서는 선, 모서리, 색상 같은 단순한 특징을 잡아내고, 층이 깊어질수록 눈, 코, 강아지의 얼굴 등 복잡하고 추상적인 패턴을 인식
2. 활성화 층 (Activation Layer)
- 역할: 모델에 비선형성(Non-linearity)을 부여
- 동작 방식: 합성곱 층을 통과해 나온 결과물(Feature Map)에 활성화 함수(주로 ReLU)를 적용하며,
ReLU는 결과값이 음수면 0으로 만들고, 양수면 그대로 통과시킵니다. - 효과: 현실 세계의 복잡한 데이터는 단순한 1차 방정식(선형 연산)들의 조합만으로는 표현할 수 없으며,
이 층을 거쳐야만 신경망이 복잡한 패턴을 제대로 학습할 수 있습니다.
3. 풀링 층 (Pooling Layer)
- 역할: 데이터의 크기(차원)를 줄이고 핵심 정보만 남기는 압축 레이어
- 동작 방식: 필터가 훑고 지나가면서 해당 영역에서 가장 큰 값만 뽑아내거나(Max Pooling), 평균값을 구합니다(Average Pooling). 이미지 분류에서는 주로 Max Pooling을 사용합니다.
- 효과: 불필요한 데이터를 버림으로써 연산량을 획기적으로 줄여 학습 속도를 높입니다.
또한, 이미지 속 객체의 위치가 살짝 바뀌거나 회전해도 모델이 동일한 특징으로 인식할 수 있도록(공간적 불변성) 돕습니다.
4. 완전 연결 층 (Fully Connected Layer)
- 역할: 앞서 추출되고 압축된 특징들을 종합하여 최종적인 판단(분류)을 내립니다.
- 동작 방식: 합성곱과 풀링을 반복하며 만들어진 3차원 형태의 텐서를 1차원 벡터로 평탄화(Flatten)한 뒤, 일반적인 인공 신경망 구조(Dense Layer)에 통과시킵니다.
- 효과: 최종적으로 Softmax 등의 함수를 거쳐 "이 이미지는 80% 확률로 강아지이고, 20% 확률로 고양이이다"와 같은 확률 기반의 예측값을 도출합니다.
샘플 코드
[ PyTorch를 사용해서 합성곱(Conv) 층과 풀링(Pool) 층이 포함된 아주 기본적인 CNN 모델을 구성하는 샘플 코드 ]
- 가장 널리 쓰이는 예제 중 하나인 '28x28 크기의 흑백 이미지(예: 손글씨 숫자)를 10가지로 분류하는 상황'을 가정하여 작성했습니다.
import torch
import torch.nn as nn
import torch.nn.functional as F
# 1. 모델 클래스 정의 (nn.Module 상속)
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
# [특징 추출 층 - Feature Extraction]
# 첫 번째 합성곱 층: 흑백 이미지(채널 1)를 입력받아 16개의 특징 맵 생성
self.conv1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=3, padding=1)
# 첫 번째 풀링 층: 2x2 영역에서 가장 큰 값만 남겨 크기를 절반으로 줄임
self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
# 두 번째 합성곱 층: 16개 채널을 받아 32개의 더 복잡한 특징 맵 생성
self.conv2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3, padding=1)
# 두 번째 풀링 층: 다시 크기를 절반으로 줄임
self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
# [분류 층 - Classification]
# 28x28 이미지가 두 번의 풀링을 거치면 7x7 크기가 됨 (28 -> 14 -> 7)
# 평탄화(Flatten)된 벡터의 크기는 32(채널) * 7(가로) * 7(세로)
self.fc1 = nn.Linear(32 * 7 * 7, 128)
# 최종 출력 층: 10개의 클래스(0~9 숫자)에 대한 예측값 출력
self.fc2 = nn.Linear(128, 10)
# 2. 데이터가 층을 통과하는 순서 정의
def forward(self, x):
# 합성곱 -> ReLU 활성화 -> 풀링 (1단계)
x = self.pool1(F.relu(self.conv1(x)))
# 합성곱 -> ReLU 활성화 -> 풀링 (2단계)
x = self.pool2(F.relu(self.conv2(x)))
# 평탄화(Flatten): 3차원 특징 맵(32x7x7)을 1차원 벡터로 쫙 폅니다.
# -1은 배치(Batch) 크기를 유지하라는 의미입니다.
x = x.view(-1, 32 * 7 * 7)
# 완전 연결 층 -> ReLU 활성화
x = F.relu(self.fc1(x))
# 최종 출력 (여기서는 분류를 위해 10개의 값이 나옵니다)
x = self.fc2(x)
return x
# ----------------------------------------------------
# 3. 모델 생성 및 테스트 해보기
# ----------------------------------------------------
model = SimpleCNN()
print("--- 모델 구조 ---")
print(model)
# 임의의 더미(Dummy) 데이터 생성 (배치 크기 1, 채널 1, 높이 28, 너비 28)
dummy_input = torch.randn(1, 1, 28, 28)
# 모델에 데이터를 통과시켜 예측값 도출
output = model(dummy_input)
print("\n--- 텐서 형태 변화 확인 ---")
print(f"입력 이미지 형태: {dummy_input.shape}")
print(f"최종 출력 형태: {output.shape} (1개의 데이터에 대한 10개의 클래스 예측 점수)")'위클리페이퍼' 카테고리의 다른 글
| 데이터 증강 (Data Augmentation)과 주요 기법 (0) | 2026.08.19 |
|---|---|
| 이미지 분류 모델의 필수 과정: 전처리, 증강, 그리고 전이 학습 (0) | 2026.08.19 |
| PyTorch에서 텐서란 무엇이고, NumPy의 Array(배열)과 어떤 차이가 있나요? (0) | 2026.08.10 |
| 딥러닝 성능 향상을 위한 하이퍼파라미터 튜닝 가이드 (0) | 2026.08.03 |
| 딥러닝과 머신러닝 간의 포함관계에 대하여 (0) | 2026.08.03 |