【问题标题】:Tensorflow Keras, How to add loss weight as a non trainable variable?Tensorflow Keras,如何将损失权重添加为不可训练的变量?
【发布时间】:2019-07-28 15:39:51
【问题描述】:

我有我从herehere 获得的自定义损失类和更新权重的回调。第二个链接有点不是我的场景,因为我们需要访问损失历史和准确性才能更新权重,所以我认为从第一个链接回调是最好的方法。

这是我得到的代码

class AdaptiveLossCallback(tf.keras.callbacks.Callback):
    def __init__(self):
        super(AdaptiveLossCallback, self).__init__()
        self.weight1 = tf.Variable(1.0, trainable=False, name='weight1', dtype=tf.float32)
        self.weight2 = tf.Variable(0.0, trainable=False, name='weight2', dtype=tf.float32)

    def on_epoch_end(self, epoch, logs=None):
        if epoch == 49:
            self.weight1 = tf.assign(self.weight1 , tf.constant(0.5))
            self.weight2 = tf.assign(self.weight2 , tf.constant(0.5))
        elif epoch == 74:
            self.weight1 = tf.assign(self.weight1 , tf.constant(0.0))
            self.weight2 = tf.assign(self.weight2 , tf.constant(1.0))


class CustomLoss(tf.keras.losses.Loss):
    def __init__(self,
                 adaptive_loss=None,
                 from_logits=False,
                 reduction=losses_utils.ReductionV2.AUTO,
                 name=None):
        super(CustomLoss, self).__init__(reduction=reduction)
        self.from_logits = from_logits
        self.adaptive_loss = adaptive_loss

    def call(self, y_true, y_pred):
        ...
        weight1 = self.adaptive_loss.weight1
        weight2 = self.adaptive_loss.weight2
        return weight1 * loss1 + weight2 * loss2

但我似乎无法让它工作。运行时我会说

尝试使用未初始化的值 weight1

在我尝试之后

session = tf.keras.backend.get_session()
session.run(tf.global_variables_initializer())
model.fit(...)

它似乎有效,但重量值根本没有更新。

我做错了什么,我该如何解决? 有没有更好的方法给 Keras 模型添加可变变量?

谢谢

PS。我无法使用 Keras 模型loss_weights,因为我只有一个输出

【问题讨论】:

  • 权重需要是张量吗?他们不能只是花车吗?
  • 因为我需要像在某个时期一样在训练期间更新权重。我在急切执行之前尝试使用 float,但 def call(self, y_true, y_pred) 在模型编译期间仅调用一次,因此我需要将其作为张量发送。
  • 好的,谢谢,现在我明白了。您可以尝试使用K.set_value 代替tf.assign 吗?我相信使用tf.assign,损失函数中的张量引用不会更新,因为权重没有就地修改。
  • @rvinas 谢谢你的工作!所以我需要调用 session.run() 来分配 op。
  • 我很高兴它有效。我会把它总结在一个答案中

标签: tensorflow keras


【解决方案1】:

问题在于损失函数中的权重引用并没有仅使用tf.assign 进行更新。要适当更新损失系数,您可以执行以下操作:

a)K.set_value(self.weightX, update_value)

b)sess.run(self.weightX.assign(update_tensor))

【讨论】:

    猜你喜欢
    • 2018-10-18
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 2021-06-14
    • 1970-01-01
    相关资源
    最近更新 更多