【发布时间】:2017-04-26 17:51:24
【问题描述】:
我已经实现并训练了一个具有 k 个二进制输入 (0,1)、一个隐藏层和一个输出层单元的 Theano 神经网络。一旦经过训练,我想获得使输出最大化的输入(例如,x 使输出层的单位最接近 1)。到目前为止我还没有找到它的实现,所以我正在尝试以下方法:
- 训练网络 => 获得训练后的权重 (theta1, theta2)
- 定义神经网络函数,x 为输入,训练的 theta1、theta2 为固定参数。即:f(x) = sigmoid(theta1*(sigmoid (theta2*x)))。此函数采用 x 并使用给定的训练权重(theta1、theta2)给出介于 0 和 1 之间的输出。
- 应用梯度下降 w.r.t. x 在神经网络函数 f(x) 上,并在给定 theta1 和 theta2 的情况下获得使 f(x) 最大化的 x。
对于这些,我使用玩具示例 (k = 2) 实现了以下代码。基于http://outlace.com/Beginner-Tutorial-Theano/ 上的教程,但更改了向量 y,因此只有一种输入组合可以提供 f(x) ~ 1,即 x = [0, 1]。
Edit1:正如建议的那样,optimizer 设置为 None,偏置单位固定为 1。
第 1 步:训练神经网络。这运行良好且没有错误。
import os
os.environ["THEANO_FLAGS"] = "optimizer=None"
import theano
import theano.tensor as T
import theano.tensor.nnet as nnet
import numpy as np
x = T.dvector()
y = T.dscalar()
def layer(x, w):
b = np.array([1], dtype=theano.config.floatX)
new_x = T.concatenate([x, b])
m = T.dot(w.T, new_x) #theta1: 3x3 * x: 3x1 = 3x1 ;;; theta2: 1x4 * 4x1
h = nnet.sigmoid(m)
return h
def grad_desc(cost, theta):
alpha = 0.1 #learning rate
return theta - (alpha * T.grad(cost, wrt=theta))
in_units = 2
hid_units = 3
out_units = 1
theta1 = theano.shared(np.array(np.random.rand(in_units + 1, hid_units), dtype=theano.config.floatX)) # randomly initialize
theta2 = theano.shared(np.array(np.random.rand(hid_units + 1, out_units), dtype=theano.config.floatX))
hid1 = layer(x, theta1) #hidden layer
out1 = T.sum(layer(hid1, theta2)) #output layer
fc = (out1 - y)**2 #cost expression
cost = theano.function(inputs=[x, y], outputs=fc, updates=[
(theta1, grad_desc(fc, theta1)),
(theta2, grad_desc(fc, theta2))])
run_forward = theano.function(inputs=[x], outputs=out1)
inputs = np.array([[0,1],[1,0],[1,1],[0,0]]).reshape(4,2) #training data X
exp_y = np.array([1, 0, 0, 0]) #training data Y
cur_cost = 0
for i in range(5000):
for k in range(len(inputs)):
cur_cost = cost(inputs[k], exp_y[k]) #call our Theano-compiled cost function, it will auto update weights
print(run_forward([0,1]))
[0,1] 向前运行的输出为:0.968905860574。
我们还可以通过theta1.get_value() 和theta2.get_value() 获得权重值
第 2 步: 定义神经网络函数 f(x)。训练后的权重 (theta1, theta2) 是该函数的常量参数。
这里的事情变得有点棘手,因为偏置单元是输入 x 向量的一部分。为此,我将 b 和 x 连接起来。但是现在代码运行良好。
b = np.array([[1]], dtype=theano.config.floatX)
#b_sh = theano.shared(np.array([[1]], dtype=theano.config.floatX))
rand_init = np.random.rand(in_units, 1)
rand_init[0] = 1
x_sh = theano.shared(np.array(rand_init, dtype=theano.config.floatX))
th1 = T.dmatrix()
th2 = T.dmatrix()
nn_hid = T.nnet.sigmoid( T.dot(th1, T.concatenate([x_sh, b])) )
nn_predict = T.sum( T.nnet.sigmoid( T.dot(th2, T.concatenate([nn_hid, b]))))
第 3 步: 现在的问题是梯度下降,因为不限于 0 到 1 之间的值。 fc2 = (nn_predict - 1)**2
cost3 = theano.function(inputs=[th1, th2], outputs=fc2, updates=[
(x_sh, grad_desc(fc2, x_sh))])
run_forward = theano.function(inputs=[th1, th2], outputs=nn_predict)
cur_cost = 0
for i in range(10000):
cur_cost = cost3(theta1.get_value().T, theta2.get_value().T) #call our Theano-compiled cost function, it will auto update weights
if i % 500 == 0: #only print the cost every 500 epochs/iterations (to save space)
print('Cost: %s' % (cur_cost,))
print x_sh.get_value()
最后一次迭代打印: 费用:0.000220317356533 [[-0.11492753] [1.99729555]]
此外,输入 1 越来越负,输入 2 增加,而最优解是 [0, 1]。如何解决这个问题?
【问题讨论】:
-
尝试执行错误消息告诉您的操作。使用 optimizer=None 重新运行,它会告诉你哪个乘法是问题。
-
做了并添加了有问题的结果。它在 T.dot(th2, nn_hid) 中吗? nn_hid 定义不明确吗?
-
定义神经网络函数 (f = sigmoid( theta1*sigmoid (theta2*x + b) + b)),它取值 theta1 和 theta2 并返回 x(k 个二进制输入的向量)。我没有得到这个。据我所知,这些问题是使用反向传播 w.r.t 输入来解决的。也就是说,您使用经过训练的网络,执行正常的前向传递,然后将错误传播回去,但要使用隐藏值和输入值,而不是权重。
-
是的,所以要训练网络,您使用反向传播 w.r.t。输入并获得权重(theta1 和 theta2)。但现在我想获得最优输入,以最大化训练后的神经网络的输出。所以我想要一个函数,它将训练的权重(theta1,theta2)和 x 作为输入。然后我想找到 x 使得在给定参数 theta1、theta2 的情况下最大化输出。在这个例子中,我想要得到的答案是:x= [0, 1] will max f(x; theta1, theta2)。
标签: python machine-learning neural-network theano