在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
。层数作为参数传递给函数。
我正在尝试在 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
。层数作为参数传递给函数。