2. 잘 읽어 왔을까? 데이터 확인하기
데이터가 잘 불러와졌는지 확인하는 과정은 매우 중요합니다. 데이터 셋 읽어 오기 코드를 실행한 후 데이터셋이 정상적으로 로드되었는지 확인하려면, 데이터의 구조(Metadata)를 출력해 보거나 실제 이미지 몇 장을 화면에 띄워보는 것이 가장 확실합니다.
코랩에서 바로 확인하실 수 있는 3가지 방법을 소개해 드립니다.
1) 데이터셋 정보 요약 보기 (info 객체 활용)
tfds.load에서 with_info=True를 설정했기 때문에 info 객체에 데이터셋의 전체 정보가 담겨 있습니다.
| # 전체 이미지 개수와 라벨 종류 확인 print(f"전체 데이터 정보: {info.features}") print(f"라벨 이름: {info.features['label'].names}") # ['cat', 'dog'] 출력 print(f"훈련 데이터 개수: {info.splits['train'].num_examples}") |

2) 실제 이미지와 라벨 시각화 (가장 추천)
데이터셋에서 샘플을 몇 개 꺼내서 눈으로 직접 확인하는 방법입니다. take(n) 함수를 사용하면 $n$개의 데이터를 가져올 수 있습니다.
# 훈련 데이터에서 5개만 가져와서 출력
plt.figure(figsize=(10, 10))
for i, (image, label) in enumerate(train_data.take(5)):
ax = plt.subplot(1, 5, i + 1)
plt.imshow(image)
plt.title(info.features['label'].int2str(label)) # 숫자로 된 라벨을 문자열로 변환
plt.axis("off")

3) 데이터 텐서 구조 확인
데이터의 형태(이미지 해상도, 채널 수)와 라벨의 자료형을 확인합니다.
| # 데이터 한 개를 추출해서 속성 확인 for image, label in train_data.take(1): print("이미지 형태(Height, Width, Channel):", image.shape) print("라벨 값:", label.numpy()) # 0(고양이) 또는 1(개) |

3. 데이터 전처리
컴퓨터가 이미지를 잘 학습할 수 있도록 크기를 통일하고, 0~255 사이의 픽셀 값을 0~1 사이로 정규화합니다.
| 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) |

1) format_image 함수 정의
def format_image ( image , label ) 에서 image와 label은 이 함수가 실행될 때 입력으로 들어오는 '재료'
image: 실제 이미지 데이터 (픽셀 값) : 이 입력값은 사진의 색상 정보를 담고 있는 거대한 숫자 묶음입니다
label: 해당 이미지의 정답 (라벨) : 이 입력값은 해당 사진이 무엇인지를 알려주는 이정표입니다.
# 1. 정수(int)를 실수(float)로 변환
image = tf.cast(image, tf.float32)
원본 이미지는 픽셀 값이 0~255 사이의 정수(uint8)입니다. 하지만 딥러닝 연산(곱셈, 나눗셈 등)을 하려면 소수점이 있는 실수 형태여야 훨씬 정교하게 학습할 수 있습니다.
# 2. 정규화 (Normalization)
image = image / 255.0
컴퓨터는 숫자가 너무 크면(예: 255) 계산에 부담을 느낍니다. 모든 값을 0.0~1.0 사이의 작은 숫자로 줄여주면 학습 속도가 훨씬 빨라지고 안정적이 됩니다.
정규화: RGB 3가지 색상 채널은 그대로 둔 채, 각 채널의 숫자 범위만 0~255에서 0.0~1.0으로 스케일만 줄이는 것입니다.
숫자가 255처럼 크면 곱하기를 반복할 때 결과값이 기하급수적으로 커져서 계산 장치에 과부하가 걸리거나 학습이 망가질 수 있습니다(이를 Gradient Exploding이라고 합니다).값을 0.0~1.0 사이로 맞춰주면 아무리 곱해도 숫자가 폭주하지 않고 미세한 차이(소수점 단위)를 정교하게 학습할 수 있습니다.
# 3. 크기 조정 (Resizing)
image = tf.image.resize(image, (150, 150))
return image, label
개와 고양이 사진은 제각각 크기가 다릅니다(가로가 길거나 세로가 길거나). 모델에 입력할 때는 동일한 규격이 필요하므로 모든 사진을 150x150 크기로 강제로 맞춥니다.
2) 파이프라인 적용 및 배치(Batch) 설정
함수를 만들었으니 이제 실제 데이터 전체에 적용하는 단계입니다
.map(format_image):
수만 장의 이미지를 일일이 하나씩 변환하는 코드를 짜는 대신, map을 쓰면 텐서플로우가 알아서 아주 빠르게 모든 이미지에 전처리 함수를 적용합니다.
.batch(32):
딥러닝 모델은 수만 장을 한꺼번에 공부하지 않습니다. 한 번에 32장씩 묶어서 공부하고, 정답을 확인하고, 다시 다음 32장을 공부하는 방식을 택합니다. 이때 한 묶음의 크기를 배치 사이즈(Batch Size)라고 합니다.
※ train_batches, test_batches 는 파이썬 코드에서 데이터를 담고 있는 변수(Variable)입니다. 단순히 숫자 하나나 문자열을 담는 변수와 달리, 여기에는 "학습을 위해 예쁘게 가공된 이미지 뭉치들"이 들어 있습니다.
4. CNN 모델 설계 (Convolutional Neural Network)
이미지의 특징을 추출하기 위해 합성곱 신경망(CNN)을 사용합니다. 구조는 크게 특징 추출부와 분류부로 나뉩니다. 가중치(Weights)를 알아서 최적화하는 핵심 단계 포함, 가중치를 스스로 최적화할 수 있도록 똑똑한 수리공(Adam)과 정교한 채점 기준(Loss)을 모델에 장착해준 것
| 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']) |

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() |

