目录
一、介绍minist数据集
二、介绍tensorflow
三、思路
四、代码实现(四种方法)
1、线性模型:logistic回归
2、浅层神经网络(sigmoid函数)
3、神经网络(ReLU函数)
4、卷积神经网络
五、遇到的问题
六、模型对比
摘要
手写数字识别是模式识别中一个非常重要和活跃的研究领域,数字识别也不是一项孤立的技术,他涉及的问题是模式识别的其他领域都无法回避的;应用上,作为一种信息处理手段,字符识别有广阔的应用背景和巨大的市场需求。因此,对数字识别的研究具有理论和应用的双重意义。
这里我们参考网上的一些教程,将用tensorflow实现MNIST手写识别。
一、mnist数据集
MNIST 数据集来自美国国家标准与技术研究所,National Institute of Standards and Technology (NIST)。训练集 (training set) 由来自 250 个不同人手写的数字构成,其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工作人员,测试集(test set) 也是同样比例的手写数字数据。
mnist数据集可以在 http://yann.lecun.com/exdb/mnist/ 获取
二、tensorflow
tensorflow是谷歌于2015年11月9日正式开源的计算框架。tensorflow计算框架可以很好地支持深度学习的各种算法,但它的应用也不限于深度学习,是由Jeff Dean领头的谷歌大脑团队基于谷歌内部第一代深度学习系统DistBelief改进而来的通用计算框架。
三、思路
把图片当成一枚枚像素来看,下图为手写体数字1的图片,它在计算机中的存储其实是一个二维矩阵,每个元素都是0~1之间的数字,0代表白色,1代表黑色,小数代表某种程度的灰色。如图:
对于minist数据集中的图片来说,我们只要把它当成长度为784的向量就可以了(忽略它的二维结构,28*28=784)。
四、代码实现
链接:https://pan.baidu.com/s/1rw_iOSs8jOWopZFA9yQACA 密码:ztmx
上面是我们这次采用的一个博主的代码链接(来源于数据魔术师 ,作者齐浩洋),一共采用了四种方式
1、线性模型:logistic回归
用线性模型来做分类
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import time
def init_weights(shape):#初始化神经网络权重
return tf.Variable(tf.random_normal(shape, stddev=0.01))
def model(X, w):
return tf.matmul(X, w) #神经网络的矩阵乘法
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)#读取数据集
#将数据集分为测试集和训练集
trX, trY, teX, teY = mnist.train.images, mnist.train.labels, mnist.test.images, mnist.test.labels
#初始化参数
X = tf.placeholder("float", [None, 784])
Y = tf.placeholder("float", [None, 10])
#函数的调用
w = init_weights([784, 10])
py_x = model(X, w)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=py_x, labels=Y)) # 计算误差
train_op = tf.train.GradientDescentOptimizer(0.05).minimize(cost) #使用梯度下降算法
predict_op = tf.argmax(py_x, 1) #对矩阵按行计算最大值
time_start=time.time()#计算程序运行时间
with tf.Session() as sess:
tf.initialize_all_variables().run()
#算法循环20次
for i in range(20):
for start, end in zip(range(0, len(trX), 128), range(128, len(trX)+1, 128)):
sess.run(train_op, feed_dict={X: trX[start:end], Y: trY[start:end]})
print(i, np.mean(np.argmax(teY, axis=1) ==
sess.run(predict_op, feed_dict={X: teX})))
#将流程图保存
file_writer = tf.summary.FileWriter(r'D:/graph', sess.graph)
time_end=time.time()
#输出运行时间
print(time_end-time_start)
2、浅层神经网络(sigmoid函数)
建立一个隐藏层,用最传统的sigmoid函数做激活函数。
其核心逻辑还是矩阵乘法。
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import time
# 所有连接随机生成权值
def init_weights(shape):
return tf.Variable(tf.random_normal(shape, stddev=0.01))
def model(X, w_h, w_o):
h = tf.nn.sigmoid(tf.matmul(X, w_h))#使用sigmoid激活函数
return tf.matmul(h, w_o)
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
trX, trY, teX, teY = mnist.train.images, mnist.train.labels, mnist.test.images, mnist.test.labels
X = tf.placeholder("float", [None, 784])
Y = tf.placeholder("float", [None, 10])
w_h = init_weights([784, 625])
w_o = init_weights([625, 10])
py_x = model(X, w_h, w_o)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=py_x, labels=Y)) # 计算误差损失
train_op = tf.train.GradientDescentOptimizer(0.05).minimize(cost) # 梯度下降算法
predict_op = tf.argmax(py_x, 1)#对矩阵按行计算最大值
#计算程序运行时间
time_start=time.time()
with tf.Session() as sess:
tf.global_variables_initializer().run()
#算法循环20次
for i in range(20):
for start, end in zip(range(0, len(trX), 128), range(128, len(trX)+1, 128)):
sess.run(train_op, feed_dict={X: trX[start:end], Y: trY[start:end]})
#输出识别准确率
print(i, np.mean(np.argmax(teY, axis=1) ==
sess.run(predict_op, feed_dict={X: teX})))
#记录程序过程图
file_writer = tf.summary.FileWriter(r'D:/graph', sess.graph)
time_end=time.time()
#输出程序运行时间
print(time_end-time_start)
这个模型的核心那两行代码,就是全连接做了一个隐藏层而己,这其中没有任何的技术,完全是靠神经网络的模型能力。
3、神经网络(ReLU函数)
线性整流函数(Rectified Linear Unit, ReLU),又称修正线性单元, 是一种人工神经网络中常用的激活函数(activation function),通常指代以斜坡函数及其变种为代表的非线性函数。
当然,Dropout也是要做的,Dropout可以比较有效地减轻过拟合的发生,一定程度上达到了正则化的效果。
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import time
#初始化权重
def init_weights(shape):
return tf.Variable(tf.random_normal(shape, stddev=0.01))
#建立神经网络模型
def model(X, w_h, w_h2, w_o, p_keep_input, p_keep_hidden):
X = tf.nn.dropout(X, p_keep_input)
h = tf.nn.relu(tf.matmul(X, w_h))
h = tf.nn.dropout(h, p_keep_hidden)
h2 = tf.nn.relu(tf.matmul(h, w_h2))
h2 = tf.nn.dropout(h2, p_keep_hidden)
return tf.matmul(h2, w_o)
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)#读取数据集
#将数据集分为测试集和训练集
trX, trY, teX, teY = mnist.train.images, mnist.train.labels, mnist.test.images, mnist.test.labels
#初始化参数
X = tf.placeholder("float", [None, 784])
Y = tf.placeholder("float", [None, 10])
#初始化权重
w_h = init_weights([784, 625])
w_h2 = init_weights([625, 625])
w_o = init_weights([625, 10])
#定义模型内数据权重
p_keep_input = tf.placeholder("float")
p_keep_hidden = tf.placeholder("float")
py_x = model(X, w_h, w_h2, w_o, p_keep_input, p_keep_hidden)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=py_x, labels=Y))#计算平方误差
train_op = tf.train.RMSPropOptimizer(0.001, 0.9).minimize(cost)#梯度下降算法
predict_op = tf.argmax(py_x, 1)#对矩阵按行计算最大值
#计算程序运行时间
time_start=time.time()
with tf.Session() as sess:
# you need to initialize all variables
tf.global_variables_initializer().run()
#程序循环20次
for i in range(20):
for start, end in zip(range(0, len(trX), 128), range(128, len(trX)+1, 128)):
sess.run(train_op, feed_dict={X: trX[start:end], Y: trY[start:end],
p_keep_input: 0.8, p_keep_hidden: 0.5})
#输出算法识别准确度
print(i, np.mean(np.argmax(teY, axis=1) ==
sess.run(predict_op, feed_dict={X: teX,
p_keep_input: 1.0,
p_keep_hidden: 1.0})))
file_writer = tf.summary.FileWriter(r'D:/graph', sess.graph)
time_end=time.time()
#输出程序运行时间
print(time_end-time_start)
4、卷积神经网络
真正的深度学习利器CNN,卷积神经网络出场。这次的模型比起前面几个,是要更复杂一些,涉及到卷积层和池化层。
什么是CNN:https://blog.csdn.net/v_JULY_v/article/details/51812459?utm_source=app&app_version=4.5.8
五、遇到的问题
我们采用了网上的这四种算法的源代码,在运行过程中出现了以下两点问题:
1、问题一:
引用tutorials.mnist时,给我报出了这样的错误信息:
据搜索查询,发现是因为在tensorflow文件夹下没有examples文件夹,所以才找不到。我去查找了这个文件夹,发现我里面是有example文件夹的,但名字是example,并且example文件夹下没有tutorials文件夹。每个人对于example文件夹的位置会有一些小小的差别,按实际来就行。
这个tutorials文件夹是我下载好的,并且正确存放的位置,引用时才不会出错。
参考:https://blog.csdn.net/weixin_43977534/article/details/107752562
并且代码要按实际的路径去修改,如我的是:
2、问题二:
据搜索,找到原因:
查看了tf版本,我的是因为在tf2下使用了tf1的API。
解决方式:
使用
六、模型对比
甚至在第18轮还跑出来100%的准确率。