Как загрузить данные во время обучения модели с несколькими выходами без итерации в Keras? - PullRequest
1 голос
/ 28 апреля 2020

У меня есть модель Keras с 1 входом и 2 выходами в TensorFlow 2. При вызове 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 l oop? Использование for l oop делает многие вещи менее практичными, а также использование train_on_batch.

Если я хочу запустить model.fit(train_dataset, ...), функция не понимает, что x и y есть, даже модель определяется как:

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

Выдает ошибку, что ожидает 2 цели при получении 1, даже в наборе данных есть 3 переменные, которые можно повторять через l oop.

Набор данных и мини-пакет генерируются как:

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

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

Модели Keras предполагают, что генераторы Python или объекты tf.data.Dataset предоставляют входные данные в виде кортежа в формате (input_data, target_data) (или (input_data, target_data, sample_weights)). Каждый из input_data или target_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),)
)
0 голосов
/ 28 апреля 2020

Используйте yield(x1, [y1,y2]), чтобы model.fit поймет ваш генератор.

...