1

我正在尝试千层面和 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()

标度 sin 函数

现在我们创建一个包含 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()

这就是我们得到的!近似函数。太荒谬了!如果我们增加隐藏神经元的数量或训练时期,没有任何变化。其他类型的非线性只会使情况变得更糟。理论上这应该工作得更好,我错过了什么?

非常感谢。

4

1 回答 1

2

我终于知道发生了什么。如果有人遇到同样的问题,我会发布我的猜测。

众所周知,来自 nolearn 环境的 NeuralNet 使用批量训练。我不完全知道它是如何选择批次的,但在我看来它是按顺序选择它们的。那么,如果数据不是随机的,一个批次就不能在统计上代表整体(数据不是静止的)。就我而言,我做了x=np.linspace(0,1,1000),因此每批的统计属性会有所不同,因为有一个自然顺序。

如果您改为随机创建数据,即 ,则x=np.random.uniform(size=[1000,1])每个批次都将具有统计代表性,而与数据的来源无关。一旦你这样做了,你就可以增加训练的时间并提高收敛到真正的最优值。我不知道我的猜测是否正确,但至少它对我有用。不过,我会更深入地研究它。

于 2016-08-19T08:00:06.943 回答