【機器學習】動手寫一個全連接神經網絡(三):分類

我們來用python寫一個沒有正則化的分類神經網絡。
傳統的分類方法有聚類LR邏輯迴歸傳統SVMLSSVM等。其中LR和svm都是二分類器,可以將多個LR或者svm組合起來,做成多分類器。
多分類神經網絡使用softmax+cross entropy組成最終的多分類代價函數J。爲什麼要用這個代價函數,可能需要廣義線性模型的知識。簡單來說就是最大化分類函數的熵。
假設一共有M個分類,softmax+cross entropy代價函數本身不需要學習。在softmax+cross entropy代價函數之前的網絡層是一個需要訓練的輸出通道爲M的全連接層。
設分類項爲K,J的表達式爲:

J=k=1M[IK(yi)log(softmax(θk,x))]+λ2θ2IK=1 if yi=K,else IK=0softmax(θk,x)=eθTkxkeθTkx

將log拆開得到:
J=k=1MIK(yi)logeθTkx+k=1MIK(yi)logkeθTkx+λ2θ2=k=1MIK(yi)logeθTkx+logkeθTkx+λ2θ2

J對θ 求導得到
Jθk=k[IK(yi)eθTkxeθTkx]x+eθTkxxkeθTkx+λθ=k[IK(yi)]x+eθTkxxkeθTkx+λθ=x(eθTkxxkeθTkx1)+λθ

如果加入批處理batch,那麼梯度變爲:
Jθk=1Ni=1n[xi(eθTkxixkeθTkxi1)]+λθ

下面給出一個簡單的非batch二分類神經網絡代碼:
import numpy as np

X = np.linspace(-50,50,100)
y = np.mat(X>0)*1.0

def sigmoid(x):
    return 1.0/(1+np.exp(-x))

lr2 = 0.0000005
inputDim = 1
fc1Dim = 2
W1 = np.random.randn(fc1Dim, inputDim)
b1 = np.zeros((fc1Dim,1))

def forward(x):
    fc1=W1.dot(x)+b1
    sig1 = fc1
    softmax=np.exp(sig1)
    softmax=softmax/np.sum(softmax)
    return fc1,sig1,softmax

def backward(x,fc1,sig1,loss,W1,b1):
    dfc2up = loss#1xn->nx1
    dsigup = dfc2up
    dW1 = np.dot(dsigup,x.T)#nx1
    db1 = dsigup#nx1
    W1 -= lr2 * dW1
    b1 -= lr2 * db1
    return W1,b1

num = 1000
for i in xrange(0,num):
    for x in X:
        fc1,sig1,softmax = forward(x)
        #print fc1,sig1,fc2
        if x > 0:
            loss = softmax-np.mat([[0.0],[1.0]])
        else:
            loss = softmax-np.mat([[1.0],[0.0]])

        W1,b1=backward(x,fc1,sig1,loss,W1,b1)
    if i % (num/5) == 0:
            print 'class is', int(softmax.argmax()),'softmax:',softmax,'actual value is :', x >0

test = np.mat([10.0])
_,_,res = forward(test)
print res,res.argmax()," actually is : ", test[0]>0
test = np.mat([-10.0])
_,_,res = forward(test)
print res,res.argmax()," actually is : ", test[0]>0
test = np.mat([-60.0])
_,_,res = forward(test)
print res,res.argmax()," actually is : ", test[0]>0
test = np.mat([100.0])
_,_,res = forward(test)
print res,res.argmax()," actually is : ", test[0]>0

輸出爲
lass is 0 softmax: [[ 1.00000000e+00]
[ 4.47127940e-11]] actual value is : True
class is 0 softmax: [[ 0.54705728]
[ 0.45294272]] actual value is : True
class is 1 softmax: [[ 0.01308647]
[ 0.98691353]] actual value is : True
class is 1 softmax: [[ 0.00294751]
[ 0.99705249]] actual value is : True
class is 1 softmax: [[ 0.00108553]
[ 0.99891447]] actual value is : True
[[ 0.17952696]
[ 0.82047304]] 1 actually is : [[ True]]
[[ 0.82047849]
[ 0.17952151]] 0 actually is : [[False]]
[[ 9.99890279e-01]
[ 1.09720611e-04]] 0 actually is : [[False]]
[[ 2.51524968e-07]
[ 9.99999748e-01]] 1 actually is : [[ True]]
分類正確。

發佈了114 篇原創文章 · 獲贊 140 · 訪問量 42萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章