'개와 고양이 분류' 실습 #2
3. 데이터 전처리def format_image(image, label): image = tf.cast(image, tf.float32) image = image / 255.0 # 정규화 image = tf.image.resize(image, (150, 150)) return image, label# map: 모든 데이터에 format_image 함수를 적용해라!# batch(
tool-2020.tistory.com
"개와 고양이 분류' 실습 #2"에서 과적합(Overfitting) 현상이 나타났습니다. 이거를 제거 하는 방법을 적용한 코드로 다시 시작 했습니다.
※ 수정된 코드
"""
'개와 고양이 분류' - 과적합(Overfitting) 개선 버전
적용 기법:
1. 데이터 증강 (Data Augmentation)
2. 드롭아웃 (Dropout)
3. L2 규제 (L2 Regularization)
4. 조기 종료 (Early Stopping)
"""
import tensorflow as tf
import tensorflow_datasets as tfds
import matplotlib.pyplot as plt
from tensorflow.keras import layers, models, regularizers
from tensorflow.keras.callbacks import EarlyStopping
# ──────────────────────────────────────────
# 1. 데이터셋 로드
# ──────────────────────────────────────────
(train_data, test_data), info = tfds.load(
'cats_vs_dogs',
split=['train[:80%]', 'train[80%:]'],
as_supervised=True,
with_info=True
)
print("전체 이미지 수:", info.splits['train'].num_examples)
print("라벨 종류:", info.features['label'].names) # ['cat', 'dog']
# ──────────────────────────────────────────
# 2. 데이터 전처리 함수 정의
# ──────────────────────────────────────────
IMG_SIZE = (150, 150)
BATCH_SIZE = 32
def format_image(image, label):
"""기본 전처리: 정규화 + 리사이즈"""
image = tf.cast(image, tf.float32)
image = image / 255.0 # 0~1 정규화
image = tf.image.resize(image, IMG_SIZE)
return image, label
# ──────────────────────────────────────────
# 3. 데이터 증강 (Data Augmentation) - 훈련 데이터 전용
# ──────────────────────────────────────────
# 모델이 학습 데이터를 '통째로 외우는' 것을 방지
# → 이미지를 랜덤으로 변형하여 다양성을 인위적으로 늘림
def augment_image(image, label):
"""증강 전처리: 기본 전처리 + 랜덤 변형"""
image, label = format_image(image, label)
image = tf.image.random_flip_left_right(image) # 랜덤 좌우 반전
image = tf.image.random_brightness(image, 0.2) # 랜덤 밝기 조정
image = tf.image.random_contrast(image, 0.8, 1.2) # 랜덤 대비 조정
image = tf.clip_by_value(image, 0.0, 1.0) # 0~1 범위로 클리핑
return image, label
# 훈련셋: 증강 적용 / 검증셋: 기본 전처리만
train_batches = (
train_data
.map(augment_image, num_parallel_calls=tf.data.AUTOTUNE)
.shuffle(1000) # 데이터 순서를 랜덤하게 섞음
.batch(BATCH_SIZE)
.prefetch(tf.data.AUTOTUNE) # 다음 배치를 미리 준비
)
test_batches = (
test_data
.map(format_image, num_parallel_calls=tf.data.AUTOTUNE)
.batch(BATCH_SIZE)
.prefetch(tf.data.AUTOTUNE)
)
# 배치 확인
for image_batch, label_batch in train_batches.take(1):
print("배치 이미지 형태:", image_batch.shape) # (32, 150, 150, 3)
print("배치 라벨 형태:", label_batch.shape) # (32,)
# ──────────────────────────────────────────
# 4. 개선된 CNN 모델 설계
# - Dropout: 과적합 방지 (학습 중 뉴런 무작위 비활성화)
# - L2 Regularization: 가중치가 너무 커지지 않도록 제약
# - Input() 객체: 권장 방식으로 입력 형태 정의 (UserWarning 제거)
# ──────────────────────────────────────────
model = models.Sequential([
# 입력 정의 (UserWarning 해결)
layers.Input(shape=(150, 150, 3)),
# ── 특징 추출 블록 1 ──
layers.Conv2D(32, (3, 3), activation='relu',
kernel_regularizer=regularizers.l2(1e-4)), # L2 규제
layers.MaxPooling2D(2, 2),
# ── 특징 추출 블록 2 ──
layers.Conv2D(64, (3, 3), activation='relu',
kernel_regularizer=regularizers.l2(1e-4)),
layers.MaxPooling2D(2, 2),
# ── 특징 추출 블록 3 ──
layers.Conv2D(128, (3, 3), activation='relu',
kernel_regularizer=regularizers.l2(1e-4)),
layers.MaxPooling2D(2, 2),
# ── 분류 블록 ──
layers.Flatten(),
layers.Dense(512, activation='relu',
kernel_regularizer=regularizers.l2(1e-4)),
layers.Dropout(0.5), # 학습 중 50% 뉴런 무작위 비활성화 → 과적합 방지
layers.Dense(1, activation='sigmoid') # 이진 분류 (0=고양이, 1=개)
])
model.compile(
optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy']
)
model.summary()
# ──────────────────────────────────────────
# 5. 조기 종료 (Early Stopping) 콜백 설정
# - val_loss가 개선되지 않으면 학습 자동 중단
# - patience=5: 5 epoch 동안 개선 없으면 멈춤
# - restore_best_weights: 가장 좋았던 시점의 가중치로 복원
# ──────────────────────────────────────────
early_stopping = EarlyStopping(
monitor='val_loss',
patience=5,
restore_best_weights=True,
verbose=1
)
# ──────────────────────────────────────────
# 6. 모델 학습
# ──────────────────────────────────────────
history = model.fit(
train_batches,
epochs=30, # 최대 30 epoch (Early Stopping이 조기 중단)
validation_data=test_batches,
callbacks=[early_stopping]
)
# ──────────────────────────────────────────
# 7. 학습 결과 시각화
# ──────────────────────────────────────────
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
# 정확도 그래프
ax1.plot(history.history['accuracy'], label='훈련 정확도')
ax1.plot(history.history['val_accuracy'], label='검증 정확도')
ax1.set_title('정확도 (Accuracy)')
ax1.set_xlabel('Epoch')
ax1.set_ylabel('Accuracy')
ax1.legend(loc='lower right')
ax1.grid(True)
# 손실 그래프
ax2.plot(history.history['loss'], label='훈련 손실')
ax2.plot(history.history['val_loss'], label='검증 손실')
ax2.set_title('손실 (Loss)')
ax2.set_xlabel('Epoch')
ax2.set_ylabel('Loss')
ax2.legend(loc='upper right')
ax2.grid(True)
plt.suptitle('개와 고양이 분류 - 과적합 개선 결과', fontsize=14)
plt.tight_layout()
plt.savefig('training_result.png', dpi=150, bbox_inches='tight')
plt.show()
# 최종 성능 출력
final_train_acc = history.history['accuracy'][-1]
final_val_acc = history.history['val_accuracy'][-1]
print(f"\n✅ 최종 훈련 정확도: {final_train_acc:.4f} ({final_train_acc*100:.2f}%)")
print(f"✅ 최종 검증 정확도: {final_val_acc:.4f} ({final_val_acc*100:.2f}%)")
print(f"✅ 훈련/검증 격차: {(final_train_acc - final_val_acc)*100:.2f}%p")
# 모델 저장
model.save("cats_vs_dogs_model.h5")
print("모델 저장 완료!")
아래와 같이 "개와 고양이 분류' 실습 #2" 코드를 아래 개선된 코드 항목들을 추가 되었습니다.

