我们来用python写一个没有正则化的分类神经网络。
传统的分类方法有聚类,LR逻辑回归,传统SVM,LSSVM等。其中LR和svm都是二分类器,可以将多个LR或者svm组合起来,做成多分类器。
多分类神经网络使用softmax+cross entropy组成最终的多分类代价函数J。为什么要用这个代价函数,可能需要广义线性模型的知识。简单来说就是最大化分类函数的熵。
假设一共有M个分类,softmax+cross entropy代价函数本身不需要学习。在softmax+cross entropy代价函数之前的网络层是一个需要训练的输出通道为M的全连接层。
设分类项为K,J的表达式为:
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]]
分类正确。