我想训练一个卷积神经网络来识别两种类型的类。
我还想使用像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)
答案 0 :(得分:1)
首先,我为您提供将数据转换为TFRecords的方法,并避免使用flow_from_directory
。 ImageDataGenerator
是快速原型制作的不错选择,但是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。