Theano渐变计算创建float64

时间:2015-06-29 22:42:10

标签: python neural-network gpu theano

我在Theano上有一些标准的NN代码,有两个独立的编译函数。一个计算成本,一个用AdaGrad更新计算成本。

对于GPU速度,我试图保留所有内容float32。问题是我收到一条警告,说明渐变计算正在创建float64。特别是对于以下代码行。

gradients = TT.grad(lossFn, self.params)
paramUpdates = [(param, param - TT.inv(TT.sqrt(sumGrad)) * grad) for param, grad, sumGrad in zip(self.params, gradients, self.gradSums)]

如果我注释掉渐变计算并用占位符替换第二行,一切都很好。显然这是垃圾更新,但它有助于查明问题。

paramUpdates = [(self.params[0], self.params[0])]

作为参考,这是损失函数:

self.loss = TT.mean(TT.sqr(self.logisticLayer.yHat - TT.cast(self.inputs[1:-1, :], floatX)), acc_dtype=floatX, dtype=floatX)

仅成本编译功能是:

    self._calculateCost = theano.function(
        inputs=[self.inputs],
        outputs=self.loss,
    )

而成本+更新功能是:

    self._calculateCostAndUpdate = theano.function(
        inputs=[self.inputs],
        outputs=self.loss,
        updates=updates
    )

更新

我将问题归结为LSTM图层。这是最小的代码

class TestLSTMLayer(object):
    def __init__(self, inputs, outputSize, dropout=0.9, inputSize=None, adagradInit=1, forgetGateBias=3, srng=None):
        self.h0 = theano.shared(np.random.randn(outputSize).astype(floatX))

        self.params = [self.h0]

        def _recurrence(hBelow):
            return hBelow

        hOutputs, _ = theano.scan(
            fn=_recurrence,
            outputs_info=self.h0,
            n_steps=inputs.shape[0]
        )
        self.hOutputs = hOutputs

    def getUpdates(self):
        gradients = TT.grad(TT.sum(self.hOutputs), self.params)
        paramUpdates = [(self.params[0], self.params[0])]
        return paramUpdates

当我调用getUpdates()来获取渐变时(例如,这是一个垃圾更新),会出现问题。我发现评论gradients = ...或将scan()替换为重复h0所需形状的内容可以解决问题。

更新2

调试显示int64函数中的scan混乱。

 |Subtensor{int64::} [@B] <TensorType(float32, matrix)> ''
   |for{cpu,scan_fn} [@C] <TensorType(float32, matrix)> ''
   | |Subtensor{int64} [@D] <TensorType(int64, scalar)> ''
   | | |Shape [@E] <TensorType(int64, vector)> ''
   | | | |<TensorType(float32, matrix)> [@F] <TensorType(float32, matrix)>
   | | |Constant{0} [@G] <int64>
   | |IncSubtensor{Set;:int64:} [@H] <TensorType(float32, matrix)> ''
   |   |Alloc [@I] <TensorType(float32, matrix)> ''
   |   | |TensorConstant{0.0} [@J] <TensorType(float32, scalar)>
   |   | |Elemwise{add,no_inplace} [@K] <TensorType(int64, scalar)> ''
   |   | | |Subtensor{int64} [@D] <TensorType(int64, scalar)> ''
   |   | | |Subtensor{int64} [@L] <TensorType(int64, scalar)> ''
   |   | |   |Shape [@M] <TensorType(int64, vector)> ''
   |   | |   | |Rebroadcast{0} [@N] <TensorType(float32, matrix)> ''
   |   | |   |   |DimShuffle{x,0} [@O] <TensorType(float32, row)> ''
   |   | |   |     |<TensorType(float32, vector)> [@P] <TensorType(float32, vector)>
   |   | |   |Constant{0} [@Q] <int64>
   |   | |Subtensor{int64} [@R] <TensorType(int64, scalar)> ''
   |   |   |Shape [@S] <TensorType(int64, vector)> ''
   |   |   | |Rebroadcast{0} [@N] <TensorType(float32, matrix)> ''
   |   |   |Constant{1} [@T] <int64>
   |   |Rebroadcast{0} [@N] <TensorType(float32, matrix)> ''
   |   |ScalarFromTensor [@U] <int64> ''
   |     |Subtensor{int64} [@L] <TensorType(int64, scalar)> ''
   |Constant{1} [@V] <int64>

2 个答案:

答案 0 :(得分:0)

您可以theano.printing.debugprint使用print_type=True来查看各种组件的类型。

例如,

class TestLSTMLayer(object):
    def __init__(self, inputs, outputSize, dropout=0.9, inputSize=None, adagradInit=1, forgetGateBias=3, srng=None):
        self.h0 = theano.shared(np.random.randn(outputSize).astype(floatX))

        self.params = [self.h0]

        def _recurrence(hBelow):
            print 'hBelow', theano.printing.debugprint(hBelow, print_type=True)    
            return hBelow

        print 'h0', theano.printing.debugprint(self.h0, print_type=True)    
        hOutputs, _ = theano.scan(
            fn=_recurrence,
            outputs_info=self.h0,
            n_steps=inputs.shape[0]
        )
        self.hOutputs = hOutputs

    def getUpdates(self):
        print 'sum', theano.printing.debugprint(TT.sum(self.hOutputs), print_type=True)    
        gradients = TT.grad(TT.sum(self.hOutputs), self.params)
        paramUpdates = [(self.params[0], self.params[0])]
        return paramUpdates

答案 1 :(得分:0)

我通过更新到最新版本(GitHub上的最新版本)来解决这个问题。 http://deeplearning.net/software/theano/install.html#bleeding-edge-install-instructions

有点奇怪,但仍然是一个解决方案。