tensorflow实现CNN识别手写数字(包括自己写的数字)

这几天有点忙,一直在弄公司信息化小程序,需求变更了好几次,加了几天班,也是醉了。

 

上一篇介绍了CNN相对于DNN有哪些好处,这次打算用CNN识别手写数字模型;DNN是怎么做的呢?把28*28的图片转成1*784的向量作为输入,然后通过784*x, x*y, y*10的隐藏层,也就是进行矩阵乘法,最后转换为一个1*10的向量,最后再将每一个数字预测一个概率,概率最大的就是预测结果。这样做有90%+的准确率,但是不好,为什么呢?第一是参数太多了,就算加上dropout参数也太多了,一幅图片我们通常看到部分就能知道这个图片是啥;第二是把图片转成784的向量,会丢失图片原有的结构信息,图像中两个相邻像素点是有相似关系的。这次通过CNN做手写数字识别,准确率几乎可以达到100%。

PS:CNN的内容上一篇已经说过了,这次主要注重实现和过程。

 

一、CNN模型

这幅图是整个CNN的流程图。有几点说明:

1.  卷积核的大小为什么是5*5的,要32个卷积?

卷积核的大小可以自己设置,一般都是奇数,比如3*3, 5*5, 7*7, 9*9等,卷积的个数也可以自己设置。正如上一篇文章中提到的,一个输入28*28*1(1是通道数),经过32个5*5的卷积层,假设padding方式选择SAME,stride=1,那么输出图像大小还是28*28,因为padding=SAME,即补0了,一个卷积核提取一个特征,有32个卷积核,那么就能提取出32个特征,因此经过第一层卷积后输出是28*28*32。

2.  激活函数为啥用Relu?

为啥要用激活函数呢?因为神经网络本质上都是线性叠加,为了让NN适应非线性,需要设置激活函数,常用的激活函数有sigmoid,tanh,relu,relu6,softplus,softsign等等,这个激活函数会影响最后准确率。至于为啥用relu不用别的,和最后的收敛速度有关,常用的有relu,tanh,效果不好可以尝试别的。激活函数不会改变原来数据形状。

3.  经过2*2池化层为啥就变成14*14*32了?

池化层一般选择的方式是最大池化,2*2的池化核表示从2*2中选最大值作为输出,假设stride=1,所以28*28经过2*2池化后就变成了14*14,池化的目的是为了减少参数而且还可以很好的保证图像的特征;此外,卷积-激活函数-池化 这三个一般都是连着的,池化不会改变特征图的个数(这里是32),只会改变图像大小。

4.  卷积层怎么和全连接层?

经过第二层卷积(激活函数,池化层)之后得到7*7*64的数据,全连接层还是原来的全连接层,就是一个矩阵,要输出1*1024的,所以需要将7*7*64这个三维数组转成1*(7*7*64)维数组,也就是压扁了,跟把28*28转成1*784一样。

5.  为啥要把模型保存?

保存训练好的模型下次就可以直接预测了呀,训练多费时间啊是吧,另外训练好的模型还要在后边要识别自己写的数字。我这里保存模型的名字是mnist_conv.ckpt,应该会生成四个文件checkpoint、mnist_conv.ckpt.index、mnist_conv.ckpt.meta、mnist_conv.ckpt.data-00000-of-00001,作用前边文章讲过,这里不赘述了。

 

二、代码

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import os
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("MNIST_data", one_hot=True)


def weight_variable(shape):
    """
    desc:
        初始化过滤器,标准差0.1
    """
    return tf.Variable(tf.truncated_normal(shape, stddev=0.1))


def bias_variable(shape):
    """
    desc:
        初始化偏置,初始化时,所有值是0.1
    """
    return tf.Variable(tf.constant(0.1, shape=shape))


def conv2d(x, W):
    """
    desc:
        卷积运算,strides表示每一维度滑动的步长,一般strides[0]=strides[3]=1
        第四个参数可选"SAME"或"VALID",“Same”表示边距使用全0填充
    """
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding="SAME")


def max_pool_2x2(x):
    """
    desc:
        池化运算
    """
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")


# 创建x占位符,用于临时存放MNIST图片的数据,
# [None, 784]中的None表示不限长度,而784则是一张图片的大小(28×28=784)
x = tf.placeholder(tf.float32, [None, 784], name="x")
# y_存的是实际图像的标签,即对应于每张输入图片实际的值
y_ = tf.placeholder(tf.float32, [None, 10], name="y")

# 将图片从784维向量重新还原为28×28的矩阵图片,
# 原因参考卷积神经网络模型图,最后一个参数代表深度,
# 因为MNIST是黑白图片,所以深度为1,
# 第一个参数为-1,表示一维的长度不限定,这样就可以灵活设置每个batch的训练的个数了
x_image = tf.reshape(x, [-1, 28, 28, 1])


