深度学习图像处理案例

# 1 重要
# 2 KNN CNN 2种
# 3 样本 
# 4 旧瓶装新酒 :数字识别的不同
# 4.1 网络 4。2 每一级 4.3 先原理 后代码 
# 本质:knn test 样本 K个 max4 3个1 -》1

样本准备

  • t10k,表示是用于测试集图片,10k表示有10000张

  • 标签存储时,存储的10维,第一列,第五行为黑色,这一行值为1,描述的是4

一、 KNN数字识别

  • 本质:如果一个样本有K个是很相似的,就把这个K个记录下来,并找到其中最有可能出现的,作为结果

  • TestLabel:是一个五行十列的数据,第一个下标:表示4,第二组:3;第三组:6

相关语法

  • shape=[None, 784]

    Here we assign it a shape of [None, 784], where 784 is the dimensionality of a single flattened 28 by 28 pixel MNIST image, and None indicates that the first dimension, corresponding to the batch size, can be of any size.

  • tf.expand_dims(testDataInput,1)

    # 't' is a tensor of shape [2]
    shape(expand_dims(t, 0)) ==> [1, 2]
    shape(expand_dims(t, 1)) ==> [2, 1]
    shape(expand_dims(t, -1)) ==> [2, 1]
      
    # 't2' is a tensor of shape [2, 3, 5]
    shape(expand_dims(t2, 0)) ==> [1, 2, 3, 5]
    shape(expand_dims(t2, 2)) ==> [2, 3, 1, 5]
    shape(expand_dims(t2, 3)) ==> [2, 3, 5, 1]
    
# 1 重要
# 2 KNN CNN 2种
# 3 样本 
# 4 旧瓶装新酒 :数字识别的不同
# 4.1 网络 4。2 每一级 4.3 先原理 后代码 
# 本质:knn test 样本 K个 max4 3个1 -》1

# step1 load Data  1.1 随机数 1.2 4组 训练 测试 (图片 和 标签)
# step2 knn test train distance 5*500 = 2500一共有2500个距离,可能情况 784=28*28
# step3 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 ; one_hot,有一个内容为1 ,其他都为0
# one_hot:一个为1,其他为0
# 全部装载进mnist
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)
# 属性设置
trainNum = 55000
testNum = 10000#一万张
trainSize = 500#训练时图片
testSize = 5
k = 4 # 四种情况,找到四个最为接近的图片
# data 分解 1 生成trainSize个随机数  ; 2范围0-trainNum; 3 replace=False 是否可以重复:不可重复
trainIndex = np.random.choice(trainNum,trainSize,replace=False)
testIndex = np.random.choice(testNum,testSize,replace=False)
# 上两步,下标生成
trainData = mnist.train.images[trainIndex]# 训练图片
trainLabel = mnist.train.labels[trainIndex]# 训练标签
# 得到测试数据
testData = mnist.test.images[testIndex]# 测试下标: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  784->image,训练数据和测试数据生成好了
# placeholder:完成数据的加载,每一个784的数据表明一个完整的图片
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具体计算
#knn distance距离公式 原先5*785.-》转换后  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维数据累加 784 abs; reduction_indices设置维度,在第二维度累加 
# 5*500 
f4 = tf.negative(f3)# 取反
f5,f6 = tf.nn.top_k(f4,k=4) # 选取f4 最大的四个值
# 等价于选取f3 最小的四个值,分别描述值的内容,以及值的下标
# f6 index->trainLabelInput,最近的四个点的下标
f7 = tf.gather(trainLabelInput,f6)# 将所有的标签获取到
# f8 num reduce_sum  reduction_indices=1 '竖直',数值方向上维度的累加

