将矩阵转换为不同维矩阵的Theano函数

时间:2015-07-31 01:09:52

标签: python numpy theano

我有矩阵,其中对角线是该行中所有其他元素之和的负数。这是一个例子

import numpy as np
Q = np.array([[-6, 2, 2, 1, 1], 
              [1, -4, 0, 1, 2],
              [1, 0, -4, 2, 1],
              [2, 1, 0, -3, 0],
              [1, 1, 1, 1, -4]])

我想编写一个Theano函数,它接收这些矩阵并返回一个行数相同的矩阵,少一列,并删除对角线。所以对于Q来说,这将是

Q_raw = np.array([[2, 2, 1, 1], 
                  [1, 0, 1, 2],
                  [1, 0, 2, 1],
                  [2, 1, 0, 0],
                  [1, 1, 1, 1]])

我也喜欢反过来,即给定Q_raw,我想写一个吐出Q的Theano函数。我怎样才能在Theano中编写这些函数?到目前为止,我还没有想出一个只将矩阵本身作为输入的解决方案。

1 个答案:

答案 0 :(得分:1)

这里有几种方法可以做我认为你要求的方法。可能有更有效的方法。

import numpy
import theano
import theano.tensor as tt


def symbolic_remove_diagonal(x):
    flat_x = x.flatten()
    indexes = tt.arange(flat_x.shape[0], dtype='int64')
    diagonal_modulo = indexes % (x.shape[0] + 1)
    off_diagonal_flat_x = flat_x[tt.neq(diagonal_modulo, 0).nonzero()]
    return off_diagonal_flat_x.reshape((x.shape[0], x.shape[1] - 1))


def symbolic_add_diagonal(x):
    diagonal_values = -x.sum(axis=1)
    flat_x = x.flatten()
    result_length = flat_x.shape[0] + x.shape[0]
    indexes = tt.arange(result_length, dtype='int64')
    diagonal_modulo = indexes % (x.shape[0] + 1)
    result = tt.zeros((result_length,), dtype=x.dtype)
    result = tt.set_subtensor(result[tt.eq(diagonal_modulo, 0).nonzero()], diagonal_values)
    result = tt.set_subtensor(result[tt.neq(diagonal_modulo, 0).nonzero()], flat_x)
    return result.reshape((x.shape[0], x.shape[1] + 1))


def main():
    theano.config.compute_test_value = 'raise'
    x1 = tt.matrix()
    x1.tag.test_value = numpy.array(
        [[-6, 2, 2, 1, 1],
         [1, -4, 0, 1, 2],
         [1, 0, -4, 2, 1],
         [2, 1, 0, -3, 0],
         [1, 1, 1, 1, -4]])
    x2 = tt.matrix()
    x2.tag.test_value = numpy.array(
        [[2, 2, 1, 1],
         [1, 0, 1, 2],
         [1, 0, 2, 1],
         [2, 1, 0, 0],
         [1, 1, 1, 1]])
    remove_diagonal = theano.function(inputs=[x1], outputs=symbolic_remove_diagonal(x1))
    add_diagonal = theano.function(inputs=[x2], outputs=symbolic_add_diagonal(x2))
    x2_prime = remove_diagonal(x1.tag.test_value)
    x1_prime = add_diagonal(x2.tag.test_value)
    print 'Diagonal removed:\n', x2_prime
    print 'Diagonal added:\n', x1_prime
    assert numpy.all(x2_prime == x2.tag.test_value)
    assert numpy.all(x1_prime == x1.tag.test_value)


main()