2016-12-05 41 views
0

我尝试在Theano中实现非负矩阵分解。更详细地说,我试图找到两个矩阵LR,使得它们的产品L x R代表尽可能准确的给出矩阵M如何有效地更新Theano中共享变量的值?

对于查找LR矩阵我使用反向传播。在某些时候,我注意到LR中的值可能是负值(当然,没有什么能够防止back prop这样做)。我试图通过反向传播步骤之后添加以下行来解决此问题:

self.L.set_value(T.abs_(self.L).eval()) 
self.R.set_value(T.abs_(self.R).eval()) 

之后,我的计划变得更加慢。

我做错了什么?我是否以错误的方式更新张量的值?有没有办法做得更快?

ADDED

正如意见中的要求,我公司提供更多的代码。这是我在__init__中定义函数的方式。

self.L = theano.shared(value=np.random.rand(n_rows, n_hids), name='L', borrow=True) 
self.R = theano.shared(value=np.random.rand(n_hids, n_cols), name='R', borrow=True) 
Y = theano.dot(self.L, self.R) 

diff = X - Y 
D = T.pow(diff, 2) 
E = T.sum(D) 
gr_L = T.grad(cost=E, wrt=self.L) 
gr_R = T.grad(cost=E, wrt=self.R) 

self.l_rate = theano.shared(value=0.000001) 
L_ups = self.L - self.l_rate*gr_L 
R_ups = self.R - self.l_rate*gr_R 

updates = [(self.L, L_ups), (self.R, R_ups)] 
self.backprop = theano.function([X], E, updates=updates) 

然后在我的train功能我有这样的代码:

for i in range(self.n_iter): 
    costs = self.backprop(X, F) 

    self.L.set_value(T.abs_(self.L).eval()) 
    self.R.set_value(T.abs_(self.R).eval()) 

A小调的话,我用的是abs_功能,但它将使实际上更有意义,使用通过更换负值的功能零。

+0

请分享你用来创建'theano.function'的代码。你需要做的是将L和R的更新改为包含T.abs_,而不是使用'.get_value()'而不是'eval()'帮助自己的梯度值 –

+0

?即'self.L.set_value(T.abs_(self.L.get_value()))' – uyaseen

回答

1

您可以强制为L和R符号更新值一直保持正向这样的:

self.l_rate = theano.shared(value=0.000001) 
L_ups = self.L - self.l_rate*gr_L 
R_ups = self.R - self.l_rate*gr_R 

# This force R and L to always be updated to a positive value 
L_ups_abs = T.abs_(L_ups) 
R_ups_abs = T.abs_(R_ups) 

# Use the update L_ups_abs instead of L_ups (same with R_ups) 
updates = [(self.L, L_ups_abs), (self.R, R_ups_abs)] 
self.backprop = theano.function([X], E, updates=updates) 

,并从训练循环删除线

self.L.set_value(T.abs_(self.L).eval()) 
self.R.set_value(T.abs_(self.R).eval())