tf.matmul
为什么不使用转置张量?
transpose_b=True
没问题,但tf.transpose(inp)
没问题。
此屏幕截图是使用tensorflow-gpu==2.0.0-rc1
在Colab中制作的:
答案 0 :(得分:1)
tf.linalg.matmul
中的 transpose_b=True
仅对第二个给定张量的最后两个轴进行转置,而tf.transpose
在没有更多参数的情况下将完全反转尺寸。等效为:
inp_t = tf.transpose(inp, (0, 2, 1))
tf.matmul(inp, inp_t)
答案 1 :(得分:1)
tf.transpose()
默认执行常规的二维矩阵转置(将perm参数设置为input_tensor_rank-1),如果您未明确指定perm
(permutation)参数。
因此,请适当设置perm参数
inp_t = tf.transpose(inp, perm=[0,2,1])
y = tf.matmul(inp, x)
print(y)
答案 2 :(得分:1)
Tensorflow告诉您的是,将两个张量相乘时,尺寸不匹配。用基本的线性代数术语来考虑它。当矩阵相乘时,您只能将矩阵相乘,其中第一个矩阵的最后一个维度与第二个矩阵的第一个维度相同。例如。您可以将2x4矩阵与4x2矩阵相乘(transpose
为您做的事情。来自the docs:
如果未给出
perm
,则将其设置为(n-1 ... 0),其中n是输入张量的秩。因此,默认情况下,此操作会在二维输入张量上执行常规矩阵转置。
因此,如果您忽略较大尺寸的烫发,tf.transform()
就像在二维张量(矩阵)上那样切换尺寸:
inp_t_without_perm = tf.transpose(inp)
inp_t_without_perm
# Output: <tf.Tensor 'transpose_8:0' shape=(1, 4, 2) dtype=float32>
因此,它仅将第一个尺寸的最后一个尺寸切换为第二个尺寸,而第二个尺寸保持不变。这等效于:
inp_t_with_wrong_perm = tf.transpose(inp, perm=[2,1,0])
inp_t_with_wrong_perm
# Output: <tf.Tensor 'transpose_8:0' shape=(1, 4, 2) dtype=float32>
如果您随后这样做:
mul = tf.matmul(inp, inp_t_without_perm) # or with inp_t_with_wrong_perm
您收到此错误,因为前两个尺寸或后两个尺寸不匹配。
现在,当将高阶张量相乘时,您必须对齐尺寸,其尺寸与2d中的尺寸相同(请考虑将张量分为矩阵和向量)。一个向量和一个矩阵...对不起,我还没有提出一个更好的隐喻,当我发现笔和纸安静了半个小时时,我可以使用爱因斯坦表示法将其变得更加正式,但这基本上是运作方式...)。
对于您而言,有效的方法是:
inp = tf.reshape(tf.linspace(-1.0, 1.0, 8), (2,4,1))
# switch the last two dimensions so you can multiply 4x1 by 1x4
# and leave first dimension as it is.
inp_t = tf.transpose(inp, perm=[0,2,1])
mul = tf.matmul(inp, inp_t)
mul
# Output: <tf.Tensor 'MatMul_8:0' shape=(2, 4, 4) dtype=float32>
请注意,在您的情况下,这是唯一有效的排列,因为这种乘法是不可交换的。因此,您将必须从左到右匹配尺寸(再次,很抱歉,但是挥舞着手,但是正式的数学证明将需要我做一些高阶张量代数,但是我认为这正是您想要实现的目标...)。我并没有深入研究文档,但是我认为transform_b
参数正在为您完成这种排列。希望能有所帮助。请进一步评论。