首页 文章

Tensorflow:逐行乘法,具有更多不同的矩阵

提问于
浏览
2

我有一个矩阵A,它被定义为张量流中的张量,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])

2 回答

  • 0

    这有点棘手,可能有更好的解决方案 . 以你的第一个例子,我的方法计算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.

  • 0

    只做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张量,您也可以使用收集

    C = tf.gather(C,[0,3,2,1])
    

相关问题