定期记录渐变,而不需要Theano中的两个功能(或减速)

时间:2016-12-09 20:07:04

标签: theano

出于诊断目的,我定期抓住网络的梯度。一种方法是将渐变返回为theano函数的输出。但是,每次将渐变从GPU复制到CPU内存可能会很昂贵,所以我宁愿定期这样做。目前,我通过创建两个函数对象来实现这一目标,一个返回渐变,另一个不返回梯度。

然而,我不知道这是否是最佳的,我正在寻找一种更优雅的方式来实现同样的目标。

1 个答案:

答案 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)