【问题标题】:Custom Traing Loop with multiple model pass through具有多个模型的自定义训练循环通过
【发布时间】:2021-05-15 04:48:42
【问题描述】:

尊敬的 stackoverflow 成员,

我目前正在尝试实现我自己的 keras 调谐器训练循环。在这个循环中,我想通过示例中的模型多次传递输入变量:

Y = Startvalue
for i in range(x):
   Y = model(Y)

我想看看这种方法能否为我的自我反馈问题​​创建更稳定的模拟。 当我实现它时,即使我不循环,我也会收到 OOM 错误。当我正常操作时不会发生此错误。 我的班级示例(当我为 logits2 切换 logits 时发生 OOM 错误:

class MyTuner(kt.Tuner):
    def run_trial(self, trial, train_ds, validation_data):

        model = self.hypermodel.build(trial.hyperparameters)

        optimizer = tf.keras.optimizers.Adam()
        epoch_loss_metric = tf.keras.metrics.MeanSquaredError()

        def microbatch(T_IN, A_IN, D_IN):
            OUT_T = []
            OUT_A = []
            for i in range(len(T_IN)):
                A_IN_R = tf.expand_dims(tf.squeeze(A_IN[i]), 0)
                T_IN_R = tf.expand_dims(tf.squeeze(T_IN[i]), 0)
                D_IN_R = tf.expand_dims(tf.squeeze(D_IN[i]), 0)
                (OUT_T_R, OUT_A_R) = model((A_IN_R, T_IN_R, D_IN_R))
                OUT_T.append(tf.squeeze(OUT_T_R))
                OUT_A.append(tf.squeeze(OUT_A_R))
            return(tf.squeeze(tf.stack(OUT_T)), tf.squeeze(tf.stack(OUT_A)))

        def run_train_step(data):
            T_IN = tf.dtypes.cast(data[0][0], 'float32')
            A_IN = tf.dtypes.cast(data[0][1], 'float32')
            D_IN = tf.dtypes.cast(data[0][2], 'float32')
            A_Ta = tf.dtypes.cast(data[1][0], 'float32')
            T_Ta = tf.dtypes.cast(data[1][1], 'float32')
            mse = tf.keras.losses.MeanSquaredError()

            with tf.GradientTape() as tape:
                logits2 = microbatch(T_IN, A_IN, D_IN)

                logits = model([A_IN, T_IN, D_IN])
                loss   = mse((T_Ta, A_Ta), logits2)
                # Add any regularization losses.
                if model.losses:
                    loss += tf.math.add_n(model.losses)
                gradients = tape.gradient(loss, model.trainable_variables)
            optimizer.apply_gradients(zip(gradients, model.trainable_variables))
            epoch_loss_metric.update_state((T_Ta, A_Ta), logits2)
            return loss

        for epoch in range(1000):
            print('Epoch: {}'.format(epoch))

            self.on_epoch_begin(trial, model, epoch, logs={})
            for batch, data in enumerate(train_ds):
                self.on_batch_begin(trial, model, batch, logs={})
                batch_loss = float(run_train_step(data))
                self.on_batch_end(trial, model, batch, logs={'loss': batch_loss})

                if batch % 100 == 0:
                    loss = epoch_loss_metric.result().numpy()
                    print('Batch: {}, Average Loss: {}'.format(batch, loss))

            epoch_loss = epoch_loss_metric.result().numpy()
            self.on_epoch_end(trial, model, epoch, logs={'loss': epoch_loss})
            epoch_loss_metric.reset_states()
    ````

【问题讨论】:

  • 尝试添加 tf.keras.backend.clear_session() 作为循环中的最后一条语句
  • 很遗憾不起作用错误没有改变

标签: python numpy tensorflow keras keras-tuner


【解决方案1】:

据我了解,微批处理功能并没有实现自反馈循环(虽然它不影响OOM)

我猜是因为你正在计算网络的输出 k 次,网络的内存消耗量增加了 k 倍(因为它需要存储中间张量用于反向传播)。

您可以做的是,在每个自我反馈实例中,您对梯度进行反向传播,以便所有中间张量不会增加超过限制。

如果您有任何疑问,请告诉我,

【讨论】:

  • 感谢您的回答是的,目前没有循环实现,但当前实现是循环实现的基础。我会试试你的方法。
猜你喜欢
  • 2020-07-25
  • 2020-05-19
  • 2021-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多