機器學習-感知機【perceptron】
- what is 感知機
- 單層感知機運用實例
- 多層感知機
感知機接收多個輸入信號,輸出一個信號。
接收兩個信號的感知機,如下圖:
x1與x2是輸入信號;y是輸出信號;
w1與w2是權重。圓圈O代表”神經元”或者”節點”。
神經元被激活:當x1w1+x2w2超過某個界限值時,y才會輸出1。
閾值:這里將界限值稱為閾值,用θ符號表示。
權重越大,對應該權重的信號的重要性就越高。
由此可以得到感知機的一種數學表示方法:
感知機的另一種數學表示方法:
上式的b稱為偏置。感知機計算輸入信號和權重的乘積,然后加上偏置,這個值大於0則輸出1,否則輸出0。
使用感知機可以實現與、或、與非門。
首先與門,兩個都是1,才輸出1:
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 if __name__ == '__main__': for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]: y = AND(xs[0], xs[1]) print(str(xs) + " -> " + str(y))
輸出結果:
(0, 0) -> 0
(1, 0) -> 0
(0, 1) -> 0
(1, 1) -> 1
然后是或門,兩個輸入只要有一個是1,就輸出1.
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 if __name__ == '__main__': for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]: y = OR(xs[0], xs[1]) print(str(xs) + " -> " + str(y))
輸出結果:
(0, 0) -> 0
(1, 0) -> 1
(0, 1) -> 1
(1, 1) -> 1
最后是與非門,就是把與的結果取反:
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 if __name__ == '__main__': for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]: y = NAND(xs[0], xs[1]) print(str(xs) + " -> " + str(y))
輸出結果:
(0, 0) -> 1
(1, 0) -> 1
(0, 1) -> 1
(1, 1) -> 0
由上面的例子我們可以看出,與、或、與非門是具有相同構造的感知機,區別只在於權重w和偏置b的值不同。
首先來看一下異或邏輯的真值表:
輸入x1 | 輸入x2 | 輸出Y |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
將他們標在平面坐標系中可發現,任何直線也不能把兩類樣本分開。
單層感知機的數學表示方法如下:
它的幾何意義:w2x1+w2x2+b=0是一條直線,這條直線分割開兩個空間,其中一個空間輸出1,另一個空間輸出0 。
也就是說通過單層感知機,無法把異或邏輯的兩類樣本分開。
單層感知機只能表示由一條直線分割的空間;非線性空間:曲線分割成的空間。
之前已經用單層感知機實現了與門、與非門、或門,那么實現異或門的話,可以把前面那幾個門疊加起來。
x1,x2表示輸入,s1表示與非門的輸出,s2表示或門的輸出,y表示與門的輸出
通過觀察x1、x2、y的值,發現,符合異或門的輸出。
實現異或門的代碼:
from and_gate import AND from or_gate import OR from nand_gate import NAND def XOR(x1, x2): s1 = NAND(x1, x2) s2 = OR(x1, x2) y = AND(s1, s2) return y if __name__ == '__main__': for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]: y = XOR(xs[0], xs[1]) print(str(xs) + " -> " + str(y))
輸出結果:
(0, 0) -> 0
(1, 0) -> 1
(0, 1) -> 1
(1, 1) -> 0
由上述可知,通過疊加層,感知機能進行更加靈活的表示。如果說通過組合與非門可實現計算機,那么通過組合感知機也可以表示計算機。
已有研究證明,2層感知機可以表示任意函數,但是不容易設計合適的權重和構造。通常用小模塊疊加的方法來構造,就比如上面的先實現與門、或門、與非門,再疊加起來實現異或門。