logo

[딥러닝] 합성곱 신경망(CNN)

 

CNN 소개

 

CNN의 정의

합성곱 신경망(Convolutional Neural Networks, CNN)은 특히 시각적 이미지를 분석하기 위해 설계된 딥러닝의 한 아키텍처입니다. 이 신경망은 이미지에서 패턴과 특징을 추출하고 식별하는 능력이 뛰어나며, 이러한 과정을 통해 이미지 분류, 객체 탐지 등 다양한 과제를 처리할 수 있습니다. 핵심적인 구성 요소로는 합성곱층(Convolutional layer), 풀링층(Pooling layer), 완전 연결층(Fully Connected layer) 등이 있으며, 각 층은 이미지로부터 점차적으로 고수준의 특징을 추출하는 역할을 수행합니다.

 

CNN의 역사적 배경

CNN의 기반은 1980년대로 거슬러 올라가며, 특히 1989년 르쿤(Yann LeCun) 등이 제안한 'LeNet'이라는 구조가 널리 알려져 있습니다. 이후 컴퓨터 성능의 향상과 대용량 데이터셋의 사용이 가능해지면서 2012년 AlexNet이 ImageNet 경쟁에서 뛰어난 성능을 보임으로써 CNN이 더욱 주목받기 시작했습니다. 이후 다양한 모델과 연구가 속속 등장하며 오늘날의 다양한 응용 분야에 활용되는 기초를 마련하였습니다.

 

CNN이 주로 사용되는 분야

CNN은 그 효율성과 정확도 덕분에 다양한 분야에서 활용되고 있습니다. 주요 활용 분야는 다음과 같습니다:

  • 이미지 인식: 사진 속 객체를 인식하고 분류합니다. 예를 들어, 사진에 있는 동물이 고양이인지 개인지 분류하는 과정이 이에 해당합니다.

  • 비디오 분석: 비디오 내의 객체를 추적하고 분석합니다. 예를 들어, CCTV 영상에서 사람 또는 차량의 움직임을 감지하고 분석하는 것이 여기에 속합니다.

  • 자연어 처리: 비록 CNN이 이미지 분석에 최적화되어 있는 구조이지만, 최근에는 단어의 위치를 고려하여 텍스트 데이터에서 패턴을 추출하는 등의 방법으로 NLP(Natural Language Processing) 분야에도 적용되고 있습니다.

  • 의료 영상 분석: MRI나 CT 스캔 같은 의료 영상을 분석하여 질병의 진단에 도움을 줍니다.

이러한 분야에서 CNN의 활용은 데이터로부터 보다 정교한 정보를 얻을 수 있게 해 줌으로써 연구 및 개발에 막대한 영향을 미치고 있습니다.

 

예시 코드 (PyTorch를 사용한 CNN 구조 구현)

아래는 PyTorch를 사용하여 간단한 CNN 모델을 구현하는 예시 코드입니다.

import torch
import torch.nn as nn
import torch.nn.functional as F

# 간단한 CNN 모델 정의
class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()

        # 첫 번째 합성곱층: 1개의 입력 채널을 받아 16개의 출력 채널 생성, 커널 크기는 3
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, stride=1, padding=1)

        # 두 번째 합성곱층: 16개의 입력 채널을 받아 32개의 출력 채널 생성, 커널 크기는 3
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1)

        # 풀링층: 최대 풀링을 사용하여 특징 맵의 크기를 줄임
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0)

        # 완전 연결층: 분류를 위한 층
        self.fc = nn.Linear(32 * 7 * 7, 10)

    def forward(self, x):
        # x: [batch_size, channels, height, width]
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))

        # 특징 맵을 평탄화(flatten)
        x = x.view(-1, 32 * 7 * 7)

        # 완전 연결층을 통과
        x = self.fc(x)

        return x

# 모델 인스턴스 생성
model = SimpleCNN()
print(model)

이 코드는 CNN의 기본 구조를 보여주며, 실제 응용 프로그램에서는 데이터의 특성과 요구 사항에 따라 모델의 구조(예를 들어, 층의 수, 필터의 크기, 풀링 방법 등)를 세밀하게 조정해야 합니다.


 

합성곱 신경망의 구성 요소

합성곱(Convolution) 레이어

