美文网首页我爱编程
TensorFlow使用mnist训练初学

TensorFlow使用mnist训练初学

作者: 不想当社畜 | 来源:发表于2018-05-08 20:04 被阅读0次

主要使用mninst数据进行训练,并且使用自己手画的图进行预测。

读取mnist数据

由于使用默认的下载链接不能使用 主要是国内进不去Google的网站 通过下载好的mnist压缩包
加载数据过程中,通过指定压缩包所在的路径
如果没有mnist压缩包(链接:https://pan.baidu.com/s/18zoIyKToc2UEe1OuZ-nSrQ
提取码:bfwi)

具体代码如下:


from tensorflow.examples.tutorials.mnist import input_data

import matplotlib.pyplot as plt #画图工具

import numpy as np  #矩阵处理

# mnist 一个计算机视觉数据集,它包含70000张手写数字的灰度图片,其中每一张图片包含 28 X 28 个像素点。可以用一个数字数组来表示这张图片:

# 导入数据集 包括训练样本inp.train.images(特征) inp.train.lables(标签)

# 同时也包括test数据

mnist_dir = "E:\\learning\\TensorFlow\\mnist\\"  # 指定mnist data 压缩包存放的路径 

# 加载数据
inp = input_data.read_data_sets(train_dir = mnist_dir,one_hot=True) 

# 其中mnist中的数据类型基本是 numpy数据类型

# 输出训练(train)样本信息特征 28*28  样本个数55000

print ( inp.train.images.shape ) #输出训练样本特征大小 55000 * 784  (28*28的像素点即784为一张图片)

# 由于输出数据太多了 此处就不输出

# print(inp.train.images[0,:])  # 输出第一张图对应数字28*28 

# 输出训练(train)标签 

# 每个特征对应的标签是一个一维数组

# 对应10个数字 0到9 当是特征表示哪个数字 那个数的位置对应为1 其他位置为零

# [0,0,0,0,0,1,0,0,0,0] 代表是数字5

print(inp.train.labels[0,:]) #输出第0个标签的值 

结果输出为:


(55000, 784)

[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]

也可以自己尝试输出不同的结果,根据numpy的数据格式输出即可,上述数据的基本类型是numpy的。

绘画出mnist的数据结果

动态显示出每个样本点图,和其对应的标签。
写好了动画 发现markdown不支持动画

代码如下:
所有代码都是接着上面的代码写的。

# 动态的画出图
from matplotlib import animation

fig = plt.figure()

plt.cla()

#定义每一帧画面显示
def anm(i):
  img = inp.train.images[i,:].reshape(28,28)
  plt.imshow(img,'Greys',Interpolation='nearest',)
  plt.xlabel((r'$the\ real\ : %s $'% np.argmax(inp.train.labels[i,:])))
  
def init():
  img = inp.train.images[1,:].reshape(28,28)
  plt.imshow(img,cmap='Greys',Interpolation='nearest',)
  plt.xlabel((r'$the\ real\ : %s $'% np.argmax(inp.train.labels[0,:])))

# 播放动画
# 函数中参数的含义 fig=图层 func= 每一帧对应的图层 frames=动画的帧数 init_func=起始帧 interval=间隔时间播放每一帧 
anim = animation.FuncAnimation(fig=fig,func=anm,frames=10,init_func=init,interval=1000,blit=False)

# 将动画保存当前目录名为mnist.mp4 
# 刚开始运行不了 缺少了ffmpeg库 
# 使用 conda install -c conda-forge ffmpeg 安装即可
# 由于对matplotlib绘图工具不熟  有些参数也不知道什么意思

Writer = animation.writers['ffmpeg']
writer = Writer(fps=15, metadata=dict(artist='Me'), bitrate=1800)
anim.save('mnist.mp4',writer= writer)

plt.show()

开始使用TensorFlow训练模型

在TensorFlow中,它是自成一套,当有需要值传给它时,这需要使用声明函数tf.placeholder()。具体实现代码如下。
所有使用tf声明的,都是属于TensorFlow它自己内部的拥有。比如下面声明的x = tf.placeholder("float32",[None,784]) x是TensorFlow的内部的参数。当外部需要使用其中参数需要使用TensorFlow.Session().run()去调用...

