tensorflow學習筆記之(二)—— Mnist For Beginner

tensorflow學習筆記之(二)—— Mnist For Beginner

(首發日期:2017年12月24日 更新日期:2018年01月12日18:58:07)


【內容摘要】:

  1. mnist for beginner 的系統運轉和解析;
  2. softmax()詳解
  3. 損失函數的生成原理

本文爲tensorflow的MNIST代碼實例,原文鏈接:

英文版tensorflow-MNIST For ML Beginner

中文版tensorflow mnist for beginner

我的學習筆記blog:

tensorflow學習筆記之(二)—— Mnist For Beginner


MNIST是一個入門級的計算機視覺數據集,它包含各種手寫數字圖片以及圖片對應的標籤:數字。本教程就是通過數據集合來訓練一個機器學習模型來實現機器自動識別圖像數字。

MNIST 數據包下載

按照教程,使用下面兩行代碼下載:
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets(“MNIST_data/”, one_hot=True)
編寫成文件:MnistDataDownload.py
執行:
這裏寫圖片描述
會新建文件夾並下載數據文件:
這裏寫圖片描述
這裏有四個文件,兩個訓練語料,兩個測試語料。訓練語料分爲圖像和標籤,測試語料一樣。
數據集包含了:55000樣本的訓練集,10000樣本的測試集以及5000個樣本的驗證集
同時要注意的是關於這些訓練和測試集的數據組成:數據(x)+標籤(y),其中數據就是指“圖片”,而標籤就是該圖片代表的手寫字母的意義,例如“b”或者”B”等。這裏數據是一個28*28的圖片,該圖片數據被展平成爲一個28*28=784長的一個數據,這個數據可以被理解爲一個長784的數組(損失部分二維信息),也可以被認爲是一個784維度的矢量。我們知道由這784個點張成的矢量空間是巨大的。

55,000 data points of training data (mnist.train)
10,000 points of test data (mnist.test)
5,000 points of validation data (mnist.validation)

對於訓練集合是一個張量T,它有着[55000,784]的shape,第一維度是圖像樣本的編號,第二個則是圖像樣本點序列編號,而每一個張量對應一個標籤也就是分類所屬標誌,這裏用0~9來分別表徵。表示此標籤的方法採用“one-hot”矢量來實現,也就是說,此矢量除了某一特定維度的值爲非零(1),其餘的都爲0,此矢量的維度總數爲分類總數。理解一下就是,希望每一個圖像與其標籤的類屬形成對應關係,例如標籤爲[0,0,1,0,0,0,0,0,0,0]則此圖像是2類的標籤,而與其他類的運算結果是0,於是訓練集合標籤就是一個[55000,10]的張量L。

L[55000,10]=X[55000,784]W[784,10]+B[10]

Softmax 迴歸

Softmax迴歸分兩步:第一步,將屬於各自分類的輸入的顯著性進行累加;第二步,將這些顯著性轉換爲概率。
對於屬於第i類的顯著程度計算:

evidencei=j=1784Wijxj+bii=1...10

寫成矩陣形式爲:
(ei,1,ei,2,,ei,10)=(xi,1,xi,2,...,xi,784)w1,1w2,1...w784,1w1,2w2,2w784,2.........w1,10w2,10w784,10+(b1,b2,...,b10)

擴展到對所有的訓練樣本圖片:

e1,1,e1,2,...,e1,10e2,1,e2,2,...,e2,10...e55000,1,e55000,2,...,e55000,10=x1,1,x1,2,...,x1,784x2,1,x2,2,...,x2,784...x55000,1,x55000,2,...,x55000,784w1,1w2,1...w784,1w1,2w2,2w784,2.........w1,10w2,10w784,10+(b1,b2,...,b10)

可見b是一個與輸入無關的量。

下面是進行mnist訓練和測試的代碼,這裏將源程序當中的main()直接添加到主程序當中,以便調試和監視。
爲了能夠將這個最簡單的Ai框架說清楚,最近的幾篇我都不厭其煩的將各個步驟單獨列寫,方便概念的養成:

程序源碼地址:
mnist_softmax.py

【框架】——環境

import argparse#參見[參考文獻1]
import sys
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
#mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
FLAGS = None
parser = argparse.ArgumentParser()
parser.add_argument('--data_dir', type=str, default='MNIST_data/',
                      help='Directory for storing input data')
FLAGS, unparsed = parser.parse_known_args()
#FLAGS.data_dir
#tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)
mnist = input_data.read_data_sets(FLAGS.data_dir)