※실행 결과

이 개선 코드를 적용하면 훈련/검증 정확도 격차가 크게 줄어들어 val_accuracy 85~90% 수준을 기대할 수 있습니다.
구글의 제미나이로 "개와 고양이 분류'" 판단하는 모델을 만들어 코랩 환경에서 실행 보았고, 문젬점을 확인하였습니다.
제미나이에서 제공한 코드 수정을 "크로이드"에서 맡겨, 수정된 코드를 만들어 코랩에서 다시 실행한 결과 만족 스런 결과를 얻었습니다
• 2025년 12월, AI 코딩의 분기점
안드레이 카파시는 2025년 12월을 AI 코딩의 중요한 분기점으로 지목합니다. 이전까지 AI 코딩 도구는 도움을 주는 수준이었으나, 해당 시점부터 에이전트가 실제로 일관성 있는 워크플로우를 통해 코드를 작성하기 시작했습니다. 이는 단순히 코드 자동 완성을 넘어, 리서치, 계획, 코드 작성, 테스트, 디버깅까지 이어지는 복잡한 과정을 가능하게 한 변화입니다.
• 소프트웨어 3.0 시대와 신경 컴퓨터의 도래
현재 소프트웨어 개발은 프롬프트 작성이 곧 프로그래밍이 되는 소프트웨어 3.0 시대로 진입했습니다. 컨텍스트 윈도우에 무엇을 넣느냐가 중요해졌으며, 복잡한 코드를 직접 작성하는 대신 AI 에이전트가 환경을 인식하고 문제를 해결하는 사례가 늘고 있습니다. 미래에는 신경망이 코드 실행의 주체가 되는 '신경 컴퓨터'가 보편화될 수 있으며, 이는 기존의 컴퓨팅 패러다임을 뒤집을 가능성을 시사합니다.
• AI의 강점과 인간의 역할: 검증 가능성과 이해
AI는 수학이나 코딩처럼 명확하게 채점 가능한 영역에서는 천재적인 능력을 발휘하지만, 상식이나 추론이 필요한 영역에서는 들쭉날쭉한 모습을 보입니다. 따라서 AI는 '생각(Thinking)'과 같은 처리 작업은 아웃소싱할 수 있지만, 정보가 자기 것으로 내면화되고 연결되는 '이해(Understanding)'는 인간 고유의 영역으로 남을 것입니다. 인간은 AI가 처리하는 과정에 대한 감독, 미학적 판단, 스펙 설계 등 더 높은 차원의 역할을 수행해야 합니다.
'업무 자동화 > AI' 카테고리의 다른 글
| 성공적이고 신뢰할 수 있는 분석 모형(Model)을 구축 (0) | 2026.06.01 |
|---|---|
| '개와 고양이 분류' 실습 #4 (0) | 2026.05.15 |
| '개와 고양이 분류' 실습 #2 (0) | 2026.05.14 |
| '개와 고양이 분류' 실습 #1 (0) | 2026.05.14 |
| '개와 고양이 분류' 프로젝트 #3 - 이미지 데이터 전처리 (0) | 2026.05.13 |