이미지 분류/판별 방법과 파이썬 예제
이미지 분류/판별 방법과 파이썬 예제
본 문서는 이미지 분류(Image Classification)의 기본 개념과 접근 방식, 특히 딥러닝 기반의 CNN 모델을 설명합니다. 또한, 파이썬과 TensorFlow/Keras 라이브러리를 사용하여 직접 이미지를 판별하는 전체 과정을 코드 예제와 함께 상세히 다룹니다.
1. 이미지 분류/판별의 개념과 방법
이미지 분류란 주어진 이미지가 어떤 클래스(레이블)에 속하는지를 컴퓨터가 판별하는 기술입니다. 예를 들어, 컴퓨터에 고양이 사진을 보여주면 '고양이'라고 정확히 예측하도록 만드는 것입니다. 이 기술은 크게 전통적인 머신러닝 방식과 딥러닝 방식으로 나눌 수 있습니다.
전통적인 머신러닝 기반 방법
딥러닝이 부상하기 전에는 사람이 직접 이미지의 특징(Feature)을 추출하고, 이 특징을 기반으로 분류기(Classifier)를 학습시키는 2단계 접근 방식을 사용했습니다.
- 특징 추출 (Feature Extraction): 전문 지식을 바탕으로 이미지의 형태(Edge), 질감(Texture), 색상 분포 등 주요 특징을 수치화합니다. (예: SIFT, HOG, SURF 기법)
- 분류기 학습 (Classifier Training): 추출된 특징 벡터를 SVM(Support Vector Machine), 랜덤 포레스트(Random Forest)와 같은 머신러닝 모델에 입력하여 특정 클래스로 분류하도록 학습시킵니다.
이 방식은 어떤 특징을 추출하느냐에 따라 성능이 크게 좌우되며, 복잡하고 다양한 이미지를 판별하는 데 한계가 있었습니다.
딥러닝 기반 방법 (CNN)
현대의 이미지 분류는 대부분 합성곱 신경망(Convolutional Neural Network, CNN)이라는 딥러닝 모델을 통해 이루어집니다. CNN은 인간의 시신경 구조를 모방하여 설계되었으며, 이미지의 특징을 자동으로 학습하고 추출하는 강력한 능력을 가집니다.
- 자동 특징 추출: 모델이 데이터로부터 직접 이미지의 계층적인 특징(단순한 선 → 복잡한 형태 → 객체의 일부)을 학습하므로, 사람이 특징을 설계할 필요가 없습니다.
- 높은 성능: 대규모 이미지 데이터셋(예: ImageNet)에서 인간의 판별 능력을 뛰어넘는 정확도를 보이며, 이미지 분류의 표준 기술로 자리 잡았습니다.
- 유명 모델: LeNet-5, AlexNet, VGGNet, ResNet, EfficientNet 등 다양한 구조의 CNN 모델이 개발되어 사용되고 있습니다.
2. 파이썬을 이용한 이미지 판별 (TensorFlow/Keras 예제)
여기서는 가장 대표적인 딥러닝 프레임워크인 TensorFlow와 그 상위 API인 Keras를 사용하여 간단한 CNN 모델을 만들고, CIFAR-10 데이터셋을 분류하는 전체 과정을 보여줍니다. CIFAR-10은 10개의 클래스(비행기, 자동차, 새, 고양이 등)로 구성된 32x32 크기의 컬러 이미지 데이터셋입니다.
프로세스 요약
- 라이브러리 임포트: 필요한 TensorFlow, Keras, NumPy, Matplotlib 등을 불러옵니다.
- 데이터셋 준비: Keras에 내장된 CIFAR-10 데이터셋을 로드하고, 학습용/테스트용으로 나눕니다.
- 데이터 전처리: 모델 학습이 용이하도록 이미지 픽셀 값을 0~1 사이로 정규화합니다.
- CNN 모델 구축: `Conv2D`, `MaxPooling2D`, `Flatten`, `Dense` 레이어를 쌓아 분류 모델을 설계합니다.
- 모델 컴파일 및 학습: 손실 함수, 옵티마이저를 설정하고 학습 데이터로 모델을 훈련(fit)시킵니다.
- 모델 평가: 학습이 끝난 모델을 테스트 데이터로 평가하여 정확도를 확인합니다.
전체 코드 예제
# 1. 라이브러리 임포트
import tensorflow as tf
from tensorflow.keras import layers, models, datasets
import numpy as np
import matplotlib.pyplot as plt
# 2. 데이터셋 준비 (CIFAR-10)
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()
# 클래스 이름 정의
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
'dog', 'frog', 'horse', 'ship', 'truck']
# 3. 데이터 전처리 (정규화)
# 픽셀 값을 0~1 사이로 조정
train_images, test_images = train_images / 255.0, test_images / 255.0
# 4. CNN 모델 구축
model = models.Sequential()
# 첫 번째 합성곱 블록
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.MaxPooling2D((2, 2)))
# 두 번째 합성곱 블록
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
# 세 번째 합성곱 블록
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
# 분류를 위한 Dense 레이어 추가
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax')) # 10개 클래스에 대한 확률 출력
# 모델 구조 확인
model.summary()
# 5. 모델 컴파일 및 학습
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['accuracy'])
history = model.fit(train_images, train_labels, epochs=10,
validation_data=(test_images, test_labels))
# 6. 모델 평가
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print(f'\n테스트 정확도: {test_acc:.4f}')
# 예측 결과 시각화 (테스트 이미지 중 첫 10개)
predictions = model.predict(test_images)
plt.figure(figsize=(10, 10))
for i in range(10):
plt.subplot(5, 2, i + 1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(test_images[i], cmap=plt.cm.binary)
predicted_label = np.argmax(predictions[i])
true_label = test_labels[i][0]
if predicted_label == true_label:
color = 'blue'
else:
color = 'red'
plt.xlabel(f"{class_names[predicted_label]} (실제: {class_names[true_label]})", color=color)
plt.tight_layout()
plt.show()