主要使用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()
结果如下:
预测的结果
最后计算结果非常有可能计算不准确。
网友评论