【2】LeNet_5模型手写数字识别
程序员文章站
2022-07-14 11:41:46
...
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 模型训练结果(部分)
下一篇: k均值聚类
推荐阅读
-
基于MNIST手写数字数据集的数字识别小程序
-
机器学习python实战之手写数字识别
-
PyTorch CNN实战之MNIST手写数字识别示例
-
Python实现识别手写数字大纲
-
python tensorflow基于cnn实现手写数字识别
-
手写数字识别 ----Softmax回归模型官方案例注释(基于Tensorflow,Python)
-
手写数字识别 ----在已经训练好的数据上根据28*28的图片获取识别概率(基于Tensorflow,Python)
-
Python实现识别手写数字 Python图片读入与处理
-
python实现识别手写数字 python图像识别算法
-
Python神经网络TensorFlow基于CNN卷积识别手写数字