神经网络的普遍性定理
神经⽹络的⼀个最显著的事实就是它可以计算任何的函数,也就是说,针对任何一种复杂而奇特的函数f(x),
都能确保有一个神经网络,能够对于任意的x, 输出f(x)的网络;即使函数有很多的输入和输出,例如f=f(x1,x2,x3...), 这个结果都成立;
结果表明神经⽹络拥有⼀种普遍性。不论我们想要计算什么样的函数,我们都确信存在⼀个 神经⽹络可以计算它。
⽽且,这个普遍性定理甚⾄在我们限制了神经⽹络只在输⼊层和输出层之间存在⼀个中间层 的情况下成⽴。所以即使是很简单的⽹络架构都极其强⼤。
在这⼀章,我给出这个普遍性定理的简单且⼤部分为可视化的解释。我们会⼀步步深⼊背后 的思想。你会理解为何神经⽹络可以计算任何的函数。你会理解到这个结论的⼀些局限。并且 你还会理解这些结论如何和深度神经⽹络关联的。
两个预先声明
- 第⼀点,这句话不是说⼀个⽹络可以被⽤来准确地计算任何函数。⽽是说,我们可以获得尽 可能好的⼀个近似。
- 通过增加隐藏元的数量,我们可以提升近似的精度。
- 第⼆点,就是可以按照上⾯的⽅式近似的函数类其实是连续函数。
- 这并不意外,因 为神经⽹络计算的就是输⼊的连续函数。然⽽,即使那些我们真的想要计算的函数是不连续的, ⼀般来说连续的近似其实也⾜够的好了。如果这样的话,我们就可以⽤神经⽹络来近似了。
总结⼀下,更加准确的关于普遍性定理的表述是包含⼀个隐藏层的神经⽹络可以被⽤来按照 任意给定的精度来近似任何连续函数。
⼀个输⼊和⼀个输出的普遍性
为了理解为何普遍性定理成⽴,我们先从理解如何构造这样⼀个神经⽹络开始,它能够近似 ⼀个只有⼀个输⼊和⼀个输出的函数:
为了构建关于如何构造⼀个计算f的⽹络的理解,让我们从⼀个只包含⼀个隐藏层的⽹络开 始,它有两个隐藏神经元,和单个输出神经元的输出层:
为了感受⼀下⽹络的组成部分⼯作的机制,我们专注于最顶上的那个隐藏神经元。在下图例 ⼦中,展⽰了顶部隐藏神经元的权重w,偏置b和输出曲线的关系。思考最上⾯的隐藏神经元变 化如何计算函数:
权重和偏置的变化,最终会导致该神经元的输出变化趋势如下:
这是一个阶跃函数。 如果把连个神经元都考虑进去,可以得到如下的趋势:
此时我们继续增加隐藏层神经元的个数:
每对神经元有⼀个值h和它联系。记住,神经元输出的连接有权重h和-h(未标记)。点击 ⼀个h值,左右拖动⿏标来改变其值。当你这么做的时候,观察函数的变化。通过改变输出权 重我们实际上在设计这个函数.
相反地,试着在图形上点击,上下拖动来改变凸起函数的⾼度。当你改变⾼度,你能看到相 应的值的变化。⽽且,虽然没有显⽰,在对应的输出权重上也有⼀个变化,h和-h。
换句话说,我们可以直接操作右边图形⾥的函数,然后看看反映到左边的值。⼀个有趣的 事情是按住⿏标按键并从图形的⼀边拖动到另⼀边。这样做你拉出了⼀个函数,观察神经⽹络 中为了适应这个函数调整的参数。
回到开头的例子:
你现在已经解决了所有⽹络的必要元素来近似计算函数!这只是⼀个粗略的近似,但我 们可以很容易地做得更好,仅仅通过增加隐藏神经元对的数量,分配更多的凹凸形状。这是所有要做的事情:现在我们有了⼀个可以很好计算我们原始⽬标函数的神经⽹络的完整 的描述。⽽且我们理解如何通过提⾼隐层神经元的数⽬来提⾼近似的质量。
多个输入变量
让我们把结果扩展到有很多个输⼊变量的情况下。这听上去挺复杂,但是所有我们需要的概 念都可以在两个输⼊的情况下被理解。所以让我们处理两个输⼊的情况。
正如你能看到的,在w2==0时输⼊y对神经元的输出没有影响。它就像是唯⼀的输⼊。
再往下,增加隐藏层的神经元个数,我们可以不断的推导出输出模型:
S型神经元的延伸
修补阶跃函数
⽬前为⽌,我们假定神经元可以准确⽣成阶跃函数。这是⼀个⾮常好的近似,但也仅仅是近 似。实际上,会有⼀个很窄的故障窗⼝,如下图说明,在这⾥函数会表现得和阶跃函数⾮常不同。
在这些故障窗⼝中我给出的普遍性的解释会失败。 现在,它不是⼀个很严重的故障。通过使得输⼊到神经元的权重为⼀个⾜够⼤的值,我们能 把这些故障窗⼝变得任意⼩。当然,我们可以把故障窗⼝窄过我在上⾯显⽰的——窄得我们的 眼睛都看不到。所以也许我们可以不⽤过于担⼼这个问题。 尽管如此,有⼀些⽅法解决问题是很好的。
假设只有一个输入和只有一个输出的神经网络,如何修补计算函数;
如果我们要使⽤前⾯描述的技术做到这⼀点,我们会使⽤隐藏神经元产⽣⼀系列的凹凸函 数: