Deep Learning/Tensorflow

[Tensorflow.keras] 모델 FPS에 대한 이상 현상

jstar0525 2022. 1. 23. 01:58
반응형

tensorflow2.4.1-gpu 도커 버전에서

모델의 FPS를 체크할 때 발견한 이상현상

(2.7.0-gpu에서도 확인함)

 

data.py 파일 안에 DataGenerator를 상속하여 만든 커스텀 클래스는 아래와 같다

import os
import numpy as np
from PIL import Image
import tensorflow as tf

class DataGenerator(tf.keras.utils.Sequence):
    'Generates data for Keras'
    def __init__(self, img_dir, lbl_dir, batch_size=32, shuffle=False):
        'Initialization'
        self.IDs = os.listdir(img_dir)
        self.IDs.sort()
        self.img_dir = img_dir
        self.lbl_dir = lbl_dir
        self.batch_size = batch_size
        self.shuffle = shuffle
        self.on_epoch_end()

    def __len__(self):
        'Denotes the number of batches per epoch'
        return int(np.floor(len(self.IDs) / self.batch_size))

    def __getitem__(self, index):
        'Generate one batch of data'
        # Generate indexes of the batch
        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]
        # Find list of IDs
        batch_IDs = [self.IDs[k] for k in indexes]
        # Generate data
        images, labels = self.__data_generation__(batch_IDs)

        return images, labels
    
    def on_epoch_end(self):
        'Updates indexes after each epoch'
        self.indexes = np.arange(len(self.IDs))
        if self.shuffle == True:
            np.random.shuffle(self.indexes)

    @staticmethod
    def stack_imgs(img_IDs):
    
        images=[]
        for img_ID in img_IDs:
            image = np.asarray(Image.open(img_ID))
            images.append(image/255)
            
        images  = np.array(images)
        
        return images

    @staticmethod
    def stack_lbls(lbl_IDs):
        
        labels=[]
        for lbl_ID in lbl_IDs:
            target = np.array(Image.open(lbl_ID))
            # 1 : node
            # 2 : internode
            # 3 : growth_point
            target[target==3] = 1
            labels.append(target)
            
        labels  = np.array(labels)
        
        return labels

    def __data_generation__(self, batch_IDs):
        'Generates data containing batch_size samples'

        images = self.stack_imgs([self.img_dir + i for i in batch_IDs])
        labels = self.stack_lbls([self.lbl_dir + i for i in batch_IDs])

        return images, labels

 

이를 이용하여 FPS를 아래와 같이 2가지 방법으로 각각 측정하였다.

 

이미지 크기는 1x640x480x3

 

import time
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

import data

test_generator = data.DataGenerator(img_dir = './dataset/train/imgs/', 
                                     lbl_dir = './dataset/train/lbls/', 
                                     batch_size=1000, shuffle=False)

model = tf.keras.models.load_model('mymodel.h5')

data = test_generator[0][0]
fps = []

for i in range(1000):
    img = np.expand_dims(data[i], axis=0)
    start = time.time()
    #1 FPS
    # mask = model.predict(img)
    #2 FPS
    # mask = model(img)
    total = time.time() - start
    print(total)
    fps.append(1/(total))
    
plt.plot(fps)
plt.show()

print(np.array(fps).mean())

 

그 결과는 아래와 같다.

 

 

model.predict()는 큰 batch size에 대하여 추론을 하는 것이기 때문에

model() 방법이 더 빠르다는 것을 아래 링크에서 확인하였다.

 

https://github.com/tensorflow/tensorflow/issues/40261

 

model.predict is much slower on TF 2.1+ · Issue #40261 · tensorflow/tensorflow

System information OS Platform and Distribution (e.g., Linux Ubuntu 16.04): WIndows 10 and Ubuntu 18.04 TensorFlow installed from (source or binary): Binary with pip3 TensorFlow version (use comman...

github.com

 

이상한 현상은 model.predict()에서 측정한 FPS는

FLOPs와 Parameters에 대하여 연관성이 보이지만,

 

model()을 이용한 FPS 측정은 이전 방법보다 빠르지만

FLOPs와 Parameters 간의 연관성을 찾기 힘들다.

 

혹시 이와 같은 문제 원인을 아시는 분은 댓글부탁드립니다.

반응형