如何使用具有两个输入和两个输出并使用两个 ImageDataGenerator 方法的函数 API 训练 Keras 模型 (flow_from_directory)
How to train a Keras model using Functional API which has two inputs and two outputs and uses two ImageDataGenerator methods (flow_from_directory)
我想使用 Functional Keras API 创建一个有两个输入和两个输出的模型。该模型将使用 ImageDataGenerator.flow_from_directory()
方法的两个实例从两个不同的目录(分别为 inputs1 和 inputs2)获取图像。
该模型还使用两个 lambda 层将生成器获取的图像附加到列表中以供进一步检查。
我的问题是如何训练这样的模型。这是一些玩具代码:
# Define our example directories and files
train_dir1 ='...\cats_v_dogs_sample_training1'
train_dir2 = '...\cats_v_dogs_sample_training2'
# Add our data-augmentation parameters to ImageDataGenerator
train_datagen = ImageDataGenerator(rescale = 1./255.,
rotation_range = 40,
width_shift_range = 0.2,
height_shift_range = 0.2,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)
# Flow training images in batches of 1 using train_datagen generator: inputs1
train_generator1 = train_datagen.flow_from_directory(train_dir1,
batch_size = 1,
class_mode = 'binary',
target_size = (150, 150), shuffle = False)
# Flow training images in batches of 1 using train_datagen generator: inputs2
train_generator2 = train_datagen.flow_from_directory(train_dir2,
batch_size = 1,
class_mode = 'binary',
target_size = (150, 150), shuffle = False)
imgs1 = []
imgs2 = []
def f_lambda1(x):
imgs1.append(x)
return(x)
def f_lambda2(x):
imgs2.append(x)
return(x)
# This returns a tensor
inputs1 = Input(shape=(150, 150, 3))
inputs2 = Input(shape=(150, 150, 3))
l1 = Lambda(f_lambda1, name = 'lambda1')(inputs1)
l2 = Lambda(f_lambda2 , name = 'lambda2')(inputs2)
x1 = Flatten()(inputs1)
x1 = Dense(1024, activation='relu')(x1)
x1 = Dropout(0.2)(x1)
outputs1 = Dense(1, activation='sigmoid')(x1)
x2 = Flatten()(inputs1)
x2 = Dense(1024, activation='relu')(x2)
x2 = Dropout(0.2)(x2)
outputs2 = Dense(1, activation='sigmoid')(x2)
model.compile()
# Train model on dataset -- The problem is that I have two not one training_generator, so the code below will not work
model.fit_generator(generator=training_generator,
validation_data=validation_generator,
use_multiprocessing=True,
workers=6)
创建一个连接的生成器。
在此示例中,两个火车生成器的长度必须相同:
class JoinedGenerator(keras.utils.Sequence):
def __init__(self, generator1, generator2)
self.generator1 = generator1
self.generator2 = generator2
def __len__(self):
return len(self.generator1)
def __getitem__(self, i):
x1, y1 = self.generator1[i]
x2, y2 = self.generator2[i]
return [x1, x2], [y1, y2]
def on_epoch_end(self):
self.generator1.on_epoch_end()
self.generator2.on_epoch_end()
注意:您可能需要在两个生成器中使用 shuffle=False
,这样您的数据就不会混合(除非这不是问题)
用作:
training_generator = JoinedGenerator(train_generator1, train_generator2)
而且您忘记定义模型了:
model = Model([inputs1, inputs2], [outputs1, outputs2])
我想使用 Functional Keras API 创建一个有两个输入和两个输出的模型。该模型将使用 ImageDataGenerator.flow_from_directory()
方法的两个实例从两个不同的目录(分别为 inputs1 和 inputs2)获取图像。
该模型还使用两个 lambda 层将生成器获取的图像附加到列表中以供进一步检查。
我的问题是如何训练这样的模型。这是一些玩具代码:
# Define our example directories and files
train_dir1 ='...\cats_v_dogs_sample_training1'
train_dir2 = '...\cats_v_dogs_sample_training2'
# Add our data-augmentation parameters to ImageDataGenerator
train_datagen = ImageDataGenerator(rescale = 1./255.,
rotation_range = 40,
width_shift_range = 0.2,
height_shift_range = 0.2,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)
# Flow training images in batches of 1 using train_datagen generator: inputs1
train_generator1 = train_datagen.flow_from_directory(train_dir1,
batch_size = 1,
class_mode = 'binary',
target_size = (150, 150), shuffle = False)
# Flow training images in batches of 1 using train_datagen generator: inputs2
train_generator2 = train_datagen.flow_from_directory(train_dir2,
batch_size = 1,
class_mode = 'binary',
target_size = (150, 150), shuffle = False)
imgs1 = []
imgs2 = []
def f_lambda1(x):
imgs1.append(x)
return(x)
def f_lambda2(x):
imgs2.append(x)
return(x)
# This returns a tensor
inputs1 = Input(shape=(150, 150, 3))
inputs2 = Input(shape=(150, 150, 3))
l1 = Lambda(f_lambda1, name = 'lambda1')(inputs1)
l2 = Lambda(f_lambda2 , name = 'lambda2')(inputs2)
x1 = Flatten()(inputs1)
x1 = Dense(1024, activation='relu')(x1)
x1 = Dropout(0.2)(x1)
outputs1 = Dense(1, activation='sigmoid')(x1)
x2 = Flatten()(inputs1)
x2 = Dense(1024, activation='relu')(x2)
x2 = Dropout(0.2)(x2)
outputs2 = Dense(1, activation='sigmoid')(x2)
model.compile()
# Train model on dataset -- The problem is that I have two not one training_generator, so the code below will not work
model.fit_generator(generator=training_generator,
validation_data=validation_generator,
use_multiprocessing=True,
workers=6)
创建一个连接的生成器。
在此示例中,两个火车生成器的长度必须相同:
class JoinedGenerator(keras.utils.Sequence):
def __init__(self, generator1, generator2)
self.generator1 = generator1
self.generator2 = generator2
def __len__(self):
return len(self.generator1)
def __getitem__(self, i):
x1, y1 = self.generator1[i]
x2, y2 = self.generator2[i]
return [x1, x2], [y1, y2]
def on_epoch_end(self):
self.generator1.on_epoch_end()
self.generator2.on_epoch_end()
注意:您可能需要在两个生成器中使用 shuffle=False
,这样您的数据就不会混合(除非这不是问题)
用作:
training_generator = JoinedGenerator(train_generator1, train_generator2)
而且您忘记定义模型了:
model = Model([inputs1, inputs2], [outputs1, outputs2])