我得到了一个图像数据集,其组织方式如下:
-dir_path文件夹:
---train-testa子文件夹:
------train(包含6个子文件夹(类别1到6),每个子文件夹包含图像样本)
-------瓦尔(包含6个子文件夹(类别1到6),每个子文件夹包含图像样本)
---train-testb子文件夹:
------train(包含6个子文件夹(类别1到6),每个子文件夹包含图像样本)
-------瓦尔(包含6个子文件夹(类别1到6),每个子文件夹包含图像样本)
---train-testc子文件夹:
------train(包含6个子文件夹(类别1到6),每个子文件夹包含图像样本)
-------瓦尔(包含6个子文件夹(类别1到6),每个子文件夹包含图像样本)
我想训练一个CNN,一次用3张图像作为输入。比如说
\dir_path\train-testa\train\class3\sample05.png,
\dir_path\train-testb\train\class3\sample05.png,
\dir_path\train-testc\train\class3\sample05.png
将是CNN的级联输入进行训练。验证输入将是相同的,但是样本仅从val子文件夹中提取。
我使用ImageDataGenerators如下:
image_generator = ImageDataGenerator(rescale = 1/255)
def generate_generator_multiple(generator,dir1, dir2, dir3, batch_size, img_height,img_width):
genX1 = generator.flow_from_directory(dir1,
target_size = (img_height,img_width),
class_mode = 'categorical',
batch_size = batch_size,
shuffle=False,
seed=7)
genX2 = generator.flow_from_directory(dir2,
target_size = (img_height,img_width),
class_mode = 'categorical',
batch_size = batch_size,
shuffle=False,
seed=7)
genX3 = generator.flow_from_directory(dir2,
target_size = (img_height,img_width),
class_mode = 'categorical',
batch_size = batch_size,
shuffle=False,
seed=7)
while True:
X1i = genX1.next()
X2i = genX2.next()
X3i = genX3.next()
yield [X1i[0], X2i[0], X3i[0]], X2i[1] #Yield images and their mutual label
train_generator=generate_generator_multiple(generator=image_generator,
dir1=dir_path + "\\train-testa" + "\\train",
dir2=dir_path + "\\train-testb" + "\\train",
dir3=dir_path + "\\train-testc" + "\\train",
batch_size=30,
img_height=217,
img_width=217)
test_generator=generate_generator_multiple(generator=image_generator,
dir1=dir_path + "\\train-testa" + "\\val",
dir2=dir_path + "\\train-testb" + "\\val",
dir3=dir_path + "\\train-testc" + "\\val",
batch_size=30,
img_height=217,
img_width=217)
在上面的函数中,我合并了train-testa、b和c的生成器。我使用了下面的CNN模型:
def CNNModel(input_shape):
X_input1 = Input(input_shape)
X_input2 = Input(input_shape)
X_input3 = Input(input_shape)
X = layers.concatenate([X_input1, X_input2, X_input3])
X = Conv2D(16, (3, 3), strides = (1, 1), name = 'conv1')(X)
X = Activation('LeakyReLU')(X)
X = Dropout(.25)(X)
X = MaxPooling2D((2, 2), name='max_pool1')(X)
X = Conv2D(32, (3, 3), strides = (1, 1), name = 'conv2')(X)
X = Activation('LeakyReLU')(X)
X = Dropout(.3)(X)
X = MaxPooling2D((2, 2), name='max_pool2')(X)
X = Conv2D(64, (3, 3), strides = (1, 1), name = 'conv3')(X)
X = Activation('LeakyReLU')(X)
X = Dropout(.3)(X)
X = Flatten()(X)
X = Dense(64, activation='LeakyReLU', name='fc1')(X)
X = Dropout(.4)(X)
X = Dense(6, activation='softmax', name='fc2')(X)
return model
最后,我用以下代码训练了模型:
CNN_Model = CNNModel((217, 217, 3));
CNN_Model.compile(optimizer = "adam",loss = "categorical_crossentropy",metrics = ["accuracy"])
callback = tf.keras.callbacks.EarlyStopping(monitor='val_accuracy', patience=50, verbose=1, restore_best_weights=True)
his = CNN_Model.fit(train_generator, epochs=200, validation_data=test_generator, callbacks=[callback], use_multiprocessing=False)
现在我有一些问题:
1-我的代码的逻辑(概念)是否正确?
2-训练过程太慢。我的总图像训练是630个文件,它已经接近3个小时,我还没有能够看到最终的结果。epoch的数量可能太大了,但我已经为单个输入图像运行了相同的代码,只花了几分钟。这是我在跑步时得到的:
“device:GPU:0,1654 MB内存:- 〉device:0,name:NVIDIA GeForce RTX 3050笔记本电脑GPU,pci总线ID:0000:01:00.0,计算能力:8.6历元1/200 21527/未知-10706 s 497 ms/步长-丢失:0.3556 -准确度:0.9668英寸
它的训练准确率虽然很慢,但仍在提高。很有可能是装得太多了。正如您所看到的,我既看不到还剩多少步骤,也看不到验证的准确性。
既然我需要训练更大的数据集,有没有办法提高速度?
如果你能和我分享你的建议,我将不胜感激。问候
1条答案
按热度按时间9gm1akwq1#
不要使用ImageDataGenerator,它非常慢,而且已经过时了。使用
image_dataset_from_directory
代替。以下是更多信息:https://www.tensorflow.org/api_docs/python/tf/keras/utils/image_dataset_from_directory在这种情况下,您可以使用3次image_dataset_from_directory来创建3个数据集,然后可以使用类似
tf.data.Dataset.zip((a, b, c))
的方法将它们连接成一个数据集。您可能需要Map,您可以使用dataset.map(...)
来完成。您还可以应用预取,并将其缓存以加快速度。这里是信息:https://www.tensorflow.org/guide/data_performance