與非門的圖片如下
示意圖
詳細解釋:
1 定義變量的代碼,包括了輸入、權值、輸出等。其中激活函數采用的是sigmod函數
1 # -*- coding: utf-8 -*- 2 __author__ = 'Administrator' 3 4 import theano 5 import theano.tensor as T 6 import random 7 import numpy as np 8 from itertools import izip 9 10 11 #定義網絡結構 12 #定義輸入 13 x=T.vector() 14 #定義權值W1 15 w1=theano.shared(np.random.randn(2)) #生成一個1行2列的隨機數 16 w2=theano.shared(np.random.randn(2)) 17 b1=theano.shared(np.random.randn(1)) 18 b2=theano.shared(np.random.randn(1)) 19 z1=T.dot(w1,x)+b1 20 a1=1/(1+T.exp(-z1)) 21 z2=T.dot(w2,x)+b2 22 a2=1/(1+T.exp(-z2)) 23 24 w=theano.shared(np.random.randn(2)) 25 b=theano.shared(np.random.randn(1)) 26 z=T.dot(w,[a1,a2])+b 27 y=1/(1+T.exp(-z))
2 定義目標輸出和損失函數計算方式,我們采用的平方損失
1 y_hat = T.scalar()#正確輸出 2 cost = T.sum((y-y_hat)**2) #采用的是平方損失函數
另外也可以采用交叉熵損失函數
cost = - (y_hat*T.log(y)+(1-y_hat)*T.log(1-y)).sum() #采用交叉熵損失函數
3 誤差反向傳播求導,直接調用theano函數求解,方便快捷
1 #誤差反向傳播求導 2 dw,db,dw1,dw2,db1,db2= T.grad(cost,[w,b,w1,w2,b1,b2])
4 權值更新
1 #手動定義一個權值更新函數 2 def MyUpdate(paramters,gradients): 3 mu=0.1 #步長 4 paramters_updates= \ 5 [(p, p-mu*g) for p,g in izip(paramters,gradients)] 6 return paramters_updates 7 8 #綁定輸入、輸出與權值更新函數 9 g = theano.function( 10 inputs=[x,y_hat], 11 outputs=[y,cost], 12 updates=MyUpdate([w,b,w1,w2,b1,b2],[dw,db,dw1,dw2,db1,db2]) 13 )
5 開始訓練
1 for i in range(50000): 2 y1,c1=g([0,0],0) 3 y2,c2=g([0,1],1) 4 y3,c3=g([1,0],1) 5 y4,c4=g([1,1],0) 6 print c1+c2+c3+c4 7 print y1,y2,y3,y4
6 結果輸出:
0.000541548001074 [ 0.01069522] [ 0.98782012] [ 0.98784247] [ 0.01144574] 0.000541536246431 [ 0.01069511] [ 0.98782025] [ 0.9878426] [ 0.01144562]
可以看到,每一項都接近[0 1 1 0],網絡已經成功訓練了。
交叉熵的結果輸出
0.00187006124627
[ 0.00044582] [ 0.99958399] [ 0.99938235] [ 0.00039013]
相同參數下,很明顯交叉熵的結果更好!