什么是感知机?

感知机就是接收多个输入,产生一个输出,其中输入输出取值为0或1.

标准CNN权重阈值如何确定_权重

上图所示为一个感知机,我们有x1和x2将其作为输入,w1和w2作为两个输入的权重,计算权重与输入的乘积之和与指定的阈值θ作比较,大于阈值则输出1,小于阈值则输出0.

标准CNN权重阈值如何确定_权重_02

上面提到几个概念:

输入:输入即外部给感知机提供的入参

输出:输出即感知机根据外部的入参,计算得到的结果。 

权重:权重用于表示不同入参之间的重要程度的一个度量。权重越大,越重要。

阈值:给不同的输出结果设定的一个界线。 

与门及感知机的实现

与门,就是当输入为0或1时,按照下面的真值表进行输出:

标准CNN权重阈值如何确定_真值表_03

 我们按照感知机的计算公式:

标准CNN权重阈值如何确定_权重_02

现在x1和x2已经知道了,预期的y也知道了,剩下的问题就是:

找到合适的w1,w2和θ,使得输入输出符合上述真值表的逻辑。

既然刚才说权重是表示参数重要程度的东西,那么在与这个操作中,我们发现,想要输出1,两个入参必须全是1才成立,所以他们的重要性可谓是五五分,所以我们可以尝试w1,w2都选择0.5 

那么θ取多少呢?因为至少要跟其他的场景区分开,所以这个值需要大于0.5,并且小于1,我们这里取0.7.

可以用(w1, w2, θ) = (0.5, 0.5, 0.7)

为什么要大于0.5?

当x1为1,x2为0时,结果需要为0

因此 0.5 * 1 + 0.5 * 0 = 0.5 < θ

当x1为0,x2为1时,结果需要为0

因此 0.5 * 0 + 0.5 * 1 = 0.5 < θ

为什么要小于1?

当x1为1,x2为1时,结果需要为1

因此 0.5 * 1 + 0.5 * 1 = 1 > θ

python代码实现:

def AND(x1, x2):
    w1, w2, theta = 0.5, 0.5, 0.7
    tmp = x1*w1 + x2*w2
    if tmp <= theta:
        return 0
    elif tmp > theta:
        return 1

与非门

与非门的真值表:

标准CNN权重阈值如何确定_真值表_05

 我们发现与与门完全颠倒,其实投机取巧,直接参数取反即可:

可以用(w1, w2, θ) = (−0.5, −0.5, −0.7)

或门

或门的真值表:

标准CNN权重阈值如何确定_权重_06

 只要有一个是1,就决定性的结果为1,因此各自的权重不再对半分。

可以用(w1, w2, θ) = (1, 1, 0.2)

偏置

感知机的公式:

标准CNN权重阈值如何确定_权重_02

这里我们发现 θ在不等式的右侧,我们习惯上把不等式的一侧简化为0,这样得到某种函数,作为判断输出的公式,令b = -θ :

标准CNN权重阈值如何确定_感知机_08

这里我们把b叫做偏置,即输入始终为1的一项:

b*1 + w1*x1 + w2*x2

标准CNN权重阈值如何确定_感知机_09

基于偏置的与门、与非门、或门感知机实现

与门,b = -θ = -0.7

def AND(x1, x2):
    x = np.array([x1, x2])
    w = np.array([0.5, 0.5])
    b = -0.7

    tmp = np.sum(w*x) + b

    if tmp <= 0:
        return 0
    else:
        return 1

与非门,b = -θ = 0.7

def NAND(x1, x2):
    x = np.array([x1, x2])
    w = np.array([-0.5, -0.5]) # 仅权重和偏置与AND不同!
    b = 0.7

    tmp = np.sum(w*x) + b

    if tmp <= 0:
        return 0
    else:
        return 1

或门,b = -θ = -0.2

def OR(x1, x2):
    x = np.array([x1, x2])
    w = np.array([0.5, 0.5]) # 仅权重和偏置与AND不同!
    b = -0.2

    tmp = np.sum(w*x) + b

    if tmp <= 0:
        return 0
    else:
        return 1

异或门无法使用单个感知机实现

真值表:

标准CNN权重阈值如何确定_真值表_10

 如果把输入输出在数轴上做出映射,他们的位置大概如下:

标准CNN权重阈值如何确定_感知机_11

 我们无法通过一条直线将其分割,使得线的一侧输出为0,线的另一侧输出为1.

但是,我们可以组合与门、与非门、或门来实现异或门,

标准CNN权重阈值如何确定_权重_12

通过拼接,得到异或门:

标准CNN权重阈值如何确定_真值表_13

 通过验证真值表,我们发现,的确可以达到异或门的效果:

标准CNN权重阈值如何确定_真值表_14

代码实现:

def XOR(x1, x2):
    s1 = NAND(x1, x2)
    s2 = OR(x1, x2)
    y = AND(s1, s2)
    return y

那么对应的感知机原型是(多层感知机):

标准CNN权重阈值如何确定_感知机_15

这也就说明,单个感知机的原理是线性的,想要实现非线性,需要进行组合。