單層感知機
最終y=t,說明經過訓練預測值和真實值一致。下面圖是sign函數
根據感知機規則實現的上述題目的代碼
1 import numpy as np 2 import matplotlib.pyplot as plt 3 #輸入數據 4 X = np.array([[1,3,3], 5 [1,4,3], 6 [1,1,1], 7 [1,0,2]]) 8 #標簽 9 Y = np.array([[1], 10 [1], 11 [-1], 12 [-1]]) 13 #權值初始化,3行1列,取值范圍-1到1 14 W = (np.random.random([3,1])-0.5)*2 15 print(W) 16 #學習率設置 17 lr = 0.11 18 #神經網絡輸出 19 O = 0 20 21 def update(): 22 global X,Y,W,lr 23 O = np.sign(np.dot(X,W)) 24 W_C = lr*(X.T.dot(Y-O))/int(X.shape[0])#除於樣本個數目的是分子計算的誤差是所有樣本誤差之和,所以要進行平均 25 W = W + W_C 26 for i in range(100): 27 update()#更新權值 28 print(W) 29 print(i) 30 O = np.sign(np.dot(X,W)) 31 if(O == Y).all(): 32 print('finished') 33 print('epoch:',i) 34 break 35 #正樣本 36 x1 = [3,4] 37 y1 = [3,3] 38 #負樣本 39 x2 = [1,0] 40 y2 = [1,2] 41 42 #計算分界線的斜率以及截距 43 k = -W[1]/W[2] 44 d = -W[0]/W[2] 45 print('k=',k) 46 print('d=',d) 47 48 xdata = (0,5) 49 50 plt.figure() 51 plt.plot(xdata,xdata*k+d,'r') 52 plt.scatter(x1,y1,c='b') 53 plt.scatter(x2,y2,c='y') 54 plt.show()
單層感知機解決異或問題
1 ''' 2 異或 3 0^0 = 0 4 0^1 = 1 5 1^0 = 1 6 1^1 = 0 7 ''' 8 import numpy as np 9 import matplotlib.pyplot as plt 10 #輸入數據 11 X = np.array([[1,0,0], 12 [1,0,1], 13 [1,1,0], 14 [1,1,1]]) 15 #標簽 16 Y = np.array([[-1], 17 [1], 18 [1], 19 [-1]]) 20 21 #權值初始化,3行1列,取值范圍-1到1 22 W = (np.random.random([3,1])-0.5)*2 23 24 print(W) 25 #學習率設置 26 lr = 0.11 27 #神經網絡輸出 28 O = 0 29 30 def update(): 31 global X,Y,W,lr 32 O = np.sign(np.dot(X,W)) # shape:(3,1) 33 W_C = lr*(X.T.dot(Y-O))/int(X.shape[0]) 34 W = W + W_C 35 for i in range(100): 36 update()#更新權值 37 print(W)#打印當前權值 38 print(i)#打印迭代次數 39 O = np.sign(np.dot(X,W))#計算當前輸出 40 if(O == Y).all(): #如果實際輸出等於期望輸出,模型收斂,循環結束 41 print('Finished') 42 print('epoch:',i) 43 break 44 45 #正樣本 46 x1 = [0,1] 47 y1 = [1,0] 48 #負樣本 49 x2 = [0,1] 50 y2 = [0,1] 51 52 #計算分界線的斜率以及截距 53 k = -W[1]/W[2] 54 d = -W[0]/W[2] 55 print('k=',k) 56 print('d=',d) 57 58 xdata = (-2,3) 59 60 plt.figure() 61 plt.plot(xdata,xdata*k+d,'r') 62 plt.scatter(x1,y1,c='b') 63 plt.scatter(x2,y2,c='y') 64 plt.show()
運行結果如上,可以知道單層感知機不適合解決如上類似的異或問題
線性神經網絡
同時相比於感知機引入了Delta學習規則
解決感知機無法處理異或問題的方法
對於第二個方法
說明:X0是偏置值,值為1,X1,X2為線性輸入,其它為添加的非線性輸入,使用purelin激活函數(y=x)進行模型訓練,再下面是y值的求法,用於圖形繪制。
程序如下
1 #題目:異或運算 2 #0^0=0 3 #0^1=1 4 #1^0=1 5 #1^1=0 6 import numpy as np 7 import matplotlib.pyplot as plt 8 #輸入數據--這里偏置定為1 9 X = np.array([[1,0,0,0,0,0], 10 [1,0,1,0,0,1], 11 [1,1,0,1,0,0], 12 [1,1,1,1,1,1]]) 13 #標簽--期望輸出 14 Y = np.array([-1,1,1,-1]) 15 #權值初始化,1行6列,取-1到1的隨機數 16 W = (np.random.random(6)-0.5)*2 17 print(W) 18 #學習率 19 lr = 0.11 20 #計算迭代次數 21 n = 0 22 #神經網絡輸出 23 o = 0 24 25 def update(): 26 global X,Y,W,lr,n 27 n+=1 28 o = np.dot(X,W.T) 29 W_C = lr*((Y-o.T).dot(X))/(X.shape[0])#權值改變數,這里除掉行數求平均值,因為行數多,權值改變就會很大。 30 W = W + W_C 31 for i in range(1000): 32 update()#更新權值 33 34 o = np.dot(X,W.T) 35 print("執行一千次后的輸出結果:",o)#看下執行一千次之后的輸出 36 37 #用圖形表示出來 38 #正樣本 39 x1 = [0,1] 40 y1 = [1,0] 41 #負樣本 42 x2 = [0,1] 43 y2 = [0,1] 44 45 def calculate(x,root): 46 a = W[5] 47 b = W[2]+x*W[4] 48 c = W[0]+x*W[1]+x*x*W[3] 49 if root == 1:#第一個根 50 return (-b+np.sqrt(b*b-4*a*c))/(2*a) 51 if root == 2:#第二個根 52 return (-b-np.sqrt(b*b-4*a*c))/(2*a) 53 54 xdata = np.linspace(-1,2) 55 56 plt.figure() 57 plt.plot(xdata,calculate(xdata,1),'r')#用紅色 58 plt.plot(xdata,calculate(xdata,2),'r')#用紅色 59 plt.plot(x1,y1,'bo')#用藍色 60 plt.plot(x2,y2,'yo')#用黃色 61 plt.show()
利用神經網絡解決上述感知機題目
1 import numpy as np 2 import matplotlib.pyplot as plt 3 #輸入數據 4 X = np.array([[1,3,3], 5 [1,4,3], 6 [1,1,1], 7 [1,0,2]]) 8 #標簽 9 Y = np.array([[1], 10 [1], 11 [-1], 12 [-1]]) 13 14 #權值初始化,3行1列,取值范圍-1到1 15 W = (np.random.random([3,1])-0.5)*2 16 17 print(W) 18 #學習率設置 19 lr = 0.11 20 #神經網絡輸出 21 O = 0 22 23 def update(): 24 global X,Y,W,lr 25 O = np.dot(X,W) 26 W_C = lr*(X.T.dot(Y-O))/int(X.shape[0]) 27 W = W + W_C 28 for i in range(100): 29 update()#更新權值 30 31 #正樣本 32 x1 = [3,4] 33 y1 = [3,3] 34 #負樣本 35 x2 = [1,0] 36 y2 = [1,2] 37 38 #計算分界線的斜率以及截距 39 k = -W[1]/W[2] 40 d = -W[0]/W[2] 41 print('k=',k) 42 print('d=',d) 43 44 xdata = (0,5) 45 if i % 10 == 0: 46 plt.figure() 47 plt.plot(xdata,xdata*k+d,'r') 48 plt.scatter(x1,y1,c='b') 49 plt.scatter(x2,y2,c='y') 50 plt.show()
BP神經網絡
反向傳播(Back Propagation,簡稱BP)神經網絡解決了多層神經網絡的學習問題,廣泛應用於分類識別、圖像識別、壓縮、逼近以及回歸等領域,其結構如下所示。
另外介紹及格激活函數:sigmoid、tanh和softsign。神經網絡中的激活函數,其作用就是引入非線性。
Sigmoid:sigmoid的優點是輸出范圍有限,數據在傳遞的過程中不容易發散,求導很容易(y=sigmoid(x), y’=y(1-y))。缺點是飽和的時候梯度太小。其輸出范圍為(0, 1),所以可以用作輸出層,輸出表示概率。
公式:
Sigmoid:sigmoid的優點是輸出范圍有限,數據在傳遞的過程中不容易發散,求導很容易(y=sigmoid(x), y’=y(1-y))。缺點是飽和的時候梯度太小。其輸出范圍為(0, 1),所以可以用作輸出層,輸出表示概率。

公式:
tanh和softsign:

要注意的是對多層神經元先對最后一層權重更新,其結果再更新前一層的權重
bp神經網絡解決異或問題的程序如下
1 import numpy as np 2 3 # 輸入數據 4 X = np.array([[1, 0, 0], 5 [1, 0, 1], 6 [1, 1, 0], 7 [1, 1, 1]]) 8 # 標簽 9 Y = np.array([[0, 1, 1, 0]]) 10 # 權值初始化,取值范圍-1到1 11 V = np.random.random((3, 4)) * 2 - 1 12 W = np.random.random((4, 1)) * 2 - 1 13 print(V) 14 print(W) 15 # 學習率設置 16 lr = 0.11 17 def sigmoid(x): 18 return 1 / (1 + np.exp(-x)) 19 def dsigmoid(x): 20 return x * (1 - x)#激活函數的導數 21 def update(): 22 global X, Y, W, V, lr 23 24 L1 = sigmoid(np.dot(X, V)) # 隱藏層輸出(4,4) 25 L2 = sigmoid(np.dot(L1, W)) # 輸出層輸出(4,1) 26 27 L2_delta = (Y.T - L2) * dsigmoid(L2) 28 L1_delta = L2_delta.dot(W.T) * dsigmoid(L1) 29 30 W_C = lr * L1.T.dot(L2_delta) 31 V_C = lr * X.T.dot(L1_delta) 32 33 W = W + W_C 34 V = V + V_C 35 36 37 for i in range(20000): 38 update() # 更新權值 39 if i % 500 == 0: 40 L1 = sigmoid(np.dot(X, V)) # 隱藏層輸出(4,4) 41 L2 = sigmoid(np.dot(L1, W)) # 輸出層輸出(4,1) 42 print('Error:', np.mean(np.abs(Y.T - L2))) 43 44 L1 = sigmoid(np.dot(X, V)) # 隱藏層輸出(4,4) 45 L2 = sigmoid(np.dot(L1, W)) # 輸出層輸出(4,1) 46 print(L2) 47 48 49 def judge(x): 50 if x >= 0.5: 51 return 1 52 else: 53 return 0 54 55 56 for i in map(judge, L2): 57 print(i)