[CV 9] VGG16 모델을 이용한 이미지 분류 1 - 기본 모델 + 증식X 데이터

방선생·2025년 2월 27일
0

Computer Vision

목록 보기
9/16

VGG16 모델

  • 개요 : 옥스포드 대학의 연구팀 VGG에 의해 개발된 이미지 분류용 모델

  • 구조 : Conv2D layer 13개 + MaxPooling2D layer 5개 + Flatten layer 1개 + Dense layer 3개

  • Conv Block : Conv2D 레이어 + Max Pooling 레이어의 계층적 구조

VGG16 모델을 이용한 이미지 분류

  • 기존 모델 불러오기
    • 필요한 라이브러리 임폴트
      • import tensorflow as tf
    • 생성 함수 호출
      • vgg_model = tf.keras.applications.vgg16.VGG16(weights=None, input_shape=(224,224,3))
    • 결과 확인하기
      - vgg_model.summary()

  • 기존 모델의 구조에서 특성 추출 외에 분류를 위한 layer 제거

  • 기존 모델의 출력 units = 1000 → 출력 units = 2로 수정

  • 재구성 모델 생성
    • base_model = tf.keras.applications.vgg16.VGG16(include_top=False,
      weights=None, input_shape=(224,224,3))
    • model = tf.keras.Sequential()
    • model.add(base_model)
    • model.add(tf.keras.layers.Flatten())
    • model.add(tf.keras.layers.Dense(units=2, activation='softmax', kernel_initializer=initializer))

tensorflow.keras.callbacks

  • 딥러닝 학습 시 종료 조건이나 모델 저장 조건 등을 사용자가 원하는 대로 설정할 수 있도록 클래스와 매서드를 제공하는 모듈

  • EarlyStopping 클래스
    • 학습의 상태를 더 이상 개선시키지 못할 경우 학습을 강제로 종료 시킬 수 있는 기능을 제공

    • 사용방법 : early_stop = tf.keras.callbacks.EarlyStopping(monitor='val_loss’,
      verbose=1, patience=5)

    • 매개 변수
      • monitor : 학습 상태 판단의 기준, 예) ‘val_loss’을 입력할 경우, val_loss가 더 이상 감소하지 않을 경우에 작동
      • verbose : 학습의 진행 사항 표시 여부 결정, 학습의 진행 사항을 표시할 경우 verbose=1
      • patience : 학습 상태가 개선 되지 않을 경우 참아주는 횟수



(이 시리즈의 모든 코드는 코랩환경에서 Python으로 작성하였습니다)

VGG16 모델 (기본 모델 + 데이터 증식X) Code 1 (기본 모델 생성)

# 필요한 라이브러리 임폴트
import tensorflow as tf
from PIL import Image
import matplotlib.pyplot as plt
import os
# 기본 모델 생성하기
vgg16_model1 = tf.keras.applications.VGG16(
    weights=None,
    input_shape=(224, 224, 3)
    )

vgg16_model1.summary()
# 모델 생성의 두번째 방법

# 기본 모델 생성하기
base_model = tf.keras.applications.VGG16(
    weights=None,
    input_shape=(224, 224, 3),
    include_top=False
    )

# 결과 확인
base_model.summary()
  • vgg16_model1과 base_model의 차이점
    • vgg16_model1 : include_top이 기본값(True)이므로 VGG16의 원래 완전 연결층(FC Layer)까지 포함한 모델
      • ImageNet과 동일한 1000개 클래스를 분류할 경우 (학습 시키지 않고 사용할 경우)
    • base_model : include_top=False로 설정하여 Fully Connected Layer를 제거
      - VGG16을 기반으로 새로운 모델을 만들거나, 다른 데이터셋을 학습할 경우

VGG16 모델 (기본 모델 + 데이터 증식X) Code 2 (이미지 데이터 전처리)

# zip 파일 압축 해제
#!unzip '/content/drive/MyDrive/CV/cats_and_dogs.zip' -d '/content/drive/MyDrive/CV'
  • 압축 해제가 필요한 경우만 사용 (처음 한번)
### 이미지의 수 확인

# 이미지 폴더 경로 설정
train_path = '/content/drive/MyDrive/CV/cats_and_dogs/train'
val_path = '/content/drive/MyDrive/CV/cats_and_dogs/val'
test_path = '/content/drive/MyDrive/CV/cats_and_dogs/test'

# 학습용 폴더에 들어있는 이미지의 이름과 개수 확인
dogs_path = train_path + '/' + 'dogs'
cats_path = train_path + '/' + 'cats'
dogs_list = os.listdir(dogs_path)
cats_list = os.listdir(cats_path)
print(f'학습용 dogs 폴더에 들어있는 강아지 이미지 파일의 이름 : \n{dogs_list}')
print('-'*80)
print(f'학습용 cats 폴더에 들어있는 고양이 이미지 파일의 이름 : \n{cats_list}')