합성곱 레이어는 CNN의 기본 빌딩 블록으로, 입력 이미지에 여러 필터를 적용하여 특징을 추출하는 역할을 합니다. 이 과정은 필터(또는 커널)가 입력 데이터 위를 지나가며, 각 위치에서 필터와 입력 데이터의 요소별 곱셈을 수행하고, 그 결과를 합산하여 출력 특징 맵(feature map)을 생성합니다.

필터(커널)의 역할

필터는 이미지의 특정 특징을 잡아내기 위한 가중치의 집합입니다. 예를 들어, 가로선, 세로선, 모서리와 같은 시각적 특징을 감지하는데 사용됩니다. 각 필터는 학습 과정을 통해 최적화되어 가장 중요한 특징을 캡처할 수 있습니다.

스트라이드(stride)와 패딩(padding)의 개념

스트라이드는 필터가 입력 데이터 위를 이동하는 간격을 나타냅니다. 더 큰 스트라이드는 출력 특징 맵의 크기를 줄입니다. 패딩은 입력 데이터의 가장자리에 추가적인 픽셀(보통 0)을 넣어, 필터가 데이터의 가장자리 정보를 더 잘 이해할 수 있게 하고, 출력 특징 맵의 크기를 조절합니다.

import torch
import torch.nn as nn

# 합성곱 레이어 예시
conv_layer = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, stride=1, padding=1)
# 예제 데이터: 1개의 채널을 가진 28x28 이미지
example_data = torch.rand(1, 1, 28, 28)
output = conv_layer(example_data)
print(output.shape) # 출력 크기 확인

활성화 함수

활성화 함수는 선형 변환 후의 비선형성을 도입하여 신경망이 복잡한 문제를 해결할 수 있도록 합니다. 가장 널리 사용되는 활성화 함수 중 하나는 ReLU(Rectified Linear Unit)입니다.

ReLU와 같은 활성화 함수의 중요성

ReLU는 음수 값을 0으로 만들어서 모델의 비선형성을 증가시키며, 계산 비용이 낮아 효율적입니다. 다른 활성화 함수로는 Sigmoid, Tanh, Leaky ReLU 등이 있습니다.

활성화 함수의 종류와 선택 기준
  • ReLU는 일반적으로 가장 많이 사용되지만, 학습 초기 단계에서 음수 값을 갖는 뉴런이 죽는 문제가 있을 수 있습니다.
  • Leaky ReLU는 이 문제를 해결하기 위해 음수 값에 대해 매우 작은 기울기를 부여합니다.
  • Sigmoid와 Tanh는 출력 범위가 각각 (0, 1), (-1, 1)으로 제한되어 있어 특정 상황에서 유용할 수 있습니다.
# 활성화 함수 예시
relu = nn.ReLU()
output = relu(output) # 앞서 정의한 conv_layer의 출력에 ReLU 적용
print(output.shape)

풀링(Pooling) 레이어

풀링 레이어는 특징 맵의 크기를 줄이는 동시에 중요한 정보를 유지하는 역할을 합니다. 이는 계산량을 줄이고, 모델의 오버피팅을 방지하는 데 도움이 됩니다.

최대 풀링(Max Pooling)과 평균 풀링(Average Pooling)의 차이

최대 풀링은 지정된 윈도우 내에서 최댓값을 취하는 방식으로, 주로 사용됩니다. 반면, 평균 풀링은 윈도우 내 모든 값의 평균을 취하여 더 부드러운 특징 맵을 생성합니다.

# 최대 풀링 레이어 예시
max_pool = nn.MaxPool2d(kernel_size=2, stride=2)
output = max_pool(output)
print(output.shape)

완전 연결 레이어(Fully Connected Layer)

완전 연결 레이어는 합성곱 및 풀링 레이어를 통해 추출된 특징을 바탕으로 최종 분류 또는 회귀를 수행합니다. 이 레이어는 모든 입력을 받아 각 클래스에 대한 예측을 생성합니다.

입력 데이터를 최종 분류 결과로 매핑하는 과정

피처 맵은 일렬로 펼쳐져 완전 연결 레이어의 입력으로 사용됩니다. 이 레이어는 학습된 가중치를 사용하여 입력을 최종 출력 클래스와 연결합니다.