# 第一层卷积
# 将过滤器设置成5×5×1的矩阵,
# 其中5×5表示过滤器大小,1表示深度,因为MNIST是黑白图片只有一层。所以深度为1
# 32表示卷积在经过每个5×5大小的过滤器后可以算出32个特征,也就是说32个卷积核,即经过卷积运算后,输出深度为32
# 经过28 * 28 * 1 经过 32个5 * 5 的卷积 会得到 28 * 28 * 32,即32个特征图
W_conv1 = weight_variable([5, 5, 1, 32])
# 有多少个输出通道数量就有多少个偏置
b_conv1 = bias_variable([32])
# 使用conv2d函数进行卷积计算,然后再用ReLU作为激活函数
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
# 卷积以后再经过池化操作
h_pool1 = max_pool_2x2(h_conv1)

# 第二层卷积
# 因为经过第一层卷积运算后,输出的深度为32,所以过滤器深度和下一层输出深度也做出改变
W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)


# 全连接层
# 经过两层卷积后,图片的大小为7×7(第一层池化后输出为(28/2)×(28/2),
# 第二层池化后输出为(14/2)×(14/2)),深度为64,
# 我们在这里加入一个有1024个神经元的全连接层,所以权重W的尺寸为[7 * 7 * 64, 1024]
W_fc1 = weight_variable([7 * 7 * 64, 1024])
# 偏置的个数和权重的个数一致
b_fc1 = bias_variable([1024])
# 这里将第二层池化后的张量(长:7 宽:7 深度:64) 变成向量(跟上一节的Softmax模型的输入一样了)
h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
# 使用ReLU激活函数
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

# dropout
# 为了减少过拟合,我们在输出层之前加入dropout
keep_prob = tf.placeholder(tf.float32, name="dropout")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)


# softmax输出层
# 全连接层输入的大小为1024,而我们要得到的结果的大小是10(0~9),
# 所以这里权重W的尺寸为[1024, 10]
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
# 最后都要经过Softmax函数将输出转化为概率问题
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2, name="predict")


# 损失函数和损失优化
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv)))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

# 测试准确率,跟Softmax回归模型的一样
correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))


# 将训练结果保存,如果不保存我们这次训练结束后的结果也随着程序运行结束而释放了
savePath = 'models/mnist_conv/'
saveFile = savePath + 'mnist_conv.ckpt'
if os.path.exists(savePath) == False:
    os.mkdir(savePath)

saver = tf.train.Saver()

# 开始训练
with tf.Session() as sess:
    # 初始化所有变量
    sess.run(tf.global_variables_initializer())
    # 训练两万次
    for i in range(20000):
        # 每次获取50张图片数据和对应的标签
        batch = mnist.train.next_batch(50)
        # 每训练100次,我们打印一次训练的准确率
        if i % 100 == 0:
            train_accuracy = sess.run(
                accuracy, feed_dict={x: batch[0], y_: batch[1], keep_prob: 1.0})
            print("step %d, training accuracy %g" % (i, train_accuracy))
        # 这里是真的训练,将数据传入
        sess.run(train_step, feed_dict={
                 x: batch[0], y_: batch[1], keep_prob: 0.5})

    print("end train, start testing...")

    mean_value = 0.0
    for i in range(mnist.test.labels.shape[0]):
        batch = mnist.test.next_batch(50)
        train_accuracy = sess.run(
            accuracy, feed_dict={x: batch[0], y_: batch[1], keep_prob: 1.0})
        mean_value += train_accuracy

    print("test accuracy %g" % (mean_value / mnist.test.labels.shape[0]))
    # #训练结束后,我们使用mnist.test在测试最后的准确率
    # print("test accuracy %g" % sess.run(accuracy, feed_dict={x:mnist.test.images, y_:mnist.test.labels, keep_prob:1.0}))

    # 最后,将会话保存下来
    saver.save(sess, saveFile)

三、输出

WARNING:tensorflow:From d:\lixin\git_projects\Machine-Learning\tensorflow\demo02.py:9: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use alternatives such as official/mnist/dataset.py from tensorflow/models.
WARNING:tensorflow:From D:\lixin\Anaconda4.2\lib\site-packages\tensorflow\contrib\learn\python\learn\datasets\mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.
Instructions for updating:
Please write your own downloading logic.
WARNING:tensorflow:From D:\lixin\Anaconda4.2\lib\site-packages\tensorflow\contrib\learn\python\learn\datasets\mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use tf.data to implement this functionality.
Extracting MNIST_data\train-images-idx3-ubyte.gz
WARNING:tensorflow:From D:\lixin\Anaconda4.2\lib\site-packages\tensorflow\contrib\learn\python\learn\datasets\mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use tf.data to implement this functionality.
Extracting MNIST_data\train-labels-idx1-ubyte.gz
WARNING:tensorflow:From D:\lixin\Anaconda4.2\lib\site-packages\tensorflow\contrib\learn\python\learn\datasets\mnist.py:110: dense_to_one_hot (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use tf.one_hot on tensors.
Extracting MNIST_data\t10k-images-idx3-ubyte.gz
Extracting MNIST_data\t10k-labels-idx1-ubyte.gz
WARNING:tensorflow:From D:\lixin\Anaconda4.2\lib\site-packages\tensorflow\contrib\learn\python\learn\datasets\mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use alternatives such as official/mnist/dataset.py from tensorflow/models.
step 0, training accuracy 0.14
step 100, training accuracy 0.82
step 200, training accuracy 0.9
step 300, training accuracy 0.94
step 400, training accuracy 0.94
step 500, training accuracy 0.96
step 600, training accuracy 0.98
step 700, training accuracy 0.82
step 800, training accuracy 0.96
step 900, training accuracy 0.94
step 1000, training accuracy 0.98
step 1100, training accuracy 0.94
step 1200, training accuracy 0.92
step 1300, training accuracy 0.94
step 1400, training accuracy 0.98
step 1500, training accuracy 0.96
step 1600, training accuracy 0.96
step 1700, training accuracy 0.98
step 1800, training accuracy 0.98
step 1900, training accuracy 0.94
step 2000, training accuracy 0.98
step 2100, training accuracy 0.98
step 2200, training accuracy 0.98
step 2300, training accuracy 0.98
step 2400, training accuracy 0.98
step 2500, training accuracy 0.98
step 2600, training accuracy 0.96
step 2700, training accuracy 0.96
step 2800, training accuracy 1
step 2900, training accuracy 1
step 3000, training accuracy 0.98
step 3100, training accuracy 0.96
step 3200, training accuracy 0.98
step 3300, training accuracy 1
step 3400, training accuracy 0.98
step 3500, training accuracy 0.98
step 3600, training accuracy 0.98
step 3700, training accuracy 0.98
step 3800, training accuracy 0.98
step 3900, training accuracy 0.96
step 4000, training accuracy 1
step 4100, training accuracy 1
step 4200, training accuracy 0.98
step 4300, training accuracy 1
step 4400, training accuracy 1
step 4500, training accuracy 1
step 4600, training accuracy 0.98
step 4700, training accuracy 0.98
step 4800, training accuracy 0.98
step 4900, training accuracy 0.98
step 5000, training accuracy 0.96
step 5100, training accuracy 0.98
step 5200, training accuracy 0.98
step 5300, training accuracy 1
step 5400, training accuracy 0.98
step 5500, training accuracy 1
step 5600, training accuracy 0.96
step 5700, training accuracy 0.98
step 5800, training accuracy 0.98
step 5900, training accuracy 1
step 6000, training accuracy 1
step 6100, training accuracy 0.98
step 6200, training accuracy 1
step 6300, training accuracy 1
step 6400, training accuracy 0.98
step 6500, training accuracy 1
step 6600, training accuracy 1
step 6700, training accuracy 0.98
step 6800, training accuracy 1
step 6900, training accuracy 0.98
step 7000, training accuracy 0.98
step 7100, training accuracy 1
step 7200, training accuracy 1
step 7300, training accuracy 1
step 7400, training accuracy 1
step 7500, training accuracy 1
step 7600, training accuracy 1
step 7700, training accuracy 1
step 7800, training accuracy 1
step 7900, training accuracy 1
step 8000, training accuracy 1
step 8100, training accuracy 1
step 8200, training accuracy 1
step 8300, training accuracy 1
step 8400, training accuracy 1
step 8500, training accuracy 0.96
step 8600, training accuracy 1
step 8700, training accuracy 1
step 8800, training accuracy 1
step 8900, training accuracy 1
step 9000, training accuracy 0.98
step 9100, training accuracy 1
step 9200, training accuracy 1
step 9300, training accuracy 1
step 9400, training accuracy 0.98
step 9500, training accuracy 0.98
step 9600, training accuracy 1
step 9700, training accuracy 1
step 9800, training accuracy 0.98
step 9900, training accuracy 1
step 10000, training accuracy 1
step 10100, training accuracy 1
step 10200, training accuracy 1
step 10300, training accuracy 1
step 10400, training accuracy 1
step 10500, training accuracy 1
step 10600, training accuracy 1
step 10700, training accuracy 0.98
step 10800, training accuracy 0.98
step 10900, training accuracy 1
step 11000, training accuracy 1
step 11100, training accuracy 1
step 11200, training accuracy 1
step 11300, training accuracy 1
step 11400, training accuracy 1
step 11500, training accuracy 0.96
step 11600, training accuracy 1
step 11700, training accuracy 1
step 11800, training accuracy 1
step 11900, training accuracy 1
step 12000, training accuracy 1
step 12100, training accuracy 1
step 12200, training accuracy 0.96
step 12300, training accuracy 1
step 12400, training accuracy 1
step 12500, training accuracy 1
step 12600, training accuracy 1
step 12700, training accuracy 0.98
step 12800, training accuracy 0.98
step 12900, training accuracy 1
step 13000, training accuracy 1
step 13100, training accuracy 1
step 13200, training accuracy 1
step 13300, training accuracy 1
step 13400, training accuracy 1
step 13500, training accuracy 1
step 13600, training accuracy 1
step 13700, training accuracy 1
step 13800, training accuracy 1
step 13900, training accuracy 1
step 14000, training accuracy 1
step 14100, training accuracy 1
step 14200, training accuracy 1
step 14300, training accuracy 1
step 14400, training accuracy 1
step 14500, training accuracy 1
step 14600, training accuracy 1
step 14700, training accuracy 1
step 14800, training accuracy 1
step 14900, training accuracy 1
step 15000, training accuracy 1
step 15100, training accuracy 1
step 15200, training accuracy 1
step 15300, training accuracy 1
step 15400, training accuracy 1
step 15500, training accuracy 1
step 15600, training accuracy 1
step 15700, training accuracy 1
step 15800, training accuracy 1
step 15900, training accuracy 1
step 16000, training accuracy 1
step 16100, training accuracy 1
step 16200, training accuracy 1
step 16300, training accuracy 1
step 16400, training accuracy 1
step 16500, training accuracy 1
step 16600, training accuracy 1
step 16700, training accuracy 1
step 16800, training accuracy 1
step 16900, training accuracy 1
step 17000, training accuracy 1
step 17100, training accuracy 1
step 17200, training accuracy 1
step 17300, training accuracy 1
step 17400, training accuracy 1
step 17500, training accuracy 1
step 17600, training accuracy 0.98
step 17700, training accuracy 1
step 17800, training accuracy 0.98
step 17900, training accuracy 1
step 18000, training accuracy 1
step 18100, training accuracy 0.98
step 18200, training accuracy 1
step 18300, training accuracy 0.98
step 18400, training accuracy 1
step 18500, training accuracy 1
step 18600, training accuracy 1
step 18700, training accuracy 1
step 18800, training accuracy 1
step 18900, training accuracy 1
step 19000, training accuracy 1
step 19100, training accuracy 1
step 19200, training accuracy 1
step 19300, training accuracy 1
step 19400, training accuracy 0.98
step 19500, training accuracy 1
step 19600, training accuracy 0.98
step 19700, training accuracy 1
step 19800, training accuracy 1
step 19900, training accuracy 1
end train, start testing...
test accuracy 0.9916

四、读取模型并测试mnist模型

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import os
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("MNIST_data", one_hot=True)


def load_mnist_model(batch_size):
    images, labels = mnist.test.next_batch(batch_size)
    with tf.Session() as sess:
        saver = tf.train.import_meta_graph(
            "models/mnist_conv/mnist_conv.ckpt.meta")
        saver.restore(sess, tf.train.latest_checkpoint("models/mnist_conv"))

        print("="*10)

        graph = tf.get_default_graph()
        # 得到两个placeholder 和 预测值
        x = graph.get_tensor_by_name("x:0")
        y = graph.get_tensor_by_name("y:0")
        dropout = graph.get_tensor_by_name("dropout:0")
        predict = graph.get_tensor_by_name("predict:0")

        predict_values = sess.run(predict, feed_dict={x: images, dropout: 1})

        for i in range(batch_size):
            predict_value = np.argmax(predict_values[i])
            label = np.argmax(labels[i])
            print("第%d张图片,预测值:%d,真实值:%d" % (i+1, predict_value, label))


if __name__ == "__main__":
    load_mnist_model(200)

输出结果:


WARNING:tensorflow:From d:\lixin\git_projects\learn-python\demo07\demo02.py:7: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use alternatives such as official/mnist/dataset.py from tensorflow/models.
WARNING:tensorflow:From D:\lixin\Anaconda4.2\lib\site-packages\tensorflow\contrib\learn\python\learn\datasets\mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.
Instructions for updating:
Please write your own downloading logic.
WARNING:tensorflow:From D:\lixin\Anaconda4.2\lib\site-packages\tensorflow\contrib\learn\python\learn\datasets\mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use tf.data to implement this functionality.
Extracting MNIST_data\train-images-idx3-ubyte.gz
WARNING:tensorflow:From D:\lixin\Anaconda4.2\lib\site-packages\tensorflow\contrib\learn\python\learn\datasets\mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use tf.data to implement this functionality.
Extracting MNIST_data\train-labels-idx1-ubyte.gz
WARNING:tensorflow:From D:\lixin\Anaconda4.2\lib\site-packages\tensorflow\contrib\learn\python\learn\datasets\mnist.py:110: dense_to_one_hot (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use tf.one_hot on tensors.
Extracting MNIST_data\t10k-images-idx3-ubyte.gz
Extracting MNIST_data\t10k-labels-idx1-ubyte.gz
WARNING:tensorflow:From D:\lixin\Anaconda4.2\lib\site-packages\tensorflow\contrib\learn\python\learn\datasets\mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use alternatives such as official/mnist/dataset.py from tensorflow/models.
2019-03-29 13:06:34.799582: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
==========
第1张图片,预测值:8,真实值:8
第2张图片,预测值:4,真实值:4
第3张图片,预测值:4,真实值:4
第4张图片,预测值:7,真实值:7
第5张图片,预测值:5,真实值:5
第6张图片,预测值:8,真实值:8
第7张图片,预测值:9,真实值:9
第8张图片,预测值:5,真实值:5
第9张图片,预测值:5,真实值:5
第10张图片,预测值:7,真实值:7
第11张图片,预测值:8,真实值:8
第12张图片,预测值:3,真实值:3
第13张图片,预测值:6,真实值:6
第14张图片,预测值:9,真实值:9
第15张图片,预测值:1,真实值:1
第16张图片,预测值:4,真实值:4
第17张图片,预测值:8,真实值:8
第18张图片,预测值:3,真实值:3
第19张图片,预测值:3,真实值:3
第20张图片,预测值:3,真实值:3
第21张图片,预测值:7,真实值:7
第22张图片,预测值:9,真实值:9
第23张图片,预测值:9,真实值:9
第24张图片,预测值:9,真实值:9
第25张图片,预测值:7,真实值:7
第26张图片,预测值:3,真实值:3
第27张图片,预测值:1,真实值:1
第28张图片,预测值:1,真实值:1
第29张图片,预测值:9,真实值:9
第30张图片,预测值:6,真实值:6
第31张图片,预测值:8,真实值:8
第32张图片,预测值:4,真实值:4
第33张图片,预测值:6,真实值:6
第34张图片,预测值:4,真实值:4
第35张图片,预测值:0,真实值:0
第36张图片,预测值:0,真实值:0
第37张图片,预测值:9,真实值:9
第38张图片,预测值:7,真实值:7
第39张图片,预测值:9,真实值:9
第40张图片,预测值:1,真实值:1
第41张图片,预测值:9,真实值:9
第42张图片,预测值:1,真实值:1
第43张图片,预测值:7,真实值:7
第44张图片,预测值:0,真实值:0
第45张图片,预测值:2,真实值:2
第46张图片,预测值:9,真实值:9
第47张图片,预测值:9,真实值:8
第48张图片,预测值:6,真实值:6
第49张图片,预测值:5,真实值:5
第50张图片,预测值:7,真实值:7
第51张图片,预测值:7,真实值:7
第52张图片,预测值:3,真实值:3
第53张图片,预测值:3,真实值:3
第54张图片,预测值:6,真实值:6
第55张图片,预测值:4,真实值:4
第56张图片,预测值:4,真实值:4
第57张图片,预测值:8,真实值:8
第58张图片,预测值:4,真实值:4
第59张图片,预测值:3,真实值:3
第60张图片,预测值:3,真实值:3
第61张图片,预测值:6,真实值:6
第62张图片,预测值:1,真实值:1
第63张图片,预测值:4,真实值:4
第64张图片,预测值:4,真实值:4
第65张图片,预测值:4,真实值:4
第66张图片,预测值:1,真实值:1
第67张图片,预测值:5,真实值:5
第68张图片,预测值:6,真实值:6
第69张图片,预测值:3,真实值:3
第70张图片,预测值:0,真实值:0
第71张图片,预测值:7,真实值:7
第72张图片,预测值:0,真实值:0
第73张图片,预测值:8,真实值:8
第74张图片,预测值:1,真实值:1
第75张图片,预测值:9,真实值:9
第76张图片,预测值:9,真实值:9
第77张图片,预测值:8,真实值:8
第78张图片,预测值:3,真实值:3
第79张图片,预测值:2,真实值:2
第80张图片,预测值:4,真实值:4
第81张图片,预测值:7,真实值:7
第82张图片,预测值:8,真实值:8
第83张图片,预测值:2,真实值:2
第84张图片,预测值:8,真实值:8
第85张图片,预测值:3,真实值:3
第86张图片,预测值:9,真实值:9
第87张图片,预测值:9,真实值:9
第88张图片,预测值:8,真实值:8
第89张图片,预测值:7,真实值:7
第90张图片,预测值:2,真实值:2
第91张图片,预测值:6,真实值:6
第92张图片,预测值:3,真实值:3
第93张图片,预测值:8,真实值:8
第94张图片,预测值:1,真实值:1
第95张图片,预测值:1,真实值:1
第96张图片,预测值:9,真实值:9
第97张图片,预测值:5,真实值:5
第98张图片,预测值:6,真实值:6
第99张图片,预测值:7,真实值:7
第100张图片,预测值:0,真实值:0
第101张图片,预测值:6,真实值:6
第102张图片,预测值:6,真实值:6
第103张图片,预测值:8,真实值:8
第104张图片,预测值:4,真实值:4
第105张图片,预测值:0,真实值:0
第106张图片,预测值:7,真实值:7
第107张图片,预测值:8,真实值:8
第108张图片,预测值:3,真实值:3
第109张图片,预测值:8,真实值:8
第110张图片,预测值:2,真实值:2
第111张图片,预测值:6,真实值:6
第112张图片,预测值:2,真实值:2
第113张图片,预测值:1,真实值:1
第114张图片,预测值:1,真实值:1
第115张图片,预测值:4,真实值:4
第116张图片,预测值:0,真实值:0
第117张图片,预测值:5,真实值:5
第118张图片,预测值:7,真实值:7
第119张图片,预测值:4,真实值:4
第120张图片,预测值:9,真实值:9
第121张图片,预测值:6,真实值:6
第122张图片,预测值:9,真实值:9
第123张图片,预测值:9,真实值:9
第124张图片,预测值:7,真实值:7
第125张图片,预测值:3,真实值:3
第126张图片,预测值:1,真实值:1
第127张图片,预测值:7,真实值:7
第128张图片,预测值:2,真实值:2
第129张图片,预测值:1,真实值:1
第130张图片,预测值:8,真实值:8
第131张图片,预测值:4,真实值:4
第132张图片,预测值:3,真实值:3
第133张图片,预测值:3,真实值:3
第134张图片,预测值:7,真实值:7
第135张图片,预测值:3,真实值:3
第136张图片,预测值:8,真实值:8
第137张图片,预测值:6,真实值:6
第138张图片,预测值:1,真实值:1
第139张图片,预测值:3,真实值:3
第140张图片,预测值:0,真实值:0
第141张图片,预测值:5,真实值:5
第142张图片,预测值:6,真实值:6
第143张图片,预测值:7,真实值:7
第144张图片,预测值:8,真实值:8
第145张图片,预测值:0,真实值:0
第146张图片,预测值:9,真实值:9
第147张图片,预测值:1,真实值:1
第148张图片,预测值:5,真实值:5
第149张图片,预测值:7,真实值:7
第150张图片,预测值:9,真实值:9
第151张图片,预测值:8,真实值:8
第152张图片,预测值:6,真实值:6
第153张图片,预测值:6,真实值:6
第154张图片,预测值:7,真实值:7
第155张图片,预测值:9,真实值:9
第156张图片,预测值:1,真实值:1
第157张图片,预测值:3,真实值:3
第158张图片,预测值:0,真实值:0
第159张图片,预测值:9,真实值:9
第160张图片,预测值:9,真实值:9
第161张图片,预测值:3,真实值:3
第162张图片,预测值:1,真实值:1
第163张图片,预测值:2,真实值:2
第164张图片,预测值:7,真实值:7
第165张图片,预测值:9,真实值:9
第166张图片,预测值:0,真实值:0
第167张图片,预测值:0,真实值:0
第168张图片,预测值:2,真实值:2
第169张图片,预测值:3,真实值:3
第170张图片,预测值:7,真实值:7
第171张图片,预测值:8,真实值:8
第172张图片,预测值:8,真实值:8
第173张图片,预测值:1,真实值:1
第174张图片,预测值:4,真实值:4
第175张图片,预测值:2,真实值:2
第176张图片,预测值:7,真实值:7
第177张图片,预测值:5,真实值:5
第178张图片,预测值:9,真实值:9
第179张图片,预测值:2,真实值:2
第180张图片,预测值:5,真实值:5
第181张图片,预测值:2,真实值:2
第182张图片,预测值:6,真实值:6
第183张图片,预测值:8,真实值:8
第184张图片,预测值:9,真实值:9
第185张图片,预测值:5,真实值:5
第186张图片,预测值:3,真实值:3
第187张图片,预测值:1,真实值:1
第188张图片,预测值:5,真实值:5
第189张图片,预测值:3,真实值:3
第190张图片,预测值:2,真实值:2
第191张图片,预测值:5,真实值:5
第192张图片,预测值:5,真实值:5
第193张图片,预测值:0,真实值:0
第194张图片,预测值:0,真实值:0
第195张图片,预测值:8,真实值:8
第196张图片,预测值:7,真实值:7
第197张图片,预测值:6,真实值:6
第198张图片,预测值:9,真实值:9
第199张图片,预测值:1,真实值:1
第200张图片,预测值:8,真实值:8

五、读取模型并测试自己写的数字

注意1:mnist模型中images是黑底白字,shape是28*28,且像素点是归一化后的像素点,也就是灰度图像像素点处以255,labels是一个float数组。

注意2:我是用画图工具画的,画出来是白底黑字,create28x28Image方法进行了反色变换,所以执行test_my_images函数的时候必须保证白底黑字,因为调用了create28x28Image这个函数,要不对结果影响特别大。

注意3:虽然转成28*28的图像,但是保存的模型输入还是784,所以最后输入到CNN还得是784。

这是我用画图制作的图片:

程序:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import os
from tensorflow.examples.tutorials.mnist import input_data


def load_mnist_model(batch_size):
    # 读取模型 测试mnist图片
    mnist = input_data.read_data_sets("MNIST_data", one_hot=True)
    images, labels = mnist.test.next_batch(batch_size)
    with tf.Session() as sess:
        saver = tf.train.import_meta_graph(
            "models/mnist_conv/mnist_conv.ckpt.meta")
        saver.restore(sess, tf.train.latest_checkpoint("models/mnist_conv"))

        print("="*10)

        graph = tf.get_default_graph()
        # 得到两个placeholder 和 预测值
        x = graph.get_tensor_by_name("x:0")
        y = graph.get_tensor_by_name("y:0")
        dropout = graph.get_tensor_by_name("dropout:0")
        predict = graph.get_tensor_by_name("predict:0")

        predict_values = sess.run(predict, feed_dict={x: images, dropout: 1})

        for i in range(batch_size):
            predict_value = np.argmax(predict_values[i])
            label = np.argmax(labels[i])
            print("第%d张图片,预测值:%d,真实值:%d" % (i+1, predict_value, label))




def test_my_images(batch_size=10):
    # 读取模型 测试自己的图片
    images, labels = create28x28Image(batch_size)
    with tf.Session() as sess:
        saver = tf.train.import_meta_graph(
            "models/mnist_conv/mnist_conv.ckpt.meta")
        saver.restore(sess, tf.train.latest_checkpoint("models/mnist_conv"))

        print("="*10)

        graph = tf.get_default_graph()
        # 得到两个placeholder 和 预测值
        x = graph.get_tensor_by_name("x:0")
        y = graph.get_tensor_by_name("y:0")
        dropout = graph.get_tensor_by_name("dropout:0")
        predict = graph.get_tensor_by_name("predict:0")

        predict_values = sess.run(predict, feed_dict={x: images, dropout: 1})

        for i in range(batch_size):
            predict_value = np.argmax(predict_values[i])
            label = np.argmax(labels[i])
            print("第%d张图片,预测值:%d,真实值:%d" % (i+1, predict_value, label))


class MnistImage:
    def __init__(self, image, label):
        self.image = image
        self.label = label

    def __str__(self):
        return "image shape is %s,label is %s" % (self.image.shape, self.label)

    def toStandardImage(self):
        return self.image / 255

    def toStandardLabel(self):
        temp_label = [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]
        temp_label[int(self.label)] = 1.0
        return temp_label


def create28x28Image(batchsize=10):
    import cv2
    import operator
    # 自己画的图片
    root = "MNIST_data/my_mnist_test/"

    mnistImageList = []
    if(os.path.exists(root)):
        dirList = os.listdir(root)
    for dirName in dirList:
        for i in range(5):
            # 拼接图片路径
            imagePath = root + "%s/%d.png" % (dirName, i)
            # 读取原始图像,用灰度图表示
            image = cv2.imread(imagePath, 0)
            # 反色变换,因为mnist图像就是黑底白字 并归一化,mnist图像像素点是[0,1]
            for row in range(image.shape[0]):
                for column in range(image.shape[1]):
                    image[row][column] = 255-image[row][column]

            if(operator.eq(image.shape, (28, 28))):
                 # 封装成对象
                mnistImage = MnistImage(image, float(dirName))
                mnistImageList.append(mnistImage)
                cv2.imwrite(imagePath, image)
            else:
                # 缩放到28*28像素
                new_image = cv2.resize(image, (28, 28), cv2.INTER_LINEAR)
                # 封装成对象
                mnistImage = MnistImage(new_image, float(dirName))
                mnistImageList.append(mnistImage)
                # 回写到原来图像路径中
                cv2.imwrite(imagePath, new_image)

    images = []
    labels = []
    for mnistImage in mnistImageList:
        # 转成784向量
        images.append(mnistImage.toStandardImage().reshape([784]))
        labels.append(mnistImage.toStandardLabel())

    return images[0:batchsize], labels[0:batchsize]


if __name__ == "__main__":
    test_my_images(50)
    # create28x28Image()
    # load_mnist_model(2)

执行结果:

2019-03-29 15:18:25.716390: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
==========
第1张图片,预测值:0,真实值:0
第2张图片,预测值:9,真实值:0
第3张图片,预测值:0,真实值:0
第4张图片,预测值:0,真实值:0
第5张图片,预测值:0,真实值:0
第6张图片,预测值:5,真实值:1
第7张图片,预测值:0,真实值:1
第8张图片,预测值:4,真实值:1
第9张图片,预测值:1,真实值:1
第10张图片,预测值:5,真实值:1
第11张图片,预测值:2,真实值:2
第12张图片,预测值:2,真实值:2
第13张图片,预测值:7,真实值:2
第14张图片,预测值:2,真实值:2
第15张图片,预测值:4,真实值:2
第16张图片,预测值:3,真实值:3
第17张图片,预测值:3,真实值:3
第18张图片,预测值:3,真实值:3
第19张图片,预测值:3,真实值:3
第20张图片,预测值:3,真实值:3
第21张图片,预测值:4,真实值:4
第22张图片,预测值:4,真实值:4
第23张图片,预测值:4,真实值:4
第24张图片,预测值:4,真实值:4
第25张图片,预测值:4,真实值:4
第26张图片,预测值:5,真实值:5
第27张图片,预测值:5,真实值:5
第28张图片,预测值:5,真实值:5
第29张图片,预测值:5,真实值:5
第30张图片,预测值:5,真实值:5
第31张图片,预测值:5,真实值:6
第32张图片,预测值:9,真实值:6
第33张图片,预测值:5,真实值:6
第34张图片,预测值:6,真实值:6
第35张图片,预测值:5,真实值:6
第36张图片,预测值:7,真实值:7
第37张图片,预测值:2,真实值:7
第38张图片,预测值:7,真实值:7
第39张图片,预测值:7,真实值:7
第40张图片,预测值:7,真实值:7
第41张图片,预测值:8,真实值:8
第42张图片,预测值:2,真实值:8
第43张图片,预测值:8,真实值:8
第44张图片,预测值:8,真实值:8
第45张图片,预测值:8,真实值:8
第46张图片,预测值:7,真实值:9
第47张图片,预测值:7,真实值:9
第48张图片,预测值:9,真实值:9
第49张图片,预测值:2,真实值:9
第50张图片,预测值:9,真实值:9

我自己做的图片链接:

链接:https://pan.baidu.com/s/1LM4VzYJfEOCooiplj-r9Zw
提取码:v8s1
复制这段内容后打开百度网盘手机App,操作更方便哦

  • 5
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
好的,以下是一个用TensorFlow搭建CNN实现手写数字识别的Python代码: ```python import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data # 导入MNIST数据集 mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) # 定义超参数 learning_rate = 0.001 training_iters = 20000 batch_size = 128 display_step = 10 # 定义网络参数 n_input = 784 # MNIST数据集中每张图片的大小为28x28 n_classes = 10 # MNIST数据集中共有10个数字类别 dropout = 0.75 # Dropout的概率,防止过拟合 # 定义输入占位符 x = tf.placeholder(tf.float32, [None, n_input]) y = tf.placeholder(tf.float32, [None, n_classes]) keep_prob = tf.placeholder(tf.float32) # 定义卷积层和池化层的函数 def conv2d(name, x, W, b, strides=1): x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME') x = tf.nn.bias_add(x, b) return tf.nn.relu(x, name=name) def maxpool2d(name, x, k=2): return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1], padding='SAME', name=name) # 定义卷积神经网络模型 def conv_net(x, weights, biases, dropout): # 将输入的图片转化为4D张量 x = tf.reshape(x, shape=[-1, 28, 28, 1]) # 第一层卷积层 conv1 = conv2d('conv1', x, weights['wc1'], biases['bc1']) conv1 = maxpool2d('maxpool1', conv1, k=2) # 第二层卷积层 conv2 = conv2d('conv2', conv1, weights['wc2'], biases['bc2']) conv2 = maxpool2d('maxpool2', conv2, k=2) # 将卷积层的输出转化为全连接层的输入 fc1 = tf.reshape(conv2, [-1, weights['wd1'].get_shape().as_list()[0]]) fc1 = tf.add(tf.matmul(fc1, weights['wd1']), biases['bd1']) fc1 = tf.nn.relu(fc1) fc1 = tf.nn.dropout(fc1, dropout) # 输出层 out = tf.add(tf.matmul(fc1, weights['out']), biases['out']) return out # 定义权重参数和偏置参数 weights = { 'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])), 'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])), 'wd1': tf.Variable(tf.random_normal([7*7*64, 1024])), 'out': tf.Variable(tf.random_normal([1024, n_classes])) } biases = { 'bc1': tf.Variable(tf.random_normal([32])), 'bc2': tf.Variable(tf.random_normal([64])), 'bd1': tf.Variable(tf.random_normal([1024])), 'out': tf.Variable(tf.random_normal([n_classes])) } # 构建模型 pred = conv_net(x, weights, biases, keep_prob) # 定义损失函数和优化器 cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y)) optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost) # 定义评估模型的准确率的函数 correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1)) accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32)) # 初始化变量 init = tf.global_variables_initializer() # 开始训练模型 with tf.Session() as sess: sess.run(init) step = 1 while step * batch_size < training_iters: batch_x, batch_y = mnist.train.next_batch(batch_size) sess.run(optimizer, feed_dict={x: batch_x, y: batch_y, keep_prob: dropout}) if step % display_step == 0: loss, acc = sess.run([cost, accuracy], feed_dict={x: batch_x, y: batch_y, keep_prob: 1.}) print("Iter " + str(step*batch_size) + ", Minibatch Loss= " + "{:.6f}".format(loss) + ", Training Accuracy= " + "{:.5f}".format(acc)) step += 1 print("Optimization Finished!") print("Testing Accuracy:", sess.run(accuracy, feed_dict={x: mnist.test.images[:256], y: mnist.test.labels[:256], keep_prob: 1.})) ``` 这个代码实现了一个两层卷积神经网络,通过对MNIST数据集进行训练,实现手写数字识别的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值