【发布时间】:2019-07-28 15:39:51
【问题描述】:
我有我从here、here 获得的自定义损失类和更新权重的回调。第二个链接有点不是我的场景,因为我们需要访问损失历史和准确性才能更新权重,所以我认为从第一个链接回调是最好的方法。
这是我得到的代码
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