# 완전 연결 레이어 예시
fc_layer = nn.Linear(output.size(1) * output.size(2) * output.size(3), 10) # 10개의 출력 클래스
output = output.view(output.size(0), -1) # 피처 맵을 1차원으로 펼치기
output = fc_layer(output)
print(output.shape)

이러한 과정을 통해, CNN은 이미지 내의 복잡한 특징을 잘 추출하고 이를 바탕으로 정확한 분류 또는 다른 예측 작업을 수행할 수 있습니다.


CNN 아키텍처 설계는 딥러닝의 핵심적인 부분으로, 복잡한 이미지 인식, 분류 및 기타 시각적 태스크를 수행하는데 있어 중요합니다. 여기서는 CNN 아키텍처의 기본 구조와 몇 가지 유명한 아키텍처에 대해 설명하고, 아키텍처를 선택할 때 고려해야 할 사항들에 대해 논의하겠습니다.

 

CNN 아키텍처의 기본 구조

CNN(합성곱 신경망)의 기본 구조는 여러 합성곱(Convolution) 층, 활성화 함수(예: ReLU), 풀링(Pooling) 층, 그리고 최종적으로 완전 연결(Fully Connected) 층으로 구성됩니다. CNN은 이러한 층들을 통해 이미지에서 고수준 특징을 자동으로 학습할 수 있습니다.

 

다양한 CNN 아키텍처 소개 및 비교

  1. LeNet: 딥러닝에서 초기에 사용된 합성곱 신경망으로, 간단한 아키텍처에도 불구하고 손글씨 숫자 인식에 효과적이었습니다.
  2. AlexNet: 이미지넷 챌린지에서 큰 성공을 거둔 아키텍처로, 깊은 층, ReLU 활성화 함수, 드롭아웃 등 현대의 많은 CNN 기법이 이 모델에서 처음 도입되었습니다.
  3. VGG: 층의 깊이에 초점을 맞춘 아키텍처로, 아주 깊은 층(16층, 19층)을 사용하여 높은 성능을 달성했습니다.
  4. GoogLeNet(이노셉션): 네트워크 내의 네트워크 구조를 도입하여 계산 효율성과 성능을 모두 잡은 모델입니다.
  5. ResNet: 잔차 연결을 도입하여 깊은 네트워크에서 발생할 수 있는 소실된 기울기 문제를 해결했습니다. 깊은 네트워크를 효율적으로 훈련할 수 있는 발판을 마련했습니다.

이 모델들의 선택은 주로 데이터셋의 크기, 문제의 복잡도, 처리해야 할 이미지의 종류, 그리고 사용 가능한 컴퓨팅 자원에 의해 결정됩니다.

 

아키텍처 선택 시 고려해야 할 요소들

  • 데이터셋 크기와 복잡도: 작은 데이터셋에는 단순한 모델이 더 적합할 수 있으며, 복잡한 데이터셋은 더 깊은 모델을 필요로 할 수 있습니다.
  • 성능: 최대 성능이 목표라면, ResNet 또는 GoogLeNet 같은 더 복잡한 모델을 고려해야 할 수 있습니다.
  • 계산 자원: 깊은 모델은 더 많은 메모리와 계산 시간을 요구합니다. 사용 가능한 자원을 고려해야 합니다.
  • 이해하기 쉬움 및 디버깅: 초기 단계에서는 아키텍처가 이해하기 쉽고 디버깅하기 쉬운 모델을 선택하는 것이 좋습니다.
 

예시 코드: PyTorch를 사용한 간단한 CNN 아키텍처

import torch
import torch.nn as nn

class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1)
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        self.fc = nn.Linear(32 * 32 * 32, 10) # 가정: 입력 이미지 크기는 3x64x64, 출력 클래스는 10개

    def forward(self, x):
        x = self.pool(self.relu(self.conv1(x)))
        x = x.view(-1, 32 * 32 * 32)
        x = self.fc(x)
        return x

# 모델 인스턴스화 및 요약 출력
model = SimpleCNN()
print(model)

이 코드는 PyTorch를 사용하여 정의된 매우 기본적인 CNN 아키텍처를 보여줍니다. 실제 상황에서는 더 많은 합성곱 층, 더 복잡한 네트워크 구조를 사용할 필요가 있습니다.

Previous
정칙화