MNIST 逻辑回归sigmoid公式推导与numpy代码实现

分几步完成

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

 

 

 

 

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值