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ù)集的文件路徑

測試圖片,訓練圖片,測試標簽,訓練標簽
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