【2】LeNet_5模型手写数字识别

1 搭建LeNet_5模型

定义前向传播过程文件为mnist_inference.py

# -*- coding: utf-8 -*-
#此文件定义了LeNet_5的前向传播过程
import tensorflow as tf

#配置神经网络的参数
#输入节点
INPUT_NODE=784
#输出节点
OUTPUT_NODE=10
#图像大小
IMAGE_SIZE=28
#图像通道
NUM_CHANNELS=1
#标签数目
NUM_LABELS=10

#定义第一层卷积层的尺寸和深度
CONV1_DEEP=32
CONV1_SIZE=5
#定义第二层卷积层的尺寸和深度
CONV2_DEEP=64
CONV2_SIZE=5
#全连接层的节点个数
FC_SIZE=512

#定义前向传播过程
def inference(input_tensor,regularizer):
    #第一层卷积层计算
    with tf.variable_scope('layel-conv1'):
        #获取第一层的权重
        con1_weight=tf.get_variable("weight",[CONV1_SIZE,CONV1_SIZE,NUM_CHANNELS,CONV1_DEEP],initializer=tf.truncated_normal_initializer(stddev=0.1))
        #获取第一层的偏值
        con1_biases=tf.get_variable("biases",[CONV1_DEEP],initializer=tf.constant_initializer(0.0))
        #计算第一层的卷积
        conv1=tf.nn.conv2d(input_tensor,con1_weight,strides=[1,1,1,1],padding='SAME')
        #添加第一层的偏值
        relu1=tf.nn.relu(tf.nn.bias_add(conv1,con1_biases))

    #第二层池化层计算 选取最大池化层
    with tf.name_scope('layer2-pool'):
        pool1=tf.nn.max_pool(relu1,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')

    #第三层卷积层的计算
    with tf.variable_scope('layer3-conv2'):
        #获取第三层的权重
        conv2_weight=tf.get_variable("weight",[CONV2_SIZE,CONV2_SIZE,CONV1_DEEP,CONV2_DEEP],initializer=tf.truncated_normal_initializer(stddev=0.1))
        #获取第三层的偏值
        conv2_biases=tf.get_variable("bias",[CONV2_DEEP],initializer=tf.constant_initializer(0.0))
        #计算第三层的卷积
        conv2=tf.nn.conv2d(pool1,conv2_weight,strides=[1,1,1,1],padding='SAME')
        #获取第三层的激活函数
        relu2=tf.nn.relu(tf.nn.bias_add(conv2,conv2_biases))

    #第四层池化层计算
    with tf.name_scope('layer4_pool2'):
        pool2=tf.nn.max_pool(relu2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
        #计算输出矩阵的维度
        pool_shape=pool2.get_shape().as_list()
        #计算矩阵变为向量后的长度
        nodes=pool_shape[1]*pool_shape[2]*pool_shape[3]
        #将第四层的输出变成一个batch的输出向量
        #pool_shape[0]表示一个batch的个数(即为行数)
        reshaped=tf.reshape(pool2,[pool_shape[0],nodes])
    #定义第五层的全连接传播过程
    with tf.variable_scope('layer5-fc1'):
        #获取第五层的权重
        fcl_weights=tf.get_variable("weight",[nodes,FC_SIZE],initializer=tf.truncated_normal_initializer(stddev=0.1))
        #全连接层需要添加正则化
        if regularizer !=None:
            tf.add_to_collection('losses',regularizer(fcl_weights))
        #获取添加了正则化的偏值
        fc1_biases=tf.get_variable("biases",[FC_SIZE],initializer=tf.constant_initializer(0.1))
        #激活函数的计算
        fc1=tf.nn.relu(tf.matmul(reshaped,fcl_weights)+fc1_biases)
        #dropout函数避免过拟合问题
        #if train: fc1=tf.nn.dropout(fc1,0.5)


    #第六层全连接层
    with tf.variable_scope('layer6-fc2'):
        #获取第六层全连接层的权重
        fc2_weights=tf.get_variable("weight",[FC_SIZE,NUM_LABELS],initializer=tf.truncated_normal_initializer(stddev=0.1))
         #加入正则化
        if regularizer !=None:
            tf.add_to_collection('losses',regularizer(fc2_weights))
        #计算第六层的偏值
        fc2_biases=tf.get_variable("bias",[NUM_LABELS],initializer=tf.constant_initializer(0.1))
        #计算最后的输出
        logit=tf.matmul(fc1,fc2_weights)+fc2_biases

    return  logit

2 定义训练文件

定义模型训练文件mnist_train.py

# -*- coding: utf-8 -*-
#此文件定义了LeNet_5的训练过程
import  os
import tensorflow as tf
import  numpy as np
from tensorflow.examples.tutorials.mnist import input_data
#加载前向传播函数
import  mnist_inference
#配置神经网络参数
BATCH_SIZE=100
LEARNING_RATE_BASE=0.01
LEARNING_RATE_DECAY=0.99
REGULARAZTION_RATE=0.0001
TRAINGING_STEPS=30000
MOVING_AVERAGE_DECAY=0.99

#模型文件的保存路径
MODEL_SAVE_PATH="data//"
MODEL_NAME="model.ckpt"

def train(mnist):
    #准备输入数据
    x=tf.placeholder(tf.float32,[BATCH_SIZE,mnist_inference.IMAGE_SIZE,mnist_inference.IMAGE_SIZE,mnist_inference.NUM_CHANNELS],name='x-input')
    y_=tf.placeholder(tf.float32,[None,mnist_inference.OUTPUT_NODE],name='y-input')
    #定义正则化的方法L2
    regularizer=tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE)
    #前向传播求出y
    y=mnist_inference.inference(x,regularizer)
    # 定义训练的轮数,需要用trainable=False参数指定不训练这个变量,
    # 这样同时也可以避免这个变量被计算滑动平均值??????????
    global_step=tf.Variable(0,trainable=False)
    #定义损失函数、学习率、滑动平均
    #滑动平均
    # 给定滑动平均衰减速率和训练轮数,初始化滑动平均类
    # 定训练轮数的变量可以加快训练前期的迭代速度
    variable_averages=tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step)
    # 用tf.trainable_variable()获取所有可以训练的变量列表,全部使用滑动平均
    variable_averages_op=variable_averages.apply(tf.trainable_variables())
    #交叉熵
    #softmax函数获取分类的概率分布
    cross_entropy=tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.argmax(y_,1))
    # 获取总损失平均值
    cross_entropy_mean=tf.reduce_mean(cross_entropy)
    #损失函数
    # 给损失加上正则化的损失
    # 使用get_collection获取losses集合的全部值的列表,然后用add_n求列表的所有值的和
    loss=cross_entropy_mean+tf.add_n(tf.get_collection('losses'))
    #指数学习率
    learning_rate=tf.train.exponential_decay(LEARNING_RATE_BASE,global_step,mnist.train.num_examples/BATCH_SIZE,LEARNING_RATE_DECAY)
    #训练方法 随机梯度下降法
    # 优化损失函数
    # global_step初始值为0,在loss更新后会+1,用来记录更新的次数
    # 返回值是训练之后的梯度,会随着global_step递增
    train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step)
    # 反向传播更新参数之后需要更新每一个参数的滑动平均值,用下面的代码可以一次完成这两个操作
    with tf.control_dependencies([train_step,variable_averages_op]):
        train_op=tf.no_op(name="train")

    saver=tf.train.Saver()
    with tf.Session() as sess:
        tf.global_variables_initializer().run()
        for i in range(TRAINGING_STEPS):
            xs,ys=mnist.train.next_batch(BATCH_SIZE)
            #喂入数据
            reshaped_xs=np.reshape(xs,(BATCH_SIZE,mnist_inference.IMAGE_SIZE,mnist_inference.IMAGE_SIZE,mnist_inference.NUM_CHANNELS))
            _,loss_value,step=sess.run([train_op,loss,global_step],feed_dict={x:reshaped_xs,y_:ys})
            #打印结果
            if i %100 ==0:
                print("After %d training step(s),loss on training batch is %g." % (step,loss_value))
                saver.save(sess,os.path.join(MODEL_SAVE_PATH,MODEL_NAME),global_step=global_step)

def main(argv=None):
    mnist=input_data.read_data_sets("",one_hot=True)
    train(mnist)

if __name__ == '__main__':
        tf.app.run()

3 模型训练结果(部分)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值