如何在Keras中无需迭代的情况下在多输出模型的训练过程中加载数据



我有一个Keras模型,在TensorFlow 2中有1个输入和2个输出。当调用model.fit时,我想将数据集作为x=train_dataset传递,并调用model.fit一次。train_datasettf.data.Dataset.from_generator组成,得到:x1,y1,y2。

我能进行训练的唯一方法是:

for x1, y1,y2 in train_dataset:
model.fit(x=x1, y=[y1,y2],...)

如何告诉TensorFlow在没有显式for循环的情况下打开变量并进行训练?使用for循环会使许多事情变得不那么实用,也会使train_on_batch的使用变得不那么实际。

如果我想运行model.fit(train_dataset, ...),函数不理解xy是什么,甚至模型的定义是:

model = Model(name ='Joined_Model',inputs=self.x, outputs=[self.network.y1, self.network.y2])

它抛出了一个错误,即它期望2个目标,而得到1个,即使数据集有3个变量,也可以在循环中迭代。

数据集和小批量生成为:

def dataset_joined(self, n_epochs, buffer_size=32):
dataset = tf.data.Dataset.from_generator(
self.mbatch_gen_joined,
(tf.float32, tf.float32,tf.int32),
(tf.TensorShape([None, None, self.n_feat]),
tf.TensorShape([None, None, self.n_feat]),
tf.TensorShape([None, None])),
[tf.constant(n_epochs)]
)
dataset = dataset.prefetch(buffer_size)
return dataset
def mbatch_gen_joined(self, n_epochs):
for _ in range(n_epochs):
random.shuffle(self.train_s_list)
start_idx, end_idx = 0, self.mbatch_size
for _ in range(self.n_iter):
s_mbatch_list = self.train_s_list[start_idx:end_idx]
d_mbatch_list = random.sample(self.train_d_list, end_idx-start_idx)
s_mbatch, d_mbatch, s_mbatch_len, d_mbatch_len, snr_mbatch, label_mbatch, _ = 
self.wav_batch(s_mbatch_list, d_mbatch_list)
x_STMS_mbatch, xi_bar_mbatch, _ = 
self.training_example(s_mbatch, d_mbatch, s_mbatch_len,
d_mbatch_len, snr_mbatch)
#seq_mask_mbatch = tf.cast(tf.sequence_mask(n_frames_mbatch), tf.float32)
start_idx += self.mbatch_size; end_idx += self.mbatch_size
if end_idx > self.n_examples: end_idx = self.n_examples
yield x_STMS_mbatch, xi_bar_mbatch, label_mbatch

Keras模型期望Python生成器或tf.data.Dataset对象以(input_data, target_data)(或(input_data, target_data, sample_weights)(格式的元组形式提供输入数据。如果模型具有多个输入/输出层,则CCD_ 15或CCD_。因此,在您的代码中,生成的数据也应该与以下预期格式兼容:

yield x_STMS_mbatch, (xi_bar_mbatch, label_mbatch)  # <- the second element is a tuple itself

此外,在传递给from_generator方法的参数中也应该考虑这一点:

dataset = tf.data.Dataset.from_generator(
self.mbatch_gen_joined,
output_types=(
tf.float32,
(tf.float32, tf.int32)
),
output_shapes=(
tf.TensorShape([None, None, self.n_feat]),
(
tf.TensorShape([None, None, self.n_feat]),
tf.TensorShape([None, None])
)
),
args=(tf.constant(n_epochs),)
)

使用yield(x1, [y1,y2]),使model.fit能够理解您的生成器输出。

最新更新