Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python - Keras를 활용한 이미지 분류 완벽 가이드

이미지 분류란?

이미지 분류(Image Classification)는 컴퓨터 비전 분야에서 가장 기본적이면서도 중요한 작업 중 하나로, 입력된 이미지를 사전에 정의된 카테고리 클래스로 자동으로 구분하는 기술입니다. 딥러닝 프레임워크인 Keras를 활용하면 비교적 간단한 코드로도 강력한 이미지 분류 모델을 구축할 수 있습니다.

일반적으로 이미지 분류 모델을 만드는 대표적인 방법은 다음 두 가지입니다.

  • 처음부터(From Scratch) 작은 신경망 학습하기 — 데이터셋의 규모가 충분히 크거나 단순한 이진 분류 문제일 때 효과적인 방법입니다.
  • VGG16 등 사전 학습 모델의 상위 레이어 미세 조정(Fine-Tuning) — 전이 학습(Transfer Learning)을 활용하여 적은 데이터로도 높은 정확도를 얻을 수 있는 방법입니다.

이 글에서는 첫 번째 방법인 '처음부터 CNN(Convolutional Neural Network) 모델을 구축하고 학습하는 과정'을 예제 코드와 함께 단계별로 살펴보겠습니다.

필요한 라이브러리 임포트

먼저 이미지 증강, 모델 구성, 레이어 정의에 필요한 라이브러리들을 불러옵니다.

# 필요한 라이브러리 임포트
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K

학습 환경 설정

다음으로 이미지 크기, 데이터 경로, 샘플 수, 에포크 수 등 학습에 필요한 기본 파라미터를 설정합니다.

  • train_data_dir: 학습 데이터셋이 위치한 디렉터리
  • validation_data_dir: 검증 데이터가 위치한 디렉터리
  • nb_train_samples: 전체 학습 샘플 수
  • nb_validation_samples: 전체 검증 샘플 수
img_width, img_height = 224, 224
train_data_dir = 'v_data/train'
validation_data_dir = 'v_data/test'
nb_train_samples = 400
nb_validation_samples = 100
epochs = 10
batch_size = 16

# 이미지 데이터 포맷(channels_first / channels_last) 확인
if K.image_data_format() == 'channels_first':
    input_shape = (3, img_width, img_height)
else:
    input_shape = (img_width, img_height, 3)

CNN 모델 구축

Keras의 Sequential API를 사용하여 합성곱 레이어와 풀링 레이어를 쌓아 올려 CNN 모델을 구성합니다.

  • Conv2D: 이미지에 합성곱 연산을 적용하여 특징(feature)을 추출하는 레이어입니다.
  • Activation('relu'): 음수 값은 0으로 만들어 비선형성을 부여하는 활성화 함수입니다.
  • MaxPooling2D: 지정된 크기의 행렬에서 최댓값만 추출하여 특징 맵의 크기를 줄이는 풀링 레이어입니다.
  • Flatten: 다차원 특징 맵을 1차원 벡터로 변환합니다.
  • Dense: 완전 연결층(Fully Connected Layer)으로, 추출된 특징을 바탕으로 최종 분류를 수행하는 은닉층 역할을 합니다.
  • Dropout: 학습 과정에서 일부 뉴런을 무작위로 비활성화하여 과적합(Overfitting)을 방지합니다.
model = Sequential()

# Conv2D: 이미지를 여러 개의 특징 맵으로 변환하는 합성곱 레이어
model.add(Conv2D(32, (2, 2), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32, (2, 2)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (2, 2)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

# 다차원 데이터를 1차원으로 평탄화
model.add(Flatten())

# Dense: 완전 연결 은닉층
model.add(Dense(64))
model.add(Activation('relu'))

# Dropout: 과적합 방지
model.add(Dropout(0.5))

# 출력층 (이진 분류이므로 뉴런 1개 + 시그모이드 활성화)
model.add(Dense(1))
model.add(Activation('sigmoid'))

모델 컴파일

컴파일 단계에서는 손실 함수(loss), 옵티마이저(optimizer), 평가 지표(metrics)를 지정합니다. 이진 분류 문제이므로 손실 함수로 binary_crossentropy, 옵티마이저로 rmsprop을 사용하고, 성능 지표로 정확도(accuracy)를 설정합니다.

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

데이터 증강 및 제너레이터 생성

ImageDataGenerator는 이미지 데이터를 실시간으로 변형하여 학습 데이터의 다양성을 높여주는 도구입니다. 아래 예제에서는 픽셀 값 스케일링(rescale), 전단 변환(shear), 확대/축소(zoom), 좌우 반전(horizontal flip)을 적용하여 이미지의 다양한 방향성을 학습에 반영합니다.

train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1. / 255)

# flow_from_directory: 디렉터리에서 이미지를 읽어 배치 단위로 공급
# target_size: 이미지를 지정한 크기로 리사이즈
train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')

모델 학습 및 저장

fit_generator(최신 버전에서는 model.fit) 함수를 사용해 앞서 만든 제너레이터의 데이터로 모델을 학습시킵니다.

  • steps_per_epoch: 한 에포크 동안 모델이 실행될 스텝 수
  • epochs: 전체 학습 데이터에 대해 순전파(forward pass)와 역전파(backward pass)를 반복할 횟수
  • validation_data: 검증/테스트 데이터를 모델에 공급
  • validation_steps: 검증 샘플 수
model.fit_generator(
    train_generator,
    steps_per_epoch=nb_train_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=nb_validation_samples // batch_size)

# 학습된 모델 가중치 저장
model.save_weights('ImgmodelKeras_saved.h5')

마무리

이상으로 Keras를 사용하여 처음부터 CNN 이미지 분류 모델을 구축하고 학습하는 전체 과정을 살펴보았습니다. 데이터 양이 많아지거나 더 복잡한 다중 클래스 분류 문제를 다룰 때는 VGG16, ResNet 같은 사전 학습 모델을 활용한 전이 학습(Transfer Learning)을 적용하면 더욱 좋은 성능을 얻을 수 있습니다. 저장된 가중치 파일(.h5)을 불러와 새로운 이미지에 대한 예측에 활용할 수도 있습니다.