首页 文章

修改TensorFlow中的传入渐变

提问于
浏览
0

考虑一个神经网络,该网络具有2个完全连接的层 "l1_dense""l2_dense" ,并且具有一些损失函数 . 在反向传播期间,我想计算 "l2_dense" w.r.t的渐变 . 丢失函数,对渐变进行一些操作,并使用此操纵渐变作为 "l1_dense" 图层的传入渐变(在链规则中) . 我知道我可以使用 tf.train.Optimizer.compute_gradients() 来计算渐变w.r.t. "l2_dense" 并能够操纵它 . 我不知道该怎么做是为了计算 "l1_dense" 渐变来提供修改后的渐变 .

作为一个非常简单的例子,让我们说我想操纵 "l2_dense" 渐变的方式是将它除以某个数字 k . 我知道所有这一切相当于只是通过 k 潜水,我只是为了问题的目的给出了这个简单的例子 . 代码将是这样的:

import tensorflow as tf

i = tf.placeholder(tf.float32, shape=[None, 3])
y = tf.placeholder(tf.float32, shape=[None, 1])

x = tf.layers.dense(i, 4, tf.nn.relu, name="l1_dense")
x = tf.layers.dense(x, 1, tf.nn.relu, name="l2_dense")

loss = tf.losses.mean_squared_error(y, x)

opt = tf.train.AdamOptimizer()

gvars = tf.get_default_graph().get_collection(tf.GraphKeys.GLOBAL_VARIABLES)
l1_dense_k = [v for v in gvars if v.name == "l1_dense/kernel:0"][0]
l1_dense_b = [v for v in gvars if v.name == "l1_dense/bias:0"][0]
l2_dense_k = [v for v in gvars if v.name == "l2_dense/kernel:0"][0]
l2_dense_b = [v for v in gvars if v.name == "l2_dense/bias:0"][0]

gvs = opt.compute_gradients(loss, var_list=[l2_dense_k, l2_dense_b])
# Manipulate gradients
gvs = [(g/10, v) for g,v in gvs]

# Compute gradients w.r.t. l1_dense_k and l1_dense_b using gvs ???

要完全清楚,我的设置要复杂得多,我不能通过改变损失函数自动进行我需要的操作 . 此外,我需要一个解决方案,其中渐变w.r.t.每个变量只计算一次 .

1 回答

  • 1

    答案其实很简单 - 你需要使用 tf.gradients() . 如果有人也遇到这种情况,这里是解决方案:

    import tensorflow as tf
    
    i = tf.placeholder(tf.float32, shape=[None, 3])
    y = tf.placeholder(tf.float32, shape=[None, 1])
    
    x1 = tf.layers.dense(i, 4, tf.nn.relu, name="l1_dense")
    x2 = tf.layers.dense(x1, 1, tf.nn.relu, name="l2_dense")
    
    loss = tf.losses.mean_squared_error(y, x2)
    
    gvars = tf.get_default_graph().get_collection(tf.GraphKeys.GLOBAL_VARIABLES)
    l1_k = [v for v in gvars if v.name == "l1_dense/kernel:0"][0]
    l1_b = [v for v in gvars if v.name == "l1_dense/bias:0"][0]
    l2_k = [v for v in gvars if v.name == "l2_dense/kernel:0"][0]
    l2_b = [v for v in gvars if v.name == "l2_dense/bias:0"][0]
    
    grads = tf.gradients(loss, [x1, l2_k, l2_b])
    x1_grad, l2_k_grad, l2_b_grad = grads
    
    # Manipulate the gradient
    x1_grad = x1_grad / 10.0
    
    # Backpropagate the gradient
    grads = tf.gradients(x1, [l1_dense_k, l1_dense_b], x1_grad)
    l1_k_grad, l1_b_grad = grads
    

相关问题