python下使用tensorflow框架通过softmax实现mnist手写数字识别功能详解

一、将要使用的函数及思路详解
1.mnist:mnist是深度学习的经典入门demo,他是由6万张训练图片和1万张测试图片构成的。我们这个项目的任务是使用神经网络的方法实现手写数字识别功能。也就是说我们希望能够训练一个神经网络,使得往神经网络中输入一张手写数字图片只后能够获得对应的这张图片中数字的输出。

2.整个任务的第一步是先要从网上下载数据集,我们可以使用python的一个脚本实现。该项目的数据集分为训练集与测试集两部分,训练集用于在训练时更改我们网络中的参数,而测试集用于在训练过程中获得我们网络暂时的loss值和准确率,进一步用于确定我们的learningrate值等网络参数的更改情况。
导入mnist数据:

from tensorflow.examples.tutorials.mnist import input_data 
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

在这里我们获得了mnist对象,它里面保存了整个mnist的数据,这里是onehot向量的形式,也就是说是一个2828=784的一维向量。
3.接下来我们要进行设置输入数据了,由于我们没有确定batch size是多少,所以我们要先使用占位符来设置。
首先说一下batch size,我认为batch size指的是我们在训练神经网络时,我们往往会认为我们输入一张图片,通过神经网络之后获得一个输出,将输出与标准label作差获得loss,之后根据loss的大小进行反向传播,不断修改我们的权值和阈值。但是在实际训练过程中如果每输入一张图片都反向传播一次的话可能会有偶然情况,同时计算量过大,所以我们使用batch_size的概念,每输入几张图片获得loss之后反向传播一次,这样就极大得减小了图片偶然情况的可能性。
之后是占位符函数:tf.placeholder(tf.float32,[None,784]):
tf.placeholder指的是我们开出一块数据空间,但是这个数据大小我暂时还无法确定,需要在真正sess设置时确定,到时候tf.placeholder可以根据输入的数据自动调整数据的大小。
tf.placeholder的两个参数:第一个tf.float32代表我的占位符中的数据格式是32位的浮点型;第二个[None,784]指的是我们占位符中数据的大小,这里是batch_size
784。
4.输入确定之后,我们下一步应该设置神经网络的计算过程了,也就是h=Wx+b。所以第一步我们要先设置权值W和阈值b的数据,这里我们使用tf.Variable(tf.zeros([ , ]))函数来实现。tf.Variable()函数指的是设置一个由变量组成的矩阵,我们可以不断修改它们。括号里我们使用tf.zeros()函数来配置权值、阈值变量的大小并将它们先设置为0。
设置好权值和阈值之后,我们就要设置计算过程了。由于计算过程是h=x
W+b,这里理解是我们认为W是784行10列的数据,x是batchsize行784列的数据,b是一行十列的数据,所以x*W得到batchsize行10列的数据,每一个行都加上b就获得了我们想要得到的隐藏层h。
5.softmax函数:经过上面的过程,我们的到了图片数(batch_size)行10列的矩阵我们将它看成batch_size个一行十列的向量,而每x列都代表0-9中第x-1个数对应的一个值,我们将这些值归一化就得到了这张图片中数字是这个数的概率,这里我们使用tf.nn.softmax()函数来实现。
6.至此我们就完成了神经网络从输入到输出的前向过程,接下来我们就要设置label与输出做比较了,我们同样使用tf.placeholder函数来设置label。
7.接下来我们使用交叉熵函数作为我们的loss损失函数,tf.reduce_mean(y_*tf.log(y))为计算过程。
8.loss函数获取之后就要配置反向传播过程了,常见的为梯度下降法tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy),第一个参数为学习率即learningrate,第二个参数为loss。
9.最后我们配置初始化函数init = tf.initialize_all_variables()。
9.这样,我们所有的设置过程就结束了,下一步就是运行了。
10.运行第一步:使用Session模式:sess = tf.Session()
11.运行第二步:初始化所有变量:sess.run(init)
12.运行第三步:训练网络,首先我们确定结束条件是运行次数,接下来我们填充输入,batch_xs, batch_ys = mnist.train.next_batch(100),也就是每运行一次循环我们都将数据集中的数据进行填充。
13.运行第四步:正式训练,运行sess.run(train_step, feed_dict={x:batch_xs,y_:batch_ys})。刚开始时我有一个疑问就是我没有运行前向的网络,直接就运行train_step,而train_step是用于设置反向传播方法的,也就是说我居然可以直接只运行反向传播,后来发现train_step有一个参数是cross_entropy,而cross_entropy的定义涉及到了整个前向过程,而tensorflow又是基于数据流图的框架,所以其实前向网络是运行了的。

