自定义Keras生成器比Keras的bult生成器慢得多

时间:2018-10-12 14:28:13

标签: python tensorflow machine-learning keras deep-learning

我有一个多标签分类问题。我写了这个自定义生成器。它从磁盘读取图像和输出标签,并以32的大小批量返回它们。

def get_input(img_name):
    path = os.path.join("images", img_name)
    img = image.load_img(path, target_size=(224, 224))

    return img


def get_output(img_name, file_path):
    data = pd.read_csv(file_path, delim_whitespace=True, header=None)

    img_id = img_name.split(".")[0]
    img_id = img_id.lstrip("0")
    img_id = int(img_id)

    labels = data.loc[img_id - 1].values
    labels = labels[1:]

    labels = list(labels)
    label_arrays = []
    for i in range(20):
        val = np.zeros((1))
        val[0] = labels[i]
        label_arrays.append(val)

    return label_arrays


def preprocess_input(img_name):
    img = get_input(img_name)
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)    
    return x

def train_generator(batch_size):
    file_path = "train.txt"
    data = pd.read_csv(file_path, delim_whitespace=True, header=None)

    while True:
        for i in range(math.floor(8000/batch_size)):
            x_batch = np.zeros(shape=(32, 224, 224, 3))
            y_batch = np.zeros(shape=(32, 20))
            for j in range(batch_size):
                img_name = data.loc[i * batch_size + j].values
                img_name = img_name[0]
                x = preprocess_input(img_name)
                y = get_output(img_name, file_path)
                x_batch[j, :, :, :] = x
                y_batch[j] = y

            ys = []
            for i in range(20):
              ys.append(y_batch[:,i])

            yield(x_batch, ys)

标签返回模型时出现了一个小问题,并在以下问题中得到解决: training a multi-output keras model

我在单个输出问题上测试了此生成器。此自定义生成器非常慢。使用此自定义生成器的单个时间段的预计到达时间约为27小时,而内置生成器(使用flow_from_directory)单个时间段则需要25分钟。我究竟做错了什么?

除了所使用的生成器外,两个测试的训练过程都相同。验证生成器类似于训练生成器。我知道我无法达到Keras内置发电机的效率,但是这种速度差异太大。

编辑

我阅读了一些有关创建自定义生成器的指南。

Writing Custom Keras Generators

custom generator for fit_generator() that yields multiple inputs with different shapes

1 个答案:

答案 0 :(得分:0)

也许当您的自定义生成器在cpu上运行时,内置的生成器会在gpu上处理数据,这会大大降低速度。

另一个猜测是因为Keras在后台使用Dataset。您的实现可能使用feed-dict,这是将信息传递给TensorFlow的最慢的方法。将数据输入模型的最好方法是使用输入管道,以确保GPU永远不必等待新的东西进入。