太长不看版:
先说结论,单层感知机在取特定的激活函数的情况下能够实现异或逻辑门。
比方说:取激活函数为判断净输入是否为零 n != 0
,而权值向量取为(1,-1)
,偏置则取0。
也就是说只根据点是否在直线 y = x 上,从而判别最终的输出。 对与异或门电路而言,y = x
((1,1)
、(0,0)
)上的数据就是0
这一类,而((1,0)
、(0,1)
)则为 1
。
一般来说,当我们使用感知机做分类时,会使用硬极限函数之类的函数来做分类,把数据经过感知机运算的结果数值的正负性映射到0,1这两个值,用来表示类别或者说最后的决策。 这样的情况下,感知机相当于时简单的在坐标系中画了一条直线(在高维的时候应该称之为超平面),把所有的数据分为两部分。
在最简单的情况下使用感知机,比方说与门、或门、与非门这些,很幸运的,他们是线性可分的,甚至即便我们仅凭观察也能发现可以很轻松的画一条直线把不同真值的数据分割成两个部分。然后我们可以选取类似硬极限函数之类的做激活函数,完成感知机对门电路的模拟。
之后来到异或门,它的四个点会形成一个'交叉'的情况。我们用一条直线不可能把他们划分成两个部分。这个时候大多数的教材都会说,我们可以通过叠加感知机实现。根据我们学习过的基础电路知识,异或门可以由几个基础的门电路组成。我们这里用代码示意一下,使用的函数假设是已经实现的基于感知机的门电路。
defXOR(x:np.ndarry):returnAND(np.vstack(NAND(x),OR(x)))
这之后有的书会说,一层感知机解决不了就加一层感知机。但是它并没有说明原因。
异或能被两层感知机表示,实际是因为它能够以非线性的方式划分数据。
非线性是来源于激活函数,很经典的异或数据的划分实际上是通过一个非线性的变换把空间做了一个类似折叠的效果,把数据集的"交叉"现象去掉了。类似如下效果
假设四个点是 -1,0 1,0 0,1 0,-1
,然后沿y轴折叠,1,0
可以看作成了-1,0
这样就可以划分了。
并不是单纯的仿射变化的叠加让数据变得可分。而是仿射变换叠加激活函数的处理,把数据变换成了可分。 所以回到开始,单层感知机是可以完成异或门的表示的。就像最开始的演示一样,把激活函数定义成我们设定个那样就行。 但是为什么一般不会这么写呢?仅仅看我们最开始说明的激活函数,显然他是过拟合的。
它限制了表示0这一类的数据只能在y=x这条直线上,如果一点噪声都不能容忍。
当然我们可以做调整,把激活函数改成点到这条直线上的距离,在一定程度上减轻过拟合效应。但是这又会有随之而来的问题,调成多少的距离呢?
激活函数它可是属于超参数,基本上依赖经验设置。有句话怎么说来着?正确来源于经验,经验来源于错误。 这样来使用感知机,怎么说呢,有种更偏向于玄学的感觉了。
与之相对比的就是多层感知机,它不是凭借这种比较玄学的方式获取需要的非线性关系,而是通过一些简单的非线性关系,经过训练得到合适的效果。
而这才是多层感知机真正的重要之处。
如果有不同意见或批评指正,欢迎评论区留言。