Tensorflow第一個例子 原 薦

安裝完Tensorflow之後,嘗試經典的MNIST手寫體識別的例子。該例子在安裝tensorflow之後自帶,可在如下目錄中找到(Anaconda_PATH代表安裝Anaconda的目錄位置)

Anaconda_PATH\envs\TensorFlow\Lib\site-packages\tensorflow\examples\tutorials\mnist

該目錄中包含三個例子mnist_softmax.py,fully_connected_feed.py,mnist_with_summaries.py。其他幾個文件是這幾個例子執行時需要引用的。先從最簡單的例子mnist_softmax.py來說明tensorflow的基本概念和原理。

 

mnist_softmax.py文件的內容如下:

# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================

"""A very simple MNIST classifier.

See extensive documentation at
http://tensorflow.org/tutorials/mnist/beginners/index.md
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import sys

# Import data
from tensorflow.examples.tutorials.mnist import input_data

import tensorflow as tf

FLAGS = None


def main(_):
  mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)

  # Create the model
  x = tf.placeholder(tf.float32, [None, 784])
  W = tf.Variable(tf.zeros([784, 10]))
  b = tf.Variable(tf.zeros([10]))
  y = tf.matmul(x, W) + b

  # Define loss and optimizer
  y_ = tf.placeholder(tf.float32, [None, 10])

  # The raw formulation of cross-entropy,
  #
  #   tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(tf.nn.softmax(y)),
  #                                 reduction_indices=[1]))
  #
  # can be numerically unstable.
  #
  # So here we use tf.nn.softmax_cross_entropy_with_logits on the raw
  # outputs of 'y', and then average across the batch.
  cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y, y_))
  train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

  sess = tf.InteractiveSession()
  # Train
  tf.global_variables_initializer().run()
  for _ in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

  # Test trained model
  correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
  accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
  print(sess.run(accuracy, feed_dict={x: mnist.test.images,
                                      y_: mnist.test.labels}))

if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument('--data_dir', type=str, default='/tmp/tensorflow/mnist/input_data',
                      help='Directory for storing input data')
  FLAGS, unparsed = parser.parse_known_args()
  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)

可在命令行執行如下命令直接運行它:

python mnist_softmax.py

但是很有可能運行報錯,因爲天朝的網絡很難下載數據集(反正我運行了好幾次都不行)。最可靠的方法是新建data目錄,下載下面四個文件(數據集)放到data中

http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz

http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz

http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz

http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz

然後執行如下命令:

python mnist_softmax.py --data_dir data

可能的輸出如下:

恭喜,說明第一個例子運行成功了。

 

接下來解釋一下這個例子做了什麼事。

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)

這兩句用於下載數據(很不幸一般很難下載下來),並將數據讀入內存。數據讀入內存後會分爲三部分,訓練集(mnist.train,包含55000個樣例),測試集(mnist.test,包含10000個樣例),校驗集(mnist.validation,包含5000個樣例)。每一個樣例可以看成一個”點“,每個點包含一張圖(手寫數字的照片,可記爲x)和一個標記(一個數字,表示這個手寫的數字是幾,可記爲y)。每張圖都是28x28=784像素大小的,如果把每個像素點記爲一個浮點數,則每個點包含784個x(因爲圖片是黑白的,所以用一個浮點數表示灰度即可)和一個0-9的整數y。

 

在此例中,採用了單層10個神經元的神經網絡,每個神經元對應0-9中的一個數,每個神經元最終的輸出相當於該圖片爲這個數字的概率。Tensorflow在python環境中獲取所有的神經網絡模型信息之後,利用底層的庫(通過NumPy庫進行轉換)來進行高效地計算(比如大量的矩陣乘法)。

import tensorflow as tf

x = tf.placeholder(tf.float32, [None, 784])

這兩句中第一句引入了tensorflow庫,第二句則定義了輸入變量,因爲要在獲得整個網絡信息之後才進行計算,所以此處的網絡輸入是未知的,因此只是定義了一個佔位符變量,表示輸入量是2維浮點數,其中第一維可能是任意長度(第一維是None,代表任意長度),第二維長度爲784,代表一張圖上所有的像素點。

 

接下來兩句定義了變量,表示在計算中可以改變但一直存在的參數,並規定其初值均爲0。由於神經網絡計算就是要求出權重W和偏置b,因此這些變量可以取任意初始值。

W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

 

本來至此應該定義模型如下,表示輸出y=f_softmax(W.x+b)

y = tf.nn.softmax(tf.matmul(x, W) + b)

但正如mnist_softmax.py原文中所解釋的,爲了後面定義訓練模型的規則,此處改爲了

y = tf.matmul(x, W) + b

y_ = tf.placeholder(tf.float32, [None, 10])

cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y, y_))

第1行僅定義了y=W.x+b,然後爲了定義該模型怎麼樣算好,或者說我們希望以什麼東西爲標準來進行優化,又定義了cross_entropy(交叉熵)的概念,該概念依賴於真實值y'和計算值y,滿足

cross_entropy = - sum_i y'_i log(y_i)

y' 代表每張圖所代表的真實值,比如 3 的話,就是(0,0,0,1,0,0,0,0,0,0)。交叉熵越大,意味着結果越差。因此第2行定義了y_佔位符來保存真正的輸出值,第3行給出了交叉熵的定義。

 

接下來利用反向傳播算法最小化cross_entropy,訓練模型

train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

該語句表示利用梯度下降算法,以learning_rate=0.5的學習速率,最小化之前定義的cross_entropy。至此,整個神經網絡模型構建好,tensorflow可以進行計算,調整參數,給出最終結果了。注意tensorflow提供了很多優化算法,可參考如下鏈接

https://www.tensorflow.org/api_guides/python/train#optimizers

 

最後可以進行真正的計算了

sess = tf.InteractiveSession()

tf.global_variables_initializer().run()
for _ in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

前兩句創建了一個session進行計算,並對變量進行初始化;後面的循環進行真正的計算。在此處共循環1000次,每次從訓練集中隨機取100個點(每個點包含一張圖和一個標籤),然後用這些點替換之前的佔位符,然後執行train_step定義的計算。值得注意的是,原則上每次循環都應該用上訓練集中的所有點,但這樣計算過於耗時,因此這個例子中使用了訓練集的子集來進行計算,也能給出不錯的結果。

 

最後,對訓練的結果進行測試

correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(sess.run(accuracy, feed_dict={x: mnist.test.images,
                                      y_: mnist.test.labels}))

tf.argmax函數給出張量沿某個方向的最大值所在的指標,因此tf.argmax(y,1)給出神經網絡模型所認爲的圖片對應的數字,而tf.argmax(y_,1)則給出該圖片真實對應的數字。correct_prediction表示神經網絡模型預言是否正確。第2行則將這些對錯序列轉化爲浮點數,比如[true, true, false, true,...]轉化爲[1,1,0,1,...],然後計算其平均值。最後一行將最終的正確率打印出來。如前面圖中的結果所示,正確率達到0.9196,約爲92%,還算不錯。

 

更詳細的說明可參考如下鏈接:

https://www.tensorflow.org/get_started/mnist/beginners

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章