---
title: "机器人实践-感知机（2）"
description: "先来看看我们上一次实现的完整代码"
canonical_url: "https://yangqiuyi.com/blog/suan-fa/ai/ji-qi-ren-shi-jian-gan-zhi-ji-2"
---

> Index of every page on this site: [llms.txt](https://yangqiuyi.com/llms.txt)

先来看看我们[上一次](https://yangqiuyi.com/blog/suan-fa/ai/ji-qi-ren-shi-jian-gan-zhi-ji-1)实现的完整代码

```python
import numpy as np

def OR(x1, x2):
    x = np.array([x1, x2, 1])
    w = np.array([0.6, 1, -0.5])
    if np.sum(x*w) > 0:
        return 1
    return 0

def AND(x1, x2):
    x = np.array([x1, x2, 1])
    w = np.array([1, 1, -1])
    if np.sum(x*w) > 0:
        return 1
    return 0

def NAND(x1, x2):
    x = np.array([x1, x2, 1])
    w = np.array([-0.5, -0.5, 0.7])
    if np.sum(x*w) > 0:
        return 1
    return 0

def XOR(a, b):
    x1 = OR(a, b)
    x2 = NAND(a, b)
    return NAND(x1, x2)

if __name__ == "__main__":
    test = [[0, 0], [0, 1], [1, 0], [1, 1]]
    for x in test:
        print(x, XOR(x[0], x[1]))
```

不难发现，每个函数的前三行都是类似的形式，于是我们可以把它抽象成 preceptron 函数，于是得到了以下代码

```python
import numpy as np

def preceptron(x1, x2, w1, w2, b):
    x = np.array([x1, x2, 1])
    w = np.array([w1, w2, b])
    tmp = np.sum(x * w)
    if tmp > 0:
        return 1
    return 0

def AND(x1, x2):
    return preceptron(x1, x2, 1, 1, -1)

def NAND(x1, x2):
    return preceptron(x2, x2, -0.5, -0.5, 0.7)

def OR(x1, x2):
    return preceptron(x1, x2, 0.6, 1, -0.5)

def XOR(a, b):
    x1 = OR(a, b)
    x2 = NAND(a, b)
    return NAND(x1, x2)

if __name__ == "__main__":
    test = [[0, 0], [0, 1], [1, 0], [1, 1]]
    for x in test:
        print(x, XOR(x[0], x[1]))
```

这时候我们回头再看一下感知机的网络图
![单层感知机](https://yangqiuyi.com/content-assets/ec3cb9909091e26de56b.png)

我们发现图中并没有 b 这个变量，所以我们可以把这张图完善一下
![完善的单层感知机网络图](https://yangqiuyi.com/content-assets/01598133b02749bf14b4.png)

其中<span className="katex">
<span className="katex-mathml">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<semantics>
<mrow>
<mi>

a

</mi>

<mo>

=

</mo>

<msub>
<mi>

w

</mi>

<mn>

1

</mn>
</msub>

<mo>

∗

</mo>

<msub>
<mi>

x

</mi>

<mn>

1

</mn>
</msub>

<mo>

+

</mo>

<msub>
<mi>

w

</mi>

<mn>

2

</mn>
</msub>

<mo>

∗

</mo>

<msub>
<mi>

x

</mi>

<mn>

2

</mn>
</msub>

<mo>

+

</mo>

<mi>

b

</mi>

<mo>

∗

</mo>

<mn>

1

</mn>
</mrow>

<annotation encoding="application/x-tex">

a=w_1*x_1+w_2*x_2+b*1

</annotation>
</semantics>
</math>
</span>

<span className="katex-html" ariaHidden="true">
<span className="base">
<span className="strut" style="height:0.4306em;">



</span>

<span className="mord,mathnormal">

a

</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>

<span className="mrel">

=

</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:0.6153em;vertical-align:-0.15em;">



</span>

<span className="mord">
<span className="mord,mathnormal" style="margin-right:0.0269em;">

w

</span>

<span className="msupsub">
<span className="vlist-t,vlist-t2">
<span className="vlist-r">
<span className="vlist" style="height:0.3011em;">
<span style="top:-2.55em;margin-left:-0.0269em;margin-right:0.05em;">
<span className="pstrut" style="height:2.7em;">



</span>

<span className="sizing,reset-size6,size3,mtight">
<span className="mord,mtight">

1

</span>
</span>
</span>
</span>

<span className="vlist-s">

​

</span>
</span>

<span className="vlist-r">
<span className="vlist" style="height:0.15em;">
<span>



</span>
</span>
</span>
</span>
</span>
</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>

<span className="mbin">

∗

</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:0.7333em;vertical-align:-0.15em;">



</span>

<span className="mord">
<span className="mord,mathnormal">

x

</span>

<span className="msupsub">
<span className="vlist-t,vlist-t2">
<span className="vlist-r">
<span className="vlist" style="height:0.3011em;">
<span style="top:-2.55em;margin-left:0em;margin-right:0.05em;">
<span className="pstrut" style="height:2.7em;">



</span>

<span className="sizing,reset-size6,size3,mtight">
<span className="mord,mtight">

1

</span>
</span>
</span>
</span>

<span className="vlist-s">

​

</span>
</span>

<span className="vlist-r">
<span className="vlist" style="height:0.15em;">
<span>



</span>
</span>
</span>
</span>
</span>
</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>

<span className="mbin">

+

</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:0.6153em;vertical-align:-0.15em;">



</span>

<span className="mord">
<span className="mord,mathnormal" style="margin-right:0.0269em;">

w

</span>

<span className="msupsub">
<span className="vlist-t,vlist-t2">
<span className="vlist-r">
<span className="vlist" style="height:0.3011em;">
<span style="top:-2.55em;margin-left:-0.0269em;margin-right:0.05em;">
<span className="pstrut" style="height:2.7em;">



</span>

<span className="sizing,reset-size6,size3,mtight">
<span className="mord,mtight">

2

</span>
</span>
</span>
</span>

<span className="vlist-s">

​

</span>
</span>

<span className="vlist-r">
<span className="vlist" style="height:0.15em;">
<span>



</span>
</span>
</span>
</span>
</span>
</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>

<span className="mbin">

∗

</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:0.7333em;vertical-align:-0.15em;">



</span>

<span className="mord">
<span className="mord,mathnormal">

x

</span>

<span className="msupsub">
<span className="vlist-t,vlist-t2">
<span className="vlist-r">
<span className="vlist" style="height:0.3011em;">
<span style="top:-2.55em;margin-left:0em;margin-right:0.05em;">
<span className="pstrut" style="height:2.7em;">



</span>

<span className="sizing,reset-size6,size3,mtight">
<span className="mord,mtight">

2

</span>
</span>
</span>
</span>

<span className="vlist-s">

​

</span>
</span>

<span className="vlist-r">
<span className="vlist" style="height:0.15em;">
<span>



</span>
</span>
</span>
</span>
</span>
</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>

<span className="mbin">

+

</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:0.6944em;">



</span>

<span className="mord,mathnormal">

b

</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>

<span className="mbin">

∗

</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:0.6444em;">



</span>

<span className="mord">

1

</span>
</span>
</span>
</span>

，把<span className="katex">
<span className="katex-mathml">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<semantics>
<mrow>
<mi>

a

</mi>
</mrow>

<annotation encoding="application/x-tex">

a

</annotation>
</semantics>
</math>
</span>

<span className="katex-html" ariaHidden="true">
<span className="base">
<span className="strut" style="height:0.4306em;">



</span>

<span className="mord,mathnormal">

a

</span>
</span>
</span>
</span>

作为输入，经由 h 函数，得到 y

<span className="katex-display">
<span className="katex">
<span className="katex-mathml">
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<semantics>
<mrow>
<mi>

a

</mi>

<mo>

=

</mo>

<msub>
<mi>

w

</mi>

<mn>

1

</mn>
</msub>

<mo>

∗

</mo>

<msub>
<mi>

x

</mi>

<mn>

1

</mn>
</msub>

<mo>

+

</mo>

<msub>
<mi>

w

</mi>

<mn>

2

</mn>
</msub>

<mo>

∗

</mo>

<msub>
<mi>

x

</mi>

<mn>

2

</mn>
</msub>

<mo>

+

</mo>

<mi>

b

</mi>

<mspace linebreak="newline">



</mspace>

<mi>

y

</mi>

<mo>

=

</mo>

<mi>

h

</mi>

<mo stretchy="false">

(

</mo>

<mi>

a

</mi>

<mo stretchy="false">

)

</mo>
</mrow>

<annotation encoding="application/x-tex">

a = w_1 * x_1+w_2 * x_2 + b \\
        y = h(a)

</annotation>
</semantics>
</math>
</span>

<span className="katex-html" ariaHidden="true">
<span className="base">
<span className="strut" style="height:0.4306em;">



</span>

<span className="mord,mathnormal">

a

</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>

<span className="mrel">

=

</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:0.6153em;vertical-align:-0.15em;">



</span>

<span className="mord">
<span className="mord,mathnormal" style="margin-right:0.0269em;">

w

</span>

<span className="msupsub">
<span className="vlist-t,vlist-t2">
<span className="vlist-r">
<span className="vlist" style="height:0.3011em;">
<span style="top:-2.55em;margin-left:-0.0269em;margin-right:0.05em;">
<span className="pstrut" style="height:2.7em;">



</span>

<span className="sizing,reset-size6,size3,mtight">
<span className="mord,mtight">

1

</span>
</span>
</span>
</span>

<span className="vlist-s">

​

</span>
</span>

<span className="vlist-r">
<span className="vlist" style="height:0.15em;">
<span>



</span>
</span>
</span>
</span>
</span>
</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>

<span className="mbin">

∗

</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:0.7333em;vertical-align:-0.15em;">



</span>

<span className="mord">
<span className="mord,mathnormal">

x

</span>

<span className="msupsub">
<span className="vlist-t,vlist-t2">
<span className="vlist-r">
<span className="vlist" style="height:0.3011em;">
<span style="top:-2.55em;margin-left:0em;margin-right:0.05em;">
<span className="pstrut" style="height:2.7em;">



</span>

<span className="sizing,reset-size6,size3,mtight">
<span className="mord,mtight">

1

</span>
</span>
</span>
</span>

<span className="vlist-s">

​

</span>
</span>

<span className="vlist-r">
<span className="vlist" style="height:0.15em;">
<span>



</span>
</span>
</span>
</span>
</span>
</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>

<span className="mbin">

+

</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:0.6153em;vertical-align:-0.15em;">



</span>

<span className="mord">
<span className="mord,mathnormal" style="margin-right:0.0269em;">

w

</span>

<span className="msupsub">
<span className="vlist-t,vlist-t2">
<span className="vlist-r">
<span className="vlist" style="height:0.3011em;">
<span style="top:-2.55em;margin-left:-0.0269em;margin-right:0.05em;">
<span className="pstrut" style="height:2.7em;">



</span>

<span className="sizing,reset-size6,size3,mtight">
<span className="mord,mtight">

2

</span>
</span>
</span>
</span>

<span className="vlist-s">

​

</span>
</span>

<span className="vlist-r">
<span className="vlist" style="height:0.15em;">
<span>



</span>
</span>
</span>
</span>
</span>
</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>

<span className="mbin">

∗

</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:0.7333em;vertical-align:-0.15em;">



</span>

<span className="mord">
<span className="mord,mathnormal">

x

</span>

<span className="msupsub">
<span className="vlist-t,vlist-t2">
<span className="vlist-r">
<span className="vlist" style="height:0.3011em;">
<span style="top:-2.55em;margin-left:0em;margin-right:0.05em;">
<span className="pstrut" style="height:2.7em;">



</span>

<span className="sizing,reset-size6,size3,mtight">
<span className="mord,mtight">

2

</span>
</span>
</span>
</span>

<span className="vlist-s">

​

</span>
</span>

<span className="vlist-r">
<span className="vlist" style="height:0.15em;">
<span>



</span>
</span>
</span>
</span>
</span>
</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>

<span className="mbin">

+

</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:0.6944em;">



</span>

<span className="mord,mathnormal">

b

</span>
</span>

<span className="mspace,newline">



</span>

<span className="base">
<span className="strut" style="height:0.625em;vertical-align:-0.1944em;">



</span>

<span className="mord,mathnormal" style="margin-right:0.0359em;">

y

</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>

<span className="mrel">

=

</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:1em;vertical-align:-0.25em;">



</span>

<span className="mord,mathnormal">

h

</span>

<span className="mopen">

(

</span>

<span className="mord,mathnormal">

a

</span>

<span className="mclose">

)

</span>
</span>
</span>
</span>
</span>

不难发现，h()所做的就是判断 a 是否大于 0，如果大于 0 则返回 1，否则返回 0，正因为我们可以用它表示状态，因此我们把它称为激活函数，激活函数有很多种，一般来说，不同的激活函数会得到不同的结果。激活函数是连接感知机和神经网络的桥梁<sup>

[1](#user-content-fn-1)

</sup>

。

接下来介绍一下常见的几种激活函数。

## 阶跃函数

```python
def step_function(x):
    if x > 0:
        return 1
    else:
        return 0
```

阶跃函数的输出只有两种情况，缺点是无法求导
![](https://yangqiuyi.com/content-assets/7e24a532c447d4419df5.png)

## sigmoid 函数

<span className="katex-display">
<span className="katex">
<span className="katex-mathml">
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<semantics>
<mrow>
<mi>

h

</mi>

<mo stretchy="false">

(

</mo>

<mi>

x

</mi>

<mo stretchy="false">

)

</mo>

<mo>

=

</mo>

<mfrac>
<mn>

1

</mn>

<mrow>
<mn>

1

</mn>

<mo>

+

</mo>

<msup>
<mi>

e

</mi>

<mrow>
<mo>

−

</mo>

<mi>

x

</mi>
</mrow>
</msup>
</mrow>
</mfrac>
</mrow>

<annotation encoding="application/x-tex">

h(x) = \frac{1}{1+e^{-x}}

</annotation>
</semantics>
</math>
</span>

<span className="katex-html" ariaHidden="true">
<span className="base">
<span className="strut" style="height:1em;vertical-align:-0.25em;">



</span>

<span className="mord,mathnormal">

h

</span>

<span className="mopen">

(

</span>

<span className="mord,mathnormal">

x

</span>

<span className="mclose">

)

</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>

<span className="mrel">

=

</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:2.0908em;vertical-align:-0.7693em;">



</span>

<span className="mord">
<span className="mopen,nulldelimiter">



</span>

<span className="mfrac">
<span className="vlist-t,vlist-t2">
<span className="vlist-r">
<span className="vlist" style="height:1.3214em;">
<span style="top:-2.314em;">
<span className="pstrut" style="height:3em;">



</span>

<span className="mord">
<span className="mord">

1

</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>

<span className="mbin">

+

</span>

<span className="mspace" style="margin-right:0.2222em;">



</span>

<span className="mord">
<span className="mord,mathnormal">

e

</span>

<span className="msupsub">
<span className="vlist-t">
<span className="vlist-r">
<span className="vlist" style="height:0.6973em;">
<span style="top:-2.989em;margin-right:0.05em;">
<span className="pstrut" style="height:2.7em;">



</span>

<span className="sizing,reset-size6,size3,mtight">
<span className="mord,mtight">
<span className="mord,mtight">

−

</span>

<span className="mord,mathnormal,mtight">

x

</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>

<span style="top:-3.23em;">
<span className="pstrut" style="height:3em;">



</span>

<span className="frac-line" style="border-bottom-width:0.04em;">



</span>
</span>

<span style="top:-3.677em;">
<span className="pstrut" style="height:3em;">



</span>

<span className="mord">
<span className="mord">

1

</span>
</span>
</span>
</span>

<span className="vlist-s">

​

</span>
</span>

<span className="vlist-r">
<span className="vlist" style="height:0.7693em;">
<span>



</span>
</span>
</span>
</span>
</span>

<span className="mclose,nulldelimiter">



</span>
</span>
</span>
</span>
</span>
</span>

sigmoid 函数图像如下：

![](https://yangqiuyi.com/content-assets/fae8a2e60b2020ab58e5.jpg)

我们可以把阶跃函数和 sigmoid 函数重叠起来：
![](https://yangqiuyi.com/content-assets/7b3126dea9793257d21c.png)

可以发现，二者去区别在于，sigmoid 函数很光滑，可以取到(0, 1)区间内任何一个实数，而阶跃函数只能取到 0 或 1. 因此，我们在感知机中使用阶跃函数，在神经网络中，则趋向于使用光滑的激活函数。

## ReLU 函数(斜坡函数)

在神经网络发展的历史上，sigmoid 函数很早就开始被使用了，而最近则主要使用 ReLU（Rectified Linear Unit）函数。<sup>

[1](#user-content-fn-1)

</sup>



<span className="katex-display">
<span className="katex">
<span className="katex-mathml">
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<semantics>
<mrow>
<mi>

h

</mi>

<mo stretchy="false">

(

</mo>

<mi>

x

</mi>

<mo stretchy="false">

)

</mo>

<mo>

=

</mo>

<mrow>
<mo fence="true">

{

</mo>

<mtable rowspacing="0.16em" columnalign="center" columnspacing="1em">
<mtr>
<mtd>
<mstyle scriptlevel="0" displaystyle="false">
<mrow>
<mi>

x

</mi>

<mo separator="true">

,

</mo>

<mi>

x

</mi>

<mo>

>
</mo>

<mn>

0

</mn>
</mrow>
</mstyle>
</mtd>
</mtr>

<mtr>
<mtd>
<mstyle scriptlevel="0" displaystyle="false">
<mrow>
<mn>

0

</mn>

<mo separator="true">

,

</mo>

<mi>

x

</mi>

<mo>

≤

</mo>

<mn>

0

</mn>
</mrow>
</mstyle>
</mtd>
</mtr>
</mtable>
</mrow>
</mrow>

<annotation encoding="application/x-tex">

h(x) = \left\{
        \begin {matrix}
            x, x \gt 0 \\
            0, x \le 0
        \end{matrix}
        \right.

</annotation>
</semantics>
</math>
</span>

<span className="katex-html" ariaHidden="true">
<span className="base">
<span className="strut" style="height:1em;vertical-align:-0.25em;">



</span>

<span className="mord,mathnormal">

h

</span>

<span className="mopen">

(

</span>

<span className="mord,mathnormal">

x

</span>

<span className="mclose">

)

</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>

<span className="mrel">

=

</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>
</span>

<span className="base">
<span className="strut" style="height:2.4em;vertical-align:-0.95em;">



</span>

<span className="minner">
<span className="mopen,delimcenter" style="top:0em;">
<span className="delimsizing,size3">

{

</span>
</span>

<span className="mord">
<span className="mtable">
<span className="col-align-c">
<span className="vlist-t,vlist-t2">
<span className="vlist-r">
<span className="vlist" style="height:1.45em;">
<span style="top:-3.61em;">
<span className="pstrut" style="height:3em;">



</span>

<span className="mord">
<span className="mord,mathnormal">

x

</span>

<span className="mpunct">

,

</span>

<span className="mspace" style="margin-right:0.1667em;">



</span>

<span className="mord,mathnormal">

x

</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>

<span className="mrel">

>
</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>

<span className="mord">

0

</span>
</span>
</span>

<span style="top:-2.41em;">
<span className="pstrut" style="height:3em;">



</span>

<span className="mord">
<span className="mord">

0

</span>

<span className="mpunct">

,

</span>

<span className="mspace" style="margin-right:0.1667em;">



</span>

<span className="mord,mathnormal">

x

</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>

<span className="mrel">

≤

</span>

<span className="mspace" style="margin-right:0.2778em;">



</span>

<span className="mord">

0

</span>
</span>
</span>
</span>

<span className="vlist-s">

​

</span>
</span>

<span className="vlist-r">
<span className="vlist" style="height:0.95em;">
<span>



</span>
</span>
</span>
</span>
</span>
</span>
</span>

<span className="mclose,nulldelimiter">



</span>
</span>
</span>
</span>
</span>
</span>

![ReLU](https://yangqiuyi.com/content-assets/a896682a2ab03bd7fed5.png)

**代码实现：**

```python
def relu(x):
    return max(0, x)
```

## 改写代码

在了解了激活函数之后，我们发现感知机代码可以进一步解耦——把激活函数抽离出去。

```python
import numpy as np

def step_function(x): # 阶跃函数
    if x > 0:
        return 1
    return 0

def linear(x1, x2, w1, w2, theta): # 计算 a = x1*w1 + x2*w2 +b
    x = np.array([x1, x2, 1])
    w = np.array([w1, w2, theta])
    tmp = np.sum(x * w)
    return tmp

def preceptron(x1, x2, w1, w2, theta):
    res = linear(x1, x2, w1, w2, theta)
    return step_function(res)

def AND(x1, x2):
    return preceptron(x1, x2, 1, 1, -1)

def NAND(x1, x2):
    return preceptron(x2, x2, -0.5, -0.5, 0.7)

def OR(x1, x2):
    return preceptron(x1, x2, 0.6, 1, -0.5)

def XOR(a, b):
    x1 = OR(a, b)
    x2 = NAND(a, b)
    return NAND(x1, x2)

if __name__ == "__main__":
    test = [[0, 0], [0, 1], [1, 0], [1, 1]]
    for x in test:
        print(x, XOR(x[0], x[1]))
```

<section className="footnotes" dataFootnotes="">

## Footnotes

1. 深度学习入门：基于 Python 的理论与实现. [日］斋藤康毅 [↩](#user-content-fnref-1) [↩<sup>

2

</sup>

](#user-content-fnref-1-2)

</section>

## Sitemap

See the full [sitemap](https://yangqiuyi.com/sitemap.md) for all pages.