# F8 , F9 完成数据的获取,完成数据的累加
f8 = tf.reduce_sum(f7,reduction_indices=1)# 当前维度设置为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]})#总共给5张图片
    print('p1=',p1.shape)# p1= (5, 1, 784),每一个图片用784来表示
    p2 = sess.run(f2,feed_dict={trainDataInput:trainData,testDataInput:testData[0:5]})
    print('p2=',p2.shape)#p2= (5, 500, 784) (1,100) 随便取(1, 100) 这样的点表示第二张测试图片和第一101张的训练图片的距离,距离放到784维中
    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])#-155.812,完成 对p3的取反
    
    # 同时查看两个参数
    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])# p5:-48.4275
    print('p6[0,0]',p6[0])# p6:314 index 下标
    
    p7 = sess.run(f7,feed_dict={trainDataInput:trainData,testDataInput:testData[0:5],trainLabelInput:trainLabel})
    print('p7=',p7.shape)# p7= (5, 4, 10),p7一共分成5组,四行数据,每一行对应一个label标签
    print('p7[]',p7)
    
    p8 = sess.run(f8,feed_dict={trainDataInput:trainData,testDataInput:testData[0:5],trainLabelInput:trainLabel})
    print('p8=',p8.shape)
    print('p8[]=',p8)
    
    p9 = sess.run(f9,feed_dict={trainDataInput:trainData,testDataInput:testData[0:5],trainLabelInput:trainLabel})
    print('p9=',p9.shape)
    print('p9[]=',p9)
    
    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) # 把最后的检测概率打印出来

Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
trainData.shape= (500, 784)
trainLabel.shape= (500, 10)
testData.shape= (5, 784)
testLabel.shape= (5, 10)
testLabel= [[  0.  0.  0.  0.  0.  1.  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.  0.  0.  0.  0.  1.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  1.  0.  0.  0.]]
p1= (5, 1, 784)
p2= (5, 500, 784)
p3= (5, 500)
p3[0,0]= 149.69
p4= (5, 500)
p4[0,0] -149.69
p5= (5, 4)
p6= (5, 4)
p5[0,0] [-107.67453003 -110.09804535 -111.78039551 -114.78039551]
p6[0,0] [228 426 370  96]
p7= (5, 4, 10)
p7[] [[[ 0.  0.  0.  0.  0.  0.  0.  0.  1.  0.]
  [ 0.  0.  0.  0.  0.  0.  0.  0.  1.  0.]
  [ 0.  0.  0.  1.  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.]
  [ 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.  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.  1.  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.  0.  1.  0.  0.  0.]
  [ 0.  0.  0.  0.  0.  0.  1.  0.  0.  0.]]]
p8= (5, 10)
p8[]= [[ 0.  0.  1.  1.  0.  0.  0.  0.  2.  0.]
 [ 4.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  4.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  1.  0.  3.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  4.  0.  0.  0.]]
p9= (5,)
p9[]= [8 0 1 5 6]
p10[]= [5 0 1 5 6]
ac= 80.0

二、CNN数字识别

#cnn : 1 卷积
# ABC 
# A以往: 激励函数+矩阵 乘法加法
# A CNN :  pool(激励函数+矩阵 卷积 加法)整体结果进行pool
# C以往:激励函数+矩阵 乘法加法(A-》B)
# C:激励函数+矩阵 乘法加法(A-》B) + softmax(矩阵 乘法加法)
# loss:tf.reduce_mean(tf.square(y-layer2))
# loss:code
#1 import 
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
# 2 load data
mnist = input_data.read_data_sets('MNIST_data',one_hot = True)
# 3 input
imageInput = tf.placeholder(tf.float32,[None,784]) # 28*28 
labeInput = tf.placeholder(tf.float32,[None,10]) # knn
# 4 data reshape
# [None,784]->M*28*28*1  2D->4D  28*28 wh 1 channel 
imageInputReshape = tf.reshape(imageInput,[-1,28,28,1])
# 5 卷积 w0 : 卷积内核 5*5 out:32  in:1 
w0 = tf.Variable(tf.truncated_normal([5,5,1,32],stddev = 0.1))
b0 = tf.Variable(tf.constant(0.1,shape=[32]))#偏移矩阵,32维,
# 6 # layer1:激励函数+卷积运算 (原先的乘加运算改成卷积运算)
# imageInputReshape :输入数据 M*28*28*1  w0:5,5,1,32 维度 ;strides步长,表明当前的内核,每一次移动的步长
# padding='SAME':表明卷积核可以停留在图像的边缘
layer1 = tf.nn.relu(tf.nn.conv2d(imageInputReshape,w0,strides=[1,1,1,1],padding='SAME')+b0)#完成卷积运算
# M*28*28*32
# 再添加一个池化层,完成样本的抽样,因为有时候数据太大,所以需要数据采样,添加池化层
# pool 采样, 下采样,数据量是不断地减小的,数据量减少很多M*28*28*32 => M*7*7*32最后得到的值
# 采用max池化方法;ksize=[1,4,4,1],M*28*28*32,每一个元素对当前的ksize进行相除,28/4=7,原来数据减少四倍
# strides 池化层步长,这一步得到layer1层输出
layer1_pool = tf.nn.max_pool(layer1,ksize=[1,4,4,1],strides=[1,4,4,1],padding='SAME')
#eg: [1 2 3 4]->[4],经过池化之后变成一维,一维的数据来自于池化层中最大的数据