print('-'*80)

print(f'학습용 dogs 폴더에 들어있는 강아지 이미지의 수 = {len(dogs_list)}')
print('-'*80)
print(f'학습용 cats 폴더에 들어있는 고양이 이미지의 수 = {len(cats_list)}')

print('-'*80)

# 검증용 폴더에 들어있는 이미지의 이름과 개수 확인
dogs_path = val_path + '/' + 'dogs'
cats_path = val_path + '/' + 'cats'
dogs_list = os.listdir(dogs_path)
cats_list = os.listdir(cats_path)
print(f'검증용 dogs 폴더에 들어있는 강아지 이미지 파일의 이름 : \n{dogs_list}')
print('-'*80)
print(f'검증용 cats 폴더에 들어있는 고양이 이미지 파일의 이름 : \n{cats_list}')

print('-'*80)

print(f'검증용 dogs 폴더에 들어있는 강아지 이미지의 수 = {len(dogs_list)}')
print('-'*80)
print(f'검증용 cats 폴더에 들어있는 고양이 이미지의 수 = {len(cats_list)}')

print('-'*80)

# 평가용 폴더에 들어있는 이미지의 이름과 개수 확인
dogs_path = test_path + '/' + 'dogs'
cats_path = test_path + '/' + 'cats'
dogs_list = os.listdir(dogs_path)
cats_list = os.listdir(cats_path)
print(f'평가용 dogs 폴더에 들어있는 강아지 이미지 파일의 이름 : \n{dogs_list}')
print('-'*80)
print(f'평가용 cats 폴더에 들어있는 고양이 이미지 파일의 이름 : \n{cats_list}')

print('-'*80)

print(f'평가용 dogs 폴더에 들어있는 강아지 이미지의 수 = {len(dogs_list)}')
print('-'*80)
print(f'평가용 cats 폴더에 들어있는 고양이 이미지의 수 = {len(cats_list)}')
# ImageDataGenerator() 클래스 함수 실행 --> 데이터 증식(X)
train_datagen1 = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1/255)
val_datagen1 = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1/255)
test_datagen1 = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1/255)
### ImageDataGenerator() 함수와 flow_from_directory() 함수를 사용, 입력 데이터 생성

# 학습용 입력 데이터(이미지 + 정답) 생성
train_generator1 = train_datagen1.flow_from_directory(directory=train_path,
                                                     target_size=(224,224),
                                                     batch_size=60,
                                                     class_mode='categorical')

# 검증용 입력 데이터(이미지 + 정답) 생성
val_generator1 = val_datagen1.flow_from_directory(directory=val_path,
                                                 target_size=(224,224),
                                                 batch_size=60,
                                                 class_mode='categorical')

# 평가용 입력 데이터(이미지 + 정답) 생성
test_generator1 = test_datagen1.flow_from_directory(directory=test_path,
                                                   target_size=(224,224),
                                                   batch_size=10,
                                                   class_mode='categorical')
# 생성되는 데이터와 정답 레이블 확인

# 결과물 생성
images, labels = next(train_generator1)

# 생성된 이미지 모양 확인
print(images.shape)

print('-'*80)

# 정답 레이블 확인
print(labels)

VGG16 모델 (기본 모델 + 데이터 증식X) Code 3 (모델 생성 및 학습)

# 재구성 모델 정의하기

# 출력 units 설정
units = 2

# 모델 생성
model1 = tf.keras.Sequential()
model1.add(base_model)

model1.add(tf.keras.layers.Flatten())
model1.add(tf.keras.layers.Dense(units=256, activation='relu'))
model1.add(tf.keras.layers.Dense(units, activation='softmax'))

# 추가 사항
model1.build(input_shape=(None, 224, 224, 3))

# 결과 확인
model1.summary()
# optimizer 재설정
optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001)

# 모델 컴파일
model1.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
# 조기 종료 조건 설정
early_stop = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss',
    patience=3
)

# 학습 진행
model1.fit(
    train_generator1,
    epochs=100,
    callbacks=[early_stop],
    validation_data=val_generator1
)
# model.evaluate() 함수 사용
score = model1.evaluate(test_generator1)

# 결과 확인
print(f'평가용 데이터에 대한 평균 loss : {score[0]}')
print('-'*80)
print(f'평가용 데이터에 대한 평균 accuracy : {score[1]}')








참고 자료

VGG16 논문

profile
AI & Robotics

0개의 댓글