Crested Gecko 성별 구분 AI 개발 과정
안녕하세요! 이전 블로그에서는 개발환경 구상에 대한 내용을 적어 보았으며 이번에는 Crested Gecko(크레스티드 게코)의 성별을 구분하는 딥러닝 모델을 개발하는 과정을 소개하려고 합니다. 이번 프로젝트는 TensorFlow와 Keras를 활용하여 CNN(Convolutional Neural Network)을 구현하고, 데이터를 증강하여 모델의 성능을 극대화하는 과정을 다룹니다.
1. 프로젝트 소개
크레스티드 게코의 성별을 구분하기 위해 사진 데이터를 사용하여 AI 모델을 학습시키는 프로젝트입니다. 이번 프로젝트의 주요 목표는 딥러닝 모델을 통해 성별을 효과적으로 분류할 수 있도록 하는 것입니다.
2. 데이터 준비
데이터 경로 설정
데이터는 "aicres/" 디렉토리에 저장되어 있으며, 학습 및 검증 데이터를 자동으로 나누는 기능을 사용하였습니다.
# 데이터 경로 설정
data_dir = "aicres/"
img_height, img_width = 224, 224
batch_size = 32
데이터셋 로드
image_dataset_from_directory를 사용하여 데이터를 학습용(train)과 검증용(validation)으로 나눕니다.
train_ds = tf.keras.utils.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="training",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size
)
val_ds = tf.keras.utils.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="validation",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size
)
3. 데이터 증강 및 최적화
데이터 증강
딥러닝 모델이 데이터 부족 문제를 극복하고 더 높은 일반화 성능을 가지도록 데이터 증강(Data Augmentation)을 적용합니다. 증강에는 좌우 반전, 회전, 줌, 대비 조정 등이 포함됩니다.
data_augmentation = tf.keras.Sequential([
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.2),
layers.RandomZoom(0.1),
layers.RandomContrast(0.1),
])
증강된 데이터셋을 생성하기 위해 map 함수를 사용합니다:
augmented_train_ds = train_ds.map(
lambda x, y: (data_augmentation(x, training=True), y)
)
데이터셋 성능 최적화
prefetch를 사용하여 데이터 로드 속도를 최적화합니다.
AUTOTUNE = tf.data.AUTOTUNE
augmented_train_ds = augmented_train_ds.prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.prefetch(buffer_size=AUTOTUNE)
4. 데이터 통계 확인
학습 데이터셋의 클래스별 샘플 수를 확인하여 데이터가 균형 잡혀 있는지 확인합니다.
class_counts = np.zeros(len(train_ds.class_names))
for images, labels in train_ds:
for label in labels.numpy():
class_counts[label] += 1
print("클래스별 샘플 수:", dict(zip(train_ds.class_names, class_counts)))
5. CNN 모델 설계
CNN이란?
CNN(Convolutional Neural Network)은 이미지 데이터 분석에 특화된 딥러닝 모델입니다. 합성곱(Convolution) 연산을 통해 이미지의 공간적 특성을 추출하며, 풀링(Pooling) 레이어를 통해 불필요한 정보를 줄이고 계산 효율성을 높입니다. CNN은 특히 이미지 분류, 물체 검출 등의 문제에서 높은 성능을 발휘합니다.
모델 정의
다음은 CNN 모델의 주요 구성 요소입니다:
- 입력 레이어: 이미지 데이터를 입력받는 첫 번째 레이어입니다.
- 합성곱층(Conv2D): 이미지의 특징을 추출하는 핵심 레이어입니다.
- 풀링층(MaxPooling2D): 데이터의 크기를 줄이고 중요한 정보를 강조하는 역할을 합니다.
- 완전 연결층(Dense): 추출된 특징을 바탕으로 최종 분류를 수행합니다.
- 출력층: 이진 분류 문제에서는 Sigmoid 활성화 함수를 사용하여 두 클래스 중 하나를 예측합니다.
model = models.Sequential([
# 입력 레이어
layers.InputLayer(input_shape=(img_height, img_width, 3)),
# 첫 번째 합성곱층
layers.Conv2D(32, (3, 3), activation='relu',
kernel_regularizer=regularizers.L2(0.001)),
layers.MaxPooling2D((2, 2)),
# 두 번째 합성곱층
layers.Conv2D(64, (3, 3), activation='relu',
kernel_regularizer=regularizers.L2(0.001)),
layers.MaxPooling2D((2, 2)),
# 세 번째 합성곱층
layers.Conv2D(128, (3, 3), activation='relu',
kernel_regularizer=regularizers.L2(0.001)),
layers.MaxPooling2D((2, 2)),
# 평탄화 및 완전 연결층
layers.Flatten(),
layers.Dense(128, activation='relu',
kernel_regularizer=regularizers.L2(0.001)),
layers.Dense(1, activation='sigmoid',
kernel_regularizer=regularizers.L2(0.001))
],name="GeckoGenderAI")
L2 정규화란?
L2 정규화는 모델의 과적합(overfitting)을 방지하기 위한 기법 중 하나입니다. 이는 가중치 값에 패널티를 추가하여 너무 큰 값이 학습되지 않도록 제어합니다. L2 정규화를 적용하면 모델이 더 일반화된 패턴을 학습하게 되어 새로운 데이터에 대해 더 나은 성능을 보일 수 있습니다. 위 코드에서는 kernel_regularizer=regularizers.L2(0.001)를 통해 L2 정규화를 적용하였습니다.
모델 컴파일
모델을 학습시키기 위해 Adam 옵티마이저와 이진 크로스엔트로피 손실 함수를 사용합니다.
model.compile(
optimizer='adam', # Adam 최적화 알고리즘
loss='binary_crossentropy', # 이진 크로스엔트로피 손실 함수
metrics=['accuracy'] # 정확도 측정
)
6. 모델 학습
모델 학습은 10 에포크(epoch) 동안 진행되며, 학습 데이터셋과 검증 데이터셋의 성능을 모니터링합니다.
history = model.fit(
augmented_train_ds, # 학습 데이터셋
epochs=10, # 학습 반복 횟수
validation_data=val_ds, # 검증 데이터셋
steps_per_epoch=train_batch_count, # 한 epoch당 학습 배치 수
validation_steps=val_batch_count, # 한 epoch당 검증 배치 수
verbose=1 # 학습 과정 출력
)
7. 학습 결과 시각화
정확도 및 손실 시각화
학습 및 검증 데이터셋의 정확도와 손실 변화를 그래프로 확인합니다.
# 정확도 시각화
plt.plot(history.history['accuracy'], label='Train Accuracy')
plt.plot(history.history['val_accuracy'], label='Val Accuracy')
plt.title('Accuracy over epochs')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()
# 손실 시각화
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Val Loss')
plt.title('Loss over epochs')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
8. 모델 평가
검증 데이터셋에서 모델의 최종 성능을 평가합니다.
val_loss, val_accuracy = model.evaluate(val_ds)
print(f"검증 데이터셋에 대한 손실: {val_loss}")
print(f"검증 데이터셋에 대한 정확도: {val_accuracy}")
결론
정확도는 약 70%에 근접하고 손실율은 처음에는 7점대가 넘었는데 L2정규화를 통하여 2.0대로 낮췄습니다. 현재 학습데이터 수가 현저하게 수가 작기에 손실율은 과소적합 때문에 발생하는게 아닐까란 생각도 들고 그렇습니다. 이를 보강하기 위해서 데이터를 조금 더 모아보고 계속 진행해 보겠습니다.
이 프로젝트가 도움이 되었길 바라며, 질문이 있다면 언제든지 댓글로 남겨주세요!
'Python > AI' 카테고리의 다른 글
[GGA] 데이터 수집 및 개발 환경 -VScode(파이썬 적용 및 이전 버전 설치) (0) | 2025.01.22 |
---|---|
[GeckoGenderAI] 프로젝트 구상 및 시작하기. (0) | 2025.01.09 |
댓글