_StoreAction(option_strings=['--data_dir'], dest='data_dir', nargs=None, const=None, default='MNIST_data/', type=<class 'str'>, choices=None, help='Directory for storing input data', metavar=None)



Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz

【框架】—— 創建圖

構造圖:構造各種神經網絡需要的節點(ops),搭建各個節點的聯繫

【AI框架】——建模+定義損失

搭建系統模型,單就針對本文,是對簡化的一維數據(圖像)進行變換(Y=XW+B),所以這就是建模部分;

接下來求取或者制定損失函數,損失函數常用的有各種距離測度,本文用的是交叉熵測度,這兩種測度有沒有什麼數學聯繫我說不好,但是說明的意義是估計值y與實際值yr 之間的差異。

# 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#預測的輸出 y,這裏應該還是個顯著性表示,shape[None,10]
# Define loss and optimizer
y_ = tf.placeholder(tf.int64, [None])
#訓練樣本的實際輸出,one-hot(後來從運行結果看,根本不是one-hot樣式),顯然y_的shape和y的模式不同,這樣如何進行誤差計算?

# 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.losses.sparse_softmax_cross_entropy on the raw
# outputs of 'y', and then average across the batch.
cross_entropy = tf.losses.sparse_softmax_cross_entropy(labels=y_, logits=y)#可見此函數隱藏了y和y_的shape差異
#計算評估測度——損失(交叉熵)
#?tf.losses.sparse_softmax_cross_entropy
the_entropy = tf.cast(y_,tf.float32) * tf.log(tf.nn.softmax(y))
raw_cross_entropy = tf.reduce_mean(-tf.reduce_sum(the_entropy, reduction_indices=[1]))

【分析】


但是,如果按照上面註釋部分所說,想了解一下到底cross_entropy是怎麼計算出來的,也就是tf.losses.sparse_softmax_cross_entropy到底幹了些什麼?那麼需要計算這麼幾個量:

the_entropy = y_ * tf.log(tf.nn.softmax(y)) 
tf.reduce_mean(-tf.reduce_sum(the_entropy, reduction_indices=[1]))


然而在運行the_entropy = y_ * tf.log(tf.nn.softmax(y))時會報錯:

“ValueError: Tensor conversion requested dtype int64 for Tensor with dtype float32: 'Tensor("Log_2:0", shape=(?, 10), dtype=float32)'”

於是進行數據類型的轉換,使用cast完成:

the_entropy = tf.cast(y_,tf.float32) * tf.log(tf.nn.softmax(y))

但是即便如此,還是會出錯,往下看:

【AI框架】——定義損失優化器

對訓練樣本進行訓練,目的讓估計值y與實際值y_誤差測度loss最小,理想狀態等於0,然後讓這個指標作爲反饋修正系統Y=XW+B 參數“W”和“B”。
選擇優化器,本文當中選擇爲梯度下降法,參數0.5,梯度下降法的目標是“最小化交叉熵”。
至此,模型建立完畢,可以開始加載實際數據進行計算:

train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
#訓練器設定,採用梯度下降法(參數0.5),最小化損失測度

【框架】——新建 會話(啓動圖)、執行會話

新建會話session有兩種方式:

1. sess = tf.Session()#如果沒有參數,那麼就是啓動默認圖

另一種是交互式會話:

2. sess = tf.InteractiveSession()#啓動交互式默認圖

執行會話採用: sess.run()完成

【AI框架】——訓練

分批次讀入數據,每次100個樣本,對這批樣本進行訓練完成後再進行下一批訓練,總共1000次。

sess = tf.InteractiveSession()#啓動交互式默認圖
tf.global_variables_initializer().run()#初始化所有變量
# Train
loopi =0
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})#開始訓練,每次訓練feed的數據來自字典feed_dict  
    #print('batch_xs =',batch_xs)
    if (loopi%40 ==0):
        print('cross_entropy =',sess.run(cross_entropy, feed_dict={x: batch_xs, y_: batch_ys}))
    loopi =loopi+1
