如何快速地近似任何函数?一个用Python构建深度神经网络极简方法

不久前,研究人员Hornik等58发现,一个隐藏层足以模拟任何分段连续函数。他们的定理非常好,值得在这里重申一下:

Hornik等人的定理:设Fn维空间有界子集上的连续函数,那么存在一个包含有限个隐藏单元的双层神经网络

,它近似等于F。也就是说,对于F域中的所有的x,。

这是一个了不起的定理。实际上,对于任何连续函数F和一定的容错ε,可以构建一个单隐藏层的神经网络用于计算F。这至少在理论上说明,一个隐藏层对于很多问题是足够的。

当然,实际情况略有不同。首先,现实世界的决策函数可能并不连续,该定理并没有指定所需的隐藏层神经元数量。对于现实世界的很多问题,看上去需要多个隐藏层来实现精确的分类和预测。

如果决策规则可以通过复杂函数进行数学建模,那么就可以使用DNN。重要的是,你不需要事先知道函数的形式。再看一下Jechang Jeong教授的去雾算法。注意,在这个例子中,研究人员承认去雾的功能(对他们)是未知的。可喜的事,他们的DNN找到了一个很好的解决方案。

(此处已添加圈子卡片,请到今日头条客户端查看)

欢迎加入程序员读书会,每日分享it好书,不定期免费赠书

一个用Python构建深度神经网络的极简方法

现在我们用Python来构建一个DNN来近似一个函数。我们将构建DNN来近似y = x2。首先,导入一些使用的基础包,这通过使用import关键字完成:

import numpy as np
import pandas as pd
import random

让我们讲解一下上面的代码。

  • import关键字用来导入3个包numpy、pandas和random。
  • NumPy(numpy)包是Python科学计算中使用的核心包59。在本书中,我们将会经常用到它。注意,这里导入了包,并在随后的代码中使用简写np来访问它的元素。我们对pandas包做同样的操作,用简写pd来表示。
  • pandas包为Python 编程语言提供了高性能的、易用的数据结构和数据分析工具[60]。它是数据科学中使用的另一个核心库。
  • 我们使用random模块生成随机数61。

 生成示例

下面生成有50个随机值的x,然后赋值y = x2。

random.seed(2016) 
sample_size=50
sample = pd.Series(random.sample(
     range(-10000,10000),sample_size))
x=sample/10000
y=x**2

Python代码的一个好处是非常容易阅读。上面的代码就是一个很好的例子。下面让我们详细分析一下:

  • 函数random.seed用来确保可以重新生成与本书中使用的相同随机样本。这通过指定种子的值来完成,在这个例子中是2016。
  • 函数random.sample用来生成50个观测值的随机样本,并将结果存储在称为Series的数据类型中,这是通过指定pd.Series()的参数来实现的。注意,我们使用了pandas的简写pd。Series是一个标签数组。它可以包含任何数据类型(整数、字符串、浮点数、Python对象等)。
  • 然后随机样本被放置在±1之间,并存储在Python对象x中。最后对象y用来存储x的平方值。

说明

可以使用type关键字来查看Python对象的“类型”。例如,查看sample的类型:

type(sample) 
<class'pandas.core.series.Series'>

Series是pandas的一个核心类型。

检查样本

不时地查看一下数据是一个好主意。那么让我们看一下x中的前10个观察值:

print x.head(10)
0  0.4758
1  -0.1026
2  0.7847
3  0.7506
4  -0.4870
5  0.3657
6  0.8647
7  -0.8361
8  -0.4067
9 -0.8568
dtype: float64

第一个观测值为0.4758,第十个观测值为–0.8568。注意,输出也包含了numpy的 dtype62,这里为float64。Numpy数组包含dtype对象的元素。

接着看一下y的前10个观察值:

print y.head(10)
0  0.226386
1  0.010527
2  0.615754
3  0.563400
4  0.237169
5  0.133736
6  0.747706
7  0.699063
8  0.165405
9  0.734106

