矩阵 wrt 矩阵的 TensorFlow 梯度没有意义
TensorFlow gradient of matrix wrt a matrix is not making sense
假设我有两个矩阵 tf_t(形状:5x3)和 tf_b(形状:3x3)。
y_tf = tf.matmul(tf_t, tf_b) 然后我使用 tf.gradient api[=25= 计算了 dy/dt ]
import tensorflow as tf
mat = [[0.8363, 0.4719, 0.9783],
[0.3379, 0.6548, 0.3835],
[0.7846, 0.9173, 0.2393],
[0.5418, 0.3875, 0.4276],
[0.0948, 0.2637, 0.8039]]
another_mat = [[ 0.43842274 ,-0.53439844, -0.07710262],
[ 1.5658046, -0.1012345 , -0.2744976 ],
[ 1.4204658 , 1.2609464, -0.43640924]]
tf_t = tf.Variable(tf.convert_to_tensor(mat))
tf_b = tf.Variable(tf.convert_to_tensor(another_mat))
with tf.GradientTape() as tape:
tape.watch(tf_t)
y_tf = tf.matmul(tf_t, tf_b)
y_t0 = y_tf[0,0]
# dy = 2x * dx
dy_dx = tape.gradient(y_tf, tf_t)
print(dy_dx)
我正低于矩阵 dy/dx
tf.Tensor(
[[-0.17307831 1.1900724 2.245003 ]
[-0.17307831 1.1900724 2.245003 ]
[-0.17307831 1.1900724 2.245003 ]
[-0.17307831 1.1900724 2.245003 ]
[-0.17307831 1.1900724 2.245003 ]], shape=(5, 3), dtype=float32)
上面的矩阵看起来不对。
因为对于元素 y_tf[0,0]
Note : y_tf[0,0] = tf_t[0,0]*tf_b[0,0] + tf_t[0,1]*tf_b[1,0] +
tf_t[0,2]*tf_b[2,0]
如果我执行
tape.gradient(y_t0, tf_t)
我得到这样的矩阵
tf.Tensor(
[[0.43842274 1.5658046 1.4204658 ]
[0. 0. 0. ]
[0. 0. 0. ]
[0. 0. 0. ]
[0. 0. 0. ]], shape=(5, 3), dtype=float32)
上面的第一行是矩阵 tf_b
的第一列,考虑到矩阵乘法的工作原理,这很有意义,如果我是,总结一下,这些数字将是 3.424693
但是,我得到的结果是 dy_dx
它的第一个元素 dy_dx[0,0]
作为 -0.17307831
这是 tf_b ( sum(tf_b[0,:])
的第一行的总和 !!
所以谁能解释一下 tf_y[0,0] wrt tf_x
的梯度是如何减少到 -0.17307831
而不是 3.424693
的?
问题可能与 类似,但我正在寻找的答案并没有用清晰的图片解决。
这里要理解的关键概念是 tf.gradients
计算输出的 sum 相对于输入的梯度。即 dy_dx
表示 y_tf
的所有元素之和随着 tf_t
的每个元素变化而变化的比例。
因此,如果您采用 tf_t[0, 0]
,则该值用于计算 y_tf[0, 0]
、y_tf[0, 1]
和 y_tf[0, 2]
,在每种情况下都使用系数 tf_b[0, 0]
, tf_b[0, 1]
和 tf_b[0, 2]
。所以,如果我将 tf_t[0, 0]
增加一,y_tf
的总和将增加 tf_b[0, 0] + tf_b[0, 1] + tf_b[0, 2]
,这是 dy_dx[0, 0]
的值。继续同样的推理,每个值 tf_t[i, j]
实际上都乘以 tf_b[j, :]
中的所有值,因此 dy_dx
是 tf_b
行总和的重复。
当您计算 y_t0
相对于 tf_t
的梯度时,tf_t[0, 0]
的变化会使结果总和改变 tf_b[0, 0]
,所以这就是那种情况下的梯度值。
假设我有两个矩阵 tf_t(形状:5x3)和 tf_b(形状:3x3)。 y_tf = tf.matmul(tf_t, tf_b) 然后我使用 tf.gradient api[=25= 计算了 dy/dt ]
import tensorflow as tf
mat = [[0.8363, 0.4719, 0.9783],
[0.3379, 0.6548, 0.3835],
[0.7846, 0.9173, 0.2393],
[0.5418, 0.3875, 0.4276],
[0.0948, 0.2637, 0.8039]]
another_mat = [[ 0.43842274 ,-0.53439844, -0.07710262],
[ 1.5658046, -0.1012345 , -0.2744976 ],
[ 1.4204658 , 1.2609464, -0.43640924]]
tf_t = tf.Variable(tf.convert_to_tensor(mat))
tf_b = tf.Variable(tf.convert_to_tensor(another_mat))
with tf.GradientTape() as tape:
tape.watch(tf_t)
y_tf = tf.matmul(tf_t, tf_b)
y_t0 = y_tf[0,0]
# dy = 2x * dx
dy_dx = tape.gradient(y_tf, tf_t)
print(dy_dx)
我正低于矩阵 dy/dx
tf.Tensor(
[[-0.17307831 1.1900724 2.245003 ]
[-0.17307831 1.1900724 2.245003 ]
[-0.17307831 1.1900724 2.245003 ]
[-0.17307831 1.1900724 2.245003 ]
[-0.17307831 1.1900724 2.245003 ]], shape=(5, 3), dtype=float32)
上面的矩阵看起来不对。 因为对于元素 y_tf[0,0]
Note : y_tf[0,0] = tf_t[0,0]*tf_b[0,0] + tf_t[0,1]*tf_b[1,0] + tf_t[0,2]*tf_b[2,0]
如果我执行
tape.gradient(y_t0, tf_t)
我得到这样的矩阵
tf.Tensor(
[[0.43842274 1.5658046 1.4204658 ]
[0. 0. 0. ]
[0. 0. 0. ]
[0. 0. 0. ]
[0. 0. 0. ]], shape=(5, 3), dtype=float32)
上面的第一行是矩阵 tf_b
的第一列,考虑到矩阵乘法的工作原理,这很有意义,如果我是,总结一下,这些数字将是 3.424693
但是,我得到的结果是 dy_dx
它的第一个元素 dy_dx[0,0]
作为 -0.17307831
这是 tf_b ( sum(tf_b[0,:])
的第一行的总和 !!
所以谁能解释一下 tf_y[0,0] wrt tf_x
的梯度是如何减少到 -0.17307831
而不是 3.424693
的?
问题可能与
这里要理解的关键概念是 tf.gradients
计算输出的 sum 相对于输入的梯度。即 dy_dx
表示 y_tf
的所有元素之和随着 tf_t
的每个元素变化而变化的比例。
因此,如果您采用 tf_t[0, 0]
,则该值用于计算 y_tf[0, 0]
、y_tf[0, 1]
和 y_tf[0, 2]
,在每种情况下都使用系数 tf_b[0, 0]
, tf_b[0, 1]
和 tf_b[0, 2]
。所以,如果我将 tf_t[0, 0]
增加一,y_tf
的总和将增加 tf_b[0, 0] + tf_b[0, 1] + tf_b[0, 2]
,这是 dy_dx[0, 0]
的值。继续同样的推理,每个值 tf_t[i, j]
实际上都乘以 tf_b[j, :]
中的所有值,因此 dy_dx
是 tf_b
行总和的重复。
当您计算 y_t0
相对于 tf_t
的梯度时,tf_t[0, 0]
的变化会使结果总和改变 tf_b[0, 0]
,所以这就是那种情况下的梯度值。