我正在尝试在theano中为具有多个隐藏层的前馈神经网络实现成本函数。成本函数是
cost=((W1*W1).sum()+(b1*b1).sum()+(W2*W2).sum()+(b2*b2).sum())*reg_lambda
但是我决定通过构造函数在运行时隐藏到网络类的数量。因此,Ws和bs的数量在运行时决定,因此必须在运行时创建成本表达式。我可以计算theano函数之外的Ws和bs的总和,并简单地传递标量值。但是我需要用于计算渐变的符号表达式。如何在运行时创建符号表达式?
答案 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正则化组件。层数作为参数传递给函数。