介绍
众所周知,神经网络可以近似任何连续数学函数的输出,不管它有多么复杂。以下面的函数为例:
Generic function
虽然它的形状相当复杂,但我们将很快讨论的定理可以保证我们可以构建一些神经网络,以尽可能精确地逼近f(x)。因此,神经网络表现出一种普遍的行为。
神经网络之所以受到如此多的关注,原因之一是除了这些相当显著的普遍特性外,它们还拥有许多强大的学习函数算法。
普遍性与基础数学
这篇文章将对人工神经网络的这些近似能力的基础数学结果(定理)作一个非正式的概述。
使用神经网络作为近似值的动机:Kolmogorov定理
1957年,俄罗斯数学家安德烈·科尔莫戈罗夫(Andrey Kolmogorov)证明了一个关于许多变量实函数表示的重要定理。根据Kolmogorov定理,多元函数可以通过(有限数量的)一元函数的和及和的组合来表示。
俄罗斯数学家Andrey Kolmogorov
这个定理指出,一个连续函数f的变量定义在n维超立方体(n≥2)可以表示如下:
Kolmogorov定理(1957)
在这个表达式中,gs是单变量函数和ϕs是连续的,完全(单调)递增函数(如下图所示),其不依赖于f的选择。
单调函数的例子
万能逼近定理(UAT)
UAT(Universal Approximation Theorem)指出,如果对激活函数的形式有较为温和的假设,则包含有限节点的单个隐藏层的前馈神经网络可用于逼近任意连续函数。现在,因为几乎我们能想象的任何过程都可以用数学函数来描述,神经网络至少在原则上,可以预测几乎每一个过程的结果。
前馈人工神经网络使用不同激活函数的通用性有几个严格的证明。为了简单起见,我们把范围限制在sigmoid函数内。sigmoids是S形的,特殊情况下包括logistic函数、Gompertz曲线和ogee曲线。
sigmoid的Python代码
用于构建和绘制sigmoid函数的快速Python代码是:
import numpy as npimport matplotlib.pyplot as plt%matplotlib inlineupper, lower = 6, -6num = 100def sigmoid_activation(x): if x > upper: return 1 elif x
sigmoid函数的图
George Cybenko的证明
Cybenko(1989)给出的证明以其优雅、简单和简洁著称。在他的文章中,他证明了下面的说法。设φ是sigmoid 类型的任何连续函数。给定任何多变量连续函数
在N维真实空间和任何正ε 的compact subset内,存在向量
(权重),常数
(偏差项)和
因此
对于compact subset内的任何x(NN输入),其中函数G由下式给出:
选择适当的参数,神经网络可用于表示具有各种不同形式的函数。
使用Python的一个例子
为了使这些语句不那么抽象,让我们构建一个简单的Python代码来说明到目前为止所讨论的内容。
我们将构建一个神经网络来近似以下简单函数:
在深入研究代码之前需要做一些评论:
为了使分析更直观,我将使用sigmoid函数的一个简单极限情况。当权值非常大时,sigmoid趋近于Heaviside阶跃函数。由于我们需要添加来自多个神经元的贡献,因此使用阶跃函数比使用一般的sigmoid要方便得多。
在sigmoid接近step函数的极限情况下,我们只需要一个参数来描述它,即step发生的点。s的值可以表示为s=-b/w,其中b和w分别为神经元的偏差和权重。
我要构建的神经网络非常简单,有一个输入,一个输出和一个隐藏层。如果两个隐藏神经元对应的权重绝对值相等,符号相反,则输出为“bump”,高度等于权值绝对值,宽度等于每个神经元s值的差值(见下图)。
我们使用以下符号,因为权重的绝对值是bump的高度。
由于我们想要近似g,隐藏层的加权输出必须涉及sigmoid的逆。实际上,它必须等于:
要重现此函数,我们选择hs 的值(参见下面的相应图):
Python代码
代码以以下定义开头:
我们首先导入inversefunc需要构建inverse sigmoid函数
然后我们为sigmoid选择一个非常大的权重,因为它类似于Heaviside函数(刚才讨论过)。
我们选择输出激活作为恒等函数(identify_activation)
该函数的作用是从s和w恢复原始(w,b)参数化。
设置架构,并选择所有ws和bs。数组weight_output的元素是从上一节给出的输出权重值中获得的。
from pynverse import inversefuncw = 500def identity_activation(x): return(x)def solve_for_bias(s, w=w): return(-w * s)steps = [0,.2,.2,.4,.4,.6,.6,.8,.8,1]bias_hl = np.array([solve_for_bias(s) for s in steps])weights_hl = np.array([w] * len(steps))bias_output = 0weights_output =np.array([-1.2, 1.2, -1.6, 1.6, -.3, .3, -1]) 1, 1, 1, -1])
最后的步骤是:
编写一个Python函数,我称之为nn,用于构建和运行网络
打印出近似值与实际函数之间的比较。
def nn(input_value): Z_hl = input_value * weights_hl + bias_hl activation_hl = np.array([sigmoid_activation(Z) for Z in Z_hl])Z_output = np.sum(activation_hl * weights_output) + bias_outputactivation_output = identity_activation(Z_output) return activation_outputx_values = np.linspace(0,1,1000)y_hat = [nn(x) for x in x_values]def f(x): return 0.2 + 0.4*(x**2) + 0.3*x*np.sin(15*x)+ 0.05*np.cos(50*x))y = [f(x) for x in x_values]inv_sigmoid = inversefunc(sigmoid_activation)y_hat = [nn(x) for x in x_values]y_invsig = [inv_sigmoid(i) for i in y]_ = plt.plot(x_values, y_invsig)_ = plt.plot(x_values, y_hat)_ = plt.xlim((0,1))
使用具有很大权值的sigmoid函数逼近隐藏层的加权输出
这种近似远非理想。然而,通过增加节点数量或层数(但同时避免过度拟合),可以直接改进它。
结论
在本文中,我描述了一些基础数学,它们是神经网络的通用属性的基础,我展示了一个简单的Python代码,它实现了一个简单函数的近似。
财经自媒体联盟更多自媒体作者
4000520066 欢迎批评指正
All Rights Reserved 新浪公司 版权所有