凡事架不住亲自跑一把—— Perceptron 篇
写这篇时,我并没有完全搞懂。谨作记录。
我们知道,单层神经网络的结构很简单:线性加权求和 + sigmoid 。而 Minsky 早就断言:单层神经网络连「异或」问题都解决不了。
但,再加一层就可以了。
但,你不觉得奇怪吗:明明线性的变换怎么就能实现非线性的分割呢?
难道真的切了两刀,然后挑对家的两块连起来?
我们先分析一下 sigmoid(z) 函数的特性:z = 0 是分界点,左边,其值介 (0, 1/2) 之间;右边,其值介 (1/2, 1) 之间。所以,我们抓住分界线:
x + y = 0
x - y = 0
就可以弄清楚大致的位置。
下面我们先试试把一片小方块丢进一个两层的神经网络,看看神经网络把它挤压成什么样了:
这和线性变换也差不多嘛,没见把哪块区域压扁了嘛
我们还是把输出函数画出来看看。我去😱:
两层神经网络的输出可以清楚地看到,出现了清晰的分层:中间的两对家大致都是 0.75 左右。不知道这算不算解决了「异或」问题了呢?
可为什么呢?我们注意到:原输入越远离远点,挤压得越厉害(注意上上图那圈淡淡的边界)。是不是就是因为这个,原本纠缠在一起的数据被拉扯开了呢?大家可以看看 colah 的文章「Neural Networks, Manifolds, and Topology」(看这篇文章之前,我从来没有想过可以从「坐标变换」的角度来看待神经网络),但我不是很清楚他做了什么变换。
关于神经网络,之前没有理解的几个点:
-
输入层的结点数 = 输入数据的维度;
-
每一次操作其实相当于做了一次坐标变换,只不过是非线性的变换。而需要这种非线性变换的理由是:压缩,以便下一层线性分割;
-
所谓「反向传播(Back Propagation)」算法,不过是梯度下降的链式求导版本;
-
神经网络的优点在于:能够自动产生中间 features 。而现在(也许是前几年吧)很火的「卷积神经网络」不过是借鉴了人眼识别的原理,在降低输入数据维度的同时生成 features 。但其实,人眼识别边缘的原理和「卷积」没什么关系,只不过是受到周围的视觉神经元压制的自然结果。
-
训练神经网络的核心算法是「Back Propagation」。其实原理不难[1],把类似动态规划的手法用在(偏微分的)链式法则上。
- 如果下一层神经元数目比当前层多,是为了将数据展开到高维,以便做线性切分;如果下一层神经元数目较当前层少,则是为了提取特征(具体参见 Autoencoder )。
本质上说,神经网络就是一个非线性分类算法。要实现非线性分类,其实都是将数据映射到高维空间,再做线性切割。不同的是,有的是一步到位(比如:支撑向量机),有的是一点一点来(比如:深度学习)。但大自然老妈用的是后一种方案,原因嘛,主要是省「钱」。
做层级结构的好处是:可以重复利用下层的抽象单元(或者叫「表征(representations)」?「特征(features)」?)。要知道,进化的成本是很高的,不管从时间跨度、还是参与个体消耗的能量看。
请注意,这里是如何通过将二维数据映射到四维空间(其实三维就够了,只是没这么好看),从而解决 XOR 问题的而如果没有映射到高维空间,再添加多少层也是枉然。
没事建议跑跑 tensor background ,对理论的理解提升不是一点半点。所以才说「可视化」才是教育的真正变革,因为它极大地降低了学生试错的成本。
-
原理是不难,但你丫咋就没实现得了呢😒 ↩