先不解释TensorFlow具体的工作流程,我也是刚上手,就简单的使用mnist训练一下。

# 开始使用tensorflow训练模型

import tensorflow as tf 

# 外部需要传入模型的值 x y_

# x表示训练样本的特征 每个样本28*28=784的大小 样本个数None 根据传入的数据给定 每个值的类型为"float32"
# y_表示训练样本的标签 每个标签10的大小 样本的个数也是None待定 根据传入的数据定 每个值的类型为"float32"

x = tf.placeholder("float32",[None,784])  
y_ = tf.placeholder("float32", [None,10]) 



# 定义模型变量权重

W = tf.Variable(tf.zeros([784,10])) # 初始化为0权重
b = tf.Variable(tf.zeros([10])) # 常数项

# 定义模型

y = tf.nn.softmax(tf.matmul(x,W) + b)



# 误差分析

cross_entropy = -tf.reduce_sum(y_*tf.log(y))

# 设置优化方法 使用梯度优化

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


# 初始化变量 

# 当设置了变量时,应该对变量进行初始化(前面的权重等)

init = tf.initialize_all_variables()

# 启动模型初始化变量

sess = tf.Session() #类似于模型的启动器
sess.run(init) # 使用了run才能对模型启动 说明启动了init参数 即所有变量已经初始化了


# 开始训练模型 训练1000次

for i in range(1000):
  batch_xs, batch_ys = inp.train.next_batch(100)  #使用分块开始训练自己的模型 每次训练样本100个

  # 开始运行模型的train_step 
  # 根据上面的连锁反应(模型关系) 
  # 当计算train_step时根据train_step = tf.train.GradientDescentOptimizer(0.01).
  # minimize(cross_entropy)需要已知cross_entropy
  # 根据cross_entropy = -tf.reduce_sum(y_*tf.log(y)) 需要y_和y 
  # 而y_是tf.placeholder()变量 需要外部传入
  # y = tf.nn.softmax(tf.matmul(x,W) + b) 需要已知x
  # (W,b是内部变量并且已经初始化了 根据模型每次迭代也会在内部更新值)
  # x 是tf.placeholder() 也需要外部传入

  # 所以当计算train_step需要从外部传入x和y_的值
  # feed_dict={x: batch_xs, y_: batch_ys} 表示将对应的值传入对应的位置(形式类似于python字典)

  sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys}) 

# 经过上述代码 模型已经训练完成
# 使用mnist中的test数据进行评估

# 评估模型

# 根据y = tf.nn.softmax(tf.matmul(x,W) + b)模型
# 
# [0 1 2 3 4 5 6 7 8 9]
# y的值是10个值对应的每个值的概率 (对应每个样本点x)


# y是样本对应的预测的值  y_是外部传入的值(真实的标签值)
# 判断两者是不是相等
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))

# tf.reduce_mean()求中间的平均值
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float32"))

# 使用mnist的test数据进行测试
# 同理激活accuracy值需要correct_prediction 则需要y和y_(外部传入的)
# 而y则需要x(外部传入的)
# 由于此时是测试 则传入的是测试数据test

print ("模型的正确率:",sess.run(accuracy, feed_dict={x: inp.test.images, y_: inp.test.labels}))
模型的正确率: 0.9003

使用自己画的图测试结果

通过上面训练好的模型,使用Windows自带的画图软件,画一个28*28像素点的图保存成png格式。


原始图片
# 使用matplotlib读取png图片
import matplotlib.pyplot as plt 

#读图片
inp1 = plt.imread('test2.png')

# 获取预测的值tf.argmax(y,1)
# tf.argmax(y,1)函数获取y(大小10*1)中最大值的下标 即对应预测为该值的概率最大
prdiction_y = sess.run(tf.argmax(y,1), feed_dict={x: inp1[:,:,0].reshape((1,784))})

plt.imshow(inp1)
plt.xlabel((r'$prdiction:%s$'%prdiction_y))
plt.show()

结果如下:


预测的结果

最后计算结果非常有可能计算不准确。

相关文章

网友评论

    本文标题:TensorFlow使用mnist训练初学

    本文链接:https://www.haomeiwen.com/subject/dogwrftx.html