ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Tensorflow Keras - 7일차 (Resnet50V2) 및 실제 이미지로 학습하기
    Machine Learning/Tensorflow 2021. 4. 2. 18:39
    반응형

    전이학습(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

     

    Joonyeong97/Tensorflow-tutorial

    GitHub Desktop tutorial repository. Contribute to Joonyeong97/Tensorflow-tutorial development by creating an account on GitHub.

    github.com

     

    반응형
Designed by Tistory.