AI 공부

CNN(컨볼루션 신경망) 딥러닝 모델 2

크레비즈 2025. 6. 2. 20:10

앞에서는 relu와 softmax 활성함수를 통해서 간단한 다층 퍼셉트론 모델을 구축했다면

 

 

CNN(컨볼루션 신경망) 딥러닝 모델 1

오늘은 컨볼루션 신경망에 대해서 공부하였습니다. CNN(Convolutional Neural Network, 합성곱 신경망)은 이미지나 영상처럼 공간 구조를 가진 데이터를 처리하는데 매우 강력한 딥러닝 모델입니다.아래

crebiz-community.tistory.com

 

이번에는 CNN 모델을 사용한 딥러닝 코드를 보겠습니다.

 

이 이미지는 합성곱 신경망(CNN, Convolutional Neural Network)의 구조와 작동 원리를 보여주고 있습니다. 한국어로 설명하겠습니다:

이미지 구성 요소:
1. 왼쪽: 28x28 픽셀 크기의 MNIST 데이터셋 이미지 (숫자 '4'를 보여줌)

2. 중앙: CNN의 주요 구조
  • 여러 층의 "컨볼루션" 레이어 (한국어로 "컨볼루션"이라고 표기됨)
  • 풀링(Pooling) 레이어 (한국어로 "풀링"이라고 표기됨)
  • 각 레이어는 색상이 다른 여러 필터/특성 맵을 나타냄
  • 레이어를 통과하면서 특징이 추출되고 이미지의 공간적 크기는 줄어듦

3. 오른쪽: 완전 연결 계층(Fully Connected Layer)
  • CNN의 마지막 부분으로, 추출된 특징들을 기반으로 분류를 수행
  • 0부터 9까지의 10개 출력 노드가 있어 MNIST 숫자 분류를 나타냄

작동 원리:
1. 입력 이미지(28x28 픽셀 크기의 숫자 '4')가 CNN에 입력됩니다.
2. 컨볼루션 레이어들이 이미지의 특징(모서리, 곡선 등)을 추출합니다.
3. 풀링 레이어는 특징 맵의 크기를 줄이고 중요한 특징을 보존합니다.
4. 여러 컨볼루션과 풀링 레이어를 통과한 후, 데이터는 완전 연결 계층으로 전달됩니다.
5. 완전 연결 계층은 추출된 특징을 기반으로 최종 분류를 수행하여 이미지가 어떤 숫자인지 예측합니다.

이 이미지는 CNN이 어떻게 이미지 데이터로부터 계층적으로 특징을 추출하고, 이를 기반으로 분류 작업을 수행하는지 시각적으로 보여주는 교육용 다이어그램입니다. 특히 MNIST 숫자 인식 작업에 CNN이 어떻게 적용되는지를 설명하고 있습니다.

 

1. CNN 구성

import os
os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
from tensorflow.keras.callbacks import ModelCheckpoint,EarlyStopping
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical

import matplotlib.pyplot as plt
import numpy as np

# 데이터를 불러옵니다.
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1).astype('float32') / 255
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1).astype('float32') / 255
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

# 컨볼루션 신경망의 설정
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), input_shape=(28, 28, 1), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128,  activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

# 모델의 실행 옵션을 설정합니다.
model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

# 모델 최적화를 위한 설정 구간입니다.
model_path = 'data/model/mnist_cnn.keras'
checkpointer = ModelCheckpoint(filepath=model_path, monitor='val_loss', verbose=1, save_best_only=True)
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=10)

# 모델을 실행합니다.
history = model.fit(X_train, y_train, validation_split=0.25, epochs=30, batch_size=200, verbose=0, callbacks=[early_stopping_callback,checkpointer])

# 테스트 정확도를 출력합니다.
print("\n Test Accuracy: %.4f" % (model.evaluate(X_test, y_test)[1]))

 

여기서 컨블루션 신경망(CNN) 모델을 구성하는 부분에 대해서 설명해보겠습니다.

# 컨볼루션 신경망 설정
1. model = Sequential()
  • 케라스의 Sequential 모델을 초기화합니다. 이는 레이어를 순차적으로 쌓아 구성하는 모델입니다.

