美文网首页我爱编程
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