TensorFlow 訓練MNIST數據集(2)—— 多層神經網絡

 

  在個人上一篇隨筆中,採用了單層神經網絡來對MNIST進行訓練,在測試集中只有約90%的正確率。此次換一種神經網絡(多層神經網絡)來進行訓練和測試。html

 

一、獲取MNIST數據git

  MNIST數據集只要一行代碼就能夠獲取的到,很是方便。關於MNIST的基本信息能夠參考個人上一篇隨筆。網絡

mnist = input_data.read_data_sets('./data/mnist', one_hot=True)

 

二、模型基本結構dom

  本次採用的訓練模型爲三層神經網絡結構,輸入層節點數與MNIST一行數據的長度一致,爲784;輸出層節點數與數字的類別數一致,爲10;隱藏層節點數爲50個;每次訓練的mini-batch數量爲64,;最大訓練週期爲50000。ide

1 inputSize  = 784
2 outputSize = 10
3 hiddenSize = 50
4 batchSize  = 64
5 trainCycle = 50000

 

三、輸入層函數

  輸入層用於接收每次小批量樣本的輸入,先經過placeholder來進行佔位,在訓練時才傳入具體的數據。值得注意的是,在生成輸入層的tensor時,傳入的shape中有一個‘None’,表示每次輸入的樣本的數量,該‘None’表示先不做具體的指定,在真正輸入的時候再根據實際的數據來進行推斷。這個很方便,但也是有條件的,也就是經過該方法返回的tensor不能使用簡單的加(+)減(-)乘(*)除(/)符號來進行計算(不然將會報錯),須要用TensorFlow中的相關函數來進行代替。測試

inputLayer = tf.placeholder(tf.float32, shape=[None, inputSize])

 

四、隱藏層優化

  在神經網絡中,隱藏層的做用主要是提取數據的特徵(feature)。這裏的權重參數採用了 tensorflow.truncated_normal() 函數來進行生成,與上次採用的 tensorflow.spa

random_normal() 不同。這二者的做用都是生成指定形狀、指望和標準差的符合正太分佈隨機變量。區別是 truncated_normal 函數對隨機變量的範圍有個限制(與指望的誤差在2個標準差以內,不然丟棄)。另外誤差項這裏也使用了變量的形式,也能夠採用常量來進行替代。 code

  激活函數爲sigmoid函數。

1 hiddenWeight = tf.Variable(tf.truncated_normal([inputSize, hiddenSize], mean=0, stddev=0.1))
2 hiddenBias   = tf.Variable(tf.truncated_normal([hiddenSize]))
3 hiddenLayer  = tf.add(tf.matmul(inputLayer, hiddenWeight), hiddenBias)
4 hiddenLayer  = tf.nn.sigmoid(hiddenLayer)

 

五、輸出層

  輸出層與隱藏層相似,只是節點數不同。

1 outputWeight = tf.Variable(tf.truncated_normal([hiddenSize, outputSize], mean=0, stddev=0.1))
2 outputBias   = tf.Variable(tf.truncated_normal([outputSize], mean=0, stddev=0.1))
3 outputLayer  = tf.add(tf.matmul(hiddenLayer, outputWeight), outputBias)
4 outputLayer  = tf.nn.sigmoid(outputLayer)

 

六、輸出標籤

  跟輸入層同樣,也是先佔位,在最後訓練的時候再傳入具體的數據。標籤,也就是每個樣本的正確分類。

outputLabel = tf.placeholder(tf.float32, shape=[None, outputSize])

 

七、損失函數

  這裏採用的是交叉熵損失函數。注意用的是v2版本,第一個版本已被TensorFlow聲明爲deprecated,準備廢棄了。

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=outputLabel, logits=outputLayer))

 

八、優化器與目標函數

  優化器採用了Adam梯度降低法,我試過了普通的GradientDescentOptimizer,效果不如Adam;也用過Adadelta,結果幾乎收斂不了。

  目標函數就是最小化損失函數。

optimizer = tf.train.AdamOptimizer()
target    = optimizer.minimize(loss)

 

