1. 程式人生 > 其它 >MNIST資料集全連線神經網路python實現

MNIST資料集全連線神經網路python實現

技術標籤:演算法的程式碼實現TensorFlow深度學習演算法原理與程式設計實戰讀書筆記pythontensorflow機器學習

# coding: utf-8
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

# 注意這裡的one_hot=True 否則label不會以向量的形式給出
mnist = input_data.read_data_sets\
    ("************", one_hot=True) # 請輸入你要儲存的位置

# 以下資訊用於檢視資料資訊
# print("Training data and label size:") # print(mnist.train.images.shape, mnist.train.labels.shape) # print("Testing data and label size:") # print(mnist.test.images.shape, mnist.test.labels.shape) # print("Validation data and label size:") # print(mnist.validation.images.shape, mnist.validation.labels.shape)
# 檢視真實資料例項,其中0表示白色背景,0~1表示有字跡區域 # print("Example training data:", mnist.train.images[0]) # print("Example training label:", mnist.train.labels[0]) # 超引數設定 batch_size = 100 # 設定每一輪訓練的Batch大小 learning_rate = 0.8 # 初始學習率 learning_rate_decay = 0.999 # 學習率的衰減 max_steps =
30000 #最大訓練步數 # 定義儲存訓練輪數的變數,在使用Tensorflow訓練神經網路時, # 一般會將代表訓練輪數的變數通過trainable引數設定為不可訓練的 training_step = tf.Variable(0, trainable=False) # 實現單隱藏層全連線網路,ReLU函式作為啟用函式 def hidden_layer(input_tensor, weights1, biases1, weights2, biases2, layer_name): layer1 = tf.nn.relu(tf.matmul(input_tensor, weights1) + biases1) return tf.nn.relu(tf.matmul(layer1, weights2) + biases2) x = tf.placeholder(tf.float32, [None, 784], name="x-input") y_=tf.placeholder(tf.float32, [None, 10], name="y-output") # 生成隱藏層引數,其中weights1包含了784*500=39200個引數 weights1 = tf.Variable(tf.truncated_normal([784, 500], stddev=0.1)) biases1 = tf.Variable(tf.constant(0.1, shape=[500])) # shape引數 都是要用[*]賦值的 # 生成輸出層引數,其中weights2包含了500*10=500個引數 weights2 = tf.Variable(tf.truncated_normal([500, 10], stddev=0.1)) biases2 = tf.Variable(tf.constant(0.1, shape=[10])) # shape引數 都是要用[*]賦值的 # 計算經過神經網路前向傳播後得到的y值 y = hidden_layer(x, weights1, biases1, weights2, biases2, 'y') # 將平滑平均的方法應用到引數上 # 初始化一個平滑平均類,衰減率為0.99 # 為了使模型訓練前期可以更新的更快,這裡提供了了num_updates引數,並設定為當前網路的訓練輪數 averages_class = tf.train.ExponentialMovingAverage(0.99, training_step) # 定義一個更新變數平滑平均值的操作需要向平滑平均類的apply()函式提供一個引數列表 # train_variables()函式返回集合上Graph.TRAINABLE_BARIABLES中的元素, # 這個集合的元素就是所有沒有指定trainable_variable_variables=False的引數 averages_op = averages_class.apply(tf.trainable_variables()) # 前向計算y average_y = hidden_layer(x, averages_class.average(weights1), averages_class.average(biases1), averages_class.average(weights2), averages_class.average(biases2),'average_y') # 計算交叉熵損失 # 函式原型為sparse_softmax_cross_entropy_with_logits() 適用於樣本只能被劃分為一類,即每個類別互相獨立互斥 # tf.argmax()函式的解釋:https://blog.csdn.net/Jiaach/article/details/78874704?utm_medium=distribute.pc_relevant_t0. # none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant_t0. # none-task-blog-BlogCommendFromMachineLearnPai2-1.control cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))# 返回按行查詢最大值下標 # 正則化損失函式 regularizer = tf.contrib.layers.l2_regularizer(0.0001) regularization = regularizer(weights1) + regularizer(weights2) loss = tf.reduce_mean(cross_entropy) + regularization # 用指數衰減法設定學習率,這裡staircase引數採用預設的False,即學習率連續衰減 learning_rate = tf.train.exponential_decay(learning_rate, training_step, mnist.train.num_examples/batch_size, learning_rate_decay) # 使用GradientDescentOptimizer優化演算法來優化交叉熵損失函式和正則化損失 train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=training_step) # 在訓練模型的時候,每過一邊資料即需要反向傳播來更新神經網路的中的引數,又需要更新每一個引數的平滑平均值 # 等價程式碼: train_op = tf.group(train_step, averages_op) with tf.control_dependencies([train_step, averages_op]): train_op = tf.no_op(name="train") # 檢查使用了滑動平均值模型的神經網路,向前傳播結果是否正確 # equal()用於判斷兩個張量的每一是否相等,相等返回True 否則False crorent_predicition = tf.equal(tf.argmax(average_y, 1), tf.argmax(y_, 1)) # cast() 函式原型為cast(x, DstT, name),在這裡用於將一個布林型的資料轉換為float32型別 # 之後對得到的float32型別的資料求平均值,這個平均值就是模型在這一組資料上的正確率 accuracy = tf.reduce_mean(tf.cast(crorent_predicition, tf.float32)) # 開始會話 with tf.Session() as sess: tf.global_variables_initializer().run() # 準備驗證資料 validate_feed = {x:mnist.validation.images, y_:mnist.validation.labels} # 準備測試資料 test_feed = {x:mnist.test.images, y_:mnist.test.labels} for i in range(max_steps): if i%1000 == 0: # 計算滑動平均模型在驗證資料上的結果 # 為了能得到百分數輸出,需要將得到的validate_accuracy擴大了100倍 validate_accuracy = sess.run(accuracy, feed_dict=validate_feed) print("After %d trainging step(s), validation accuracy" "using average model is %g%%" %(i, validate_accuracy*100)) # 產生這一輪使用一個batch的訓練資料,並進行訓練 # input_data.read_data_sets()函式生成的類提供train.next_batch()函式 xs, ys = mnist.train.next_batch(batch_size=100) sess.run(train_op, feed_dict={x:xs, y_:ys}) # 使用測試資料集檢驗神經網路訓練之後的最終正確率 # 為了能得到百分數的輸出,需要將得到的test_accuracy擴大100倍 test_accuracy = sess.run(accuracy, feed_dict=test_feed) print("After %d trainging step(s), test_accuracy using average" "model is %g%%" %(max_steps, test_accuracy*100))

參考文獻:《TensorFlow 深度學習演算法原理與程式設計實戰》