-
반응형
전이학습(Transfer learning)을 이용한 학습 방법입니다.
라이브러리
import tensorflow as tf import matplotlib.pyplot as plt from tensorflow.keras.layers import * from tensorflow.keras.models import Model,Sequential import zipfile import gdown
google drive에서 데이터 다운로드
google_path = 'https://drive.google.com/uc?id=' file_id = '1Of_X6StezV0vwE0WrQ7MNbIFjITkW4dJ' output_name = 'animals_images.zip' gdown.download(gdrive_url+file_id,output_name)
zip 압축 해제
input_path = './animals_images.zip' output_path = './data'
zip_animal = zipfile.ZipFile(input_path) zip_animal.extractall(output_path)
train_path = './data/animals'
Hyper parameter 수정
# 예측할 클래스 수 classes = 3 # Input으로 사용될 크기와 채널수 height = 256 width = 256 channels = 3
이미지 처리 진행
image_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1/255, validation_split=0.33) image_data_train = image_generator.flow_from_directory(train_path,subset='training') image_data_test = image_generator.flow_from_directory(train_path,subset='validation')
케라스에서 제공하는 ImageDataGenerator를 이용하면 처음 설정때는 이미지를 스케일하는 방법과
이미지 증폭, 이미지 회전등을 제공합니다. 인스턴스를 받고나면 flow_form_directory 메서드를 이용해서 path만 넣으면 자동으로 전처리가 되는거죠!
모델로드
resnetv2 = tf.keras.applications.ResNet50V2(include_top=False,input_shape=(height,width,channels))
여기서 include_top은 마지막 레이어인 1000개의 클래스를 예측하는 Dense Layer를 안쓰겠다는 뜻입니다.
이러면 이미지의 크기와 상관없이 이미 만들어진 레이어가 resnetv2라는 변수에 담기게 되는거죠!
include_top을 True로 설정하면 크기는 224,224,3으로 제한됩니다.
하지만 우리는 레이어와 이미 학습된 가중치만을 사용합니다.
resnetv2.trainable=False
기존 레이어의 가중치의 학습을 안하겠다고 하는겁니다.
model = Sequential([ resnetv2, Dense(512,activation='relu'), BatchNormalization(), GlobalAveragePooling2D(), Dense(classes,activation='softmax') ])
우리만의 레이어를 다시 한번 쌓아줍니다.
이미 깊게 쌓여진 Resnet이기 때문에 다른 레이어는 거의 할필요 없고,
GlobalAveragePooling2D와 마지막 레이어인 Dense 레이어만 사용을 권합니다.
GlobalAveragePooling2D는 Flatten과 비슷한 역할을 하지만 성능은 전자가 낫다고 합니다..^^
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
resnet50v2 (Functional) (None, 8, 8, 2048) 23564800
_________________________________________________________________
dense_30 (Dense) (None, 8, 8, 512) 1049088
_________________________________________________________________
batch_normalization_15 (Batc (None, 8, 8, 512) 2048
_________________________________________________________________
global_average_pooling2d_5 ( (None, 512) 0
_________________________________________________________________
dense_31 (Dense) (None, 3) 1539
=================================================================
Total params: 24,617,475
Trainable params: 1,051,651
Non-trainable params: 23,565,824
_________________________________________________________________모델학습
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics='accuracy')
def scheduler(epoch, lr): if epoch < 2: return lr else: return lr * tf.math.exp(-0.1) lrs = tf.keras.callbacks.LearningRateScheduler(scheduler)
model.fit(image_data_train,batch_size=32,epochs=5,callbacks=[lrs],validation_data=(image_data_test), validation_steps =image_data_test.samples/image_data_test.batch_size)
Epoch 1/5 63/63 [==============================] - 17s 235ms/step - loss: 0.1536 - accuracy: 0.9465 - val_loss: 0.0319 - val_accuracy: 0.9899 Epoch 2/5 63/63 [==============================] - 14s 220ms/step - loss: 0.0171 - accuracy: 0.9945 - val_loss: 0.0351 - val_accuracy: 0.9889 Epoch 3/5 63/63 [==============================] - 14s 219ms/step - loss: 0.0043 - accuracy: 0.9983 - val_loss: 0.0329 - val_accuracy: 0.9899 Epoch 4/5 63/63 [==============================] - 14s 219ms/step - loss: 0.0022 - accuracy: 1.0000 - val_loss: 0.0317 - val_accuracy: 0.9889 Epoch 5/5 63/63 [==============================] - 14s 220ms/step - loss: 0.0017 - accuracy: 0.9998 - val_loss: 0.0307 - val_accuracy: 0.9899
[185]:
<tensorflow.python.keras.callbacks.History at 0x7f30ac771b50>
Test
from tensorflow.keras.preprocessing.image import load_img from tensorflow.keras.preprocessing.image import img_to_array import matplotlib.pyplot as plt import numpy as np img_height = 256 img_width = 256 filename = ['./data/test/cat.jpg','./data/test/dog.jpg','./data/test/panda.jpg'] predict_dictionary = {0:'cat',1:'dog',2:'panda'} for file in filename: original = load_img(file, target_size = (img_height,img_width)) numpy_image = img_to_array(original) plt.imshow(np.uint8(numpy_image)) plt.show() print("numpy array size : ", numpy_image.shape) image_batch = np.expand_dims(numpy_image , axis = 0) predict = np.argmax(model.predict(image_batch/255.)) print('결과 : ',predict_dictionary[predict])
numpy array size : (256, 256, 3) 결과 : cat
numpy array size : (256, 256, 3) 결과 : dog
numpy array size : (256, 256, 3) 결과 : panda
예측이 잘됐네요~
예측을 하실땐 꼭 이미지를 학습하기전에 전처리 할때 처럼 꼭 전처리를 해줘야합니다!
이미지는 대부분 255.로 나누어줍니다 0~1사이로 Scale하는거죠
긴글 봐주셔서 감사합니다.
다음엔 YoloV5 사용하는 방법을 올립니다.
최종코드는 깃허브에 업로드됩니다.
github.com/Joonyeong97/Tensorflow-tutorial
반응형'Machine Learning > Tensorflow' 카테고리의 다른 글
Tensorflow-tutorial / Test Code 모음집 (0) 2022.04.11 [Python,TF]Upbit API를 이용해서 코인 시세를 예측해보자! (0) 2021.04.15 Tensorflow Keras - 6 (Self Attention layer 이용하기) (0) 2021.03.20 Tensorflow Keras - 5 (자연어처리,IMDB 데이터 이용하기) (0) 2021.03.17 Tensorflow Keras - 4 (자연어처리,감정분석) (0) 2021.03.16