Tensorflow:点积中的 'axis' 参数
Tensorflow: 'axis' argument in dot product
谁能告诉我如何在 tf.tensordot
中使用 axis
参数?
我阅读了文档,但它很复杂,我仍然感到困惑。我看到 在 tf.one_hot
中询问了 axis
,并且在答案中对此事有一些很好的见解,但这对我 tf.tensordot
没有帮助。我想你也可以给我一些见解。
例如,我知道我可以像这样对向量和张量进行点积:
my_vector = tf.random.uniform(shape=[n])
my_tensor = tf.random.uniform(shape=[m, n])
dp = tf.tensordot(my_tensor, my_vector, 1)
但是当我 batch 它们并向它们添加一个维度时,形状为 (b, n)
和 (b, m, n)
得到一个(b, m, 1)
,现在不知道怎么每批点积
你想做的操作不能用 tf.tensordot
. There is, however, a dedicated function for that operation, tf.linalg.matvec
, which will work with batches out of the box. And you can also do the same thing with tf.einsum
完成(以有效的方式),比如 tf.einsum('bmn,bn->bm', my_tensors, my_vectors)
。
关于 tf.tensordot
,通常它计算两个给定张量的“全部 vs 全部”乘积,但匹配和减少一些轴。当没有给出轴时(您必须显式传递 axes=[[], []]
才能执行此操作),它会创建一个张量,将两个输入的维度连接起来。所以,如果你有 my_tensors
形状 (b, m, n)
和 my_vectors
形状 (b, n)
并且你做:
res = tf.tensordot(my_tensors, my_vectors, axes=[[], []])
你得到 res
形状 (b, m, n, b, n)
,这样 res[p, q, r, s, t] == my_tensors[p, q, r] * my_vectors[s, t]
.
axes
参数用于指定输入张量中“匹配”的维度。沿匹配轴的值相乘并相加(如点积),因此这些匹配的维度从输出中减少。 axes
可以采用两种不同的形式:
- 如果它是单个整数,
N
则第一个参数的最后 N
个维度与 b
的第一个 N
个维度相匹配。在您的示例中,这对应于 my_tensor
和 my_vector
. 中具有 n
元素的维度
- 如果它是一个列表,它必须包含两个子列表,
axes_a
和 axes_b
,每个子列表具有相同的 N
个整数。在这种形式中,您明确指出了给定值的哪些维度是匹配的。因此,在您的示例中,您可以传递 axes=[[1], [0]]
,这意味着“将第一个参数 (my_tensor
) 的维度 1
与第二个参数的维度 0
匹配(my_vector
)".
如果您现在有 my_tensors
形状 (b, m, n)
和 my_vectors
形状 (b, n)
,那么您需要匹配尺寸 2
第一个到第二个的维度1
,所以你可以通过axes=[[2], [1]]
。但是,这会给你一个结果 res
,形状 (b, m, b)
,使得 res[i, :, j]
是矩阵 my_tensors[i]
和向量 my_vectors[j]
的乘积。然后你可以只得到你想要的结果(i == j
的结果),有些东西或多或少像 tf.transpose(tf.linalg.diag_part(tf.transpose(res, [1, 0, 2])))
,但你会做比你需要得到相同结果更多的计算。
谁能告诉我如何在 tf.tensordot
中使用 axis
参数?
我阅读了文档,但它很复杂,我仍然感到困惑。我看到 tf.one_hot
中询问了 axis
,并且在答案中对此事有一些很好的见解,但这对我 tf.tensordot
没有帮助。我想你也可以给我一些见解。
例如,我知道我可以像这样对向量和张量进行点积:
my_vector = tf.random.uniform(shape=[n])
my_tensor = tf.random.uniform(shape=[m, n])
dp = tf.tensordot(my_tensor, my_vector, 1)
但是当我 batch 它们并向它们添加一个维度时,形状为 (b, n)
和 (b, m, n)
得到一个(b, m, 1)
,现在不知道怎么每批点积
你想做的操作不能用 tf.tensordot
. There is, however, a dedicated function for that operation, tf.linalg.matvec
, which will work with batches out of the box. And you can also do the same thing with tf.einsum
完成(以有效的方式),比如 tf.einsum('bmn,bn->bm', my_tensors, my_vectors)
。
关于 tf.tensordot
,通常它计算两个给定张量的“全部 vs 全部”乘积,但匹配和减少一些轴。当没有给出轴时(您必须显式传递 axes=[[], []]
才能执行此操作),它会创建一个张量,将两个输入的维度连接起来。所以,如果你有 my_tensors
形状 (b, m, n)
和 my_vectors
形状 (b, n)
并且你做:
res = tf.tensordot(my_tensors, my_vectors, axes=[[], []])
你得到 res
形状 (b, m, n, b, n)
,这样 res[p, q, r, s, t] == my_tensors[p, q, r] * my_vectors[s, t]
.
axes
参数用于指定输入张量中“匹配”的维度。沿匹配轴的值相乘并相加(如点积),因此这些匹配的维度从输出中减少。 axes
可以采用两种不同的形式:
- 如果它是单个整数,
N
则第一个参数的最后N
个维度与b
的第一个N
个维度相匹配。在您的示例中,这对应于my_tensor
和my_vector
. 中具有 - 如果它是一个列表,它必须包含两个子列表,
axes_a
和axes_b
,每个子列表具有相同的N
个整数。在这种形式中,您明确指出了给定值的哪些维度是匹配的。因此,在您的示例中,您可以传递axes=[[1], [0]]
,这意味着“将第一个参数 (my_tensor
) 的维度1
与第二个参数的维度0
匹配(my_vector
)".
n
元素的维度
如果您现在有 my_tensors
形状 (b, m, n)
和 my_vectors
形状 (b, n)
,那么您需要匹配尺寸 2
第一个到第二个的维度1
,所以你可以通过axes=[[2], [1]]
。但是,这会给你一个结果 res
,形状 (b, m, b)
,使得 res[i, :, j]
是矩阵 my_tensors[i]
和向量 my_vectors[j]
的乘积。然后你可以只得到你想要的结果(i == j
的结果),有些东西或多或少像 tf.transpose(tf.linalg.diag_part(tf.transpose(res, [1, 0, 2])))
,但你会做比你需要得到相同结果更多的计算。