ResNet50 Classification Model Transfer Learning

snoop2head·2021년 5월 18일
0
post-thumbnail

Get dataset from Github Private Repo

# get current working directory

import os
os.getcwd()
# Clone dataset github (private) repository to Google Colab

from getpass import getpass
import urllib

username = "snoop2head" #NOT EMAIL!
repo_owner_name = "snoop2head"
repo_name = "custom_dataset"
password = getpass('Password: ')
password = urllib.parse.quote(password) # your password is converted into url format

# Command Line Example: !git clone https://username:password@github.com/username/repository.git
clone_command = 'git clone https://{0}:{1}@github.com/{2}/{3}.git'.format(username, password, repo_owner_name, repo_name)
os.system(clone_command) # commence command line
clone_command, password = "", "" # removing the password from the variable

Gather data into directories

# making directories(or folders) to gather custom dataset

parent_folder = "/content/dataset/"
object_folder = "/content/dataset/custom-object/"
background_folder = "/content/dataset/background/" 

os.mkdir(parent_folder)
os.mkdir(object_folder)
os.mkdir(background_folder)
# Collect picture data into object class and background class folder

import glob
import shutil

source1_object_folder = "/content/custom_dataset/source1_dataset/JPEGImages"
source2_object_folder = "/content/custom_dataset/frame-img"
source2_bg_folder = "/content/custom_dataset/frame-background"

list_object_dir = [source1_object_folder, source2_object_folder]
# move source1 and source2 object images to destination object folder
for source_dir in list_object_dir:
  temp_files_object = os.listdir(source_dir)
  for f in temp_files_object:
      shutil.move(f"{source_dir}/{f}", object_folder)
# move background pics to destination background folder
temp_files_bg = os.listdir(source2_bg_folder)
for f in temp_files_bg:
  shutil.move(f"{source2_bg_folder}/{f}", background_folder)
import random
print("object pics:",random.sample(os.listdir(object_folder), 20))
print("background pics:",random.sample(os.listdir(object_folder), 20))

Reallocate dataset into train, val, test

# Reallocate training dataset, validation dataset, test dataset
!pip install split_folders
import splitfolders

reallocated_parent_folder = "/content/reallocated-dataset/"
os.mkdir(reallocated_parent_folder)

splitfolders.ratio(parent_folder, reallocated_parent_folder, seed=42, ratio=(0.6, 0.2, 0.2))

Transfer Learning Preset

!pip install keras
!pip install matplotlib
import keras
from keras.applications.resnet50 import ResNet50
import matplotlib.pyplot as plt
# Load ResNet50 pretrained on imagenet dataset
resnet_model = ResNet50(weights="imagenet")
resnet_model.summary()
from keras.preprocessing import image
from keras.applications.resnet50 import decode_predictions, preprocess_input
import numpy as np
# Sample Inference on pretrained model
IMG_PATH = "/content/reallocated-dataset/test/custom_object/source1_0006.jpg"
img = image.load_img(IMG_PATH, target_size=(224, 224))

x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
preds = resnet_model.predict(x)
print('Predicted:', decode_predictions(preds, top=5)[0])

plt.imshow(img)

Transfer Learning custom dataset to pretrained model


# fix image height and width - THIS MIGHT LOWER THE INFERENCE PERFORMANCE
img_height, img_width = (224, 224)
batch_size = 32

train_data_dir = "/content/reallocated-dataset/train"
test_data_dir = "/content/reallocated-dataset/test"
val_data_dir = "/content/reallocated-dataset/val"

class_names = ["custom_object","background"]
from keras.applications.resnet50 import preprocess_input, decode_predictions
from keras.preprocessing.image import ImageDataGenerator, load_img
# training settings
train_datagen = ImageDataGenerator(preprocessing_function=preprocess_input, 
                                   shear_range=0.2,
                                   zoom_range=0.2,
                                   horizontal_flip=True,
                                   validation_split=0.4)

train_generator = train_datagen.flow_from_directory(
  train_data_dir,
  target_size=(img_height,img_width),
  batch_size=batch_size,
  class_mode="categorical",
  subset="training"
)

valid_generator = train_datagen.flow_from_directory(
  val_data_dir,
  target_size=(img_height,img_width),
  batch_size=batch_size,
  class_mode="categorical",
  subset="validation"
)

test_generator = train_datagen.flow_from_directory(
  test_data_dir,
  target_size=(img_height,img_width),
  batch_size=batch_size,
  class_mode="categorical",
  subset="validation" # subset only exists as training and validation. No testing.
)
# peeking into sample inputs
x,y = test_generator.next()
print(x.shape)
plt.imshow(x[6])
# training settings
from keras.layers import Conv2D, Flatten, Dense, MaxPool2D, BatchNormalization, GlobalAveragePooling2D
from keras.models import Sequential, Model

# Weights are downloaded automatically when instantiating a model. ResNet 50 Top1 Accuracy is 0.749, Top 5 Accuracy is 0.921
base_model = ResNet50(include_top=False, weights="imagenet") 

# Training Final Layer only
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation="relu")(x)
predictions = Dense(train_generator.num_classes, activation="softmax")(x)

# gets pretrained base_model input, predicts based on custom-dataset trained prediction
model = Model(inputs=base_model.input, outputs=predictions)

# don't touch pretrained base_model
for layer in base_model.layers:
  layer.trainable = False

# adamw optimizer is not available on keras, unfortunately :( 
model.compile(optimizer="adam", loss="categorical_crossentropy", metrics=["accuracy"])

# training begins!
model.fit(train_generator, epochs = 10)
# saving model
MODEL_PATH = os.getcwd()
model.save(f"{MODEL_PATH}/ResNet50_custom_object_Classifier.h5")

test_loss, test_acc = model.evaluate(test_generator, verbose=2)
print("Test Accuracy:", test_acc)
profile
break, compose, display

0개의 댓글