학습이 끝나고 나오는 그래프(plt.show())를 통해 모델의 상태를 진단할 수 있습니다.
- accuracy (파란색 실선): 훈련 데이터에 대한 정답률입니다. 보통 학습이 진행될수록 1.0(100%)을 향해 올라갑니다.
- val_accuracy (주황색 점선): 검증 데이터에 대한 정답률입니다. 이 선이 파란색 선과 함께 잘 올라가야 모델이 제대로 배운 것입니다.
💡 그래프를 볼 때 주의할 점 (과적합 Check)
만약 accuracy는 계속 올라가는데 val_accuracy가 어느 순간부터 멈추거나 떨어진다면, 모델이 새로운 사진을 구분하는 능력을 키우는 대신 훈련 데이터의 사진들을 그냥 통째로 외워버린 상태(과적합, Overfitting)일 가능성이 높습니다.
이때는 데이터를 더 늘리거나, 앞서 언급한 드롭아웃(Dropout) 기법을 추가하여 모델을 더 겸손하게 만들어야 합니다.
입력한 이미지로 개와 고양이를 구분 하는 프로그램 만들기
import numpy as np
from google.colab import files
from tensorflow.keras.preprocessing import image
# 1. 파일 업로드 창 띄우기
uploaded = files.upload()
for fn in uploaded.keys():
# 2. 이미지 불러오기 및 학습 때와 동일한 크기(150x150)로 조정
path = fn
img = image.load_img(path, target_size=(150, 150))
x = image.img_to_array(img)
# 3. 정규화 및 배치 차원 추가 (모델은 묶음 단위로 입력을 받기 때문)
x = x / 255.0
x = np.expand_dims(x, axis=0)
# 4. 예측 수행
images = np.vstack([x])
classes = model.predict(images, batch_size=10)
# 5. 결과 출력 (Sigmoid 결과값이 0.5보다 크면 개, 아니면 고양이)
print(f"파일명: {fn}")
if classes[0] > 0.5:
print(f"결과: 이 사진은 '개(Dog)'일 확률이 {classes[0][0]*100:.2f}% 입니다.")
else:
print(f"결과: 이 사진은 '고양이(Cat)'일 확률이 {(1-classes[0][0])*100:.2f}% 입니다.")
관련 동영상
'업무 자동화 > AI' 카테고리의 다른 글
| '개와 고양이 분류' 실습 #2 (0) | 2026.05.14 |
|---|---|
| '개와 고양이 분류' 실습 #1 (0) | 2026.05.14 |
| '개와 고양이 분류' 프로젝트 #2 - 이미지 데이터셋 읽어오기 (0) | 2026.05.13 |
| '개와 고양이 분류' 프로젝트 #1 (0) | 2026.05.13 |
| 딥러닝 #2 . . . .Gradient Descent(경사 하강법) (0) | 2026.04.21 |