TensroFlow學習——第三章(二)
阿新 • • 發佈:2018-12-05
MINIST數字識別問題
卷積神經網路實現手寫數字識別
採用了L2正則化、滑動平均模型,固定學習率
訓練結果為:訓練集100%,驗證集99.4%,測試集99.43%
第一部分:前向傳播和網路引數
# 定義前向傳播和神經網路中的引數 import tensorflow as tf # 配置神經網路引數 INPUT_NODE=784 # 輸入層節點個數 OUTPUT_NODE=10 # 輸出層節點個數 IMAGE_SIZE=28 NUM_CHANNELS=1 # 第一層卷積的尺寸和深度 CONV1_DEEP=32 CONV1_SIZE=5 # 第二層卷積的尺寸和深度 CONV2_DEEP=64 CONV2_SIZE=5 # 全連線層的節點個數 FC_SIZE=512 # 前向傳播 def inference(input_tensor,regularizer,avg_class,train=True,reuse=False): # 第一層卷積層 with tf.variable_scope('layer_conv1',reuse=reuse): conv1_weights=tf.get_variable('weights',[CONV1_SIZE,CONV1_SIZE,NUM_CHANNELS,CONV1_DEEP],initializer=tf.truncated_normal_initializer(mean=0,stddev=0.1)) conv1_biases=tf.get_variable('biases',[CONV1_DEEP],initializer=tf.constant_initializer(0.0)) conv1=tf.nn.conv2d(input_tensor,conv1_weights,[1,1,1,1],padding='SAME') relu1=tf.nn.relu(tf.nn.bias_add(conv1,conv1_biases)) # 第一層池化層 with tf.name_scope('layer_pool1'): pool1=tf.nn.max_pool(relu1,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME') # 第二層卷積層 with tf.variable_scope('layer_conv2',reuse=reuse): conv2_weights=tf.get_variable('weights',[CONV2_SIZE,CONV2_SIZE,CONV1_DEEP,CONV2_DEEP],initializer=tf.truncated_normal_initializer(stddev=0.1)) conv2_biases=tf.get_variable('biases',[CONV2_DEEP],initializer=tf.constant_initializer(0.0)) conv2=tf.nn.conv2d(pool1,conv2_weights,[1,1,1,1],padding='SAME') relu2=tf.nn.relu(tf.nn.bias_add(conv2,conv2_biases)) # 第二層池化層 with tf.name_scope('layer_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() # pool_shape[0]為BATCH_SIZE維度 nodes=pool_shape[1]*pool_shape[2]*pool_shape[3] FC_INPUT=tf.reshape(pool2,[pool_shape[0],nodes]) # 宣告第一層神經網路的變數並完成前向傳播 with tf.variable_scope('layer1',reuse=reuse): weights=tf.get_variable('weights',[nodes,FC_SIZE],initializer=tf.truncated_normal_initializer(mean=0,stddev=0.1)) biases=tf.get_variable('biases',[FC_SIZE],initializer=tf.constant_initializer(0.0)) if regularizer != None: tf.add_to_collection('losses',regularizer(weights)) if avg_class == None: fc1=tf.nn.relu(tf.matmul(FC_INPUT,weights)+biases) else: fc1=tf.nn.relu(tf.matmul(FC_INPUT,avg_class.average(weights))+avg_class.average(biases)) # dropout正則化,降低過擬合 if train: fc1=tf.nn.dropout(fc1,0.5) # 宣告第二層神經網路的變數並完成前向傳播 with tf.variable_scope('layer2',reuse=reuse): weights=tf.get_variable('weights',[FC_SIZE,OUTPUT_NODE],initializer=tf.truncated_normal_initializer(mean=0,stddev=0.1)) biases=tf.get_variable('biases',[OUTPUT_NODE],initializer=tf.constant_initializer(0.0)) if regularizer != None: tf.add_to_collection('losses',regularizer(weights)) if avg_class == None: fc2=tf.matmul(fc1,weights)+biases else: fc2=tf.matmul(fc1,avg_class.average(weights))+avg_class.average(biases) return fc2
第二部分:訓練,包括訓練集和驗證集
# 神經網路訓練程式 import numpy as np import tensorflow as tf import matplotlib.pyplot as plt from tensorflow.examples.tutorials.mnist import input_data import mnist_inference # 配置神經網路引數 BATCH_SIZE=128 LEARNING_RATE_BASE=0.8 LEARNING_RATE_DECAY=0.99 REGULARAZTION_RATE=0.0001 TRAINING_STEP=30000 MOVING_AVERAGE_DECAY=0.99 # 模型儲存路徑和檔名 MODEL_SAVE_PATH='./model2.ckpt' # 訓練引數 train_acc,valid_acc=[],[] train_loss,valid_loss=[],[] epochs=[] def train(mnist): x=tf.placeholder(tf.float32,[None,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') regularizer=tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE) y=mnist_inference.inference(x,regularizer=regularizer,avg_class=None,reuse=False,train=True) global_step=tf.Variable(0,trainable=False) variable_averages=tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step) variable_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=0.1 # tf.train.exponential_decay(LEARNING_RATE_BASE,global_step,mnist.train.num_examples/BATCH_SIZE,LEARNING_RATE_DECAY) train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step) with tf.control_dependencies([train_step,variable_averages_op]): train_op=tf.no_op(name='train') # 計算使用滑動平均之後的前向傳播結果 average_y=mnist_inference.inference(x,regularizer=regularizer,avg_class=variable_averages,train=True,reuse=tf.AUTO_REUSE) correct_prediction=tf.equal(tf.argmax(average_y,1),tf.argmax(y_,1)) #tf.cast為轉化資料格式 accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) # 初始化TensorFlow持久化類 saver=tf.train.Saver() with tf.Session() as sess: tf.initialize_all_variables().run() for i in range(TRAINING_STEP): xs,ys=mnist.train.next_batch(BATCH_SIZE) xs=np.reshape(xs,[BATCH_SIZE,mnist_inference.IMAGE_SIZE,mnist_inference.IMAGE_SIZE,mnist_inference.NUM_CHANNELS]) _,tra_loss,step=sess.run([train_op,loss,global_step],feed_dict={x:xs,y_:ys}) val_xs,val_ys=mnist.validation.next_batch(BATCH_SIZE) val_xs=np.reshape(val_xs,[BATCH_SIZE,mnist_inference.IMAGE_SIZE,mnist_inference.IMAGE_SIZE,mnist_inference.NUM_CHANNELS]) val_loss=sess.run([loss],feed_dict={x:val_xs,y_:val_ys}) epochs.append(step) train_acc.append(sess.run(accuracy,feed_dict={x:xs,y_:ys})) train_loss.append(tra_loss) valid_acc.append(sess.run(accuracy,feed_dict={x:val_xs,y_:val_ys})) valid_loss.append(val_loss) # 每1000輪 if (i+1)%1000==0: print('<==%d==>,loss on training batch is %g.'%(i+1,tra_loss)) print(train_acc[-1]) print(valid_acc[-1]) plt.figure(1) plt.grid(True) plt.subplot(1,2,1) plt.plot(epochs, train_loss, color='red',label='train') plt.plot(epochs, valid_loss, color='blue',label='valid') plt.legend() plt.xlabel('Epochs',fontsize=15) plt.ylabel('Y',fontsize=15) plt.title('Loss',fontsize=15) plt.subplot(1,2,2) plt.plot(epochs, train_acc, color='red',label='train') plt.plot(epochs, valid_acc, color='blue',label='valid') plt.legend() plt.xlabel('Epochs',fontsize=15) plt.ylabel('Y',fontsize=15) plt.title('Acc',fontsize=15) plt.show() saver.save(sess,MODEL_SAVE_PATH) def main(argv=None): mnist=input_data.read_data_sets('E:/User-Duanduan/python/Deep-Learning/tensorflow/data/MNIST_data/',one_hot=True) train(mnist) if __name__=='__main__': tf.app.run()
第三部分:測試集
# 測試模型 import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data import matplotlib.pyplot as plt import numpy as np import mnist_inference import mnist_train BATCH_SIZE=10000 def evaluate(mnist): with tf.Graph().as_default() as g: # 定義輸入輸出格式 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,[BATCH_SIZE,mnist_inference.OUTPUT_NODE],name='y-input') # 測試批量圖 y=mnist_inference.inference(x,None,None,train=False, reuse=False) correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(y_,1)) accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) # 讀取測試圖集 xs=mnist.test.images xs=np.reshape(xs,[BATCH_SIZE,mnist_inference.IMAGE_SIZE,mnist_inference.IMAGE_SIZE,mnist_inference.NUM_CHANNELS]) test_feed={x:xs,y_:mnist.test.labels} # 測試單張圖片 show_image=mnist.test.images[5000] label=mnist.test.labels[5000] flatten_image=np.reshape(show_image,[1,mnist_inference.IMAGE_SIZE,mnist_inference.IMAGE_SIZE,mnist_inference.NUM_CHANNELS]) actual_label=label.tolist().index(max(label.tolist())) x_test=tf.placeholder(tf.float32,[1,mnist_inference.IMAGE_SIZE,mnist_inference.IMAGE_SIZE,mnist_inference.NUM_CHANNELS],name='x-input') y_test=mnist_inference.inference(x_test,None,None,train=False,reuse=tf.AUTO_REUSE) pred_label=tf.argmax(y_test,1) variable_averages=tf.train.ExponentialMovingAverage(mnist_train.MOVING_AVERAGE_DECAY) variable_to_restore=variable_averages.variables_to_restore() saver=tf.train.Saver(variable_to_restore) with tf.Session() as sess: # 載入模型 saver.restore(sess,'./model.ckpt') # 批量測試 accuracy_score=sess.run(accuracy,feed_dict=test_feed) print('Test accuracy is %g%%'%(accuracy_score*100)) # 單張測試 result=sess.run(pred_label,feed_dict={x_test:flatten_image}) print('Actual:%g,predtion:%g'%(actual_label,result)) show_image=tf.reshape(show_image,[28,28]) plt.figure('Show') plt.imshow(show_image.eval()) plt.show() def main(argv=None): mnist=input_data.read_data_sets('E:/User-Duanduan/python/Deep-Learning/tensorflow/data/MNIST_data/',one_hot=True) evaluate(mnist) if __name__=='__main__': tf.app.run()