2016-12-05 57 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())