【问题标题】:Approximating a simple sin() function with lasagne用千层面逼近一个简单的 sin() 函数
【发布时间】:2016-08-18 08:30:21
【问题描述】:

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

Scaled sin function

现在我们创建一个包含 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。太荒谬了!如果我们增加隐藏神经元的数量或训练时期,没有任何变化。其他类型的非线性只会使情况变得更糟。理论上这应该会更好,我错过了什么?

非常感谢。

【问题讨论】:

  • SO 上已经有大量相关问题。你已经通读了吗?
  • 用神经网络逼近简单的 sin 似乎不是一个好主意,因为它是解析函数,您可以为此构建 Taylor 甚至更快的收敛级数。神经网络擅长逼近未知形状的数据,即使回归逼近也无法奏效
  • @JulienBernu 有很多问题与使用千层面和数字识别等大规模问题有关。我已经成功地在类似问题上实现了神经网络,结果非常好,但不知何故,这似乎不适用于这个简单的问题,而且据我所知,没有任何问题可以解决这个问题。
  • @thodnev 当然,傅立叶级数确实是完美的。我的目标不是用另一个函数基来逼近这个函数,而是展示神经网络在逼近任何形状的一般函数方面的能力。如果这在这个简单的例子中不起作用,它怎么能在一个复杂的例子中起作用?
  • @JorgedelVal 是的,例如:/questions/1565115/approximating-function-with-neural-network /questions/13897316/approximating-the-sine-function-with-a-neural-network还有更多...

标签: python lasagne nolearn function-approximation


【解决方案1】:

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

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

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

【讨论】:

  • 默认的BatchIterator 有一种方法可以在每个时期自动打乱数据集。当你实例化NeuralNet时传递这样的东西:from nolearn.lasagne import BatchIterator; NeuralNet(batch_iterator_train=BatchIterator(batch_size=128, shuffle=True))
猜你喜欢
  • 2021-08-13
  • 2019-08-18
  • 1970-01-01
  • 2010-12-25
  • 1970-01-01
  • 2018-07-23
  • 2020-12-28
  • 2016-07-19
  • 1970-01-01
相关资源
最近更新 更多