01 KNN手写数字识别

knn的本质:假设一张待检测的图片,与存在的样本进行比较,如果样本存在k个与待检测图样相类似,那么把当前k记录下,在这k中找到相似性最大的,假设样本10个,有8个描述的当前的数字是1,那么检测结果就是1。
也就是说在样本中找出最接近的图片,然后在最接近的图片中统计哪个出现的概率最高,把这个概率最高的作为检测结果。


安装时候出现的小插曲:

使用手写字识别的时候,因为tensorflow1.15之后的版本移除了'tensorflow.contrib'的模块,导致没法使用数据集,此时需要卸载了

pip uninstall tensorflow==1.15

安装1.13.1版本

pip install tensorflow==1.13.1

如果使用:pip install tensorflow默认安装的是最新版tensorflow,目前最新为2.0

导入数据的时候出现提示: 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,表示有一个数为1,其余为0,例如:0001000000
'MNIST_data',表示数据集的文件路径

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   #导入数据集

# load data 2 one_hot : 1 0000 1 fileName 
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)  #装载数据
tf.logging.set_verbosity(old_v)

再运行等待下载mnist数据集


代码如下:

import tensorflow as tf
import numpy as np
import random 
from tensorflow.examples.tutorials.mnist import input_data   #导入数据集
# load data 2 one_hot : 1 0000 1 fileName 
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)  #装载数据,数据中,有一个为1其余为0000,例如0001000000
# 属性设置
trainNum = 55000
testNum = 10000
trainSize = 500  #训练的时候使用500张照片
testSize = 5     #测试图片5张
k = 4           #样本有K张图与测试图片最接近
# data 分解 1 trainSize   2范围0-trainNum 3 replace=False 
#将数据分成4种类型:训练数据,训练标签,测试数据,测试标签
trainIndex = np.random.choice(trainNum,trainSize,replace=False) #生产一组随机数
testIndex = np.random.choice(testNum,testSize,replace=False) #范围在0-testNum之间,一共生产testSize个,不可重复
trainData = mnist.train.images[trainIndex]# 训练图片
trainLabel = mnist.train.labels[trainIndex]# 训练标签
testData = mnist.test.images[testIndex]# 测试图片(数据)
testLabel = mnist.test.labels[testIndex]# 测试标签
# 28*28 = 784
print('trainData.shape=',trainData.shape)#500*784 1 图片个数 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 

运行结果:

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.]表示代表数字6
第二列 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]代表数字1
一次类推

分别执行f1,f2,f3得到p1,p2,p3,输出结果:

import tensorflow as tf
import numpy as np
import random 
from tensorflow.examples.tutorials.mnist import input_data   #导入数据集
# load data 2 one_hot : 1 0000 1 fileName 
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)  #装载数据
# 属性设置
trainNum = 55000
testNum = 10000
trainSize = 500  #训练的时候使用500张照片
testSize = 5     #测试图片5张
k = 4           #样本有K张图与测试图片最接近
# data 分解 1 trainSize   2范围0-trainNum 3 replace=False 
#将数据分成4种类型:训练数据,训练标签,测试数据,测试标签
trainIndex = np.random.choice(trainNum,trainSize,replace=False) #生产一组随机数
testIndex = np.random.choice(testNum,testSize,replace=False) #范围在0-testNum之间,一共生产testSize个,不可重复
trainData = mnist.train.images[trainIndex]# 训练图片
trainLabel = mnist.train.labels[trainIndex]# 训练标签
testData = mnist.test.images[testIndex]# 测试图片(数据)
testLabel = mnist.test.labels[testIndex]# 测试标签
# 28*28 = 784
print('trainData.shape=',trainData.shape)#500*784 1 图片个数 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代表图片张数
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)
#以上为数据加载,以下为开始计算,计算训练图片与测试图片的距离之差
#knn distance 5*785.  5*1*784(转换为:5行*1列*784)
# 5张侧视图 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)# 在第二维度上完成数据取绝对值累加 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 旧瓶装新酒 :数字识别的不同
# 4.1 网络 4。2 每一级 4.3 先原理 后代码 
# 本质:knn test 样本 K个 max4 3个1 -》1

# 1 load Data  1.1 随机数 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 -》 数字 p9 测试图片-》数据
# 6 检测概率统计
import tensorflow as tf
import numpy as np
import random 
from tensorflow.examples.tutorials.mnist import input_data   #导入数据集
# load data 2 one_hot : 1 0000 1 fileName 
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)  #装载数据
# 属性设置
trainNum = 55000
testNum = 10000
trainSize = 500  #训练的时候使用500张照片
testSize = 5     #测试图片5张
k = 4           #样本有K张图与测试图片最接近
# data 分解 1 trainSize   2范围0-trainNum 3 replace=False 
#将数据分成4种类型:训练数据,训练标签,测试数据,测试标签
trainIndex = np.random.choice(trainNum,trainSize,replace=False) #生产一组随机数
testIndex = np.random.choice(testNum,testSize,replace=False) #范围在0-testNum之间,一共生产testSize个,不可重复
trainData = mnist.train.images[trainIndex]# 训练图片
trainLabel = mnist.train.labels[trainIndex]# 训练标签
testData = mnist.test.images[testIndex]# 测试图片(数据)
testLabel = mnist.test.labels[testIndex]# 测试标签
# 28*28 = 784
print('trainData.shape=',trainData.shape)#500*784 1 图片个数 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代表图片张数
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)
#以上为数据加载,以下为开始计算,计算训练图片与测试图片的距离之差
#knn distance 5*785.  5*1*784(转换为:5行*1列*784)
# 5张侧视图 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)# 在第二维度上完成数据取绝对值累加 784 abs,
# 5*500

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

#得到了上面的5张图片分别对应最接近的4张图片和距离之后,要求其数据进行解析
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张)分别对应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张图片对应的数进行累加,比如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,代表数字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] #测试预测的结果
p10[]= [0 4 7 8 7] #测试集原标签的内容,人眼区分的时候
ac= 40.0 #准确率只有百分之40

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • 【博客的主要内容主要是自己的学习笔记,并结合个人的理解,供各位在学习过程中参考,若有疑问,欢迎提出;若有侵权,请告...
    Paullu阅读 982评论 1 6
  • 最近在看机器学习实战这本书。刚开始看kNN算法,并写了些程序,分享下一些感悟和细节。 什么是kNN kNN中文又称...
    sixleaves阅读 1,480评论 0 5
  • KNN算法全称是K近邻算法 (K-nearst neighbors,KNN) KNN是一种基本的机器学习算法,所谓...
    白尔摩斯阅读 10,609评论 1 11
  • 1、k-近邻算法介绍 k近邻法(k-nearest neighbor, k-NN)的工作原理是:存在一个样本数据集...
    nobodyyang阅读 498评论 0 2
  • 一、knn简介 k临近算法采用测量不同特征值之间的距离来分类,在样本数据及中找出k个待分类数据最相似的样本,这k个...
    子无不语阅读 310评论 0 0