cross_entropy = 1.85022
cross_entropy = 0.583476
cross_entropy = 0.392438
cross_entropy = 0.369045
cross_entropy = 0.304192
cross_entropy = 0.364163
cross_entropy = 0.391069
cross_entropy = 0.320981
cross_entropy = 0.323675
cross_entropy = 0.248099
cross_entropy = 0.211977
cross_entropy = 0.211069
cross_entropy = 0.348796
cross_entropy = 0.279707
cross_entropy = 0.288246
cross_entropy = 0.153795
cross_entropy = 0.228082
cross_entropy = 0.223977
cross_entropy = 0.269843
cross_entropy = 0.255193
cross_entropy = 0.205329
cross_entropy = 0.198503
cross_entropy = 0.24288
cross_entropy = 0.223308
cross_entropy = 0.340573

【AI框架】——測試

訓練完成之後對訓練好的系統使用測試樣本進行測試,分析計算精度等信息。

#訓練完成
# Test trained model
#觀察估計值y和樣本結果y_
print('y =',sess.run(y ,feed_dict={x: mnist.test.images,y_: mnist.test.labels}))
print('y_ =',sess.run(y_, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
y = [[  0.82457638  -8.54294777   1.04939973 ...,  10.39043713  -0.45304376
    2.54141474]
 [  4.10910511  -1.04704607  10.18125534 ..., -14.02100372   3.85313344
   -8.19689178]
 [ -5.23071909   6.07755136   1.88477743 ...,   0.2769537    0.51267183
   -1.44546151]
 ..., 
 [ -6.92563915  -6.94087696  -2.38390899 ...,   1.44899988   3.00235152
    4.39945078]
 [ -1.91081893  -1.35006583  -1.97515893 ...,  -4.29256821   4.62356377
   -2.99994278]
 [  3.77089262  -9.82412243   5.68950176 ...,  -7.78482723  -0.64836574
   -3.81424999]]
y_ = [7 2 1 ..., 4 5 6]

【分析】

從上面的觀測結果可以看到,實際值y_是一個指示(0~9)的位置信息,而y仍舊是最初的顯著性信息,也就是與各類的“距離”測度(不過是越近值越大),若要讓y和y_具有相同的結構形式,還需要y經過如下步驟:

1.將顯著性信息轉化爲概率;

2.選出概率顯著最大的一個分類所在的位置。

可是這樣以來,兩個類似y_這樣形式的序列會損失與各類的距離測度信息,這樣無論如何也不能得到很好的y和有y_之間的誤差信息了,更別說按照交叉熵的概念進行誤差計算了。怎麼辦?後面在下一個工程當中再加以說明。

看看上面這個1和2,實際就是softmax()函數,好在tensorflow夠NB的,已經替我們把這個過程考慮了。看計算損失測度的函數“sparse_softmax_cross_entropy”就是典型的完成了上述過程:

cross_entropy = tf.losses.sparse_softmax_cross_entropy(labels=y_, logits=y)

接下來逐個分析損失函數:

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

print('the  first  position of maxvalue of y is:',sess.run(tf.argmax(y, 1),feed_dict={x: mnist.test.images,
                                  y_: mnist.test.labels}))
print('correct_prediction =',sess.run(correct_prediction, feed_dict={x: mnist.test.images,
                                  y_: mnist.test.labels}))
#tf.reduce_mean進行均值求解
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print('accuracy =',sess.run(accuracy, feed_dict={x: mnist.test.images,
                                  y_: mnist.test.labels}))


#tf.cast將correct_prediction轉成float32數據類型
print('change correct_prediction to float:',sess.run(tf.cast(correct_prediction, tf.float32), feed_dict={x: mnist.test.images,
                                  y_: mnist.test.labels}))
#求TRUE的總數
print('In test samples total right mounts:',sess.run(tf.reduce_sum(tf.cast(correct_prediction, tf.float32)), feed_dict={x: mnist.test.images,
                                  y_: mnist.test.labels}))  
#觀察訓練樣本當中估計值y的最大值位置序列
print('In test samples the maxvalue position sequence of y:',sess.run(tf.argmax(y, 1),feed_dict={x: mnist.train.images,
                                  y_: mnist.train.labels}))
#觀測訓練樣本中目標值y_的序列
print('In train samples y_ sequence:',sess.run(y_,feed_dict={x: mnist.train.images,y_: mnist.train.labels}))
#求訓練樣本估計值y的位置估計正確計數
print('In train samples total right mounts:',sess.run(tf.reduce_sum(tf.cast(correct_prediction, tf.float32)), feed_dict={x: mnist.train.images,
                                  y_: mnist.train.labels})) 
#求訓練樣本估計值y的位置估計正確率
print('In train samples  the right rate:',sess.run(tf.reduce_mean(tf.cast(correct_prediction, tf.float32)), feed_dict={x: mnist.train.images,
                                  y_: mnist.train.labels})) 
#mnist.test數據幾個總共有10000個樣本,總共檢測正確9198,所以正確概率就是0.9198 
cross_entropy = 0.291158
the  first  position of maxvalue of y is: [7 2 1 ..., 4 5 6]
correct_prediction = [ True  True  True ...,  True  True  True]
accuracy = 0.9159
change correct_prediction to float: [ 1.  1.  1. ...,  1.  1.  1.]
In test samples total right mounts: 9159.0
In test samples the maxvalue position sequence of y: [4 6 1 ..., 9 0 8]
In train samples y_ sequence: [5 6 1 ..., 9 0 0]
In train samples total right mounts: 50347.0
In train samples  the right rate: 0.9154

【分析】

correct_prediction計算的是估計值和實際值之間一致性結果。

[函數解釋]

tf.argmax(y, 1):在軸1((x方向)取值範圍:(0~9))上首次出現y的最大值的位置,與y_是否一致,結果是一個TRUE/FALSE列表。

loss function

測試樣本的交叉熵:cross_entropy

但是這個cross_entropy的獲取函數是封裝的,不好從原理上了解,於是分析測試樣本的raw_cross_entropy

但是這個報錯“InvalidArgumentError: Incompatible shapes: [10000] vs. [10000,10]”,就是說維度不一致,也是,看看the_entropy = tf.cast(y_,tf.float32) * tf.log(tf.nn.softmax(y))就是一個怪胎,按道理說tf.log(tf.nn.softmax(y)應該與y同形,tf.cast(y_,tf.float32)與y_同形,可是y和y_長啥樣子,從前面運行結果可以看到。
到這裏只能說明一點:y_是爲了輸入簡便被簡化了,其原形應該是one-hot形狀,也就是說應該是[none,10]這種shape的。
還好,我往前查github當中老版本的本文件(mnist_softmax.py)印證了這個判斷,原形真就是這樣的:

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

這樣就可以驗證損失函數的原理了!不過爲了本程序的完整性,先將剩餘部分運行完畢,然後再進行損失原理的驗證。

#觀測點
print('tf.nn.softmax(y) =',sess.run(tf.nn.softmax(y), feed_dict={x: mnist.train.images,y_: mnist.train.labels})) 
print('y_ =',sess.run(y_, feed_dict={x: mnist.train.images,y_: mnist.train.labels})) 
print('cross_entropy =',sess.run(cross_entropy, feed_dict={x: mnist.test.images,
                                  y_: mnist.test.labels}))
tf.nn.softmax(y) = [[  2.44244933e-04   5.53123129e-04   1.30039785e-04 ...,   4.17812960e-04
    1.89713668e-02   8.49443860e-03]
 [  2.90261116e-04   2.54770453e-06   1.23852934e-03 ...,   9.17976934e-07
    1.46925065e-03   4.56442976e-05]
 [  1.87889356e-07   9.94371891e-01   3.53084004e-04 ...,   1.01975893e-04
    8.14021274e-04   3.61652143e-04]
 ..., 
 [  3.20325809e-04   6.26534384e-05   4.80176322e-03 ...,   1.12831250e-01
    5.38507383e-03   7.01800406e-01]
 [  7.81273782e-01   1.53009722e-04   3.65735292e-02 ...,   7.55545974e-04
    7.90198445e-02   4.38847695e-04]
 [  1.22215010e-01   4.24635684e-04   3.62438530e-01 ...,   3.30023991e-04
    4.31141585e-01   3.11407614e-02]]
y_ = [5 6 1 ..., 9 0 0]
cross_entropy = 0.291158

重新寫入程序用以詳細說明損失測度的計算原理

【框架】——環境

# 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
parser = argparse.ArgumentParser()
parser.add_argument('--data_dir', type=str, default='MNIST_data/',
                  help='Directory for storing input data')
FLAGS, unparsed = parser.parse_known_args()
mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)
'A very simple MNIST classifier.\nSee extensive documentation at\nhttp://tensorflow.org/tutorials/mnist/beginners/index.md\n'






_StoreAction(option_strings=['--data_dir'], dest='data_dir', nargs=None, const=None, default='MNIST_data/', type=<class 'str'>, choices=None, help='Directory for storing input data', metavar=None)



Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz

【框架】——創建圖

【AI框架】——建模

估計值:y=XW+b

對估計值y進行處理softmax(y) ,將權值轉化爲概率值,使用的公式爲:(更多latex語法見:
latex語法)

softmax(yi)=exp(yi)ni=0exp(yi)=exp(yi)9i=0exp(yi)

舉例:”’ y[0]=[ 0.08268377 -8.16894245 0.93535107 4.74310637 -2.66201568
-0.33481109 -7.27464342 10.49776363 -0.2320832 2.41363335]”’

sy0=softmax(y0)=[sy0[0],sy0[1],sy0[2],sy0[3],sy0[4],sy0[5],sy0[6],sy0[7],sy0[8],sy0[9]]

爲簡便起見,任選一個計算:

sy0[5]=y0[5]9i=0exp(y0[i])=exp(0.33481109)exp(0.08268377)+exp(8.16894245)+exp(0.93535107)+exp(4.74310637)+...+exp(2.41363335)

如此得到softmaxy,然後計算交叉熵:

CrossEntropy=jnyjlog(syj)

其中y 是樣本的實際y值y_,是一個one-hot類型的值,比如說y0=[0,0,1,0,0,0,0,0,0,0] ,對應[2]這個分類,而
sy0=[0.069740620.115204990.047087130.084678430.107775620.085996690.051925030.035933640.336040850.06561705]
於是有:

y0log(sy0)=log(sy0[2])
相當於y0 挑選了sy0 當中的元素,實際上就沒有必要“浪費”y’的其他存儲空間,只需要知道其one-hot到底哪個爲”1”就行了,所以爲此編寫一個函數,將上述過程簡化一下,於是就有了最新版本的下面的表達式:
“cross_entropy = tf.losses.sparse_softmax_cross_entropy(labels=y_, logits=y)”

在新版當中y_就只是一個one-hot的序號了,作爲挑選y每行(所有分類)的指示器就是了,其實並沒有信息損失的。

接着,使用此損失函數進行剩下的訓練就是了,其他就沒有什麼好說的了。


# 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(labels=y_, logits=y))
softmaxy =tf.nn.softmax(y)
#注意,這裏並不是直接對y進行log而是對softmax,否則會因爲y有負數導致計算log出錯!從原理上也是,softmax就是一個歸一化的過程,其歸一化函數爲:
#exp(yi)/sigma(exp(y))(函數示意一下,可以markdown重新寫一下)
multi_entropy =y_*tf.log(softmaxy)
#abs_multi =tf.abs(multi_entropy)
#sum_result = tf.reduce_sum(abs_multi[0])
#raw_cross_entropy = -tf.reduce_sum(multi_entropy)#lucky added 2017年12月27日17:02:47
cross_entropy = -tf.reduce_sum(multi_entropy)#lucky added 2017年12月27日17:02:47
#依照這個新的損失測度進行訓練,不過訓練參數不是以前的0.5而是選擇了<0.01的數值,這個目前還沒有詳細瞭解這個梯度下降爲何參數比前面小那麼多
train_step = tf.train.GradientDescentOptimizer(0.005).minimize(cross_entropy)

sess = tf.InteractiveSession()
# Train
tf.global_variables_initializer().run()
loopi=0
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})
    #觀察估計值y和樣本結果y_
    if (loopi%40 ==0):
        #print('W =',sess.run(W ,feed_dict={x: batch_xs, y_: batch_ys}))
        #print('b =',sess.run(b ,feed_dict={x: batch_xs, y_: batch_ys}))
        #print('y =',sess.run(y ,feed_dict={x: batch_xs, y_: batch_ys}))#爲什麼會有負數元素,這下還怎麼logy?
        #print('y_ =',sess.run(y_, feed_dict={x: batch_xs, y_: batch_ys}))

        #print('softmaxy =',sess.run(softmaxy, feed_dict={x: batch_xs, y_: batch_ys}))
        #print('multi_entropy =',sess.run(multi_entropy, feed_dict={x: batch_xs, y_: batch_ys}))
        print('cross_entropy =',sess.run(cross_entropy, feed_dict={x: batch_xs, y_: batch_ys}))
        #print('abs_multi =',sess.run(abs_multi, feed_dict={x: batch_xs, y_: batch_ys}))
        #print('sum_result =',sess.run(sum_result, feed_dict={x: batch_xs, y_: batch_ys}))



    loopi =loopi+1
