我正在尝试为Hessian-Free优化实现共轭渐变的theano版本,如本文所述:http://icml2010.haifa.il.ibm.com/papers/458.pdf。
用于共轭梯度算法的终止条件是目标Phi的值相对于其迭代前几倍的值没有减少很多。
即(Phi(t) - Phi(t-k))/ Phi(t)< k eps。其中eps是容差。
我正在使用Theano Scan实际实现共轭渐变,因此停止标准将要求我作为一个水龙头输入,Phi K迭代前的值。
对于固定K,这很容易,并在下面的代码中显示。但是,K的值应该根据迭代次数而变化。 K = max(10,0.1 * iters)。这需要一个共享变量的水龙头? 那可能吗?你怎么做呢?
我尝试在step函数中使用theano变量用于K但是然后扫描不能使用该K作为输入。
这是我的代码:
r_init = b_vec - mat_vec_func(x_init)
d_init = r_init
delta_0 = T.dot(r_init.transpose(), r_init)
# initial value of the CG objective
phi_0 = -T.dot(x_init.transpose(), r_init)
phis_0 = phi_0.dimshuffle(['x'])
def conj_step(iters, x, d, r, delta_new, phi_tm5, phi_tm1):
q = mat_vec_func(d)
alpha = delta_new/(T.dot(d.transpose(), q))
x = x + alpha*d
r = ifelse(T.eq(iters%50, 0), b_vec - mat_vec_func(x), r - alpha*q)
delta_old = delta_new
delta_new = T.dot(r.transpose(), r)
beta = delta_new/delta_old
d = r + beta*d
# calculate the CG objective to use for the stopping criterion.
phi = -T.dot(x.transpose(), r)
k = max(k, 0.1*iters.eval())
return [x, d, r, delta_new, phi], theano.scan_module.until(T.le((phi - phi_tm5)/phi , tol))
xdrd, _ = theano.scan(conj_step,
sequences = [T.arange(max_iter)],
outputs_info=[x_init, d_init, r_init, delta_0,
dict(initial=phis_0,taps=[-5, -1])],
)
共轭梯度算法求解方程Ax = b,mat_vec_func只是计算Ax的函数。
在我的例子中,K被硬编码为5,但我希望能够使其变化。
谢谢!