神经网络:
重点在阙值和w,因为y=w1*x1+w2*x2+w3*x3...
激活函数:在隐藏层,每个输出点带入激活函数,然后再继续向后,最后输出的y预测值不需要激活
损失函数:定义的形式(三种):均方误差(西瓜书)、自定义需要的参数、交叉熵(吴恩达里面定义的有log的损失函数)
优化神经网络方法:1.定义合适的损失函数loss、选择合适的激活函数、2.不断更新学习率(梯度下降的学习率)、3.创建滑动平均值、4.正则化
实现过程:
1.(0,1)范围初始化所以连接权和阙值。
2.计算出y预测值。
3.BP算法,在循环中迭代,利用梯度下降算法优化w,使定义的损失函数最小化,同时得到w最优值。
4.输出连接权和阙值确定最优化的多层前馈神经网络。
1.前向传播
import tensorflow as tf INPUT_NODE=784 OUTPUT_NODE=10 LAYER1_NODE=500 #初始化w def get_weight_variable(shape,regularizer): weights=tf.get_variable("weights",shape,initializer=tf.truncated_normal_initializer(stddev=0.1)) #初始化变量 if regularizer !=None: tf.add_to_collection('losses',regularizer(weights)) #当前变量的正则化损失加到losses中 return weights #前向传播 def inference(input_tensor,regularizer): with tf.variable_scope('layer1'): #tf.get_variable 与tf.Variable 用法一致 weights=get_weight_variable([INPUT_NODE,LAYER1_NODE],regularizer) #784*500 biases=tf.get_variable("biases",[LAYER1_NODE],initializer=tf.constant_initializer(0.0)) #500个隐藏层神经元 layer1=tf.nn.relu(tf.matmul(input_tensor,weights)+biases) #relu激活函数 在0 和 x的选择 with tf.variable_scope('layer2'): weights=get_weight_variable([LAYER1_NODE,OUTPUT_NODE],regularizer) #500*10 biases=tf.get_variable("biases",[OUTPUT_NODE],initializer=tf.constant_initializer(0.0)) layer2=tf.matmul(layer1,weights)+biases return layer2 #n*784 * 784*500 =n*500 #n*500 * 500*10 =n*10 #返回y
2.反向传播训练过程
import os import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data import mnist_inference BATCH_SIZE = 100 #每轮喂入多少张图片 LEARNING_RATE_BASE=0.8 #学习率 LEARNING_RATE_DECAY=0.99 #衰减率 REGULARIZER_RATE=0.0001 #正则化系数 STEPS= 30000 #迭代次数 MOVING_AVERAGE_DECAY=0.99 #滑动平均衰减率 MODEL_SACE_PATH="./model/" #模型保存路径 MODEL_NAME="mnist_model" #模型保存文件名 def train(mnist): x=tf.placeholder(tf.float32,[None,mnist_inference.INPUT_NODE],name='x-input') y_=tf.placeholder(tf.float32,[None,mnist_inference.OUTPUT_NODE],name='y-input') regularizer = tf.contrib.layers.l2_regularizer(REGULARIZER_RATE) y=mnist_inference.inference(x,regularizer) #得出的预测y gloabl_step=tf.Variable(0,trainable=False) #轮数,不可改变 variable_averages=tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,gloabl_step)#定义滑动平均类 variables_averages_op=variable_averages.apply(tf.trainable_variables())#在实际应用中会使tf.trainable_variables() # 自动将所有训练的参数汇总为列表 # average_y=mnist_inference.inference(xxxxxxx) 滑动平均,影子值 #交叉熵定义损失函数,loss 交叉熵和softmax一起使用,softmax是y呈概率分布 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=tf.train.exponential_decay(LEARNING_RATE_BASE,gloabl_step,mnist.train.num_examples/BATCH_SIZE,LEARNING_RATE_DECAY) #梯度下降算法 train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=gloabl_step) with tf.control_dependencies([train_step,variables_averages_op]):#一步完成多个操作 train_op=tf.no_op(name='train') saver=tf.train.Saver() #保存模型 #生成会话` with tf.Session() as sess: tf.global_variables_initializer().run() #设置断点 ckpt = tf.train.get_checkpoint_state(MODEL_SACE_PATH) if ckpt and ckpt.model_checkpoint_path: saver.restore(sess,ckpt.model_checkpoint_path) for i in range(STEPS): #导入数据,迭代更新 xs,ys=mnist.train.next_batch(BATCH_SIZE) #产生数据 _,loss_value,step=sess.run([train_op,loss,gloabl_step],feed_dict={x:xs,y_:ys}) if i%1000 == 0: #打印,1000次输出loss print(variables_averages_op) print("After %d training step(s) , loss on training batch is %g"%(step,loss_value)) saver.save(sess,os.path.join(MODEL_SACE_PATH,MODEL_NAME),global_step=gloabl_step) def main(argv=None): mnist=input_data.read_data_sets("./data/",one_hot=True) train(mnist) if __name__ == '__main__': tf.app.run()
3.输出准确率检验
import time import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data import mnist_inference import mnist_train EVAL_INTERVAL_SECS=10 #10s加载一次正确率 def evaluate(mnist): with tf.Graph().as_default() as g: #输入数据定义 x=tf.placeholder(tf.float32,[None,mnist_inference.INPUT_NODE],name='x-input') y_=tf.placeholder(tf.float32,[None,mnist_inference.OUTPUT_NODE],name='y-input') validata_feed={x:mnist.validation.images,y_:mnist.validation.labels} #正确率计算 y = mnist_inference.inference(x, None) 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: #会话生成 ckpt = tf.train.get_checkpoint_state(mnist_train.MODEL_SACE_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=validata_feed) print("After %s training step(s) ,validation accuracy=%g" % (global_step, accuracy_score)) else: return time.sleep(EVAL_INTERVAL_SECS) def main(): mnist=input_data.read_data_sets("./data/",one_hot=True) evaluate(mnist) if __name__ == '__main__': main()
4.识别自己写的数字,注意:写时要把图片填满,然后字体识别度保持高一点
from PIL import Image import os import tensorflow as tf import numpy as np from tensorflow.examples.tutorials.mnist import input_data import mnist_inference import mnist_eval import mnist_train import matplotlib.pyplot as plt def resore_model(testPicArr): with tf.Graph().as_default() as tg: # 重现计算图 x = tf.placeholder(tf.float32, [None, mnist_inference.INPUT_NODE]) y = mnist_inference.inference(x, None) # 输出y preValue = tf.argmax(y, 1) # y的最大值代表种类 # 下面这一坨到with中都是优化, () 直接得出结果 variable_averages = tf.train.ExponentialMovingAverage(mnist_train.MOVING_AVERAGE_DECAY) variable_to_restore = variable_averages.variables_to_restore() saver = tf.train.Saver() with tf.Session() as sess: ckpt = tf.train.get_checkpoint_state(mnist_train.MODEL_SACE_PATH) ckpt.model_checkpoint_path = ckpt.model_checkpoint_path saver.restore(sess, ckpt.model_checkpoint_path) #print(ckpt.model_checkpoint_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] preValue = sess.run(preValue, feed_dict={x: testPicArr}) #print(preValue) return preValue def pre_pic(picName): # 图片预处理。转化为1*784矩阵,作为特征输入 img = Image.open(picName) # 打开图片 reIm = img.resize((28, 28), Image.ANTIALIAS) # 图片转化为28*28像素 im_arr = np.array(reIm.convert('L')) # 转化为矩阵 threshold = 50 #print(im_arr) for i in range(28): # 求互补反色 让图片只有黑白色的点 for j in range(28): im_arr[i][j] = 255 - im_arr[i][j] if (im_arr[i][j] < threshold): im_arr[i][j] = 0 else: im_arr[i][j] = 255 nm_arr = im_arr.reshape([1, 784]) # 784像素点 nm_arr = nm_arr.astype(np.float32) img_ready = np.multiply(nm_arr, 1.0 / 255.0) #print(img_ready) #plt.imshow(im_arr) #plt.show() return img_ready def application(): testNum = int(input("input the number of test pictures:")) for i in range(testNum): testPic = input("the path of test picture:") testPicArr = pre_pic(testPic) preValue = resore_model(testPicArr) # 在神经网络中喂入预处理的图片的矩阵 print("The prediction number is :", preValue) def main(): application() if __name__ == '__main__': main()