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(32): 데이터를 32개씩 묶어서 가져와라!
train_batches = train_data.map(format_image).batch(32)
test_batches = test_data.map(format_image).batch(32)
위 코드를 실행하고, "train_batches"에 데이터가 있는지 확인을 합니다
for image_batch, label_batch in train_batches.take(1):
print("배치 이미지 형태:", image_batch.shape) # (batch_size, 150, 150, 3)
print("배치 라벨 형태:", label_batch.shape) # (batch_size,)
print("첫 번째 이미지 형태 (정규화 및 리사이즈 후):", image_batch[0].shape)
↓
| 배치 이미지 형태: (32, 150, 150, 3) 배치 라벨 형태: (32,) 첫 번째 이미지 형태 (정규화 및 리사이즈 후): (150, 150, 3) |
4. CNN 모델 설계 (Convolutional Neural Network)
model = models.Sequential([
# 특징 추출 (Convolution & Pooling)
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)),
layers.MaxPooling2D(2, 2),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D(2, 2),
layers.Conv2D(128, (3, 3), activation='relu'),
layers.MaxPooling2D(2, 2),
# 분류 (Dense Layers)
layers.Flatten(),
layers.Dense(512, activation='relu'),
layers.Dense(1, activation='sigmoid') # 개/고양이 이진 분류이므로 sigmoid 사용
])
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
↓
| /usr/local/lib/python3.12/dist-packages/keras/src/layers/convolutional/base_conv.py:113: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead. super().__init__(activity_regularizer=activity_regularizer, **kwargs) |
- 데이터셋 로드 및 확인 (Cells FtziPCNs0Oqs, BaPQkAx00YPW, mZcpDzwl0-JN):
- tensorflow_datasets를 사용하여 'cats_vs_dogs' 데이터셋을 불러왔습니다. 이 데이터셋은 고양이와 개의 이미지로 구성되어 있습니다.
- 전체 데이터 중 80%는 훈련 데이터로, 나머지 20%는 테스트 데이터로 분리했습니다.
- 데이터셋에 대한 기본적인 정보(전체 이미지 개수, 라벨 종류)를 확인했으며, 훈련 데이터에서 몇 개의 샘플 이미지를 시각화하여 확인했습니다.
- 개별 이미지의 형태와 라벨 값(고양이: 0, 개: 1)도 확인했습니다.
- 이미지 전처리 및 배치 처리 (Cells bnOrbkEp1Cl5, 335086da):
- format_image 함수를 정의하여 이미지를 전처리했습니다. 이 함수는 이미지를 0과 1 사이로 정규화하고, 모든 이미지를 150x150 픽셀 크기로 조정합니다.
- map과 batch 함수를 사용하여 훈련 및 테스트 데이터에 이 전처리 함수를 적용하고, 데이터를 32개씩 묶어 배치(batch) 형태로 만들었습니다.
- train_batches에서 하나의 배치를 가져와 이미지와 라벨의 형태를 확인하여, 배치가 32개의 150x150 크기 이미지로 구성되어 있음을 확인했습니다.
- 모델 정의 및 컴파일 (Cell 8ibqQtCD393X):
- 케라스(Keras)의 Sequential API를 사용하여 컨볼루션 신경망(CNN) 모델을 정의했습니다.
- 모델은 특징 추출을 위한 여러 개의 Conv2D 및 MaxPooling2D 레이어와, 분류를 위한 Flatten 및 Dense 레이어로 구성됩니다.
- 마지막 레이어는 개/고양이 이진 분류를 위해 sigmoid 활성화 함수를 사용했습니다.
- adam 옵티마이저와 binary_crossentropy 손실 함수를 사용하여 모델을 컴파일했습니다.
이 메시지는 오류(Error)가 아니라 **경고(Warning)**입니다. 모델은 정상적으로 컴파일되었습니다. 케라스 Sequential 모델을 사용할 때, 첫 번째 레이어에 input_shape 인자를 직접 전달하는 대신, Input(shape=(150, 150, 3))과 같은 Input 객체를 모델의 첫 번째 레이어로 명시적으로 추가하는 것을 권장한다는 의미입니다. 이는 Functional API 스타일에서 모델을 구성할 때 더 유연하고 명확한 방법이지만, 현재 코드 방식도 동작하는 데 문제는 없습니다. 지금은 이 경고를 무시하고 다음 단계로 진행하셔도 됩니다.
5. 모델 학습 및 결과 확인
history = model.fit(train_batches, epochs=10, validation_data=test_batches)
# 학습 결과 시각화
plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label = 'val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')
plt.show()
↓