# 7 实现输出层;layer2 out : 激励函数+乘加运算:  softmax(激励函数 + 乘加运算)是一个回归计算
# [7*7*32,1024]
# 生成一个正态分布的例子
w1 = tf.Variable(tf.truncated_normal([7*7*32,1024],stddev=0.1))# stddev=0.1;方差 # 2维
b1 = tf.Variable(tf.constant(0.1,shape=[1024]))
# 维度转换,将pool_layer结果四维降到二维
h_reshape = tf.reshape(layer1_pool,[-1,7*7*32])# M*7*7*32 -> N*N1
# [N*7*7*32]  [7*7*32,1024] = N行*1024列
# 完成激励函数+乘加运算; 通过relu完成乘法
h1 = tf.nn.relu(tf.matmul(h_reshape,w1)+b1)

# 7.1 softMax
w2 = tf.Variable(tf.truncated_normal([1024,10],stddev=0.1))
b2 = tf.Variable(tf.constant(0.1,shape=[10]))
pred = tf.nn.softmax(tf.matmul(h1,w2)+b2)# N*1024  1024*10 = N*10
# pred 得到最终预测数据
# N(N张图片)*10( 概率 )N1【0.1 0.2 0.4 0.1 0.2 。。。】分别表示0~9数字出现的概率
# label。        【0 0 0 0 1 0 0 0.。。】也是N行*10列

# 极端误差,通过对误差的不断减少
loss0 = labeInput*tf.log(pred)# 取log,对当前数据范围进行压缩,loss只有一个唯一的标识

loss1 = 0
# 7.2  因为label维度是十维,所以它的维度需要重新累加,采用for循环
for m in range(0,500):#  test 100 训练时,每次给100张
    for n in range(0,10):# 因为标签中有十个维度,想要对这个有一个累加
        loss1 = loss1 - loss0[m,n]# 因为想取的是最小值,进行取反
loss = loss1/500

# 8 train 让当前误差尽可能减小
train = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
# 9 run
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(100):
        images,labels = mnist.train.next_batch(500)# 图片标签读取进来,每次读取500张图片
        sess.run(train,feed_dict={imageInput:images,labeInput:labels})
        # 拿到当前预测的值,最终的预测结果是十维的
        pred_test = sess.run(pred,feed_dict={imageInput:mnist.test.images,labeInput:labels})
        # 进行比较,看是否相等
        # mnist.test.labels 一万张图片组成
        acc = tf.equal(tf.arg_max(pred_test,1),tf.arg_max(mnist.test.labels,1))
        # reduce_mean 完成当前均值的计算
        acc_float = tf.reduce_mean(tf.cast(acc,tf.float32))
        # 当前的最终输出结果;feed_dict:1, 输入图片; 2 所有标签
        acc_result = sess.run(acc_float,feed_dict={imageInput:mnist.test.images,labeInput:mnist.test.labels})
        print(acc_result)
    

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