感知器對線性可分或近似線性可分數據有很好的效果,但對於線性不可分數據的效果不理想.Minsky在1969年出版的<>中用詳細的數學證實了感知器沒法解決XOR(異或)分類問題.而咱們要說的XOR問題
正是線性不可分的python
x1 | x2 | AND |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
x1 | x2 | OR |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
x1 | x2 | OR |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
注意:XOR=OR-ANDweb
x1 | x2 | AND | OR | XOR |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 0 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
將上表的結果可視化,其中圓點表示0,方塊表示1.AND,OR,NAND問題都是線性可分,但XOR是線性不可分算法
from IPython.display import Image
Image(filename="./data/1.png",width=500)
根據定義,線性模型將產生某種類型的線性(2D線,3D線平面或直線且缺少曲線的高維表面)功能網絡
Image(filename="./data/3.png",width=500)
在上圖中,點x̄y和xȳ是應由XOR函數做爲"True"或"1"發出信號的輸入.挑戰在於,XOR是一個非線性函數,意味着x̄y和xȳ不能與xy和x̄ȳ線性分離
session
Image(filename="./data/4.png",width=500)
若是XOR函數有效地分離出x̄y和xȳ,那麼函數是什麼樣的?架構
Image(filename="./data/5.png",width=500)
Image(filename="./data/6.png",width=500)
如上圖所示,XOR及XNOR在布爾函數中是惟一的,由於它們不能用單行捕獲dom
下面描繪14個線性布爾函數中的每個svg
Image(filename="./data/7.png",width=500)
感知器包括單層輸入單元-包括一個偏置單元-和單個輸出單元,這裏,偏置單元用虛線圓圈表示,而其餘單元用藍色圓圈表示。有兩個非偏置輸入單元表示XOr的兩個二進制輸入值。能夠包括任意數量的輸入單元函數
Image(filename="./data/8.png",width=500)
感知器是一種前饋網絡,這意味着產生輸出的過程(稱爲前向傳播)在一個方向上從輸入層流向輸出層。輸入層中的單元之間沒有鏈接。相反,輸入層中的全部單元都直接鏈接到輸出單元優化
前向傳播過程的簡化說明是輸入值X1和X2以及偏置值1乘以它們各自的權重W0…W2,並解析爲輸出單元
此問題的解決方案是經過添加額外的單元層而不是直接訪問外部世界(稱爲隱藏層)來擴展到單層體系結構以外.另外一種稱爲多層感知器(MLP)的前饋網絡
Image(filename="./data/9.png",width=500)
反向傳播算法首先將前向傳播過程輸出的實際值與預期值進行比較,而後向後移動經過網絡,在一個方向上稍微調整每一個權重,以減少偏差的大小。前向和後向傳播在每一個輸入組合上從新運行數千次,直到網絡可使用前向傳播準確地預測可能輸入的預期輸出
Image(filename="./data/11.png",width=500)
上圖左邊爲詳細結構,右邊爲向量式結構
輸入數據中有兩個特徵:x1,x2,共4個樣本.分別爲[0,0]T,[1,0]T.取x1,x2兩列,每行表明一個樣本,每一個樣本x都是一個向量,若是用矩陣表示就是:
肯定隱含層及初始化權重矩陣W,w.隱含層主要肯定激活函數.這裏咱們採用整流線性激活函數:g(z)=max{0,z}
初始化如下矩陣:
輸入層到隱含層的權重矩陣:
偏移量爲:
隱含層到輸出層的權重矩陣:
偏移量爲:
b2=0
Image(filename="./data/12.png",width=500)
激活函數仍是使用ReLU函數,代價函數使用MSE,優化器使用Adam自適應算法
初始化權重和偏移量,只有隨機取些較小值便可,無須考慮一些特殊值,最終這些權重值或偏移量,會在循環迭代中不斷更新.隨機生成權重初始化數據,生成的數據符合正態分佈
import tensorflow as tf import numpy as np # 定義輸入與目標值 X=np.array([[0,0],[0,1],[1,0],[1,1]]) Y=np.array([[0],[1],[1],[0]]) # 定義佔位符 x=tf.placeholder(tf.float32,[None,2]) y=tf.placeholder(tf.float32,[None,1]) # 初始化權重 w1=tf.Variable(tf.random_normal([2,2])) w2=tf.Variable(tf.random_normal([2,1])) # 定義偏移量 b1=tf.Variable([0.1,0.1]) b2=tf.Variable(0.1) # 激活函數 h=tf.nn.relu(tf.matmul(x,w1)+b1) # 輸出層 out=tf.matmul(h,w2)+b2 # 定義代價函數 loss=tf.reduce_mean(tf.square(out-y)) # 利用Adam自適應優化函數 train=tf.train.AdamOptimizer(0.15).minimize(loss) with tf.Session() as session: session.run(tf.global_variables_initializer()) for i in range(2000): session.run(train,feed_dict={x:X,y:Y}) loss_=session.run(loss,feed_dict={x:X,y:Y}) if i%200==0: print("Step:%d,Loss:%.3f"%(i,loss_)) print("X:%r"%X) print("Pred:%r"%session.run(out,feed_dict={x:X}))
Step:0,Loss:0.277 Step:200,Loss:0.000 Step:400,Loss:0.000 Step:600,Loss:0.000 Step:800,Loss:0.000 Step:1000,Loss:0.000 Step:1200,Loss:0.000 Step:1400,Loss:0.000 Step:1600,Loss:0.000 Step:1800,Loss:0.000 X:array([[0, 0], [0, 1], [1, 0], [1, 1]]) Pred:array([[-8.351956e-04], [ 9.974783e-01], [ 9.967382e-01], [-8.351956e-04]], dtype=float32)