i具有神经网络out = f(s)
,其中s
是带有Shape [None, dim_s]
的输入的一批输入,而OUT是Scaleer,f
只是MLP。使用tf.gradient(out, tf.trainable_variables())
,我可以获得out
W.R.T的梯度f
的神经网络参数,这是梯度的列表。
现在,我有两批s
:s1
和s2
,然后我们可以获得两个不同的渐变G1
和G2
。
例如:
import tensorflow as tf
import numpy as np
batch_1=np.random.normal(0,1, [2, 3])
batch_2=np.random.normal(0,1, [2, 3])
x = tf.placeholder(tf.float32, shape=(None, 3))
out = tf.layers.dense(x, 2, tf.tanh,
kernel_initializer=tf.random_normal_initializer(
stddev=np.sqrt(1 / 100)))
predictions = tf.layers.dense(out, 1, tf.tanh,
kernel_initializer=tf.random_normal_initializer(
stddev=np.sqrt(1 / 100)))
opt = tf.train.GradientDescentOptimizer(learning_rate=0.01)
gradient_step = opt.compute_gradients(predictions, tf.trainable_variables())
sess=tf.Session()
sess.run(tf.global_variables_initializer())
gradients_1 = sess.run(gradient_step, feed_dict={x: batch_1})
gradients_2 = sess.run(gradient_step, feed_dict={x: batch_2})
如果可以在G1
和G2
之间计算余弦?我需要首先将两个梯度弄平吗?G1
和G2
是否是数学的通常梯度?
re natematical:据我所知,"数学"的含义,tensorflow中的梯度是"数学"。例如,如果您的f
是f(x) = x^3
,则在x=5
上运行它,并获取它的tf.gradients
,您将获得75 = 3*5^2
。
re cesine:是的,您可以做到这一点,但是需要更深入地了解TensorFlow梯度计算。要计算梯度,您需要记住前向通行证的值。在上面的示例中,要计算75
,您需要记住5
。通常,这可能是f
中所有操作计算的所有张量。默认情况下,TensorFlow仅在计算梯度之前记住这些值。然后,将值丢弃。
如果您想使用两组梯度,最简单的方法是两次实例化模型。这通常称为有两个"塔"。这些塔将共享变量,它们的结构将是相同的,但是每个塔将具有自己的操作集(Tensorflow图中的节点)。然后,将s1
作为输入输入第一个塔,将s2
作为输入到第二座塔中(在同一会话中。run()呼叫)。
如果您有数百万的操作和实例化两个塔非常昂贵,则可以创建一个张量的功能(此实验性API)。
另一个可能更容易的选择是使用最近发布的急切执行,在该执行中,立即执行操作(没有图形,没有session.run()
),并且您可以轻松控制使用渐变图像的梯度计算。您可以在此处找到其用法的示例。急切的执行在目前处于α前状态,仅在TF-of-nightly构建中可用。请参阅此处的"夜间建造"。
响应评论3:据我所知,您的示例清楚地表明梯度是在批处理上求和的。密集层中的变量具有形状3x1
和1x1
:
print tf.trainable_variables()
[<tf.Variable 'dense/kernel:0' shape=(3, 1) dtype=float32_ref>,
<tf.Variable 'dense/bias:0' shape=(1,) dtype=float32_ref>]
第一个梯度(对于3x1
变量)是:
print gradients_1[0][0]
array([[-0.098351 ],
[-0.6422075 ],
[ 0.09750339]], dtype=float32)
因此,即使batch_1
对于每个标量变量具有2个标量,每个标量变量都有一个标量。
我已经写了如何使用"塔"来与来自不同输入的两个渐变一起工作。这是基于您的代码段的示例。我认为"余弦"是指"余弦相似性"
import tensorflow as tf
import numpy as np
x1 = tf.placeholder(tf.float32, shape=(None, 3))
x2 = tf.placeholder(tf.float32, shape=(None, 3))
predictions1 = tf.layers.dense(x1, 1, tf.tanh,
kernel_initializer=tf.random_normal_initializer(
stddev=np.sqrt(1 / 100)),
reuse=None)
predictions2 = tf.layers.dense(x2, 1, tf.tanh,
kernel_initializer=tf.random_normal_initializer(
stddev=np.sqrt(1 / 100)),
reuse=True)
weights = tf.trainable_variables()[0] # the 3x1 weight variable
g1 = tf.reshape(tf.gradients(predictions1, weights), [-1]) # 3x1 gradient tensor
g2 = tf.reshape(tf.gradients(predictions2, weights), [-1]) # 3x1 gradient tensor
cos_similarity = 1 - tf.losses.cosine_distance(tf.nn.l2_normalize(g1, 0),
tf.nn.l2_normalize(g2, 0),
dim=0)
sess=tf.Session()
sess.run(tf.global_variables_initializer())
print sess.run([g1, g2, cos_similarity], feed_dict={
x1: [[1,2,3], [2,4,6]],
x2: [[1,2,3], [2,4,7]]
})
# prints
# [array([ 3., 6., 9. ], dtype=float32),
# array([ 3., 6., 10.], dtype=float32),
# 0.99876773]