在theano中动态创建符号表达式

Dynamically creating symbolic expressions in theano

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

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

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

您可以使用常规 Python 循环来构建动态层数的成本。请注意 Theano 'run time' 和 Python 'run time' 是两个不同的东西。 Theano 的 'compile time' 发生在 Python 的 'run time' 期间,因此您可以使用 Python 代码来构造依赖于仅当 Python 代码是已知参数的动态 Theano 表达式运行.

你给的代价只是网络参数的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 循环,它将 L2 正则化组件添加到每个层的 cost。层数作为参数传递给函数。