您的位置:首页 > 编程语言 > Python开发

BP神经网络之手写数据识别(python-tensorflow)

2019-03-17 10:35 225 查看

BP神经网络之手写数据识别(python-tensorflow)

  • 全代码
  • 介绍

    这是一个基于Python的tensorflow的,神经网络对手写数字的识别。
    采用两层隐含层的BP神经网络。
    本文采用BP全连接网络:输入层(32x32=784)—隐藏层1(256个神经元)—隐藏层2(64个神经元)—输出层(10)。激活函数选择ReLu。
    数据集:
    下载地址:http:https://yann.lecun.com/exdb/mnist/
    其中包含训练集55000条,验证集5000条,测试集10000条。
    图像大小:28x28,灰度图像(通道数=1)。

    数据加载与获取

    import tensorflow as tf
    import tensorflow.examples.tutorials.mnist.input_data as input_data #输入数据
    mnist=input_data.read_data_sets("MNIST_data/",one_hot=True)#载入数据,独热编码

    独热编码:一种疏向量,1个元素为1,其他为0。常用于有限个可能值的字符串或标识符中。优点:使距离计算更合理。

    图像显示:

    import matplotlib.pyplot as plt
    def plot_image(image):
    plt.imshow(image.reshape(28,28),cmap='binary')
    plt.show()
    plot_image(mnist.train.images[2000])

    创建模型

    定义全连接层函数:

    def fcn_layer(inputs,input_dim,output_dim,activation=None):#全连接层
    W=tf.Variable(tf.truncated_normal([input_dim,output_dim],stddev=0.1))
    b=tf.Variable(tf.zeros([output_dim]))
    XWb=tf.matmul(inputs,W)+b
    if activation is None:
    outputs=XWb
    else:
    outputs=activation(XWb)
    return outputs

    创建模型:
    输入层(32x32=784)—隐藏层1(256个神经元)—隐藏层2(64个神经元)—输出层(10)。

    x=tf.placeholder(tf.float32,[None,784],name='X')
    y=tf.placeholder(tf.float32,[None,10],name='Y')
    H1_NN=256#第一隐藏层
    H2_NN=64#第二隐藏层
    h1=fcn_layer(inputs=x,input_dim=784,output_dim=H1_NN,activation=tf.nn.relu)
    h2=fcn_layer(inputs=h1,input_dim=H1_NN,output_dim=H2_NN,activation=tf.nn.relu)
    forward=fcn_layer(inputs=h2,input_dim=H2_NN,output_dim=10)#输出
    pred=tf.nn.softmax(forward)#输出

    第一隐藏层和第二隐藏层的激活函数为ReLu,输出层用softmax。
    Softmax:为每一类别分配一个小数表示的概率,用小数表示的概率相加和为0.1。
    Pi=eyi∑k=1ceykPi= \frac{e^{yi}}{\sum_{k=1}^{c}e^{yk}}Pi=∑k=1c​eykeyi​
    初始化损失函数,训练批次等:

    loss_function=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=forward))#损失函数
    train_epochs=40#轮次
    batch_size=50#每次的样本数
    total_batch=int(mnist.train.num_examples/batch_size)
    display_step=1#显示
    learning_rate=0.01#学习率,更新率
    optimizer=tf.train.AdamOptimizer(learning_rate).minimize(loss_function)#优化器
    correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(pred,1))#正确预测表
    accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))#准确率

    优化器采用AdamOptimizer.
    Adam:一阶优化算法,适应性矩估计。通过计算梯度的一阶矩估计和二阶矩估计而为不同参数设计独立自适应性学习率。一般:alpha=0.001,beta1=0.9,beta2=0.999,epslon=10^(-8)。

    训练模型

    '''创建模型'''
    sess=tf.Session()#会话
    sess.run(tf.global_variables_initializer())#初始化
    '''训练模型'''
    for epoch in range(train_epochs):
    for batch in range(total_batch):
    xs,ys=mnist.train.next_batch(batch_size)
    sess.run(optimizer,feed_dict={x:xs,y:ys})#训练
    summary_str=sess.run(merged_summary_op,feed_dict={x:xs,y:ys})#tensorboard
    loss,acc=sess.run([loss_function,accuracy],feed_dict={x:mnist.validation.images,y:mnist.validation.labels})
    if (epoch+1)%display_step==0:#显示
    print("Train Epoch:",'%02d'%(epoch+1),"Loss=",'{:.9f}'.format(loss),"Accuracy=","{:.4f}".format(acc))
    accu_test=sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})#在测试集上准确率
    print("Test Accuracy: ",accu_test)



    预测

    import numpy as np
    prediction_result=sess.run(tf.argmax(pred,1),feed_dict={x:mnist.test.images})#预测结果
    def print_predict_errs(labels,prediction):#找出预测错误的
    count=0
    compare_lists=(prediction==np.argmax(labels,1))
    err_list=[i for i in range(len(compare_lists)) if compare_lists[i]==False]
    ax=[]
    bx=[]
    cx=[]
    for x in err_list:
    #print("index="+str(x)+"标签值:",np.argmax(labels[x]),"预测值:",prediction[x])
    count+=1
    ax.append(mnist.test.images[x][:])#图像
    bx.append(np.argmax(labels[x]))#标签
    cx.append(prediction[x])#预测值
    print("总计:"+str(count))
    return ax,bx,cx
    
    ax,bx,cx=print_predict_errs(labels=mnist.test.labels,prediction=prediction_result)
    
    import matplotlib.pyplot as plt
    def plot_images_labels_prediction(images,labels,prediction,index,num=10):#结果可视化
    fig=plt.gcf()
    fig.set_size_inches(10,14)
    if num>25:
    num=25
    for i in range(0,num):
    plt.subplot(5,5,i+1)
    plt.imshow(np.reshape(images[index],(28,28)),cmap='binary')
    title="label="+str(labels[index])
    if len(prediction)>0:
    title+=", predict="+str(prediction[index])
    plt.title(title,fontsize=10)
    plt.axis('off')
    index+=1
    plt.show()
    
    plot_images_labels_prediction(ax,bx,cx,0,25)

    预测错误的图像:

    补充

    手写数据的训练、预测已经完成了。如果我们想计算它训练的时间、想保 1c140 存模型、想在tensorboard中可视化显示,该怎么做呢?

    记录耗时

    在训练前加入:

    '''时间计算'''
    from time import time
    startTime=time()

    训练结束后加入代码:

    duration=time()-startTime#耗时
    print("Train Finished takes:","{:.2f}".format(duration))

    保存模型

    训练前加入:

    save_step=5#保存间隔
    import os
    ckpt_dir="./ckpt_dir/"#路径
    if not os.path.exists(ckpt_dir):
    os.makedirs(ckpt_dir)
    saver=tf.train.Saver()

    训练中加入:

    if (epoch+1)%save_step==0:#保存
    saver.save(sess,os.path.join(ckpt_dir,'mnist_h256_model_{:06d}.ckpt'.format(epoch+1)))
    print('mnist_h256_model_{:06d}.ckpt saved'.format(epoch+1))

    训练后加入:

    saver.save(sess,os.path.join(ckpt_dir,'mnist_h256_model.ckpt'))#保存
    print('Model saved!')

    模型读取:(注意:读取模型要求定义和训练时一样的模型,且在读取前要删除所有节点)
    ‘’‘模型读取’’’

    mode_file=tf.train.latest_checkpoint('./ckpt_dir/')#路径
    saver.restore(sess,mode_file)#加载
    print("Accuracy:",accuracy.eval(session=sess,feed_dict={x:mnist.test.images,y:mnist.test.labels}))

    TensorBoard

    训练前加入:

    '''tensorbord可视化'''
    tf.reset_default_graph()#去除节点
    logdir='D:/log'
    image_shape_input=tf.reshape(x,[-1,28,28,1])#tensorboard,输入图像,-1:一次进多少数据(不确定)
    tf.summary.image('input',image_shape_input,10)#输入图像加入summary
    '''tensorbord可视化'''
    tf.summary.histogram('forward',forward)#直方图
    tf.summary.scalar('loss',loss_function)#标量
    tf.summary.scalar('accuracy',accuracy)#标量
    merged_summary_op=tf.summary.merge_all()#合并所有summary
    writer=tf.summary.FileWriter('log/',sess.graph)

    训练中加入:

    summary_str=sess.run(merged_summary_op,feed_dict={x:xs,y:ys})#tensorboard
    writer.add_summary(summary_str,epoch)#tensorboard

    训练后加入:

    writer.close()#tensorboard

    全代码

    # -*- coding: utf-8 -*-
    '''
    手写数字识别,MNIST,两层隐藏层
    '''
    
    import tensorflow as tf
    import tensorflow.examples.tutorials.mnist.input_data as input_data #输入数据
    '''
    tensorbord可视化
    '''
    tf.reset_default_graph()#去除节点
    logdir='D:/log'
    '''
    网络结构
    '''
    mnist=input_data.read_data_sets("MNIST_data/",one_hot=True)#载入数据,独热编码
    x=tf.placeholder(tf.float32,[None,784],name='X')
    y=tf.placeholder(tf.float32,[None,10],name='Y')
    H1_NN=256#第一隐藏层
    H2_NN=64#第二隐藏层
    
    image_shape_input=tf.reshape(x,[-1,28,28,1])#tensorboard,输入图像,-1:一次进多少数据(不确定)
    tf.summary.image('input',image_shape_input,10)#输入图像加入summary
    
    def fcn_layer(inputs,input_dim,output_dim,activation=None):#全连接层
    W=tf.Variable(tf.truncated_normal([input_dim,output_dim],stddev=0.1))
    b=tf.Variable(tf.zeros([output_dim]))
    XWb=tf.matmul(inputs,W)+b
    if activation is None:
    outputs=XWb
    else:
    outputs=activation(XWb)
    return outputsh1=fcn_layer(inputs=x,input_dim=784,output_dim=H1_NN,activation=tf.nn.relu)
    h2=fcn_layer(inputs=h1,input_dim=H1_NN,output_dim=H2_NN,activation=tf.nn.relu)
    forward=fcn_layer(inputs=h2,input_dim=H2_NN,output_dim=10)#输出
    pred=tf.nn.softmax(forward)#输出
    
    loss_function=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=forward))#损失函数
    train_epochs=40#轮次
    batch_size=50#每次的样本数
    total_batch=int(mnist.train.num_examples/batch_size)
    display_step=1#显示
    learning_rate=0.01#学习率,更新率
    optimizer=tf.train.AdamOptimizer(learning_rate).minimize(loss_function)#优化器
    correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(pred,1))#正确预测表
    accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))#准确率'''tensorbord可视化'''
    tf.summary.histogram('forward',forward)#直方图
    tf.summary.scalar('loss',loss_function)#标量
    tf.summary.scalar('accuracy',accuracy)#标量
    merged_summary_op=tf.summary.merge_all()#合并所有summary
    
    '''模型保存'''
    save_step=5#保存间隔
    import os
    ckpt_dir="./ckpt_dir/"#路径
    if not os.path.exists(ckpt_dir):
    os.makedirs(ckpt_dir)
    saver=tf.train.Saver()'''时间计算'''
    from time import time
    startTime=time()'''创建模型'''
    sess=tf.Session()#会话
    sess.run(tf.global_variables_initializer())#初始化
    writer=tf.summary.FileWriter('log/',sess.graph)
    
    '''训练模型'''
    for epoch in range(train_epochs):
    for batch in range(total_batch):
    xs,ys=mnist.train.next_batch(batch_size)
    sess.run(optimizer,feed_dict={x:xs,y:ys})#训练
    summary_str=sess.run(merged_summary_op,feed_dict={x:xs,y:ys})#tensorboard
    writer.add_summary(summary_str,epoch)#tensorboard
    loss,acc=sess.run([loss_function,accuracy],feed_dict={x:mnist.validation.images,y:mnist.validation.labels})
    if (epoch+1)%display_step==0:#显示
    print("Train Epoch:",'%02d'%(epoch+1),"Loss=",'{:.9f}'.format(loss),"Accuracy=","{:.4f}".format(acc))
    if (epoch+1)%save_step==0:#保存
    saver.save(sess,os.path.join(ckpt_dir,'mnist_h256_model_{:06d}.ckpt'.format(epoch+1)))
    print('mnist_h256_model_{:06d}.ckpt saved'.format(epoch+1))saver.save(sess,os.path.join(ckpt_dir,'mnist_h256_model.ckpt'))#保存
    print('Model saved!')duration=time()-startTime#耗时
    print("Train Finished takes:","{:.2f}".format(duration))
    accu_test=sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})#在测试集上准确率
    print("Test Accuracy: ",accu_test)
    
    writer.close()#tensorboard
    import numpy as np
    prediction_result=sess.run(tf.argmax(pred,1),feed_dict={x:mnist.test.images})#预测结果
    def print_predict_errs(labels,prediction):#找出预测错误的
    count=0
    compare_lists=(prediction==np.argmax(labels,1))
    err_list=[i for i in range(len(compare_lists)) if compare_lists[i]==False]
    ax=[]
    bx=[]
    cx=[]
    for x in err_list:
    #print("index="+str(x)+"标签值:",np.argmax(labels[x]),"预测值:",prediction[x])
    count+=1
    ax.append(mnist.test.images[x][:])#图像
    bx.append(np.argmax(labels[x]))#标签
    cx.append(prediction[x])#预测值
    print("总计:"+str(count))
    return ax,bx,cx
    ax,bx,cx=print_predict_errs(labels=mnist.test.labels,prediction=prediction_result)
    
    import matplotlib.pyplot as plt
    def plot_images_labels_prediction(images,labels,prediction,index,num=10):#结果可视化
    fig=plt.gcf()
    fig.set_size_inches(10,14)
    if num>25:
    num=25
    for i in range(0,num):
    plt.subplot(5,5,i+1)
    plt.imshow(np.reshape(images[index],(28,28)),cmap='binary')
    title="label="+str(labels[index])
    if len(prediction)>0:
    title+=", predict="+str(prediction[index])
    plt.title(title,fontsize=10)
    plt.axis('off')
    index+=1
    plt.show()
    plot_images_labels_prediction(ax,bx,cx,0,25)
    
    '''模型读取'''
    mode_file=tf.train.latest_checkpoint('./ckpt_dir/')#路径
    saver.restore(sess,mode_file)#加载
    print("Accuracy:",accuracy.eval(session=sess,feed_dict={x:mnist.test.images,y:mnist.test.labels}))
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: