Python 用千层面逼近简单sin()函数

Python 用千层面逼近简单sin()函数,python,lasagne,nolearn,function-approximation,Python,Lasagne,Nolearn,Function Approximation,我正在尝试千层面和nolearn NeuralNet函数来近似一个简单的sin函数。毕竟,神经网络已经被证明是通用的近似器,所以我想用一个简单的非线性函数来尝试千层面,在实验上证明这一点。代码如下: import lasagne import numpy as np from lasagne import layers from lasagne.updates import nesterov_momentum from nolearn.lasagne import NeuralNet impor

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

现在,我们创建一个包含100个隐藏单元的简单神经网络来近似函数:

pylab.plot(x,y)
pylab.show()
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()
这就是我们得到的。太可笑了!如果我们增加隐藏神经元的数量或训练时间,一切都不会改变。其他类型的非线性只会让情况变得更糟。从理论上讲,这应该更好,我还缺少什么


非常感谢。

我终于知道发生了什么事。我发表我的猜测,以防有人遇到同样的问题

众所周知,来自nolearn环境的NeuralNet使用批量培训。我不知道它是如何选择批次的,但在我看来,它是按顺序选择的。然后,如果数据不是随机化的,那么一批数据就不能代表整个数据(数据不是平稳的)。在我的例子中,我制作了
x=np.linspace(0,11000)
,因此每个批次的统计特性都会有所不同,因为存在一个自然顺序


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

目前已有大量相关问题。你已经读过了吗?用神经网络逼近简单的sin似乎不是个好主意,因为它是解析函数,你可以建立泰勒级数,甚至更快的收敛级数。神经网络擅长于逼近形状未知的数据,即使是回归逼近也行不通good@JulienBernu有很多问题都与千层面的使用有关,比如数字识别。我已经在类似的问题上成功地实现了神经网络,并取得了很好的效果,但不知何故,这似乎对这个简单的问题不起作用,而且据我所知,没有任何问题可以解决这个问题。@thodnev当然,傅里叶级数确实是完美的。我的目标不是用另一个函数基来逼近这个函数,而是展示神经网络在逼近任何形状的一般函数方面的能力。如果这在这个简单的例子中不起作用,它如何能在复杂的情况下工作?@JorgedelVal是的,有:/questions/1565115/神经网络逼近函数/questions/13897316/例如,神经网络逼近正弦函数等等……默认的
BatchIterator
有一种方法可以在每个历元中自动洗牌数据集。当您从nolearn.lasagne import BatchIterator实例化
NeuralNet
时,请传递类似的消息;NeuralNet(批迭代器列=批迭代器(批大小=128,随机播放=真))