在可训练变量上应用掩模后,梯度变为无

问题描述 投票:0回答:1

我有一个问题,当我实现以下代码时,在对可训练变量应用掩码后,x 的梯度变为无。移除掩模后,就可以计算梯度了。我想知道这是什么原因。

layer = tf.keras.layers.Dense(2, activation='relu')
x = tf.Variable([[1., 2., 3.]], name = "tfv", trainable=True)
mask = tf.constant([0., 1., 0.], shape = (3,1))
x_ = x@mask
with tf.GradientTape() as tape:
  # Forward pass
  y = layer(x_)
  loss = tf.reduce_mean(y**2)

# Calculate gradients with respect to every trainable variable
grad = tape.gradient(loss, [layer.trainable_variables, x])

grad的输出是

[[<tf.Tensor: shape=(1, 2), dtype=float32, numpy=array([[0.       , 5.2745185]], dtype=float32)>,
  <tf.Tensor: shape=(2,), dtype=float32, numpy=array([0.       , 2.6372592], dtype=float32)>],
 None]

摘下面膜后

layer = tf.keras.layers.Dense(2, activation='relu')
x = tf.Variable([[1., 2., 3.]], name = "tfv", trainable=True)
with tf.GradientTape() as tape:
  # Forward pass
  y = layer(x)
  loss = tf.reduce_mean(y**2)

# Calculate gradients with respect to every trainable variable
grad = tape.gradient(loss, [layer.trainable_variables,x])

梯度的输出为

[[<tf.Tensor: shape=(3, 2), dtype=float32, numpy=
  array([[1.2404386, 3.1709769],
         [2.4808772, 6.3419538],
         [3.7213159, 9.512931 ]], dtype=float32)>,
  <tf.Tensor: shape=(2,), dtype=float32, numpy=array([1.2404386, 3.1709769], dtype=float32)>],
 <tf.Tensor: shape=(1, 3), dtype=float32, numpy=array([[2.8783302 , 0.38053298, 2.651462  ]], dtype=float32)>]

非常感谢您的帮助!

tensorflow keras deep-learning neural-network gradient
1个回答
0
投票

原因很可能是您想要梯度 w.r.t。

x
,但是您将 x 与 GradientTape 之外的蒙版 相乘。因此,磁带永远不会将梯度记录回
x
,而只会记录到
x_
。这也是你的第二个例子有效的原因。在那里,您定义
x
,然后
x
上的每个操作都在
GradientTape
内部。
解决方案是将
x@mask
移动到
with
块内:

with tf.GradientTape() as tape:
  x_ = x@mask
  # Forward pass
  y = layer(x_)
  loss = tf.reduce_mean(y**2)

这样,磁带就知道了

x
x_
之间的关系。

© www.soinside.com 2019 - 2024. All rights reserved.