【问题标题】:How to load data during training of a multi-output model without iteration in Keras?如何在没有迭代的情况下在 Keras 中训练多输出模型时加载数据?
【发布时间】:2020-04-28 14:06:54
【问题描述】:

我在 TensorFlow 2 中有一个带有 1 个输入和 2 个输出的 Keras 模型。在调用 model.fit 时,我想将数据集作为 x=train_dataset 传递并调用 model.fit 一次。 train_dataset 是用 tf.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

【问题讨论】:

  • 能否在您定义和创建Dataset 实例的位置添加代码以及生成器代码?
  • y1 和 y2 是什么?一个热门编码值?您能否解释一下您的目标数据。也可以请您分享代码。
  • 嗨,我已经在@today上面的问题中添加了代码

标签: python tensorflow keras tensorflow2.0 tensorflow-datasets


【解决方案1】:

Keras 模型期望 Python 生成器或 tf.data.Dataset 对象以元组形式提供输入数据,格式为 (input_data, target_data)(或 (input_data, target_data, sample_weights))。如果模型有多个输入/输出层,每个input_datatarget_data 可以而且应该是一个列表/元组。因此,在您的代码中,生成的数据也应该与这种预期格式兼容:

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),)
)

【讨论】:

  • 非常感谢@today,我很接近但没有你的帮助就无法做到。你能看看这个问题吗? link
【解决方案2】:

使用yield(x1, [y1,y2]),以便 model.fit 了解您的生成器输出。

【讨论】:

  • 您好,这是一个很好的起点,应该相应地更改生成器。我尝试在生成器和数据集中使用相同的结构,但它拒绝生成。 The two structures don't have the same sequence length. Input structure has length 3, while shallow structure has length 2.
  • 我已经添加了上面的代码。当产生值为 (x1, [y1,y2]) 时,应更改数据集生成。仅将值放在括号 [] 内并不能完成这项工作。
  • 但是目标有不同的形状,np.stack 要求所有输入具有相同的维度。我不确定你在哪里以及如何说 np.stack 可以帮助解决这个问题。 @Augusto
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-27
  • 1970-01-01
  • 2021-01-05
  • 2018-12-12
  • 1970-01-01
  • 2019-11-26
  • 1970-01-01
相关资源
最近更新 更多