機器學習實戰之0-9手寫字識別

嗯 覺得自己很棒棒哦 總之進步挺大的 哈哈哈哈
0-9的數字識別 屬於多分類問題 需要用到softmax分類的知識 具體講解請參考下面幾個博客:
1
2
3
4

首先有兩個數據集 訓練集和測試集,兩個數據集都有txt文件 如0_0.txt表示該txt文件屬於第0類 後面的0表示該類別下的一個訓練樣本 其實每一個txt文件都是一個樣本而且裏邊的32*32維(1024)的數字代表特徵,假設每一個類別都含有80個樣本(txt文件),那麼總共訓練集的特徵 800*1024

所以需要把每一個txt在文件讀取時都存成一個含有1024個特徵的列表 在把所有的txt文件存成一個大的矩陣 總共包括800個樣本 每一個樣本1024個特徵
對於每一個樣本也把其對應的label存成800*1的矩陣
這裏需要說明一下本次處理 把所有的數據都處理成矩陣了 便於後續進行運算,所以需要特別注意維數 以及矩陣的操作 關於numpy 數組 矩陣的相關知識可以參考其他博客
只要足夠細心,基礎紮實就可以。

數據集在這裏: 解壓一下放在指定路徑就可以
鏈接:https://pan.baidu.com/s/1NYYwz55eJPOOE48V6Majig 密碼:l6i0

接下來直接上代碼(python)

# -*- coding: utf-8 -*-
"""
Created on Thu Mar 29 13:59:05 2018

@author: xuanxuan
"""

#手寫數字識別 (自己寫的) 純粹練習所用
import numpy as np
import random

#首先導入數據
def getdata(filename0):  #filename0主要是一個參數 根據訓練集和測試集的路徑不一樣  傳入的參數也不一樣
    dataarr=[]
    labelarr=[]
    for i in range(10):
        for j in range(50):
            L1=[]
            L2=[]
            filename=filename0+str(i)+'_'+str(j)+'.txt'
            file=open(filename)
            for row in range(32):
                line=file.readline()
                linearr=line.strip('\n')
                for conlum in range(32):
                    L1.append(float(linearr[conlum]))  #把每一個txt文件都存到L1列表中其中每個元素都是string L裏共2014個 也就是一個txt文件共1024個值 對應data矩陣中一行表示一個樣本有1024個特徵
                    #append時一定要注意強制類型轉換float()或者int()一下 如果後面要進行矩陣的運算的話 最好這樣!!
            L2.append(i)  #把每一個txt文件的index作爲該行樣本的label
            dataarr.append(L1)
            labelarr.append(L2)
    #print(np.shape(dataarr),np.shape(labelarr))   #這裏的datalabel 500*1024,labelarr 500*1都是二維數組
    datamat,labelmat=np.mat(dataarr),np.mat(labelarr)
    #print(np.shape(datamat),np.shape(labelmat))  #變成了矩陣      
    return datamat,labelmat            


#由於datamat的一行datamat[1]仍然是一個矩陣 1*1024 和w 1024*10相乘後仍爲一個1*10的矩陣 需要構建softmax模型 返回概率最大值以及相應的索引作爲預測的類別
def softmax(matx): #matx是一個1*10的矩陣
    return np.exp(matx)/np.sum(np.exp(matx),axis=1)   #返回的是一個1*10的矩陣 ,矩陣中的每一個元素都被softmax函數處理過就是e指數/10個e值數和

#********************測試softmax()函數**************************
#x=np.mat([1,2,3])
#print(type(x))
#y=softmax(x)
#print(y)
#print(type(Y))  #[[ 0.09003057  0.24472847  0.66524096]]  仍然是一個矩陣 只不過矩陣打印出來之後沒有matrix顯示了



#接下來求一個1*10矩陣中元素最大的位置 返回該索引位置 和對應的概率值
def findmax(matx):  #matx是一個1*10的矩陣 只不過這裏的matx被softmax處理過了 歸一化之後表示概率值
    maxvalue=matx[0,0]  #將maxvalue 初始化爲1*10矩陣的第一個元素
    maxposition=0  #認爲是矩陣datamat的某一行datamat[randindex] 1*1024和w 1024*10乘完之後得到的1*10矩陣 最大的爲該樣本與w0相乘的  也就應該判爲0類
    for i in range(1,10): #跟其餘的9個數進行比較
        if maxvalue<matx[0,i]:
            maxvalue=matx[0,i]
            maxposition=i
    return maxvalue,maxposition

#*******************測試finmax()函數**************************
#x=np.mat([0.09003057,0.24472847,0.66524096])   #就是上一步得出的softmax的結果 對應概率值  注意上一步的range(10)這裏相應改爲3纔可以運行  因爲這裏只有3列
#y1,y2=findmax(x)  #y1表示 概率最大的值,y2表示該最大值對應的索引
#print(y1,y2)


def accuracy():
    pass




def gradent(traindatamat,trainlabelmat,iternum=150):   #triandatamat 500*1024的矩陣 trainlabelmat500*1的矩陣
    m,n=np.shape(traindatamat)
    #print(m,n)  #traindatamat 是500*1024的矩陣
    w=np.mat(np.ones((n,10)))  #w是1024*10的矩陣  因爲一共有10個類別  想要創建矩陣一定要np.mat()! 否則np.ones()是一個array數類型!
    alpha=0.05
    for i in range(iternum): 
        for j in range(m):
            p,pos=findmax(softmax(traindatamat[j]*w))  #表示對該行樣本預測爲pos類的概率
            #print(p,pos,softmax(traindatamat[j]*w))
            if trainlabelmat[j,0]==pos:

                w[:,pos]=w[:,pos]-alpha*(-(1-p)*traindatamat[j].T)  #w[:,pos]是一個1024*1的矩陣 traindatamat[randindex].T也是一個1024*1的矩陣

            else:
                w[:,pos]=w[:,pos]-alpha*(-(0-p)*traindatamat[j].T)

    #print(w)
    return w

#對測試數據集測試準確率:
def accuracy(testdatamat,testlabelmat):
    num=0
    m,n=np.shape(testdatamat)
    #print(m,n)    #測試數據集的準確率
    for i in range(m):
        p,pos,=findmax(softmax(testdatamat[i]*w))

        if pos==testlabelmat[i,0]:
            num+=1
    accu=num/m
    return accu




if __name__=="__main__":
    filename0="E://pyhtonworkspace//py3-pratice//bymyself_practice//python_mechinelearning_homework//04//softmax_multi_datasets//testDigits//"
    filename1="E://pyhtonworkspace//py3-pratice//bymyself_practice//python_mechinelearning_homework//04//softmax_multi_datasets//trainingDigits//"
    traindatamat,trainlabelmat=getdata(filename0)
    testdatamat,testlabelmat=getdata(filename1)
    w=gradent(traindatamat,trainlabelmat,200)
    accu=accuracy(testdatamat,testlabelmat)
    print(w)
    print('\n'+"您預測的準確率可以達到{}".format(accu))

以上。
歡迎交流~~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章