Neural network Theano——梯度平方的平均值

Neural network Theano——梯度平方的平均值,neural-network,gradient,theano,Neural Network,Gradient,Theano,在theano中,给定具有形状(批次大小)的批次成本cost,很容易计算平均成本的梯度,如T.grad(T.mean(cost,axis=0),p),p是计算成本时使用的参数。通过在计算图中反向传播梯度,可以有效地实现这一点。我现在想做的是计算批次上梯度平方的平均值。这可以使用以下代码来完成: import theano.tensor as T g_square = T.mean(theano.scan(lambda i:T.grad(cost[i],p)**2,sequences=T.ara

在theano中,给定具有形状(批次大小)的批次成本
cost
,很容易计算平均成本的梯度,如
T.grad(T.mean(cost,axis=0),p)
,p是计算
成本时使用的参数。通过在计算图中反向传播梯度,可以有效地实现这一点。我现在想做的是计算批次上梯度平方的平均值。这可以使用以下代码来完成:

import theano.tensor as T

g_square = T.mean(theano.scan(lambda i:T.grad(cost[i],p)**2,sequences=T.arange(cost.shape[0]))[0],axis=0)
其中,为方便起见,
p
被假定为一个单一的theano张量,而不是张量列表。 通过简单地将梯度反向传播到最后一步,并将最后一个操作的分量平方(应为批次索引的和),可以有效地执行计算。在这一点上我可能是错的,但是计算应该和简单的反向传播一样简单,几乎一样快。然而,theano似乎无法优化计算,它一直使用循环,使得计算速度非常慢

有没有人知道一种解决方案,可以通过强制优化、以不同的方式表示计算,甚至通过反向传播过程来提高计算效率


提前感谢。

您的函数
g_square
恰好具有O(批大小**2)的复杂性,而不是预期的O(批大小)。这使得它在较大批量的情况下显得异常缓慢

原因是,在每次迭代中,向前和向后传递都是在整个批次中计算的,即使只需要一个数据点的
cost[i]
。 我假设
cost
计算图
x
的输入是一个张量,第一个维度是size
batch\u size
。Theano没有办法沿着这个维度自动切片这个张量。因此,计算总是在整个批次上进行

不幸的是,我认为没有比切割输入并在Theano之外执行循环更好的解决方案了:

# x: input data batch
batch_size = x.shape[0]
g_square_fun = theano.function( [p], T.grad(cost[0],p)**2) 

g_square_value = 0
for i in batch_size:
    g_square_value += g_square_fun( x[i:i+1])

也许当Theano的未来版本具有更好的内置能力来计算雅可比矩阵时,会有更优雅的解决方案

在Theano文档中深入挖掘后,我找到了一个解决方案,可以在计算图中运行。关键思想是在scan函数中克隆网络图,从而显式地分割输入张量。我尝试了以下代码,根据经验,它显示了预期的O(批次大小):

 # x: input data batch
 # assuming cost = network(x,p)

 from theano.gof.graph import clone_get_equiv

 def g_square(cost,p):

    g = T.zeros_like(p)

    def scan_fn( i, g, cost, p):
        # clone the graph computing cost, but slice it's input 
        cloned = clone_get_equiv([],[cost], 
                                 copy_inputs_and_orphans=False,
                                 memo={x: x[i:i+1]})
        cost_slice = cloned[cost].reshape([])
        return  g+T.grad(cost_slice,p)**2 

    result,updates = theano.reduce( scan_fn,
                                    outputs_info=g,
                                    sequences=[T.arange(cost.size)],
                                    non_sequences=[cost.flatten(),p])

    return result

我们是否提前(在函数调用之前)知道
batch\u size
?@dontloo确实在函数调用之前可用
batch\u size
。请不要添加其他答案,您应该编辑旧答案并添加新发现。正在标记关闭此项