使用Keras图层时区分用户定义的变量

时间:2019-11-04 23:58:09

标签: python tensorflow keras tensorflow2.0

我想将Keras图层与自己的变量相乘。

然后,我要计算相对于我定义的变量的某些损失的梯度。

这是我正在尝试做的简化的MWE:

import tensorflow as tf

x = input_shape = tf.keras.layers.Input((10,))
x = tf.keras.layers.Dense(5)(x)

s = tf.Variable(tf.ones((5,)))
x = x*s

model = tf.keras.models.Model(input_shape, x)

X = tf.random.normal((50, 10))  # random sample

with tf.GradientTape() as tape:
    tape.watch(s)
    y = model(X)
    loss = y**2

print(tape.gradient(loss, s))  # why None ??

print打印None ...为什么?

请注意,我正在使用eager-execution(TF版本2.0.0)。

2 个答案:

答案 0 :(得分:0)

我通过子类化Model并在模型内部创建变量来解决问题:

class MyModel(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.dense = tf.keras.layers.Dense(5)
        self.s = tf.Variable(tf.ones((5,)))

    def call(self, inputs):
        x = self.dense(inputs)
        x = x * self.s
        return x

或者,定义我自己的自定义图层也可以。

必须进行某种魔术操作,才能使模型内部以外的变量不向后传播(例如在PyTorch中)。

我将开放这个问题,因为我很好奇为什么我的代码无法正常工作以及更简单的修复是什么样子。

答案 1 :(得分:-1)

这可能是解释。基于对文档的审查,我怀疑问题在于模型层“ s”(或任何其他层“ x”)之间的差异可能不是有意义的计算。例如,可以这样做:

print(tape.gradient(loss, model.variables))
并获得相对于模型权重/参数的梯度,但是相对于“层”区分模型是不合适的。这是我目前的猜测。我希望这会有所帮助。