出于诊断目的,我定期抓住网络的梯度。一种方法是将渐变返回为theano函数的输出。但是,每次将渐变从GPU复制到CPU内存可能会很昂贵,所以我宁愿定期这样做。目前,我通过创建两个函数对象来实现这一目标,一个返回渐变,另一个不返回梯度。
然而,我不知道这是否是最佳的,我正在寻找一种更优雅的方式来实现同样的目标。
答案 0 :(得分:3)
您的第一个功能显然会执行训练步骤并更新您的所有参数。
第二个函数必须返回参数的渐变。
最快的方法是将训练步骤的更新添加到第二个函数中,在记录渐变时,不要调用第一个函数,而只调用第二个函数。
gradients = [ ... ]
train_f = theano.function([x, y], [], updates=updates)
train_grad_f = theano.function([x, y], gradients, updates=updates)
num_iters = 1000
grad_array = []
for i in range(num_iters):
# every 10 training steps keep log of gradients
if i % 10 == 0:
grad_array.append(train_grad_f(...))
else:
train_f(...)
更新
如果您希望使用单个功能执行此操作,则可以执行以下操作
from theano.ifelse import ifelse
no_grad = T.iscalar('no_grad')
example_gradient = T.grad(example_cost, example_variable)
# if no_grad is > 0 then return the gradient, otherwise return zeros array
out_grad = ifelse(T.gt(no_grad,0), example_gradient, T.zeros_like(example_variable))
train_f = theano.function([x, y, no_grad], [out_grad], updates=updates)
因此,当您想要检索渐变时,请调用
train_f(x_data, y_data, 1)
,否则
train_f(x_data, y_data, 0)