如何通过预先训练的InceptionV3加速我的Keras CNN

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过预先训练的InceptionV3加速我的Keras CNN相关的知识,希望对你有一定的参考价值。

我想训练一个卷积神经网络,以识别两种类型的类。 我还想使用已经训练过的模型(如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)
答案

首先,我建议您将数据转换为TFRecords并避免使用flow_from_directoryImageDataGenerator可以作为快速原型设计的一个很好的选择,但TFRecords和相应的TF基础设施(队列/跑步者/读者)真正优化了快速阅读。通过使用tf.data API,尤其是Dataset.prefetch(),您可以获得可观的加速。

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

另一答案

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

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

然后,您可以将任何解析函数随机播放,批处理并映射到此数据集。您可以控制将使用shuffle缓冲区预加载的示例数。重复控制纪元计数,最好留下无,所以它将无限重复。您可以使用普通批处理功能或与之结合使用

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

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

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(数据集)那样做smth所以它应该提前计算。

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。

以上是关于如何通过预先训练的InceptionV3加速我的Keras CNN的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TensorFlow 中增加训练步数?

CoreML - 如何将 InceptionV3 的图像预处理为 MultiArray <Double, 3>?

如何使用预先训练。模型文件Android Studio中的预测?

r xml-to-dataframe - 可选择通过提供预先结构来加速处理

为多个分类编辑 tensorflow inceptionV3 retraining-example.py

如何使用 Scipy 的 Kd-tree 函数来加速 K-Nearest Neighbors (KNN) [关闭]