神经网络与感知器

September 2017 2 minute read

综述

And God said, “Let there be light,” and there was light.

这个系列的主要目标是讲清楚什么是神经网络以及它的原理。既然题目是无痛入门,我会用尽量简单的数学讲明白问题。在遇到一定要用到的复杂数学知识时,我会提前做好介绍。编程方面,我也会最简单的Python代码实现。即这个系列对读者的最低要求为有求常见函数导数和可以用Python写出for循环的能力。

感知器的历史

现在即使是很多没有接触过神经网络的人也知道神经网络由于架构的不同分为 深度神经网络(DNN),积卷神经网络(CNN),循环神经网络(RNN)和对抗神经网络(GAN)等,但是在上世纪六十年代的时候,并没有神经网络这个名词,那时候只有一种被称作感知器的学习工具,在最开始的时候它很看起来很有前景。但是在1969年,Marvin Minsky在名为<< perceptron >>的书中分析了它的功能和它的局限性,导致了当时很多人对感知器以及神经网络嗤之以鼻。然而感知器的学习过程依然在广泛使用,比如google就在很多产品中使用了相关算法。

感知器的架构

一个感知器的架构如下图所示,

perceptron 分别为:

感知器的训练过程

感知器训练过程可以分为两步:

在输入向量中加入一列都为1的偏置列(bias)

这是因为有可能我们选取的特值肯定不是完全反应了客观规律的,偏置列可以理解为对特值的补充,也就是在设计这个系统的时候没有考虑到的偏差 。比如我们都要设计一个来表示数学中或运算的感知器,它的真值表如下

x1 x2 结果
0 0 0
0 1 1
1 0 1
1 1 1

那么相对应的Python代码生成的输入向量和期待结果应该为

from numpy import array
training_data = [
    (array([0,0,1]), 0),
    (array([0,1,1]), 1),
    (array([1,0,1]), 1),
    (array([1,1,1]), 1),
]

随机选择输入向量中的一个执行下面的步骤,重复n次。

在步骤重复若干次后, 我们可以得到一个不变权重向量,即收敛结束。有了这个权重向量我们就可以用新的输入向量来预测结果了。 具体代码为:

from random import choice
from numpy import array,dot,random

#随机生成权重向量
weight = random.rand(3)
#重复100次
n = 100
#阶梯函数
unit_step = lambda x:0 if x < 0 else 1
#训练过程
for i in range(n):
    x,expect = choice(training_data)
    output = dot(x,weight)
    flag = expect - unit_step(output)
    weight += flag * x
#结果展示
for x, _ in training_data:
  results = dot(x,weight)
  print("{}:{} -> {}".format(x[:2],results,unit_step(results)))

如果取第一步中的traning_data训练,就可以得到一个符合或真值表的感知器了

感知器的局限性

在一开始讲感知器历史的时候我就说过感知器是有局限性的,举个例子,如果我们要让感知器来判断x1,x2,是否一样,我们可以想到这样的一组训练数据

相同: (1,1)->1,(0,0)->1

不相同: (1,0)->0,(0,1)->0

用Python向量来表示就是

from numpy import array
training_data = [
    (array([0,0,1]), 1),
    (array([0,1,1]), 0),
    (array([1,0,1]), 0),
    (array([1,1,1]), 1),
]

但是如果你用这个training_data带入刚刚的代码训练,你会发现每次执行之后的感知器判断的结果都不一样,换而言之,这次没有收敛,我们没有得到一个稳定的权重向量。

我们从代数上证明感知器没有办法完成这件事情,首先假设权重向量为 {w1,w2},那根据训练数据和向量乘法法则我们可以得到下面四个不等式:

$$ z = \sum_{k=1}^n xw +b $$

$$ w_1 \cdot 0 + w_2 \cdot 0 = 0 >= 0 $$

$$ w_1 \cdot 0 + w_2 \cdot 1 < 0 $$ $$ w_1 \cdot 1 + w_2 \cdot 0 < 0 $$ $$ w_1 \cdot 1 + w_2 \cdot 1 >= 0 $$

显而易见这是不可能成立的。

局限性的原因和解决办法

无论个体还是集体,过于单一化只会走向毁灭 —攻殻機動隊 (1995)

如果我们想将输入向量质量对训练结果的影响降低,那么最容易想到的办法是增加层数,有更多的权重向量可以记录更多的信息。但这还不够,因为是单纯的增加层数没有解决单一化的问题。我们需要的是一个多层的,每一层都是非线性的神经网络。这样除了输入层和输出层,中间的隐藏层可以帮助我去分辨输入向量中的哪个纬度重要,这样就不会有感知器那样的局限性。但是新的问题就是我们如何去训练一个这样复杂的神经网络呢?嗯,下次我会讲讲这个的。

reference:

  1. Ian Goodfellow and Yoshua Bengio and Aaron Courville,Deep Learning,2016

  2. Marvin Minsky and Seymour A. Papert,Perceptrons Expanded Edition,1987

  3. Danilo Bargen’s blog,2017