728x90
반응형
SMALL
Dog&Cat 데이터
# 데이터 불러오기 : Cats vs Dogs dataset
!curl -O https://download.microsoft.com/download/3/E/1/3E1C3F21-ECDB-4869-8368-6DEBA77B919F/kagglecatsanddogs_5340.zip
import os
import shutil
import zipfile
ROOT_DIR = '/content'
DATA_ROOT_DIR = os.path.join(ROOT_DIR, 'catsanddogs')
with zipfile.ZipFile(os.path.join(ROOT_DIR, 'kagglecatsanddogs_5340.zip'), 'r') as target_file:
target_file.extractall(DATA_ROOT_DIR)
EfficientNet
import tensorflow as tf
from tensorflow.keras import Input
from tensorflow.keras.applications import EfficientNetB0
from tensorflow.keras.applications.efficientnet import preprocess_input, decode_predictions
from tensorflow.keras.preprocessing.image import load_img, img_to_array, array_to_img, ImageDataGenerator
from tensorflow.keras.layers import Activation, Dropout, Flatten, Dense, Lambda, GlobalAveragePooling2D
from tensorflow.keras.models import Model
from tensorflow.keras import optimizers
from tensorflow.keras.utils import to_categorical
import glob
import sys
import numpy as np
from skimage.io import imread
import matplotlib.pyplot as plt
from IPython.display import Image
batch_size = 48
width = 150
height = 150
epochs = 40
NUM_TRAIN = 2000
NUM_TEST = 1000
dropout_rate = 0.2
input_shape = (height, width, 3)
# 실제 데이터가 존재하는 패스
original_dataset_dir = DATA_ROOT_DIR + '/PetImages'
cat_images = glob.glob(os.path.join(original_dataset_dir, "Cat", '*.jpg'))
dog_images = glob.glob(os.path.join(original_dataset_dir, "Dog", '*.jpg'))
print("total cat images: {}\n\rtotal dog images: {}".format(len(cat_images), len(dog_images)))
# 데이터셋을 저장할 폴더
base_dir = './data/dog_vs_cat_small'
os.makedirs(base_dir, exist_ok=True)
# 학습, 검증, 테스트 데이터가 들어갈 폴더 설정
train_dir = os.path.join(base_dir, 'train')
os.makedirs(train_dir, exist_ok=True)
validation_dir = os.path.join(base_dir, 'validation')
os.makedirs(validation_dir, exist_ok=True)
test_dir = os.path.join(base_dir, 'test')
os.makedirs(test_dir, exist_ok=True)
# 각 dog, cat 이미지에 대한 폴더를 제작
train_cats_dir = os.path.join(train_dir, 'cats')
os.makedirs(train_cats_dir, exist_ok=True)
train_dogs_dir = os.path.join(train_dir, 'dogs')
os.makedirs(train_dogs_dir, exist_ok=True)
validation_cats_dir = os.path.join(validation_dir, 'cats')
os.makedirs(validation_cats_dir, exist_ok=True)
validation_dogs_dir = os.path.join(validation_dir, 'dogs')
os.makedirs(validation_dogs_dir, exist_ok=True)
test_cats_dir = os.path.join(test_dir, 'cats')
os.makedirs(test_cats_dir, exist_ok=True)
test_dogs_dir = os.path.join(test_dir, 'dogs')
os.makedirs(test_dogs_dir, exist_ok=True)
# NUM_TRAIN//2개의 영상을 나누어 각 폴더에 복사
fnames = cat_images[:NUM_TRAIN//2]
for fname in fnames:
dst = os.path.join(train_cats_dir, os.path.basename(fname))
shutil.copyfile(fname, dst)
offset = NUM_TRAIN//2
fnames = cat_images[offset:offset + NUM_TEST // 2]
for fname in fnames:
dst = os.path.join(validation_cats_dir, os.path.basename(fname))
shutil.copyfile(fname, dst)
offset = offset + NUM_TEST // 2
fnames = cat_images[offset:offset + NUM_TEST // 2]
for fname in fnames:
dst = os.path.join(test_cats_dir, os.path.basename(fname))
shutil.copyfile(fname, dst)
fnames = dog_images[:NUM_TRAIN//2]
for fname in fnames:
dst = os.path.join(train_dogs_dir, os.path.basename(fname))
shutil.copyfile(fname, dst)
offset = NUM_TRAIN//2
fnames = dog_images[offset:offset + NUM_TEST // 2]
for fname in fnames:
dst = os.path.join(validation_dogs_dir, os.path.basename(fname))
shutil.copyfile(fname, dst)
offset = offset + NUM_TEST // 2
fnames = dog_images[offset:offset + NUM_TEST // 2]
for fname in fnames:
dst = os.path.join(test_dogs_dir, os.path.basename(fname))
shutil.copyfile(fname, dst)
total cat images: 12500
total dog images: 12500
데이터셋 분리
train_datagen = ImageDataGenerator(rescale=1./255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_dir,
target_size=(height, width),
batch_size=batch_size,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(validation_dir,
target_size=(height, width),
batch_size=batch_size,
class_mode='categorical')
Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.
모델 생성
Tensorflow.keras의 ImageDataGenerator 라이브러리를 통해 위에서 나눈 각 데이터들의 generator를 만들어준다.
base_model = EfficientNetB0(weights='imagenet', include_top=False)
모델을 transfer learning (전이 학습) 방법으로 사용할 때, Keras 라이브러리에서는 top-layer를 제거할 수 있는 옵션을 제공한다. 이 옵션은 1280개의 feature를 1000개의 ImageNet 클래스 예측으로 바꾸는 마지막 Dense layer를 제외한다. Top layer를 원하는 다른 레이어로 바꿈으로써 EfficientNet을 전이 학습 워크플로우의 feature extractor로써 사용할 수 있다.
x = base_model.output # 4d
print(np.shape(x))
x = GlobalAveragePooling2D()(x) # 2d
print(np.shape(x))
x = Dense(64, activation='relu')(x)
predictions = Dense(2, activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=predictions)
for layer in base_model.layers:
layer.trainable = False
model.summary()
model.compile(loss='categorical_crossentropy',
optimizer=optimizers.RMSprop(lr=2e-5),
metrics=['acc'])
history = model.fit_generator(train_generator,
steps_per_epoch=NUM_TRAIN // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=NUM_TEST // batch_size,
verbose=1,
use_multiprocessing=True,
workers=4)
모델 평가
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_x = range(len(acc))
plt.plot(epochs_x, acc, 'bo', label='Training acc')
plt.plot(epochs_x, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs_x, loss, 'bo', label='Training loss')
plt.plot(epochs_x, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
cat_img = cat_images[-1]
dog_img= dog_images[-1]
앞서 학습한 모델을 새로운 test set에 적용하여 정확도를 평가할 수 있다.
from tensorflow.keras.preprocessing import image
def predict_image(img_path):
img = image.load_img(img_path, target_size=(height, width))
x = image.img_to_array(img)
x = x.reshape((1,) + x.shape)
x /= 255.
result = model.predict([x])[0][0]
if result > 0.5:
animal = "cat"
else:
animal = "dog"
result = 1 - result
return animal,result
print(predict_image(cat_img))
print(predict_image(dog_img))
728x90
반응형
LIST
'Visual Intelligence > Image Classification' 카테고리의 다른 글
[Image Classification] MobileNet V2 (0) | 2022.09.23 |
---|---|
[Image Classification] MobileNet V1 (0) | 2022.09.14 |
[Image Classification] EfficientNet (0) | 2022.09.14 |
[Image Classification] DenseNet (MNIST) (0) | 2022.09.14 |
[Image Classification] DenseNet (0) | 2022.09.13 |