Tensorflow:张量逐行乘以更多不同的矩阵
Tensorflow: tensor multiplication row-by-row with more different matrices
我有一个矩阵 A,它在 tensorflow 中定义为张量,有 n 行和 p 列。此外,我说有 k 个矩阵 B1,...,Bk 有 p 行和 q 列。我的目标是获得 n 行和 q 列的结果矩阵 C,其中 C 的每一行是 A 中相应行与 B 矩阵之一的矩阵乘积。选择哪个 B 由给定的 n 维索引向量 I 确定,该索引向量的取值范围为 1 到 k。在我的例子中,B 是权重变量,而 I 是作为输入给出的另一个张量变量。
numpy 中的代码示例如下所示:
A = array([[1, 0, 1],
[0, 0, 1],
[1, 1, 0],
[0, 1, 0]])
B1 = array([[1, 1],
[2, 1],
[3, 6]])
B2 = array([[1, 5],
[3, 2],
[0, 2]])
B = [B1, B2]
I = [1, 0, 0, 1]
n = A.shape[0]
p = A.shape[1]
q = B1.shape[1]
C = np.zeros(shape = (n,q))
for i in xrange(n):
C[i,:] = np.dot(A[i,:],B[I[i]])
如何在张量流中进行翻译?
在我的特定情况下,变量定义为:
A = tf.placeholder("float", [None, p])
B1 = tf.Variable(tf.random_normal(p,q))
B2 = tf.Variable(tf.random_normal(p,q))
I = tf.placeholder("float",[None])
这有点棘手,可能有更好的解决方案。以您的第一个示例为例,我的方法计算 C 如下:
C = diag([0,1,1,0]) * A * B1 + diag([1,0,0,1]) * A * B2
其中 diag([0,1,1,0])
是对角线向量 [0,1,1,0]
的对角矩阵。这可以通过 TensorFlow 中的 tf.diag() 来实现。
为方便起见,让我假设k<=n(否则一些B矩阵将保持未使用状态)。以下脚本从矢量 I 获取这些对角线值并计算 C 如上所述:
k = 2
n = 4
p = 3
q = 2
a = array([[1, 0, 1],
[0, 0, 1],
[1, 1, 0],
[0, 1, 0]])
index_input = [1, 0, 0, 1]
import tensorflow as tf
# Creates a dim·dim tensor having the same vector 'vector' in every row
def square_matrix(vector, dim):
return tf.reshape(tf.tile(vector,[dim]), [dim,dim])
A = tf.placeholder(tf.float32, [None, p])
B = tf.Variable(tf.random_normal(shape=[k,p,q]))
# For the first example (with k=2): B = tf.constant([[[1, 1],[2, 1],[3, 6]],[[1, 5],[3, 2],[0, 2]]], tf.float32)
C = tf.Variable(tf.zeros((n, q)))
I = tf.placeholder(tf.int32,[None])
# Create a n·n tensor 'indices_matrix' having indices_matrix[i]=I for 0<=i<n (each row vector is I)
indices_matrix = square_matrix(I, n)
# Create a n·n tensor 'row_matrix' having row_matrix[i]=[i,...,i] for 0<=i<n (each row vector is a vector of i's)
row_matrix = tf.transpose(square_matrix(tf.range(0, n, 1), n))
# Find diagonal values by comparing tensors indices_matrix and row_matrix
equal = tf.cast(tf.equal(indices_matrix, row_matrix), tf.float32)
# Compute C
for i in range(k):
diag = tf.diag(tf.gather(equal, i))
mul = tf.matmul(diag, tf.matmul(A, tf.gather(B, i)))
C = C + mul
sess = tf.Session()
sess.run(tf.initialize_all_variables())
print(sess.run(C, feed_dict={A : a, I : index_input}))
作为一项改进,可以使用矢量化实现而不是使用 for 循环来计算 C。
只需进行 2 次矩阵乘法
A1 = A[0:3:3,...] # this will get the first last index of your original but just make a new matrix
A2 = A[1:2]
在张量流中
A1 = tf.constant([matrix elements go here])
A2 = tf.constant([matrix elements go here])
B = ...
B1 = tf.matmul(A1,B)
B2 = tf.matmul(A2,B)
C = tf.pack([B1,B2])
当然如果你需要重组 C 张量你也可以使用 gather
C = tf.gather(C,[0,3,2,1])
我有一个矩阵 A,它在 tensorflow 中定义为张量,有 n 行和 p 列。此外,我说有 k 个矩阵 B1,...,Bk 有 p 行和 q 列。我的目标是获得 n 行和 q 列的结果矩阵 C,其中 C 的每一行是 A 中相应行与 B 矩阵之一的矩阵乘积。选择哪个 B 由给定的 n 维索引向量 I 确定,该索引向量的取值范围为 1 到 k。在我的例子中,B 是权重变量,而 I 是作为输入给出的另一个张量变量。
numpy 中的代码示例如下所示:
A = array([[1, 0, 1],
[0, 0, 1],
[1, 1, 0],
[0, 1, 0]])
B1 = array([[1, 1],
[2, 1],
[3, 6]])
B2 = array([[1, 5],
[3, 2],
[0, 2]])
B = [B1, B2]
I = [1, 0, 0, 1]
n = A.shape[0]
p = A.shape[1]
q = B1.shape[1]
C = np.zeros(shape = (n,q))
for i in xrange(n):
C[i,:] = np.dot(A[i,:],B[I[i]])
如何在张量流中进行翻译?
在我的特定情况下,变量定义为:
A = tf.placeholder("float", [None, p])
B1 = tf.Variable(tf.random_normal(p,q))
B2 = tf.Variable(tf.random_normal(p,q))
I = tf.placeholder("float",[None])
这有点棘手,可能有更好的解决方案。以您的第一个示例为例,我的方法计算 C 如下:
C = diag([0,1,1,0]) * A * B1 + diag([1,0,0,1]) * A * B2
其中 diag([0,1,1,0])
是对角线向量 [0,1,1,0]
的对角矩阵。这可以通过 TensorFlow 中的 tf.diag() 来实现。
为方便起见,让我假设k<=n(否则一些B矩阵将保持未使用状态)。以下脚本从矢量 I 获取这些对角线值并计算 C 如上所述:
k = 2
n = 4
p = 3
q = 2
a = array([[1, 0, 1],
[0, 0, 1],
[1, 1, 0],
[0, 1, 0]])
index_input = [1, 0, 0, 1]
import tensorflow as tf
# Creates a dim·dim tensor having the same vector 'vector' in every row
def square_matrix(vector, dim):
return tf.reshape(tf.tile(vector,[dim]), [dim,dim])
A = tf.placeholder(tf.float32, [None, p])
B = tf.Variable(tf.random_normal(shape=[k,p,q]))
# For the first example (with k=2): B = tf.constant([[[1, 1],[2, 1],[3, 6]],[[1, 5],[3, 2],[0, 2]]], tf.float32)
C = tf.Variable(tf.zeros((n, q)))
I = tf.placeholder(tf.int32,[None])
# Create a n·n tensor 'indices_matrix' having indices_matrix[i]=I for 0<=i<n (each row vector is I)
indices_matrix = square_matrix(I, n)
# Create a n·n tensor 'row_matrix' having row_matrix[i]=[i,...,i] for 0<=i<n (each row vector is a vector of i's)
row_matrix = tf.transpose(square_matrix(tf.range(0, n, 1), n))
# Find diagonal values by comparing tensors indices_matrix and row_matrix
equal = tf.cast(tf.equal(indices_matrix, row_matrix), tf.float32)
# Compute C
for i in range(k):
diag = tf.diag(tf.gather(equal, i))
mul = tf.matmul(diag, tf.matmul(A, tf.gather(B, i)))
C = C + mul
sess = tf.Session()
sess.run(tf.initialize_all_variables())
print(sess.run(C, feed_dict={A : a, I : index_input}))
作为一项改进,可以使用矢量化实现而不是使用 for 循环来计算 C。
只需进行 2 次矩阵乘法
A1 = A[0:3:3,...] # this will get the first last index of your original but just make a new matrix
A2 = A[1:2]
在张量流中
A1 = tf.constant([matrix elements go here])
A2 = tf.constant([matrix elements go here])
B = ...
B1 = tf.matmul(A1,B)
B2 = tf.matmul(A2,B)
C = tf.pack([B1,B2])
当然如果你需要重组 C 张量你也可以使用 gather
C = tf.gather(C,[0,3,2,1])