# 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('accuracy =',sess.run(accuracy, feed_dict={x: mnist.test.images,
                                  y_: mnist.test.labels}))
cross_entropy = 173.525
cross_entropy = 41.3516
cross_entropy = 45.0877
cross_entropy = 35.3884
cross_entropy = 41.3567
cross_entropy = 33.6548
cross_entropy = 32.8296
cross_entropy = 21.8187
cross_entropy = 26.1059
cross_entropy = 27.3202
cross_entropy = 49.0285
cross_entropy = 19.3386
cross_entropy = 17.7098
cross_entropy = 19.5953
cross_entropy = 15.073
cross_entropy = 33.4526
cross_entropy = 18.6684
cross_entropy = 12.3083
cross_entropy = 20.8409
cross_entropy = 29.5781
cross_entropy = 19.9576
cross_entropy = 41.4405
cross_entropy = 12.7272
cross_entropy = 30.428
cross_entropy = 22.0893
accuracy = 0.917
#觀察估計值y和樣本結果y_
print('y =',sess.run(y ,feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
print('y_ =',sess.run(y_, feed_dict={x: mnist.test.images,y_: mnist.test.labels}))
print('cross_entropy =',sess.run(cross_entropy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
print('accuracy =',sess.run(accuracy, feed_dict={x: mnist.test.images,y_: mnist.test.labels}))
y = [[  0.27163482  -8.54197216   1.02978182 ...,  10.7032032   -0.05718756
    2.58103871]
 [  3.98500156  -0.74353385  10.13602829 ..., -13.43181515   3.47936964
   -8.5496397 ]
 [ -5.31200171   6.4805789    1.80999207 ...,   0.79157996   0.32139075
   -1.74984384]
 ..., 
 [ -7.80383253  -6.34750366  -2.69591594 ...,   2.75616956   3.64855099
    3.8128643 ]
 [ -2.35135865  -0.63847101  -1.83041203 ...,  -3.76779127   4.61254835
   -3.43423176]
 [  3.08908606  -9.13648891   5.52334976 ...,  -6.70019484  -0.26597619
   -4.03241014]]
y_ = [[ 0.  0.  0. ...,  1.  0.  0.]
 [ 0.  0.  1. ...,  0.  0.  0.]
 [ 0.  1.  0. ...,  0.  0.  0.]
 ..., 
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]]
cross_entropy = 2848.62
accuracy = 0.9192

【分析】

分析兩個損失測度訓練結果的差異:

1.精度感覺沒有明顯差異;accuracy = 0.9116和accuracy = 0.9155

2.訓練步長tf.train.GradientDescentOptimizer(0.005)變化明顯,新版本是0.5,雖然速度沒有進行比對,估計新版的訓練更快;

3.交叉熵,之前的封裝損失測度居然只有cross_entropy = 0.308743,而使用這個原理的損失測度居然有cross_entropy = 2934.49



算法流程圖



x======BBW=======Wxw+byyentropysoftmaxyryeyrlog(ye)yp
假設每張圖片樣本的尺寸爲(28*28=784),訓練樣本總數爲none,即有多少算多少,分10類那麼參數說明:

x :[none,784] 輸入圖像數據

B :[1,10] 偏置

W :[784,10] 權值矩陣

y :[none,10] 估計值

yr :[none,10] 樣本值、標籤(實際值),是一個one-hot格式的數據,也就是類似於{0,0,1,0,0,0…}這樣的形式

ye :[none,10] 估計值的softmax() 結果

yp :[none,10] 交叉熵矩陣

yentropy :[1] 交叉熵

在訓練過程當中,輸入的數據有$(x,y_r),B,W$,首先由初始的B、W以及一批(本文使用100個一批)訓練樣本$x_{[100,784]}$,計算出估計值$y_{[100,10]}$,通過softmax(y)將估計值轉化爲概率值$y_e$,也就是每個訓練樣本x屬於某類的概率,各類屬概率和爲1。由樣本實際值$y_r$和估計概率值$y_e$得到交叉熵矩陣$y_p=y_r*log(y_e)$,接着對交叉熵矩陣所有元素求和$y_{entropy}$,實現對loss值的計算。然後使用對交叉熵$y_{entropy}$以梯度下降法爲優化算法,對權值W進行訓練(train_step = tf.train.GradientDescentOptimizer(0.005).minimize(cross_entropy)),直到完成訓練。

訓練完成之後,使用測試樣本對訓練得到的模型進行測試,計算精度:
sess.run(accuracy, feed_dict={x: mnist.test.images,y_: mnist.test.labels})
完成!



[參考文獻]:

  1. Python 命令行解析工具 Argparse介紹(一)
  2. 2.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章