王权富贵:在树莓派上根据MNIST库的BP神经网络搭建
前言:
树莓派简单实现手写体识别,(根据MNIST库的BP神经网络搭建),因为是代码所以,不知道用什么格式,直接复制黏贴了。效果在最后面,也没有什么好说的直接运行就好。代码虽然下面有,但是复制过程不知道会不会出错,最好用完整代码,完整代码在红色框框中(每行注释),后面两个文件夹在没有熟悉代码之前,先运行看看效果比较好,对理解很有帮助。(要百度网盘的可以备注一下)
感谢:
王灵芝老师(让我写文档总结,每行注释超级变态,其实挺好的,选着准没错)
网络下载的话,请进:https://download.****.net/download/a1103688841/10695027
正文:
好,进入我们的教学,根据前面的步骤,树莓派上面安装的是2.7Python的TensorFlow,所以要用2.7的Python打开。
具体代码如下:
================BP_inference.py====================
BP神经网络接口部分
===================================================
#!/usr/bin/env python
# coding:utf-8
import tensorflow as tf #TensoFlow导入
#BP神经网络的节点
INPUT_NODE = 784 #输入层节点数
OUTPUT_NODE = 10 #输出层节点数
LAYER1_NODE = 500 #隐藏层节点数
#申请权重和保存正则化
def get_weight_variable(shape, regularizer):
#申请权重(前向传输)
weights = tf.get_variable("weights", shape, initializer=tf.truncated_normal_initializer(stddev=0.1))
#有正则化,加入losses集合(这边注意regularizer是L2正则函数加一个惩罚系数传过来)
if regularizer != None: tf.add_to_collection('losses', regularizer(weights))
#返回申请权重
return weights
#BP神经网络搭建
def inference(input_tensor, regularizer=None):
#进入第一层变量管理器
with tf.variable_scope('layer1'):
#申请第一层权重和保存正则化
weights = get_weight_variable([INPUT_NODE, LAYER1_NODE], regularizer)
#申请第一层的偏置
biases = tf.get_variable("biases", [LAYER1_NODE], initializer=tf.constant_initializer(0.0))
#用**函数RELU,进行前向传播(输入层到隐藏层)
layer1 = tf.nn.relu(tf.matmul(input_tensor, weights) + biases)
#进入第二层变量管理器
with tf.variable_scope('layer2'):
#申请第二层权重和保存正则化
weights = get_weight_variable([LAYER1_NODE, OUTPUT_NODE], regularizer)
#申请第二层的偏置
biases = tf.get_variable("biases", [OUTPUT_NODE], initializer=tf.constant_initializer(0.0))
#用**函数RELU,进行前向传播(隐藏层到输出层)
layer2 = tf.matmul(layer1, weights) + biases
#返回输出层信息
return layer2
===============mnist_train.py=======================
训练部分
====================================================
#!/usr/bin/env python
# coding:utf-8
import tensorflow as tf #TensoFlow导入
from tensorflow.examples.tutorials.mnist import input_data #导入数据集
import BP_inference #导入自己写的BP神经网络的张量
import os #一些shell指令
BATCH_SIZE = 100 #采用随机梯度下降法,一批数据为100大小
LEARNING_RATE_BASE = 0.8 #初始学习率
LEARNING_RATE_DECAY = 0.99 #学习率更新倍数
REGULARIZATION_RATE = 0.0001 #正则化的惩罚系数
TRAINING_STEPS = 30000 #训练次数
MOVING_AVERAGE_DECAY = 0.99
MODEL_SAVE_PATH="MNIST_model/" #模型保存路径
MODEL_NAME="mnist_model" #模型保存名字
#训练模型
def train(mnist):
#输入占位符
x = tf.placeholder(tf.float32, [None, BP_inference.INPUT_NODE], name='x-input')
#输出占位符
y_ = tf.placeholder(tf.float32, [None, BP_inference.OUTPUT_NODE], name='y-input')
#正则化函数(L2正则加·第一个(惩罚系数)为参数传入BP神经网络函数中,在里面在加入·第二个(权重)参数)
regularizer = tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)
#将输入和正则方法传入
y = BP_inference.inference(x, regularizer)
#记录训练次数
global_step = tf.Variable(0, trainable=False)
###############################################################
#(第一个参数是衰减率,第二个参数是步长)
variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
#更新影子
variables_averages_op = variable_averages.apply(tf.trainable_variables())
#误差函数的交叉熵
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)
#为误差函数加入正则化
loss = cross_entropy_mean + tf.add_n(tf.get_collection('losses'))
#自定义学习率
#(初始学习率 ,全局步数 ,更新步数 ,更新倍数 ,阶梯/连续 )
#( LEARNING_RATE_BASE ,global_step ,mnist.train.num_examples / BATCH_SIZE,LEARNING_RATE_DECAY ,staircase=True)
learning_rate = tf.train.exponential_decay(
LEARNING_RATE_BASE,
global_step,
mnist.train.num_examples / BATCH_SIZE, LEARNING_RATE_DECAY,
staircase=True)
#采用梯度下降的优化方式
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
#指定顺序(将并行数据做成串行),或者糅合多个行为为一个。这里train_op行为代替train_step和variables_averages_op行为
with tf.control_dependencies([train_step, variables_averages_op]):
train_op = tf.no_op(name='train')
#################################################################
#初始化TensoFlow持久化类
saver = tf.train.Saver()
#打开会话
with tf.Session() as sess:
#初始化变量(开始给变量赋值)
tf.global_variables_initializer().run()
#训练次数
for i in range(TRAINING_STEPS):
#采用随机梯度下降法,一次batch为100大小
xs, ys = mnist.train.next_batch(BATCH_SIZE)
#更新train_op,loss,gloabl_step行为
_, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: xs, y_: ys})
#1000次输出和保存一次信息
if i % 1000 == 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)
#下3行代码,就可以可视化。指定文件的路径,没有会自动生成。指定数据源:计算图
#将计算图上面的数据写入events文件里面,tensorboard可以同时从events文件里面读取数据并显示在web端
#可以用with优化
writer=tf.summary.FileWriter('./improved_graph2',sess.graph)
writer.flush()
writer.close()
#防退出
input("Prease <enter>")
#主函数
def main(argv=None):
mnist = input_data.read_data_sets(".MNIST_data", one_hot=True)
train(mnist)
if __name__ == '__main__':
tf.app.run()
===================mnist_eval.py====================
测试部分
====================================================
#!/usr/bin/env python
# coding: utf-8
import time #导入时间库
import tensorflow as tf #导入TensoFlow库
from tensorflow.examples.tutorials.mnist import input_data #导入数据集
#导入BP神经网络(变量初始化)
import BP_inference
import mnist_train
# 加载的时间间隔。
EVAL_INTERVAL_SECS = 10
#判定函数
def evaluate(mnist):
#创建图
with tf.Graph().as_default() as g:
#创建X占位符
x = tf.placeholder(tf.float32, [None, BP_inference.INPUT_NODE], name='x-input')
#创建Y_占位符
y_ = tf.placeholder(tf.float32, [None, BP_inference.OUTPUT_NODE], name='y-input')
#输入变量的batch
validate_feed = {x: mnist.validation.images, y_: mnist.validation.labels}
#创建BP模型
y = BP_inference.inference(x, None)
#对比是否正确(正确1,错误0)
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
#计算准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
variable_averages = tf.train.ExponentialMovingAverage(mnist_train.MOVING_AVERAGE_DECAY)
variables_to_restore = variable_averages.variables_to_restore()
saver = tf.train.Saver(variables_to_restore)
while True:
#创建会话
with tf.Session() as sess:
#通过查找checkpoint文件,查找最新模型名字
ckpt = tf.train.get_checkpoint_state(mnist_train.MODEL_SAVE_PATH)
#模型路径存在
if ckpt and ckpt.model_checkpoint_path:
#加载模型
saver.restore(sess, ckpt.model_checkpoint_path)
global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
accuracy_score = sess.run(accuracy, feed_dict=validate_feed)
#步数和准确率
print("After %s training step(s), validation accuracy = %g" % (global_step, accuracy_score))
else:
#没有文件输出信息
print('No checkpoint file found')
return
#延时
time.sleep(EVAL_INTERVAL_SECS)
# 主程序
def main(argv=None):
mnist = input_data.read_data_sets("./MNIST_data", one_hot=True)
evaluate(mnist)
if __name__ == '__main__':
main()
最后在树莓派上运行mnist_eval.py的测试结果如下图: