分几步完成
1. 将伯努利分布化为指数族分布的一般形式
2. 利用广义线性模型建模(sigmoid函数)
3. 推导评估模型的似然函数
4. 推导损失函数
5. 代码实现
6. 查看运行结果
-----------------------------------------------
1. 将伯努利分布化为指数族分布的一般形式
2. 利用广义线性模型建模(sigmoid函数)
3. 推导评估模型的似然函数
4. 推导损失函数: 由于取得极大似然函数的时候,损失最小,所以直接用似然函数的负数作为损失函数
sigmoid公式快速推导
5. 代码实现
import numpy as np
import scipy.special as spc
#加载数据集档案
def loaddata(filename):
fp=open(filename,'r')
dataset=[]
labelset=[]
for i in fp.readlines():
a=i.strip().split(',')
# 由于sigmoid函数在-6到6之间较为敏感,对数据0-255进行压缩到0.01-1之间
labelset.append(int(a[0]))
dataset.append([(int(j) / 255.0 * 0.99 + 0.01) for j in a[1:]])
return np.array(dataset),np.array(labelset)
def amend_label_one_hat(labelset):
# 即tensorflow的 y = tf.one_hot(y, depth=10)
new_labelset=[]
for label in labelset:
new_label=[0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01]
new_label[label]=0.99
new_labelset.append(new_label)
return new_labelset
def initialize_param():
w=np.random.normal(1,0.005,(784,10))
b=np.random.normal(1,0.005,(1,10))
return w,b
def sigmoid(betaX):
return spc.expit(betaX)
def train(dataset,labelset,w,b):
for i in range(len(dataset)):
# print(i)
#计算结果
x=np.mat(dataset[i]) #(1, 784)
betaX=np.dot(x, w)+b #(1, 10)
hx=sigmoid(betaX) #(1, 10)
#梯度下降
outputset = np.mat(labelset[i]) #
diff=outputset-hx #(1, 10)
dLdw=-np.dot(np.transpose(x),diff) #(784, 1)(1, 10)=(784, 10)
dLdb=-diff #(1, 10)
learningRate = 0.001
#前半部的数据learning rate加大
if(i<len(dataset)/2):
learningRate=learningRate*10
w=w-learningRate*dLdw
b=b-learningRate*dLdb
return w,b
def resulttest(test_dataset,test_labelset,w,b):
test_dataset=np.mat(test_dataset)
rightcount=0
for i in range(len(test_dataset)):
x = np.mat(test_dataset[i]) # (1, 784)
betaX = np.dot(x, w) + b # (1, 10)
hx = sigmoid(betaX) # (1, 10)
result=int(np.argmax(hx))
y=int(test_labelset[i])
if(y==result):
rightcount+=1
return rightcount/len(test_dataset)
if __name__ == '__main__':
# 加载数据集
dataset,labelset=loaddata('mnist_train.csv')
# dataset,labelset=loaddata('mnist_train_100.csv') #加载较小的数据集档案
# one-hat调整
labelset_new=amend_label_one_hat(labelset)
# 初始化参数 w b
w,b=initialize_param()
#训练前测试
test_dataset,test_labelset=loaddata('mnist_test.csv')
result1=resulttest(test_dataset,test_labelset,w,b)
print("训练前正确率为 %f" %(result1))
#开始训练
print('开始训练')
w,b= train(dataset,labelset_new,w,b)
print('训练完成')
#训练后测试
result2 =resulttest(test_dataset,test_labelset,w,b)
print("训练后正确率为 %f" %(result2))
6. 查看运行结果
训练前正确率为 0.098400
开始训练
训练完成
训练后正确率为 0.904600