54

从一个双控开关思考神经网络(上)

 6 years ago
source link: http://mp.weixin.qq.com/s/ObnZFrdTo4ezrL7UZr5DPQ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

从一个双控开关思考神经网络(上)

Claude AI启蒙研究院 2017-10-26 03:19 Posted on



内容提要

引子--双控开关和三控开关

拓展--数字电路

深入--神经网络

     --神经网络之感知器:给定模型,通过数据训练参数,可以解决分类问题。

     --神经网络之隐藏层:更强大的神经网络(更多参数)

     --神经网络之激活函数:超越线性(非线性的引入)

     --神经网络之反向传播:质的飞跃(性能大幅提升)

     --神经网络之实用关键:算法收敛(快速有效地找到合适的参数)

双控开关和三控开关

我在进行乐高编程的时候,可以在电脑上启动,也可以在乐高机器人的可编程程序块上启动。就像家里客厅的灯,有时希望可以有两个开关来控制它。比如在楼上或楼下各安装一个,都可以独立控制灯泡的开关。初中生知道,最简单的办法是用两个单刀双掷开关来实现,如下图。

                                  

Image

如果还想在卧室增加一个开关,实现用三个开关来控制一个灯泡呢?经典的办法是两个单刀双掷开关加一个双刀双掷开关,如下图。

如果想要四个开关,五个,甚至七八个开关来控制这个灯泡呢?电路图会是多复杂?有没有什么通用的办法来解决?

引入数字电路

我们先回到最简单的“双控开关”。开关只有2个状态,“开”和“关”,我们分布用“1”和“0”来表示。1代表开,0代表关。这样,2个开关可以用一个2位的二进制数表示,两个开关有四种组合{开开,开关,关开,关关},记做{00,01,10,11}。和上面双控开关对应起来,有{00,11}灯泡亮,{01,10}灯泡灭。

我们把它写出函数的形式:y = f(b[1],b[2])。b[1],b[2]分布代表开关1和2的状态,取值为0或1。函数值y取值也是0或1表示灯泡亮或灭。期待的结果为:

灯泡亮:y = 1 = f(0,0) = f(1,1)

灯泡灭:y = 0 = f(1,0) = f(0,1)

函数f是一个什么运算?不难发现,其实f是一个异或/模二相加运算加一个取反。即 f(b[1],b[2]) = !(b[1]+b[2]),这里+表示模二相加,!表示取反。这用一个简单的数字电路就可以实现!只要把一个标准与非门+一个异或门串联起来。

用数字电路解决多控开关

一旦写成数字电路的“数字运算”形式,就很容易打开思路拓展到三控开关。y = f(b[1],b[2],b[3])。假设初始状态{000}是亮的,拨动任意一个开关一次,将会有3种可能状态{001,010,100},这三种状态是灭的。在这3种状态下再拨动一个开关一次,再次灯泡亮,此时要么回到状态{000},要么得到状态{011,101,110}。以此类推,得到:

灯泡亮:{000,011,101,110}

灯泡灭:{111,001,010,100}

仍然是这3个开关状态的模二相加再取非!

即 f(b[1],b[2],b[3]) = !(b[1]+b[2]+b[3])

不管增加到几个开关,都可以简答地用与非门和异或门来实现!

数字电路基本概念

我们已经用数字电路实现了多控开关,用到了与非门和异或门,对应着数字电路的两个基本运算:取反NOT,异或XOR。数字电路4个基本运算还有与AND和或OR。

与门(AND):

f(0,0) = 0; f(0,1) = 0; f(1,0) = 0; f(1,1) = 1

与非门(NAND):

f(0,0) = 1; f(0,1) = 1; f(1,0) = 1; f(1,1) = 0

或门(OR):

f(0,0) = 0; f(0,1) = 1; f(1,0) = 1; f(1,1) = 1

异或门(XOR):

f(0,0) = 1; f(0,1) = 0; f(1,0) = 0; f(1,1) = 1

注意到前面一直说的是与非门而不是非门。因为与非门是一般数字电路的标准,电路实现上,非门不太稳定所以设计成与非门形式。很容易通过与非门来实现取反功能,只要把与非门的另一个输入固定成1即可。

关于数字电路的一些思考

我们已经了解到了与门、与非门、或门以及异或门的逻辑。这是构成数字电路的最基本要素。上面函数 f(b[1],b[2]) 的2个输入 (b[1],b[2]) 是独立的,很自然地想到可以看作在直角坐标系中的一个点。然后把函数值 y = f(b[1],b[2]) 看作是坐标系中点(b[1],b[2])的标签(label)。这样就把求函数值问题转化为分类问题了。对两输入问题来说,就是把4个点{00,01,10,11}分成两类{y=0, y=1}。

如下图所示。与门,与非门,或门都可以找到一个线性方程(一条直线)就能把结果0和1区分开来。不过异或无法找到这样一条直线进行区分。

然而神经网络刚好擅长解决这种分类问题。

最简单的神经网络

受生物神经结构的启发,有人提出了最简单的神经网络:感知器。

感知器的结构如下:加权求和值经过一个函数得到输出。权重是可以调节的参数,函数可能是一个简答的阈值/门限判定。

对只有2个输入 (b[1],b[2]) 的情况来说,可以把上面感知器用公式表达如下。

加权求和:z =  w[1]*b[1] + w[2]*b[2]

比较判定:y = g(z),g:当z大于/小于b时,y = 1 ,否则 y = 0

很容易写出来,AND的实现之一:w[i] = 1;g:当 z = b[1] + b[2] 大于门限 b = 1.5 时取1否则取0。NAND只要把AND的判定函数取0或1反过来即可。OR把门限 b 取 0.5 即可。我们还是来写一点代码来搜索符合条件的参数吧!以AND为例。

  1. def perceptron(x,w,b):

  2.    """

  3.    感知器

  4.    """

  5.    sum_val = 0

  6.    for e in zip(x,w):

  7.        sum_val += e[0]*e[1]

  8.    if sum_val>b:

  9.        return 1

  10.    else:

  11.        return 0

  12. def prediction(input_vecs, w, b, labels):

  13.    """

  14.    给定感知器参数,获取所有数据的输出并和标签对比,输出对比结果

  15.    """

  16.    for e in zip(input_vecs,labels):

  17.        if perceptron(e[0],w,b)!=e[1]:

  18.            return False

  19.    return True

  20. #数据

  21. input_vecs = [[1,1], [0,0], [1,0], [0,1]]

  22. labels = [1, 0, 0, 0]

  23. #参数的可能取值,[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]

  24. w_range = [x/10.0 for x in range(0,10)]

  25. #遍历所有参数,打印符合的系数

  26. for b in [0, 0.5, 1, 1.5, 2]:

  27.    for w1 in w_range:

  28.        for w2 in w_range:

  29.            w = [w1,w2]

  30.            if prediction(input_vecs, w, b, labels)==True:

  31.                print w,b

运行这段代码可以得到几十条符合条件的参数。是不是对给定的这个数学模型(感知器),通过调节模型参数(w, b),都可以通过“数据-标签”进行训练来实现分类功能?继续尝试,NAND,OR都可以得到,可是找不到可以实现异或的参数。看来感知器模型还不够强大。

更多相关教程,请关注我们的公众号

Image

AI启蒙研究院

人工智能启蒙之旅


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK