01 KNN手寫數(shù)字識別

knn的本質(zhì):假設(shè)一張待檢測的圖片,與存在的樣本進行比較,如果樣本存在k個與待檢測圖樣相類似,那么把當前k記錄下,在這k中找到相似性最大的,假設(shè)樣本10個,有8個描述的當前的數(shù)字是1,那么檢測結(jié)果就是1。
也就是說在樣本中找出最接近的圖片,然后在最接近的圖片中統(tǒng)計哪個出現(xiàn)的概率最高,把這個概率最高的作為檢測結(jié)果。


安裝時候出現(xiàn)的小插曲:

使用手寫字識別的時候,因為tensorflow1.15之后的版本移除了'tensorflow.contrib'的模塊,導(dǎo)致沒法使用數(shù)據(jù)集,此時需要卸載了

pip uninstall tensorflow==1.15

安裝1.13.1版本

pip install tensorflow==1.13.1

如果使用:pip install tensorflow默認安裝的是最新版tensorflow,目前最新為2.0

導(dǎo)入數(shù)據(jù)的時候出現(xiàn)提示: Instructions for updating: Please use urllib or similar directly.

from tensorflow.examples.tutorials.mnist import input_data之前,加入

old_v = tf.logging.get_verbosity()
tf.logging.set_verbosity(tf.logging.ERROR)

mnist = input_data.read_data_sets('./data/mnist', one_hot=True)之后,加入

tf.logging.set_verbosity(old_v)

如下

mnist = input_data.read_data_sets('MNIST_data',one_hot=True)
one_hot,表示有一個數(shù)為1,其余為0,例如:0001000000
'MNIST_data',表示數(shù)據(jù)集的文件路徑

image.png

測試圖片,訓練圖片,測試標簽,訓練標簽

import tensorflow as tf
import numpy as np
import random 
old_v = tf.logging.get_verbosity()
tf.logging.set_verbosity(tf.logging.ERROR)
from tensorflow.examples.tutorials.mnist import input_data   #導(dǎo)入數(shù)據(jù)集

# load data 2 one_hot : 1 0000 1 fileName 
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)  #裝載數(shù)據(jù)
tf.logging.set_verbosity(old_v)

再運行等待下載mnist數(shù)據(jù)集


代碼如下:

import tensorflow as tf
import numpy as np
import random 
from tensorflow.examples.tutorials.mnist import input_data   #導(dǎo)入數(shù)據(jù)集
# load data 2 one_hot : 1 0000 1 fileName 
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)  #裝載數(shù)據(jù),數(shù)據(jù)中,有一個為1其余為0000,例如0001000000
# 屬性設(shè)置
trainNum = 55000
testNum = 10000
trainSize = 500  #訓練的時候使用500張照片
testSize = 5     #測試圖片5張
k = 4           #樣本有K張圖與測試圖片最接近
# data 分解 1 trainSize   2范圍0-trainNum 3 replace=False 
#將數(shù)據(jù)分成4種類型:訓練數(shù)據(jù),訓練標簽,測試數(shù)據(jù),測試標簽
trainIndex = np.random.choice(trainNum,trainSize,replace=False) #生產(chǎn)一組隨機數(shù)
testIndex = np.random.choice(testNum,testSize,replace=False) #范圍在0-testNum之間,一共生產(chǎn)testSize個,不可重復(fù)
trainData = mnist.train.images[trainIndex]# 訓練圖片
trainLabel = mnist.train.labels[trainIndex]# 訓練標簽
testData = mnist.test.images[testIndex]# 測試圖片(數(shù)據(jù))
testLabel = mnist.test.labels[testIndex]# 測試標簽
# 28*28 = 784
print('trainData.shape=',trainData.shape)#500*784 1 圖片個數(shù) 2 784?
print('trainLabel.shape=',trainLabel.shape)#500*10
print('testData.shape=',testData.shape)#5*784
print('testLabel.shape=',testLabel.shape)#5*10
print('testLabel=',testLabel)# 4 :testData [0]  3:testData[1] 6 

運行結(jié)果:

trainData.shape= (500, 784)
trainLabel.shape= (500, 10)
testData.shape= (5, 784)
testLabel.shape= (5, 10)
testLabel= [[0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]]
[Finished in 8.3s]

