如何使用预训练的InceptionV3加速Keras CNN

时间:2019-03-20 11:55:28

标签: python tensorflow keras conv-neural-network

我想训练一个卷积神经网络来识别两种类型的类。
我还想使用像InceptionV3这样已经受过训练的模型的第一层卷积层。
但是,培训过程真的很慢。您有什么建议可以改善吗?我不会提到我的CPU,RAM,这里我只关心瓶颈在哪里,我可以改进些什么(我的图像已经是229x299x3)。

from keras.applications import InceptionV3
from keras import layers
from keras.models import Model
from keras import optimizers
from keras.preprocessing.image import ImageDataGenerator
import numpy as np
import os


def generator(images_dir):
    datagen = ImageDataGenerator(rescale=1. / 255)
    gen = datagen.flow_from_directory(
        images_dir,
        target_size=(segment_size, segment_size),
        batch_size=batch_size,
        class_mode='categorical',
        shuffle=True)
    return gen


def num_files_in_folder(folder):
    count = 0
    for subdir, dirs, files in os.walk(folder):
        for file in files:
            if not file.startswith("."):
                count += 1
    return count


segment_size = 229
batch_size = 32
base_model = InceptionV3(weights='imagenet',
                         include_top=False,
                         input_shape=(segment_size, segment_size, 3))
x = base_model.output
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dense(1024, activation='relu')(x)
predictions = layers.Dense(2, activation='softmax')(x)

model = Model(inputs=base_model.input, outputs=predictions)

for layer in base_model.layers:
    layer.trainable = False

model.compile(optimizer=optimizers.SGD(lr=0.01, nesterov=True),
              loss='categorical_crossentropy',
              metrics=['acc'])

train_dir = "/home/user/train"
validation_dir = "/home/user/val"
train_gen = generator(train_dir)
val_gen = generator(validation_dir)
steps_per_epoch = int(np.ceil(num_files_in_folder(train_dir) / batch_size))
validation_steps = int(np.ceil(num_files_in_folder(validation_dir) / batch_size))

history = model.fit_generator(
    generator=train_gen,
    steps_per_epoch=steps_per_epoch,
    epochs=10,
    validation_data=val_gen,
    validation_steps=validation_steps,
    use_multiprocessing=False,
    verbose=1)

2 个答案:

答案 0 :(得分:1)

首先,我为您提供将数据转换为TFRecords的方法,并避免使用flow_from_directoryImageDataGenerator是快速原型制作的不错选择,但是TFRecords及其对应的TF基础结构(队列/运行器/阅读器)实际上已针对快速阅读进行了优化。通过使用tf.data API,尤其是Dataset.prefetch(),可以大大提高速度。

在大多数情况下,读取的数据是瓶颈,我可以在这里停下来。但是在那之后,我也会尝试:

答案 1 :(得分:0)

我会用tf.data.Dataset.from_tensor_slices试试 假设您有训练集train_path的路径。首先,您从中创建数据集对象。您也可以传递路径from_tensor_slices((image_path, labels_path))或文件名/标签列表,而不是路径。稍后可以使用解析功能对其进行处理。

dataset = tf.data.Dataset.from_tensor_slices(image_path)

然后,您可以将任何解析函数进行混洗,批处理和映射到该数据集。您可以控制将随机播放缓冲区预装入多少个示例。重复控件的纪元计数,最好不要设置为None,因此它将无限期地重复。您可以使用普通批处理功能,也可以与

结合使用
dataset = dataset.shuffle().repeat()
dataset.apply(tf.data.experimental.map_and_batch(map_func=parse_func, batch_size,num_parallel_batches))

您需要定义解析函数以从文件名加载实际数据

def parse_func(filename):
    f = tf.read_file(filename)
    img = tf.image.decode_image(f)
    label = #get label from filename
    return img, l

将其应用于数据集对象后,将包含成对的图像/标签对。

请记住,批处理在此管道内进行,因此您不需要在model.fit中使用批处理,但是您需要传递历元数和每个历元的步骤。后者可能会有些棘手,因为您无法像len(dataset)一样进行处理,因此应事先进行计算。

model.fit(dataset, epochs, steps_per_epoch)

您可以对测试数据集执行相同的操作。您也可以使用

检查其内容
iterator = dataset.make_one_shot_iterator()
with tf.Session() as sess:
    print(sess.run(iterator.get_next()))

这将输出num_batches。