train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

其中feed_dict就是用来赋值的,例如feed_dict={a:8}。

14.获取模型评价
首先是tf.argmax()函数,tf.argmax()返回最大数值的下标,通常和tf.equal()一起使用,计算模型准确度,0表示按列找,1表示按行找。
tf.cast(x, dtype, name=None)函数,此函数是类型转换函数,参数: x:输入; dtype:转换目标类型; name:名称 。
tf.reduce_mean():计算张量的各个维度上的元素的平均值.
tf.equal(A, B)是对比这两个矩阵或者向量的相等的元素,如果是相等的那就返回True,反正返回False,返回的值的矩阵维度和A是一样的。

    import tensorflow as tf
    import numpy as np
     
    A = [[1,3,4,5,6]]
    B = [[1,3,4,3,2]]
     
    with tf.Session() as sess:
        print(sess.run(tf.equal(A, B)))

输出:[[ True True True False False]]
在这里,tf.argmax(y,1)找到每一行最大值的下标,与y_的下标比较,得到一个batchsize行一列的向量,每个向量元素的值为0或1。之后tf.cast将向量转化为浮点型,再用 tf.reduce_mean求出平均值,也就是准确率。最后用sess.run(accuracy , feed_dict={x: mnist.test.images , y_: mnist.
test.labels})实现。

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction , "float"))
print(sess.run(accuracy , feed_dict={x: mnist.test.images , y_: mnist.
test.labels}))

二、代码:

# -*- coding: utf-8 -*-
#mnist 回顾一下tensorflow用法
#这里只使用全连接,所以输入的是28*28=784的一维向量
from tensorflow.examples.tutorials.mnist import input_data   #导入数据
import tensorflow as tf                                      #调用tensorflow

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

#设置输入,tf.placeholder为占位函数,输入图片数量不一定,设置为none,每张为28*28
#1.设置获取输入
x = tf.placeholder(tf.float32,[None,784])

#设置权值和阈值
#2.第一层:权值、阈值
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))

#3.第一层softmax层
y = tf.nn.softmax(tf.matmul(x,W) + b)

#4.第一层设置获取label
y_ = tf.placeholder(tf.float32,[None,10])

#5.使用交叉熵作为目标loss函数
cross_entropy = -tf.reduce_mean(y_*tf.log(y))

#6.设置反向传播方法,梯度下降方法
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

#7.设置初始化所有变量
init = tf.initialize_all_variables()

#在Session中启用模型
sess = tf.Session()
#8.进行初始化
sess.run(init)

#9.正式训练
for i in range(10000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={x:batch_xs,y_:batch_ys})

#10.获取模型评价
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction , "float"))
print(sess.run(accuracy , feed_dict={x: mnist.test.images , y_: mnist.
test.labels}))

输出:

/usr/bin/python2.7 /home/sun/binocular/simple_mnist.py
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
0.8699

Process finished with exit code 0

三、小结
1.使用tensorflow进行训练网络时,输入与输出数据往往使用占位符来实现。因为我们需要修改batch_size的值,所以我们往往使用tf.placeholder(tf.float32,[None, xxx])来实现。
2.网络中需要不断修改的权值和阈值的数据我们往往使用tf.Variable(zeros([ , ]))函数来实现。
3.进行bp神经网络运算是使用tf.matmul函数即可。
4.实现归一化时,我们通过softmax函数,往往使用tf.nn.softmax(),括号里是向量,即将这个向量中所有数进行归一化。
5.常用的反向传播方法:tf.train.GradientDescentOptimizer、tf.train.AdamOptimizer和tf.train.MomentumOptimizer。
6.初始化函数:init = tf.initialize_all_variables()
7.启用模式:sess=tf.Session();使用sess.run()函数运行操作。
8.填充数据:batch_xs, batch_ys = mnist.train.next_batch(100)
9.运行: sess.run(train_step, feed_dict={x:batch_xs,y_:batch_ys})
10.准确率:

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction , "float"))
print(sess.run(accuracy , feed_dict={x: mnist.test.images , y_: mnist.
test.labels}))
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值