在testLabel中,第一列[0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]表示代表數(shù)字6
第二列 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]代表數(shù)字1
一次類推

分別執(zhí)行f1,f2,f3得到p1,p2,p3,輸出結(jié)果:

import tensorflow as tf
import numpy as np
import random 
from tensorflow.examples.tutorials.mnist import input_data   #導(dǎo)入數(shù)據(jù)集
# load data 2 one_hot : 1 0000 1 fileName 
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)  #裝載數(shù)據(jù)
# 屬性設(shè)置
trainNum = 55000
testNum = 10000
trainSize = 500  #訓練的時候使用500張照片
testSize = 5     #測試圖片5張
k = 4           #樣本有K張圖與測試圖片最接近
# data 分解 1 trainSize   2范圍0-trainNum 3 replace=False 
#將數(shù)據(jù)分成4種類型:訓練數(shù)據(jù),訓練標簽,測試數(shù)據(jù),測試標簽
trainIndex = np.random.choice(trainNum,trainSize,replace=False) #生產(chǎn)一組隨機數(shù)
testIndex = np.random.choice(testNum,testSize,replace=False) #范圍在0-testNum之間,一共生產(chǎn)testSize個,不可重復(fù)
trainData = mnist.train.images[trainIndex]# 訓練圖片
trainLabel = mnist.train.labels[trainIndex]# 訓練標簽
testData = mnist.test.images[testIndex]# 測試圖片(數(shù)據(jù))
testLabel = mnist.test.labels[testIndex]# 測試標簽
# 28*28 = 784
print('trainData.shape=',trainData.shape)#500*784 1 圖片個數(shù) 2 784?
print('trainLabel.shape=',trainLabel.shape)#500*10
print('testData.shape=',testData.shape)#5*784
print('testLabel.shape=',testLabel.shape)#5*10
print('testLabel=',testLabel)# 4 :testData [0]  3:testData[1] 6 

# tf input  (500*784) 784->image,每個784代表一張完整圖片,500代表圖片張數(shù)
trainDataInput = tf.placeholder(shape=[None,784],dtype=tf.float32)
trainLabelInput = tf.placeholder(shape=[None,10],dtype=tf.float32)
testDataInput = tf.placeholder(shape=[None,784],dtype=tf.float32)
testLabelInput = tf.placeholder(shape=[None,10],dtype=tf.float32)
#以上為數(shù)據(jù)加載,以下為開始計算,計算訓練圖片與測試圖片的距離之差
#knn distance 5*785.  5*1*784(轉(zhuǎn)換為:5行*1列*784)
# 5張側(cè)視圖 500張訓練圖 每張784維 (3D) 2500*784  這里是三維的,所以要把下面拓展到三維
f1 = tf.expand_dims(testDataInput,1) # 維度擴展到三維
f2 = tf.subtract(trainDataInput,f1)# 784 sum(784) (訓練圖片與測試圖片只差)
f3 = tf.reduce_sum(tf.abs(f2),reduction_indices=2)# 在第二維度上完成數(shù)據(jù)取絕對值累加 784 abs,
# 5*500

with tf.Session() as sess:
    # f1 <- testData 5張圖片
    p1 = sess.run(f1,feed_dict={testDataInput:testData[0:5]})
    print('p1=',p1.shape)# p1= (5, 1, 784)
    p2 = sess.run(f2,feed_dict={trainDataInput:trainData,testDataInput:testData[0:5]})
    print('p2=',p2.shape)#p2= (5, 500, 784) (1,100)  
    p3 = sess.run(f3,feed_dict={trainDataInput:trainData,testDataInput:testData[0:5]})
    print('p3=',p3.shape)#p3= (5, 500)
    print('p3[0,0]=',p3[0,0]) #130.451 knn distance p3[0,0]= 155.812

p1= (5, 1, 784)
p2= (5, 500, 784)
p3= (5, 500)
p3[0,0]= 111.24315 #距離差值

在500張照片中,找到4張與測試圖片最接近的圖片

# 1 重要
# 2 KNN CNN 2種
# 3 樣本 
# 4 舊瓶裝新酒 :數(shù)字識別的不同
# 4.1 網(wǎng)絡(luò) 4。2 每一級 4.3 先原理 后代碼 
# 本質(zhì):knn test 樣本 K個 max4 3個1 -》1

# 1 load Data  1.1 隨機數(shù) 1.2 4組 訓練 測試 (圖片 和 標簽)
# 2 knn test train distance 5*500 = 2500 784=28*28
# 3 knn k個最近的圖片5 500 1-》500train (4)
# 4 k個最近的圖片-> parse centent label
# 5 label -》 數(shù)字 p9 測試圖片-》數(shù)據(jù)
# 6 檢測概率統(tǒng)計
import tensorflow as tf
import numpy as np
import random 
from tensorflow.examples.tutorials.mnist import input_data   #導(dǎo)入數(shù)據(jù)集
# load data 2 one_hot : 1 0000 1 fileName 
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)  #裝載數(shù)據(jù)
# 屬性設(shè)置
trainNum = 55000
testNum = 10000
trainSize = 500  #訓練的時候使用500張照片
testSize = 5     #測試圖片5張
k = 4           #樣本有K張圖與測試圖片最接近
# data 分解 1 trainSize   2范圍0-trainNum 3 replace=False 
#將數(shù)據(jù)分成4種類型:訓練數(shù)據(jù),訓練標簽,測試數(shù)據(jù),測試標簽
trainIndex = np.random.choice(trainNum,trainSize,replace=False) #生產(chǎn)一組隨機數(shù)
testIndex = np.random.choice(testNum,testSize,replace=False) #范圍在0-testNum之間,一共生產(chǎn)testSize個,不可重復(fù)
trainData = mnist.train.images[trainIndex]# 訓練圖片
trainLabel = mnist.train.labels[trainIndex]# 訓練標簽
testData = mnist.test.images[testIndex]# 測試圖片(數(shù)據(jù))
testLabel = mnist.test.labels[testIndex]# 測試標簽
# 28*28 = 784
print('trainData.shape=',trainData.shape)#500*784 1 圖片個數(shù) 2 784?
print('trainLabel.shape=',trainLabel.shape)#500*10
print('testData.shape=',testData.shape)#5*784
print('testLabel.shape=',testLabel.shape)#5*10
print('testLabel=',testLabel)# 4 :testData [0]  3:testData[1] 6 

# tf input  (500*784) 784->image,每個784代表一張完整圖片,500代表圖片張數(shù)
trainDataInput = tf.placeholder(shape=[None,784],dtype=tf.float32)
trainLabelInput = tf.placeholder(shape=[None,10],dtype=tf.float32)
testDataInput = tf.placeholder(shape=[None,784],dtype=tf.float32)
testLabelInput = tf.placeholder(shape=[None,10],dtype=tf.float32)
#以上為數(shù)據(jù)加載,以下為開始計算,計算訓練圖片與測試圖片的距離之差
#knn distance 5*785.  5*1*784(轉(zhuǎn)換為:5行*1列*784)
# 5張側(cè)視圖 500張訓練圖 每張784維 (3D) 2500*784  這里是三維的,所以要把下面拓展到三維
f1 = tf.expand_dims(testDataInput,1) # 維度擴展到三維
f2 = tf.subtract(trainDataInput,f1)# 784 sum(784) (訓練圖片與測試圖片只差)
f3 = tf.reduce_sum(tf.abs(f2),reduction_indices=2)# 在第二維度上完成數(shù)據(jù)取絕對值累加 784 abs,
# 5*500

f4 = tf.negative(f3)# 取反
f5,f6 = tf.nn.top_k(f4,k=4) # 選取f4 最大的四個值
# f3 最小的四個值
# f6 index->trainLabelInput

#得到了上面的5張圖片分別對應(yīng)最接近的4張圖片和距離之后,要求其數(shù)據(jù)進行解析
f7 = tf.gather(trainLabelInput,f6)
# f8 num reduce_sum  reduction_indices=1 '豎直'
f8 = tf.reduce_sum(f7,reduction_indices=1)
# tf.argmax 選取在某一個最大的值 index
f9 = tf.argmax(f8,dimension=1)
# f9 -> test5 image -> 5 num
with tf.Session() as sess:
    # f1 <- testData 5張圖片
    p1 = sess.run(f1,feed_dict={testDataInput:testData[0:5]})
    print('p1=',p1.shape)# p1= (5, 1, 784)
    p2 = sess.run(f2,feed_dict={trainDataInput:trainData,testDataInput:testData[0:5]})
    print('p2=',p2.shape)#p2= (5, 500, 784) (1,100)  
    p3 = sess.run(f3,feed_dict={trainDataInput:trainData,testDataInput:testData[0:5]})
    print('p3=',p3.shape)#p3= (5, 500)
    print('p3[0,0]=',p3[0,0]) #130.451 knn distance p3[0,0]= 155.812
    
    p4 = sess.run(f4,feed_dict={trainDataInput:trainData,testDataInput:testData[0:5]})
    print('p4=',p4.shape)
    print('p4[0,0]',p4[0,0])
    
    p5,p6 = sess.run((f5,f6),feed_dict={trainDataInput:trainData,testDataInput:testData[0:5]})
    #p5= (5, 4) 每一張測試圖片(5張)分別對應(yīng)4張最近訓練圖片
    #p6= (5, 4)
    print('p5=',p5.shape)
    print('p6=',p6.shape)
    print('p5[0,0]',p5[0])
    print('p6[0,0]',p6[0])# p6 index
    
    p7 = sess.run(f7,feed_dict={trainDataInput:trainData,testDataInput:testData[0:5],trainLabelInput:trainLabel})
    print('p7=',p7.shape)#p7= (5, 4, 10)  #解析出來可以看到在9個0和1個1中,1所在的位置
    print('p7[]',p7)   #0010000000 
    
    p8 = sess.run(f8,feed_dict={trainDataInput:trainData,testDataInput:testData[0:5],trainLabelInput:trainLabel})
    print('p8=',p8.shape) 
    print('p8[]=',p8)  #在豎直方向上對4張圖片對應(yīng)的數(shù)進行累加,比如0010003000
    
    p9 = sess.run(f9,feed_dict={trainDataInput:trainData,testDataInput:testData[0:5],trainLabelInput:trainLabel})
    print('p9=',p9.shape)
    print('p9[]=',p9) #在上面p8中找到最大的值,并記錄其下標到p9上,比如0010003000,最大是3,其下標是6,代表數(shù)字6
    
    p10 = np.argmax(testLabel[0:5],axis=1)
    print('p10[]=',p10)
j = 0
for i in range(0,5):
    if p10[i] == p9[i]:
        j = j+1
print('ac=',j*100/5)

p4= (5, 500)
p4[0,0] -175.36469
p5= (5, 4)
p6= (5, 4)
p5[0,0] [-59.2235 -68.50982 -72.57253 -73.87845]
p6[0,0] [ 54 81 187 31]
p7= (5, 4, 10)
p7[] [[[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]]

[[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]]

[[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]]

[[0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]]

[[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
[0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]]]
p8= (5, 10)
p8[]= [[3. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 3. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 4. 0. 0.]
[0. 0. 0. 2. 0. 0. 0. 0. 2. 0.]
[0. 0. 1. 0. 2. 0. 0. 1. 0. 0.]]
p9= (5,)
p9[]= [0 6 7 3 4] #測試預(yù)測的結(jié)果
p10[]= [0 4 7 8 7] #測試集原標簽的內(nèi)容,人眼區(qū)分的時候
ac= 40.0 #準確率只有百分之40

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 【博客的主要內(nèi)容主要是自己的學習筆記,并結(jié)合個人的理解,供各位在學習過程中參考,若有疑問,歡迎提出;若有侵權(quán),請告...
    Paullu閱讀 1,057評論 1 6
  • 最近在看機器學習實戰(zhàn)這本書。剛開始看kNN算法,并寫了些程序,分享下一些感悟和細節(jié)。 什么是kNN kNN中文又稱...
    sixleaves閱讀 1,537評論 0 5
  • KNN算法全稱是K近鄰算法 (K-nearst neighbors,KNN) KNN是一種基本的機器學習算法,所謂...
    白爾摩斯閱讀 11,128評論 1 11
  • 1、k-近鄰算法介紹 k近鄰法(k-nearest neighbor, k-NN)的工作原理是:存在一個樣本數(shù)據(jù)集...
    nobodyyang閱讀 578評論 0 1
  • 一、knn簡介 k臨近算法采用測量不同特征值之間的距離來分類,在樣本數(shù)據(jù)及中找出k個待分類數(shù)據(jù)最相似的樣本,這k個...
    子無不語閱讀 342評論 0 0

友情鏈接更多精彩內(nèi)容