如何有效地更新 Theano 中共享变量的值?
How to update a value of a shared variable in Theano efficiently?
我尝试在 Theano 中实现非负矩阵分解。更详细地说,我尝试找到两个矩阵 L
和 R
使得它们的乘积 L x R
尽可能准确地表示给定矩阵 M
。
为了找到 L
和 R
矩阵,我使用反向传播。在某些时候,我注意到 L
和 R
中的值可以是负数(当然没有什么能阻止 back prop 这样做)。我试图通过在反向传播步骤后添加以下行来纠正此行为:
self.L.set_value(T.abs_(self.L).eval())
self.R.set_value(T.abs_(self.R).eval())
之后我的程序变得更慢了。
我是不是做错了什么?我是否以错误的方式更新了张量的值?有没有更快的方法?
已添加
根据评论中的要求,我提供了更多代码。这就是我在 __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())
注意一点,我使用 abs_
函数,但使用将负值替换为零的函数实际上更有意义。
您可以像这样强制 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())
来自你的训练循环
我尝试在 Theano 中实现非负矩阵分解。更详细地说,我尝试找到两个矩阵 L
和 R
使得它们的乘积 L x R
尽可能准确地表示给定矩阵 M
。
为了找到 L
和 R
矩阵,我使用反向传播。在某些时候,我注意到 L
和 R
中的值可以是负数(当然没有什么能阻止 back prop 这样做)。我试图通过在反向传播步骤后添加以下行来纠正此行为:
self.L.set_value(T.abs_(self.L).eval())
self.R.set_value(T.abs_(self.R).eval())
之后我的程序变得更慢了。
我是不是做错了什么?我是否以错误的方式更新了张量的值?有没有更快的方法?
已添加
根据评论中的要求,我提供了更多代码。这就是我在 __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())
注意一点,我使用 abs_
函数,但使用将负值替换为零的函数实际上更有意义。
您可以像这样强制 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())
来自你的训练循环