XOR Gate 網路結構

引用相關的 Library


In [1]:
import theano 
import theano.tensor as T
import numpy as np
import numpy

In [2]:
x = T.vector()
w1 = theano.shared(np.random.randn(2))
b1 = theano.shared(np.random.randn(1))

w2 = theano.shared(np.random.randn(2))
b2 = theano.shared(np.random.randn(1))

w = theano.shared(np.random.randn(2))
b = theano.shared(np.random.randn(1))

z1 = T.dot(w1,x) + b1
a1 = 1/(1+T.exp(-1*z1))

z2 = T.dot(w2,x) + b2
a2 = 1/(1+T.exp(-1*z2))


z = T.dot(w,[a1,a2]) + b
a = 1/(1+T.exp(-1*z))

In [3]:
# define xor's output function
fa = theano.function(inputs=[x] ,outputs=a)

In [4]:
fa([1,1])


Out[4]:
array([ 0.36364409])

In [5]:
# 期望的 output 值
y_hat = T.scalar()

cross entropy 且記得使用 T.sum() 將值變成 scalar


In [6]:
cost = -1*(y_hat*T.log(a)+(1-y_hat)*T.log(1-a)).sum()

In [7]:
fcost = theano.function(inputs=[x,y_hat],outputs=cost )

In [8]:
fcost([1,1],0)


Out[8]:
array(0.4519972715005039)

使用 Theano 內建的 T.grad 來對每一個變數求得偏微分後的值


In [9]:
dw1,db1,dw2,db2,dw,db = T.grad(cost,[w1,b1,w2,b2,w,b]  )

由於 Theano 沒有很好 update 變數的程式寫法,故通常會再自行定義 update function


In [10]:
from itertools import izip
def Myupdates(ps,gs):
    r = 0.1
    pu = [ (p,p-r*g) for p,g in izip(ps,gs)   ]
    return pu
print Myupdates([w,],[dw,]   )


[(<TensorType(float64, vector)>, Elemwise{sub,no_inplace}.0)]

In [11]:
g = theano.function(inputs=[x,y_hat],outputs=[cost,a]  ,  updates=Myupdates([w,b,w1,b1,w2,b2],[dw,db,dw1,db1,dw2,db2]   ) )

開始進行 Training

  • 由於 XOR 只有4種不同組合的 input 及兩種 output,故 training set 如下

In [12]:
for i in range(100000):


    g([0,1],1)
    g([1,0],1)
    g([0,0],0)
    g([1,1],0)

最後來看一下學習完的結果


In [13]:
print    g([0,1],1)
print    g([1,0],1)
print    g([0,0],0)
print    g([1,1],0)


[array(0.00020638787401764517), array([ 0.99979363])]
[array(0.00020646812521735717), array([ 0.99979355])]
[array(0.000269387797377268), array([ 0.00026935])]
[array(0.00024128309929592184), array([ 0.00024125])]

In [ ]: