我正在尝试千篇一律和nolearn NeuralNet函数来逼近一个简单的sin
函数。毕竟,神经网络被证明是通用的近似,所以我想在一个简单的非线性函数上尝试千层面,以实验证明这一事实。这是代码:
import lasagne
import numpy as np
from lasagne import layers
from lasagne.updates import nesterov_momentum
from nolearn.lasagne import NeuralNet
import matplotlib.pylab as pylab
x=np.linspace(0,1,1000)
y=np.sin(8*x)
# Fit the dimensions and scale
x=x.reshape(1000,1).astype(np.float32)
y=y.astype(np.float32)
y=(y-np.min(y))/np.max(y)
我们得到以下功能:
pylab.plot(x,y)
pylab.show()
现在我们创建一个简单的神经网络,其中有100个隐藏单位来近似函数:
net= NeuralNet(
layers=[
('input', layers.InputLayer),
('hidden', layers.DenseLayer),
('output', layers.DenseLayer),
],
input_shape=(None,1),
hidden_num_units=100,
hidden_nonlinearity=lasagne.nonlinearities.rectify,
hidden_W=lasagne.init.GlorotUniform(),
output_num_units=1,
output_nonlinearity=None,
output_W=lasagne.init.GlorotUniform(),
update=nesterov_momentum,
update_learning_rate=0.001,
update_momentum=0.9,
regression=True,
max_epochs=500,
verbose=0,
)
net=net.fit(x,y)
现在我们使用受过训练的网络预测x
值,看看我们得到了什么:
yp=net.predict(x)
pylab.plot(x,yp,hold=1)
pylab.plot(x,y)
pylab.show()
这就是我们得到的! Approximated function。这太荒谬了!如果我们增加隐藏神经元的数量或训练时期没有任何变化。其他类型的非线性只会使情况变得更糟。从理论上讲,这应该会更好,我缺少什么?
非常感谢。
答案 0 :(得分:2)
我终于知道发生了什么。如果有人遇到同样的问题,我会发布我的猜测。
众所周知,来自nolearn环境的NeuralNet使用批量训练。我不知道它是如何选择批次的,但在我看来它依次选择它们。然后,如果数据未被随机化,则批次将不能在统计上代表整体(数据不是静止的)。在我的例子中,我做了x=np.linspace(0,1,1000)
,因此每个批次的统计属性会有所不同,因为这是一个自然顺序。
如果您随机创建数据,即x=np.random.uniform(size=[1000,1])
,则每个批次在统计上都具有代表性,与其取自何处无关。一旦你这样做,你可以增加训练的时代,并改善收敛到真正的最佳。我不知道我的猜测是否正确,但至少它对我有用。不过我会深入研究它。