2. model.add(Conv2D(32, kernel_size=(3, 3), input_shape=(28, 28, 1), activation='relu'))
  • 첫 번째 합성곱(Convolution) 레이어를 추가합니다.
  • 32: 필터의 개수로, 32개의 특징 맵(feature map)을 생성합니다.
  • kernel_size=(3, 3): 3x3 크기의 필터(커널)를 사용합니다.
  • input_shape=(28, 28, 1): 입력 이미지의 크기가 28x28 픽셀이며, 채널이 1개(흑백)임을 지정합니다.
  • activation='relu': 활성화 함수로 ReLU를 사용합니다.

3. model.add(Conv2D(64, (3, 3), activation='relu'))
  • 두 번째 합성곱 레이어를 추가합니다.
  • 64: 64개의 필터를 사용하여 더 많은 특징을 추출합니다.
  • (3, 3): 3x3 크기의 필터를 사용합니다.
  • activation='relu': 활성화 함수로 ReLU를 사용합니다.

4. model.add(MaxPooling2D(pool_size=(2,2)))
  • 최대 풀링(Max Pooling) 레이어를 추가합니다.
  • pool_size=(2,2): 2x2 크기의 풀링 윈도우를 사용합니다.
  • 이 레이어는 특징 맵의 크기를 줄이고 중요한 특징을 보존하는 역할을 합니다.

5. model.add(Dropout(0.25))
  • 드롭아웃 레이어를 추가합니다.
  • 0.25: 25%의 뉴런을 무작위로 비활성화합니다.
  • 이는 과적합(overfitting)을 방지하는 정규화 기법입니다.

6. model.add(Flatten())
  • 다차원 특징 맵을 1차원 벡터로 변환합니다.
  • 이는 합성곱 레이어의 출력을 완전 연결 레이어(Dense)에 입력하기 위해 필요합니다.

7. model.add(Dense(128, activation='relu'))
  • 완전 연결 레이어를 추가합니다.
  • 128: 128개의 뉴런을 가진 레이어입니다.
  • activation='relu': 활성화 함수로 ReLU를 사용합니다.

8. model.add(Dropout(0.5))
  • 또 다른 드롭아웃 레이어를 추가합니다.
  • 0.5: 50%의 뉴런을 무작위로 비활성화합니다.
  • 완전 연결 레이어는 파라미터가 많아 과적합 위험이 높으므로, 더 높은 드롭아웃 비율을 적용합니다.

9. model.add(Dense(10, activation='softmax'))
  • 출력 레이어를 추가합니다.
  • 10: MNIST 데이터셋의 클래스 수(0~9)와 일치하는 10개의 뉴런을 가집니다.
  • activation='softmax': 활성화 함수로 소프트맥스를 사용하여 각 클래스에 속할 확률을 계산합니다.

# 모델 실행 옵션 설정
1. model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
  • 모델의 학습 과정을 설정합니다.
  • loss='categorical_crossentropy': 다중 클래스 분류 문제에 적합한 손실 함수를 사용합니다.
  • optimizer='adam': Adam 최적화 알고리즘을 사용합니다.
  • 이는 학습률을 자동으로 조정하는 효율적인 알고리즘입니다.
  • metrics=['accuracy']: 모델의 성능을 평가하는 지표로 정확도를 사용합니다.

# 종합적 설명
이 코드는 MNIST 숫자 이미지를 분류하기 위한 CNN 모델을 구성합니다. CNN은 이미지 처리에 특화된 신경망으로, 합성곱 레이어를 통해 이미지의 공간적 특징을 효과적으로 추출할 수 있습니다.
모델의 구조는 다음과 같습니다:
  • 두 개의 합성곱 레이어로 이미지의 특징을 추출
  • 최대 풀링으로 특징 맵의 크기를 줄이고 중요 특징을 보존
  • 드롭아웃으로 과적합 방지
  • 특징 맵을 1차원으로 변환
  • 완전 연결 레이어로 고수준 특징 학습
  • 최종 출력 레이어로 10개 클래스에 대한 확률 계산

이러한 구조는 이미지 분류 작업에서 높은 성능을 발휘하며, 특히 MNIST와 같은 비교적 단순한 이미지 데이터셋에서는 매우 효과적입니다.

 

 

2. 이전과 동일한 방법으로 그래프를 비교해봅니다.

# 검증셋과 학습셋의 오차를 저장합니다.
y_vloss = history.history['val_loss']
y_loss = history.history['loss']

# 그래프로 표현해 봅니다.
x_len = np.arange(len(y_loss))
plt.plot(x_len, y_vloss, marker='.', c="red", label='Testset_loss')
plt.plot(x_len, y_loss, marker='.', c="blue", label='Trainset_loss')

