
《DLS》第二章筆記:感知機
2.1 感知機
2.1.1 神經元
對于生物學意義上的神經元,一個神經元具有多個樹突接收輸入信號,一個細胞主體處理輸入信號,一個軸突傳遞輸出信號,如下圖:

將神經元抽象為一個演算法模型:

我們將這個模型稱為人工神經元,也稱感知機,
2.1.2 感知機的組成
一個感知機由輸入權值、激活函式、輸出三部分組成,
y
=
{
0
,
(
b
+
w
1
x
1
+
w
2
w
2
+
.
.
.
+
w
n
x
n
≤
0
)
1
,
(
b
+
w
1
x
1
+
w
2
w
2
+
.
.
.
+
w
n
x
n
>
0
)
y=\begin{cases} 0,(b+w_{1}x_{1}+w_{2}w_{2}+...+w_{n}x_{n}\leq 0)\\ 1,(b+w_{1}x_{1}+w_{2}w_{2}+...+w_{n}x_{n}>0)\\ \end{cases}
y={0,(b+w1?x1?+w2?w2?+...+wn?xn?≤0)1,(b+w1?x1?+w2?w2?+...+wn?xn?>0)?
輸入權值:一個感知機可以接收多個輸入
x
1
,
x
2
,
.
.
.
,
x
n
(
x
i
∈
R
)
x_{1},x_{2},...,x_{n}(x_{i}\in\mathbb{R})
x1?,x2?,...,xn?(xi?∈R),每個輸入上有一個權重值
w
i
∈
R
w_{i}\in\mathbb{R}
wi?∈R,此外還有一個偏置項
b
∈
R
b\in\mathbb{R}
b∈R,即
w
0
w_{0}
w0?,輸入信號被送往神經元時會被分別乘以固定的權重,
(權重是控制輸入信號重要性的引數,偏置是調整神經元被激活的容易程度的引數)
激活函式: f ( x ) f(x) f(x) 決定如何來計算輸入信號的總和,只有當總和超過某個界限時,才會輸出1,即“神經元被激活”,這個界限值被稱為閾值,
輸出:輸出 y = f ( x ) y=f(x) y=f(x),輸出值只有兩個,即0或1,總和超過閾值時輸出1,總和未超過閾值時輸出0,
2.1.3 神經元和感知機的對應關系
| 神經元 | 感知機 |
|---|---|
| 樹突接收的信號 | 輸入權值 |
| 細胞主體 | 激活函式 |
| 軸突輸出的信號 | 輸出 |
2.2 邏輯門
2.2.1 與門
與門對應邏輯運算“與”,真值表如下:

用感知機實作與門,實際上就是尋找一組能滿足與門真值表的
w
1
w_{1}
w1?、
w
2
w_{2}
w2?、
θ
\theta
θ的值,這樣的值有無數多個,選擇不同的值就是選擇不同的權重,
Python實作:
import numpy as np
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
x1, x2 = map(int, input().split())
print(AND(x1, x2))
C++實作:
#include<iostream>
using namespace std;
bool AND(bool x1,bool x2);
int main()
{
bool x1,x2;
cin>>x1>>x2;
cout<<AND(x1,x2);
return 0;
}
bool AND(bool x1,bool x2)
{
double w1 = 0.5,w2 = 0.5,b = -0.7;
double tmp = x1*w1+x2*w2+b;
return tmp <= 0 ? 0 : 1;
}
2.2.2 與非門
與非門對應邏輯運算“與”和“非”,真值表如下:

與非門的輸出實際上就是顛倒了與門的輸出,只要把實作與門的引數值
w
1
w_{1}
w1?、
w
2
w_{2}
w2?、
θ
\theta
θ取反就可以實作與非門,
Python實作:
import numpy as np
def NAND(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
x1, x2 = map(int, input().split())
print(AND(x1, x2))
C++實作:
#include<iostream>
using namespace std;
bool NAND(bool x1,bool x2);
int main()
{
bool x1,x2;
cin>>x1>>x2;
cout<<NAND(x1,x2);
return 0;
}
bool NAND(bool x1,bool x2)
{
double w1 = -0.5,w2 = -0.5,b = 0.7;
double tmp = x1*w1+x2*w2+b;
return tmp <= 0 ? 0 : 1;
}
2.2.3 或門
或門對應邏輯運算“或”,真值表如下:

用感知機實作或門,實際上就是尋找一組能滿足或門真值表的
w
1
w_{1}
w1?、
w
2
w_{2}
w2?、
θ
\theta
θ的值,這樣的值有無數多個,選擇不同的值就是選擇不同的權重,
Python實作:
import numpy as np
def OR(x1,x2):
x = np.array([x1,x2])
w = np.array([0.5,0.5])
b = -0.2
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1
x1, x2 = map(int, input().split())
print(AND(x1, x2))
C++實作:
#include<iostream>
using namespace std;
bool OR(bool x1,bool x2);
int main()
{
bool x1,x2;
cin>>x1>>x2;
cout<<OR(x1,x2);
return 0;
}
bool OR(bool x1,bool x2)
{
double w1 = 0.5,w2 = 0.5,b = -0.2;
double tmp = x1*w1+x2*w2+b;
return tmp <= 0 ? 0 : 1;
}
與門、與非門和或門是具有相同結構的感知機,區別只在于權重引數的值,
2.2.4 異或門
異或門對應邏輯運算“異或”,真值表如下:

異或(XOR)的運算是特性是“相同為0,不同為1”,即僅當
x
1
x_{1}
x1?或
x
2
x_{2}
x2?中的一方為1時,才會輸出1(“異或”是拒絕其他的意思),簡單實踐就可發現,我們無法用單層感知機實作異或門,
2.3 多層感知機
2.3.1或門可視化
對于或門
def OR(x1,x2):
x = np.array([x1,x2])
w = np.array([0.5,0.5])
b = -0.2
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1
表示
y
=
{
0
,
(
?
0.5
+
x
1
+
w
2
≤
0
)
1
,
(
?
0.5
+
x
1
+
w
2
>
0
)
y=\begin{cases} 0,(-0.5+x_{1}+w_{2}\leq 0)\\ 1,(-0.5+x_{1}+w_{2}>0)\\ \end{cases}
y={0,(?0.5+x1?+w2?≤0)1,(?0.5+x1?+w2?>0)?
即,坐標系被直線?0.5 + x1 + x2 = 0分割開的兩個空間,其中一個空間輸出1,另一個空間輸出0,

2.3.2異或門可視化
對于異或門

顯然,無法使用一條直線把三角和圓圈分割開來,考慮:

即通過與門、或門、與非門的組合來實作異或門,

尋找實作異或門的組合:

2.3.3 異或門的實作
列出與門的真值表:
| x 1 x_{1} x1? | x 2 x_{2} x2? | y y y (AND) |
|---|---|---|
| 0 | 0 | 0 |
| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 1 | 1 |
列出與非門的真值表:
| x 1 x_{1} x1? | x 2 x_{2} x2? | s 1 s_{1} s1? (NAND) |
|---|---|---|
| 0 | 0 | 1 |
| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 1 | 0 |
列出或門的真值表:
| x 1 x_{1} x1? | x 2 x_{2} x2? | s 2 s_{2} s2? (OR) |
|---|---|---|
| 0 | 0 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 1 | 1 | 1 |
則可發現:
| s 1 s_{1} s1?(NAND) | s 2 s_{2} s2?(OR) | y y y (AND) |
|---|---|---|
| 1 | 0 | 0 |
| 1 | 1 | 1 |
| 1 | 1 | 1 |
| 0 | 1 | 0 |
因此可作如下組合:

Python實作:
import numpy as np
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
def NAND(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
def OR(x1,x2):
x = np.array([x1,x2])
w = np.array([0.5,0.5])
b = -0.2
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1
def XOR(x1, x2):
s1 = NAND(x1, x2)
s2 = OR(x1, x2)
y = AND(s1, s2)
return y
x1, x2 = map(int, input().split())
print(XOR(x1, x2))
C++實作:
#include<iostream>
using namespace std;
bool AND(bool x1,bool x2);
bool NAND(bool x1,bool x2);
bool OR(bool x1,bool x2);
bool XOR(bool x1,bool x2);
int main()
{
bool x1,x2;
cin>>x1>>x2;
cout<<XOR(x1,x2);
return 0;
}
bool AND(bool x1,bool x2)
{
double w1 = 0.5,w2 = 0.5,b = -0.7;
double tmp = x1*w1+x2*w2+b;
return tmp <= 0 ? 0 : 1;
}
bool NAND(bool x1,bool x2)
{
double w1 = -0.5,w2 = -0.5,b = 0.7;
double tmp = x1*w1+x2*w2+b;
return tmp <= 0 ? 0 : 1;
}
bool OR(bool x1,bool x2)
{
double w1 = 0.5,w2 = 0.5,b = -0.2;
double tmp = x1*w1+x2*w2+b;
return tmp <= 0 ? 0 : 1;
}
bool XOR(bool x1,bool x2)
{
double s1 = NAND(x1, x2);
double s2 = OR(x1, x2);
double y = AND(s1,s2);
return y;
}
2.3.4 多層感知機
疊加了超過兩層的感知機被稱為多層感知機,異或門就是通過雙層感知機實作的,多層感知機可以實作單層感知機實作不了的結構,通過疊加層(加深層),感知機能進行更加靈活的表示,

上圖所示的2層感知機中,先在第0層和第1層的神經元之間進行信號的傳送和接收,然后在第1層和第2層之間進行信號的傳送和接收,具體如下所示:
1.第0層的兩個神經元接收輸入信號,并將信號發送至第1層的神經元,
2.第1層的神經元將信號發送至第2層的神經元,第2層的神經元輸出y,
2.4 感知機和計算機
兩層感知機(使用sigmoid函式為激活函式)就可以表示任意函式,
《計算機系統要素:從零開始構建現代計算機》:以深入理解計算機為主題,論述了僅通過 NAND構建可運行俄羅斯方塊的計算機的程序,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/259847.html
標籤:AI
上一篇:每天學點5G-5G AMF
下一篇:網路結構——BatchNorm