第一次观测值为0.226386,第十次观测值为0.734106。快速抽查表明,第一个观测值(0.4758)2 = 0.226386,第十个观测值(0.4758)2 = 0.226386,所以数字和预期的y值一样为x的平方。图4.7显示了模拟数据的可视化图。



图4.7 模拟数据y = x2 的图表

也可以用.describe()方法快速查看数据的摘要信息。这里检查一下x的摘要:

print x.describe()
count  50.000000
mean   -0.100928
std    0.534392
min   -0.937000
25%   -0.562275
50%   -0.098400
75%    0.359750
max    0.864700

.describe()函数提供了样本的最大值、最小值、观测值数量以及四分位数等细节。正如我们所期望的,x值位于±1之间,最大值为0.8647,最小值为–0.937。

格式化数据

在这个例子中,我们使用的neuralpy包63——这是一个专门研究神经网络的机器学习库。它的接口非常直观,让你可以快速地开始训练数据,并测试深度学习模型。

为了使用该包,我们需要把数据转换成一个合适的格式。为此,我们将创建一个名为dataSet的Python对象。该对象是一个观察值xy的列表。我们可以通过一个while循环来完成格式的变换。

count = 0 
dataSet = [([x.ix[count]],[y.ix[count]])]
count=1
while (count < sample_size):
 print "Working on data item: ", count
 dataSet = (dataSet+[([x.ix[count,0]], [y.ix[count]])])
 count = count +

下面分析一下上述代码。

  • count对象用于循环遍历,并在每一个新的xy样本添加到dataSet后递增。
  • .ix方法用于索引,让我们能遍历xy中的每一个观察值,并添加到dataSet中。

模型运行时,你能看到如下的输出。

Working on data item:  1
Working on data item:  2
Working on data item:  3
.    .    .
Working on data item:  47
Working on data item:  48
Working on data item:  49

说明

注意dataSet是一个列表对象:

type(dataSet) 
<type 'list'>

这是neuralpy包所需要的类型。

拟合模型

我们将拟合一个有两个隐藏层的DNN。第一个隐藏层包含3个神经元,第二个隐藏层有7个神经元,如图4.8所示。这可以通过neuralpy.Network方法指定:

import neuralpy
fit = neuralpy.Network(1, 3,7,1)



图4.8 neuralpy 神经网络模型的结构

模型通过学习算法迭代的最大次数由epochs参数控制,我们将此值设置为100。学习速率控制梯度下降算法的步长大小,设置为1。

epochs = 100 
learning_rate = 1

现在我们可以使用fit.train函数来拟合模型了。

print "fitting model right now"
fit.train(dataSet, epochs, learning_rate)

可以看到,传递给fit.train的第一个参数是样本,然后是迭代最大次数和学习速率。最后,经过一段时间后模型收敛得到一个解决方案。

性能表现评估

让我们看一下模型在逼近y值时的表现有多好。预测值可以使用fit.forward函数获得。我们使用一个简单的while循环将预测结果存储在Python对象out中,并使用print函数将结果显示在屏幕上。

count = 0 
pred=[]
while (count < sample_size):
  out=fit.forward(x[count])
  print("Obs: ",count+1,
    " y = ", round(y[count],4),
    " prediction = ",
    round(pd.Series(out),4))
  pred.append(out)
  count = count + 1

当模型运行时,会将结果打印到屏幕上。对于前5个观测值,你应该能看到如下内容:



当然,显示在屏幕上的数字与上面显示的不同。为什么呢?因为neuralpy随机设置权重和偏差。每次模型运行这些值,结果都是不同的。尽管如此,整体结果会非常接近实际的观测值。

记录的数据表明该DNN提供了一个虽然不是精确的,但已经是对实际函数非常好的近似。图4.9显示了所有观测值所预测的yx值。你自己判断一下,DNN模型的准确性如何?结果与显示的有多相似?你会怎样来提高整体的性能?



图4.9 使用neuralpy的x和预测值

发表评论
留言与评论(共有 0 条评论)
   
验证码:

相关文章

推荐文章

'); })();