九、訓練過程

  先建立一個會話,而後初始化tensors,最後進行迭代訓練。模型的收斂速度很快,在1000次的時候就達到了大概90%的正確率。

 1 with tf.Session() as sess:
 2     sess.run(tf.global_variables_initializer())
 3 
 4     for i in range(trainCycle):
 5         batch = mnist.train.next_batch(batchSize)
 6         sess.run(target, feed_dict={inputLayer: batch[0], outputLabel: batch[1]})
 7 
 8         if i % 1000 == 0:
 9             corrected = tf.equal(tf.argmax(outputLabel, 1), tf.argmax(outputLayer, 1))
10             accuracy = tf.reduce_mean(tf.cast(corrected, tf.float32))
11             accuracyValue = sess.run(accuracy, feed_dict={inputLayer: batch[0], outputLabel: batch[1]})
12             print(i, 'train set accuracy:', accuracyValue)

模型訓練輸出:

 

十、測試訓練結果

  在測數據集上測試。準確率達到96%,比單層的神經網絡好不少。

1     corrected = tf.equal(tf.argmax(outputLabel, 1), tf.argmax(outputLayer, 1))
2     accuracy  = tf.reduce_mean(tf.cast(corrected, tf.float32))
3     accuracyValue = sess.run(accuracy, feed_dict={inputLayer: mnist.test.images, outputLabel: mnist.test.labels})
4     print("accuracy on test set:", accuracyValue)

測試集上的輸出:

 

 

附:

  完整代碼以下:

 1 import tensorflow as tf
 2 from tensorflow.examples.tutorials.mnist import input_data
 3 
 4 mnist = input_data.read_data_sets('./data/mnist', one_hot=True)
 5 
 6 inputSize  = 784
 7 outputSize = 10
 8 hiddenSize = 50
 9 batchSize  = 64
10 trainCycle = 50000
11 
12 # 輸入層
13 inputLayer = tf.placeholder(tf.float32, shape=[None, inputSize])
14 
15 # 隱藏層
16 hiddenWeight = tf.Variable(tf.truncated_normal([inputSize, hiddenSize], mean=0, stddev=0.1))
17 hiddenBias   = tf.Variable(tf.truncated_normal([hiddenSize]))
18 hiddenLayer  = tf.add(tf.matmul(inputLayer, hiddenWeight), hiddenBias)
19 hiddenLayer  = tf.nn.sigmoid(hiddenLayer)
20 
21 # 輸出層
22 outputWeight = tf.Variable(tf.truncated_normal([hiddenSize, outputSize], mean=0, stddev=0.1))
23 outputBias   = tf.Variable(tf.truncated_normal([outputSize], mean=0, stddev=0.1))
24 outputLayer  = tf.add(tf.matmul(hiddenLayer, outputWeight), outputBias)
25 outputLayer  = tf.nn.sigmoid(outputLayer)
26 
27 # 標籤
28 outputLabel = tf.placeholder(tf.float32, shape=[None, outputSize])
29 
30 # 損失函數
31 loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=outputLabel, logits=outputLayer))
32 
33 # 優化器
34 optimizer = tf.train.AdamOptimizer()
35 
36 # 訓練目標
37 target = optimizer.minimize(loss)
38 
39 # 訓練
40 with tf.Session() as sess:
41     sess.run(tf.global_variables_initializer())
42 
43     for i in range(trainCycle):
44         batch = mnist.train.next_batch(batchSize)
45         sess.run(target, feed_dict={inputLayer: batch[0], outputLabel: batch[1]})
46 
47         if i % 1000 == 0:
48             corrected = tf.equal(tf.argmax(outputLabel, 1), tf.argmax(outputLayer, 1))
49             accuracy = tf.reduce_mean(tf.cast(corrected, tf.float32))
50             accuracyValue = sess.run(accuracy, feed_dict={inputLayer: batch[0], outputLabel: batch[1]})
51             print(i, 'train set accuracy:', accuracyValue)
52 
53     # 測試
54     corrected = tf.equal(tf.argmax(outputLabel, 1), tf.argmax(outputLayer, 1))
55     accuracy  = tf.reduce_mean(tf.cast(corrected, tf.float32))
56     accuracyValue = sess.run(accuracy, feed_dict={inputLayer: mnist.test.images, outputLabel: mnist.test.labels})
57     print("accuracy on test set:", accuracyValue)
58 
59     sess.close()
View Code

 

本文地址:http://www.javashuo.com/article/p-basqmewq-by.html

相關文章
相關標籤/搜索