• One layer SoftMax Classifier, "Handwriting recognition"


     

    import lib needed

    In [1]:
    from PIL import Image
    import numpy as np
    import matplotlib.pyplot as plt
    import re
    from glob import glob
    
     

    begin, load data

    In [2]:
    def load_data(train_path='train/',test_path='test/'):
        train_list=glob(r'train/*.png')
        pattern = re.compile(r'num(d).png')
        train_id = np.array([float(pattern.search(img_name).groups()[0]) for img_name in train_list])
        train_data=np.concatenate([np.array(Image.open(img_name)).reshape(1,784) for img_name in train_list],axis=0).astype(np.float)
        test_list=glob(r'test/*.png')
        test_id=np.array([float(pattern.search(img_name).groups()[0]) for img_name in test_list])
        test_data=np.concatenate([np.array(Image.open(img_name)).reshape(1,784) for img_name in test_list],axis=0).astype(np.float)
        return train_id,train_data,test_id,test_data
    
     

    load data, print the shape of data

    In [3]:
    train_id,train_data,test_id,test_data=load_data()
    train_id.shape,train_data.shape,test_id.shape,test_data.shape
    
    Out[3]:
    ((60000,), (60000, 784), (10000,), (10000, 784))
     

    convert the shape of id/label

    e.g. data_id "3" can be converted to [0,0,0,1,0,0,0,0,0,0]

    In [5]:
    train_val=np.zeros((train_id.shape[0],10))
    for i in range(train_id.shape[0]):
        train_val[i,train_id[i].astype('int')]=1
    
     

    split data into minibatches

    In [6]:
    mini_batch_num=100
    mini_batch_size=600
    
     

    define function need, such as softmax, propagation,back_propagation

    In [7]:
    def softmax(x):
        x=x-np.max(x) #using softmax(x)=softmax(x+c)
        exp_x=np.exp(x)
        softmax_x=exp_x/sum(np.exp(x))
        return softmax_x
    
     if you want to know more about softmax, https://segmentfault.com/a/1190000010039529?utm_source=tag-newest  is recommended to you

    use cross entrophy to compute loss, this is part of propagation

    In [8]:
    def propa(train_x,train_y,W,b): #propagation
        yt=softmax(np.dot(train_x,W)+b)
        loss=-np.sum(train_y.T.dot(np.log(yt))) #cross entrophy
        dy=(yt-train_y).T
        return dy,loss
    
     if you wan to know more about softmax's cross entrophy, https://blog.csdn.net/lilong117194/article/details/81542667  is recommended to you

    update W

    In [9]:
    def back_propa(train_data,train_id,W,b,alpha,data_size):
        for i in range(data_size):
            dy,loss=propa(train_data[i,:],train_id[i,:],W,b)
            dy=dy.reshape(1,10)
            p=train_data[i,:]
            p=p.reshape(784,1)
            dW=alpha*np.dot(p,dy)
            W-=dW
        return W,loss
    
     

    initialize W and b

    In [14]:
    W=np.zeros((784,10))
    b=1
    
     

    loop and update, also print accurancy of our traindataset

    In [16]:
    for i in range(mini_batch_num):
        for iteration in range(20):
            lb=(mini_batch_size*i)
            ub=(mini_batch_size*(i+1))
            mini_batch_data=train_data[lb:ub,:]
            mini_batch_id=train_val[lb:ub,:]
            W,loss=back_propa(mini_batch_data,mini_batch_id,W,b,0.01,600)
            count=0
            for j in range(600):
                if np.argmax(softmax(train_data[j,:].dot(W)))==train_id[j].astype('int'):
                    count+=1
            acc=count/600
        if i%10==0:
            print('batch={},acc={}'.format(i+1,acc))
    
     
    e:Anaconda3libsite-packagesipykernel_launcher.py:3: RuntimeWarning: divide by zero encountered in log
      This is separate from the ipykernel package so we can avoid doing imports until
    
     
    batch=1,acc=1.0
    batch=11,acc=0.8833333333333333
    batch=21,acc=0.865
    batch=31,acc=0.8983333333333333
    batch=41,acc=0.8766666666666667
    batch=51,acc=0.8883333333333333
    batch=61,acc=0.8733333333333333
    batch=71,acc=0.845
    batch=81,acc=0.89
    batch=91,acc=0.8766666666666667
    
     

    predict in the test dataset

    In [17]:
    for j in range(test_id.shape[0]):
        if np.argmax(softmax(test_data[j,:].dot(W)))==test_id[j].astype('int'):
            count+=1
    acc=count/test_id.shape[0]
    print(acc)
    
     
    0.9103
    
  • 相关阅读:
    20165101刘天野 2017-2018-2 《Java程序设计》 结对编程练习_四则运算(第一周)
    20165101刘天野 2017-2018-2 《Java程序设计》第6周学习总结
    20165101 实验一 Java开发环境的熟悉
    20165101刘天野 2017-2018-2 《Java程序设计》第5周学习总结
    HTML——meta
    CSS——改变浏览器滚动条样式
    HTML5——移动端的点击、拖拽
    JS高级——弹出框的美化
    JS高级——监听浏览器的返回事件
    JS高级——文件操作
  • 原文地址:https://www.cnblogs.com/runsdeep/p/11631020.html
Copyright © 2020-2023  润新知