机器学习实战之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))

以上。
欢迎交流~~~

猜你喜欢

转载自blog.csdn.net/jiaowosiye/article/details/79766807
今日推荐