在theano

时间:2015-12-19 10:08:27

标签: python neural-network theano

我正在尝试在theano中为具有多个隐藏层的前馈神经网络实现成本函数。成本函数是

cost=((W1*W1).sum()+(b1*b1).sum()+(W2*W2).sum()+(b2*b2).sum())*reg_lambda

但是我决定通过构造函数在运行时隐藏到网络类的数量。因此,Ws和bs的数量在运行时决定,因此必须在运行时创建成本表达式。我可以计算theano函数之外的Ws和bs的总和,并简单地传递标量值。但是我需要用于计算渐变的符号表达式。如何在运行时创建符号表达式?

1 个答案:

答案 0 :(得分:1)

您可以使用常规Python循环来构建动态数量的图层的成本。请注意,Theano'运行时间'和Python'运行时间'是两件不同的事情。 Theano'编译时间'在Python的运行时间和#39;因此,您可以使用Python代码构建动态的Theano表达式,这些表达式依赖于仅在Python代码运行时已知的参数。

您提供的成本仅为网络参数的L2正则化。您可能需要额外的组件才能支付全部费用。这是一个完整的例子。

import numpy
import theano
import theano.tensor as tt


def compile(input_size, hidden_sizes, output_size, reg_lambda, learning_rate):
    ws, bs = [], []
    x = tt.matrix('x')
    x.tag.test_value = numpy.random.standard_normal(size=(2, input_size))\
        .astype(theano.config.floatX)
    previous_size = input_size
    h = x
    for hidden_size in hidden_sizes:
        w = theano.shared(
                numpy.random.standard_normal(size=(previous_size, hidden_size))
                          .astype(theano.config.floatX))
        b = theano.shared(numpy.zeros((hidden_size,), dtype=theano.config.floatX))
        h = tt.tanh(tt.dot(h, w) + b)
        ws.append(w)
        bs.append(b)
        previous_size = hidden_size
    w = theano.shared(numpy.random.standard_normal(size=(previous_size, output_size))
                      .astype(theano.config.floatX))
    b = theano.shared(numpy.zeros((output_size,), dtype=theano.config.floatX))
    y = tt.nnet.softmax(tt.dot(h, w) + b)
    ws.append(w)
    bs.append(b)
    z = tt.ivector('z')
    z.tag.test_value = numpy.random.randint(output_size, size=(2,))
    cost = tt.nnet.categorical_crossentropy(y, z).mean()
    for w, b in zip(ws, bs):
        cost += tt.sum(w ** 2) * reg_lambda
        cost += tt.sum(b ** 2) * reg_lambda
    updates = [(p, p - learning_rate * tt.grad(cost, p)) for p in ws + bs]
    return theano.function([x, z], outputs=[cost], updates=updates)


theano.config.compute_test_value = 'raise'
compile(10, [8, 6, 4, 8, 16], 32, 0.1, 0.01)

注意第二个for循环,它为每个层的cost添加了L2正则化组件。层数作为参数传递给函数。