학습 결과 그래프와 로그를 보니, 아주 전형적인 과적합(Overfitting) 현상이 나타나고 있습니다. 인공지능이 공부를 한 게 아니라 답안지를 통째로 외워버린 상태
1. 주요 지표 분석
| 구분 | 훈련 데이터 (accuracy) | 검증 데이터 (val_accuracy) | 상태 |
| 최종 수치 | 99.17% (거의 완벽) | 79.49% (정체 중) | 격차 매우 큼 |
| 추세 | 계속해서 매끄럽게 상승 | Epoch 2 이후로 정체 또는 하락 | 전형적인 과적합 |
- 훈련 정확도 (accuracy): 1.00에 가까워질 정도로 매우 높습니다. 모델이 주어진 훈련 데이터 안에서는 개와 고양이를 완벽하게 구별한다는 뜻입니다.
- 검증 정확도 (val_accuracy): 그래프의 주황색 선을 보시면, 초반에 잠깐 오르다가 어느 순간부터는 더 이상 오르지 않고 80% 근처에서 머물고 있습니다.
- 손실값 (val_loss): 로그를 보면 val_loss가 Epoch 3(0.4383) 이후로 계속 커져서 마지막에는 1.2180까지 치솟았습니다. 이는 모델이 새로운 데이터를 봤을 때 점점 더 엉뚱한 대답을 하며 확신을 잃어가고 있다는 강력한 신호입니다
2. 왜 이런 결과가 나왔을까요?
모델이 학습 데이터의 특징(귀 모양, 털 색깔 등)을 배우는 대신, 학습 데이터에 포함된 노이즈나 특정 사진의 배경까지 통째로 외워버렸기 때문입니다. 이로 인해 "시험 공부는 열심히 해서 연습 문제는 다 맞히는데, 실제 시험(새로운 데이터)에서는 점수가 안 나오는" 상황이 된 것입니다.
3. 어떻게 해결하면 좋을까요? (개선 팁)
이 성능을 80% 이상으로 끌어올리기 위해서는 다음과 같은 방법들을 시도해 볼 수 있습니다.
10 데이터 증강 (Data Augmentation): 사진을 살짝 돌리거나(Rotation), 좌우를 반전(Flip)시켜서 모델이 사진을 외우지 못하게 방해합니다.
2) 드롭아웃 (Dropout) 추가: 학습 중에 무작위로 일부 신경망을 꺼버리는 기법입니다. 특정 경로에만 의존하지 않게 만들어 과적합을 방지합니다.
예: layers.Dropout(0.5)를 Dense 층 앞에 추가
3) L2 규제 (Regularization): 가중치가 너무 커지지 않게 제한을 두어 모델을 더 단순하게 만듭니다.
4) 조기 종료 (Early Stopping): val_loss가 더 이상 줄어들지 않고 늘어나기 시작할 때(이 그래프에서는 Epoch 2~3 지점) 학습을 스스로 멈추게 설정합니다.
현재 모델은 훈련 데이터에 너무 과하게 맞춰져 있습니다. val_accuracy를 높이기 위해 모델 구조에 Dropout을 추가하거나 데이터 증강 기법을 적용해 보시는 것을 추천
'업무 자동화 > AI' 카테고리의 다른 글
| '개와 고양이 분류' 실습 #4 (0) | 2026.05.15 |
|---|---|
| '개와 고양이 분류' 실습 #3 (0) | 2026.05.15 |
| '개와 고양이 분류' 실습 #1 (0) | 2026.05.14 |
| '개와 고양이 분류' 프로젝트 #3 - 이미지 데이터 전처리 (0) | 2026.05.13 |
| '개와 고양이 분류' 프로젝트 #2 - 이미지 데이터셋 읽어오기 (0) | 2026.05.13 |