Neural Network

神经网络是很早之前就听到过的,而且相信不少人也知道他是干什么的,但应该很少人亲自从底写一个测测神经网络是不是真的那么牛B。

最早的神经网络应用是手写文字的识别和车辆自动导航,也是CMU的走在前面。在20世纪前还是有很多人研究的,但是20世纪初就渐渐不行了,遇到瓶颈了。最近计算能力强了,有了deep learning,神经网络又火了。我先搞搞20世纪前的神经网络再说。(过了一年,我牛b多了,这篇太sb,可以看新的神经网络近似函数。)

基本原理:

nn

 

输入向量,如图像是每一个像素点,或者平面上的坐标点(x,y)。如果没有隐藏层,网络只能进行线性划分,而有一个隐含层则能近似所有函数(据说)。可能因为这一点导致到现在才出现deep learning. 因为只有一层隐含层对于复杂问题比较难训练。而对我一层足够了。输入信号根据权重相互组合,可以是线性也可以是非线性,输入到下一层,触发响应函数如sigmoid函数。一层层下去,就能得到输出信号。

道理我都懂,可是为什么正确的。关键在于怎么训练。每一个数据输入,都能得到计算出的结果,然后与预期结果比较,根据这个差值调节信号组合的权重。比如根据输出层的差值调节隐含层到输出层权重。这个求导即可。详见Networks and Learning Machines第130页。但是从隐含层调节输入到隐含层的权重就比较麻烦,因为不知道隐含层的期望值。这可以用导数的性质解决,同样见Networks and Learning Machines。

初步实验:

最好的实验就是XOR,因为非线性而且简单。但也不是一下子成功,因为训练的时候涉及一点参数,刚开始根本不知道设置多少。只有4个数据怎么训练,需要循环的训练,否则基本没有效果。代码见github。从测试结果看,还是很有适应性的。

xor

 

双螺旋分类:

two spiral常常用来测试分类器的性能。加一个二次项会让结果比较好。代码见github。我也用matlab内置的神经网络训练器nnstart来了一发,对比结果见下。效果好像差不多。

builtinnnmynn

 

总之,神经网络确实帅,“我根本不知道他是怎么工作的”,就是这么神奇。但是写代码还是有点蛋疼,我这个c++版本很简陋,也没有进行封装,只是为了看看神经网络是不是真的屌。