# 그래프에 그리드를 주고 레이블을 표시하겠습니다.
plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

 

 

 

3. MLP(다층 퍼셉트론) 와 CNN(합성곱 신경망) 모델의 차이점에 대해서

MLP와 CNN 모델의 차이점과 성능 차이 분석
MLP(다층 퍼셉트론)와 CNN(합성곱 신경망) 모델 간의 정확도 차이(MLP: 0.9816, CNN: 0.9917)에 대해 설명해 드리겠습니다.

# 두 모델의 구조적 차이점
MLP(다층 퍼셉트론) 모델
  • 구조: 입력층, 은닉층, 출력층으로 구성된 완전 연결 네트워크
  • 데이터 처리: 이미지를 1차원 벡터(784 = 28×28)로 펼쳐서 처리
  • 특징: 각 뉴런이 이전 층의 모든 뉴런과 연결됨
  • 공간 정보: 이미지의 2D 공간 정보(픽셀 간의 위치 관계)를 보존하지 못함

CNN(합성곱 신경망) 모델
  • 구조: 합성곱 층, 풀링 층, 완전 연결 층으로 구성
  • 데이터 처리: 이미지의 2D 구조를 그대로 유지하며 처리(28×28×1)
  • 특징: 지역적 특징을 추출하는 필터(커널)를 사용
  • 공간 정보: 이미지의 공간적 구조와 특징을 보존

# CNN이 더 높은 정확도를 보이는 이유
1. 공간적 특징 인식 능력:
  • CNN은 이미지의 공간적 구조를 보존하며 처리하기 때문에, 숫자의 모양과 같은 공간적 패턴을 더 잘 인식합니다.
  • MLP는 이미지를 1차원으로 펼치면서 픽셀 간의 공간적 관계 정보가 손실됩니다.

2. 지역적 특징 추출:
  • CNN의 합성곱 필터는 이미지의 지역적 특징(모서리, 곡선 등)을 효과적으로 추출합니다.
  • 이러한 특징들은 숫자 인식에 중요한 요소입니다.

3. 파라미터 효율성:
  • CNN은 파라미터 공유를 통해 MLP보다 적은 수의 학습 가능한 파라미터로 더 효과적인 학습이 가능합니다.
  • 예: 3×3 필터는 위치에 상관없이 동일한 파라미터를 사용합니다.

4. 계층적 특징 학습:
  • CNN은 저수준 특징(선, 모서리)에서 고수준 특징(숫자의 부분, 전체 형태)까지 계층적으로 학습합니다.
  • 이러한 계층적 특징 추출이 복잡한 패턴 인식에 유리합니다.

5. 풀링을 통한 위치 불변성:
  • 최대 풀링(Max Pooling)은 특징의 위치 변화에 강인한 표현을 학습하게 합니다.
  • 이는 약간 기울어지거나 위치가 이동한 숫자도 잘 인식할 수 있게 합니다.

# 실제 코드에서의 차이점
  • MLP 코드:
      model.add(Dense(512, input_dim=784, activation='relu'))
      model.add(Dense(10, activation='softmax'))
      단순히 두 개의 완전 연결 층으로 구성되어 있습니다.
  • CNN 코드:
      model.add(Conv2D(32, kernel_size=(3, 3), input_shape=(28, 28, 1), activation='relu'))
      model.add(Conv2D(64, (3, 3), activation='relu'))
      model.add(MaxPooling2D(pool_size=(2,2)))
      model.add(Dropout(0.25))
      model.add(Flatten())
      model.add(Dense(128, activation='relu'))
      model.add(Dropout(0.5))
      model.add(Dense(10, activation='softmax'))
      합성곱 층, 풀링 층, 드롭아웃 층, 완전 연결 층 등 더 복잡하고 특화된 구조를 가집니다.

# 결론
CNN이 MLP보다 약 1% 정도 높은 정확도(0.9917 vs 0.9816)를 보이는 것은 이미지 데이터의 공간적 특성을 더 잘 활용하는 CNN의 구조적 장점 때문입니다. MNIST와 같은 비교적 단순한 데이터셋에서도 이러한 차이가 나타나며, 더 복잡한 이미지 데이터셋(예: CIFAR-10, ImageNet)에서는 그 차이가 더욱 두드러집니다.

이러한 이유로 현대 컴퓨터 비전 분야에서는 이미지 처리에 CNN이 표준 모델로 자리 잡게 되었습니다.

--- Claude 3.7 Sonnet 의 설명