加权矩阵给出重量矢量与扫描(theano)

时间:2017-06-09 13:26:01

标签: python theano theano.scan

我是theano的新手,仍然在扫描周围。我想从行权重计算加权矩阵,通过权重的概率计算权重并得到相应的加权矩阵。但是,我无法在theano中重复权重,同时跟踪矩阵总和。

作为一个玩具示例:

import numpy as np

mtx = np.asarray([[1,0],[0,1],[0.5,0.5]]) 
weights = np.asarray([0.1,0.8]) #weight 1 and weight 2
weights_p = np.asarray([0.8, 0.2]) #prob. of weight 1 and weight 2

将是

weights_p[0] * (mtx * [weights[0],(1-weights[0])]) +\
weights_p[1] * (mtx * [weights[1],(1-weights[1])])

更一般地使用numpy,indexing和for-loop示例我想要的函数会这样做:

def get_weighted(mtx,weights,weights_p):
    mtx_store = np.zeros(np.shape(mtx))
    for idx in xrange(len(weights)):
        mtx_store += weights_p[idx] * (mtx * [weights[idx], 1-weights[idx]])
    return mtx_store

现在我需要在theano中这样做。我尝试了什么:

import theano as t
v,w = t.tensor.vectors('v','w')
m,n = t.tensor.matrices('m','n')

def step(v, w, m, cum_sum):
    return v * (m * [w,1-w]) + cum_sum

output, updates = t.scan(fn=step,
                         sequences=[v,w],
                         non_sequences=[m],
                         outputs_info=[n])

get_weighted = t.function(inputs=[v,w,m,n],
                  outputs=output,
                  updates=updates)

我的想法是有一个空数组来迭代存储总和:

mtx_store = np.zeros(np.shape(mtx))
get_weighted(weights_p, weights, mtx, mtx_store)

但我得到了:

array([[[ 1.  ,  0.  ],
        [ 0.  ,  1.  ],
        [ 0.5 ,  0.5 ]],

       [[ 1.16,  0.  ],
        [ 0.  ,  1.04],
       [ 0.58,  0.52]]])

而不是

array([[ 0.24,  0.  ],
       [ 0.  ,  0.76],
       [ 0.12,  0.38]])

我确信这源于我对扫描的不理解。有什么不对,如何更有效地完成?

1 个答案:

答案 0 :(得分:0)

我发现了问题。后人:主要问题是扫描的语法要求:

sequences (if any), prior result(s) (if needed), non-sequences (if any)

虽然我按此顺序提供了参数:

sequences, non-sequences, prior-results

正确的代码如下:

def step(v, w, cum_sum,m):
    return v * (m * [w,1-w]) + cum_sum

output, updates = t.scan(fn=step,
                         sequences=[v,w],
                         non_sequences=[m],
                         outputs_info=[t.tensor.zeros_like(m)])

final_result = output[-1] #take the final outcome of the sum


get_weighted = t.function(inputs=[v,w,m],
                  outputs=final_result,
                  updates=updates)

(传递矩阵来存储参数显然也没有必要。我不认为这是问题所在,但可以直接指定为上面'outputs_info'中所做的那样)