TensorFlow實戰Google深度學習框架1-4章學習筆記

目錄算法

第1章 深度學習簡介編程

第2章 TensorFlow環境搭建數組

第3章 TensorFlow入門網絡

第4章 深層神經網絡dom

 

 


第1章 深度學習簡介

對於許多機器學習問題來講,特徵提取不是一件簡單的事情。在一些複雜問題上,要經過人工的方式設計有效的特徵集合,須要不少的時間和精力,有時甚至須要整個領域數十年的研究投入。機器學習

 

深度學習解決的核心問題之一就是自動地將簡單的特徵組合成更加複雜的特徵。並使用這些組合特徵解決問題。深度學習是機器學習的一個分支,它除了能夠學習特徵和任務之間的關聯,還能自動從簡單特徵中提取更加複雜的特徵。編程語言

 

深度學習在不少領域都有很是出色的表現,例如在計算機視覺、語音識別、天然語言處理和人機博弈等。函數

 

 


第2章 TensorFlow環境搭建

TensorFlow主要依賴兩個工具包——Protocol Buffer和Bazel。工具

 

Protocol Buffer是谷歌開發的處理結構化數據的工具,和XML或者JSON格式的數據有較大的區別。首先Protocol Buffer序列化以後獲得的數據不是可讀的字符串,而是二進制流。其次,XML或JSON格式的數據信息都包含在了序列化以後的數據中,不須要任何其餘信息就能還原序列化以後的數據。但使用Protocol Buffer時須要先定義數據的格式,還原一個序列化以後的數據將須要使用到這個定義好的數據格式。由於這樣的差異,Protocol Buffer序列化出來的數據要比XML格式的數據小3到10倍,解析時間快20到100倍。如下是Protocol Buffer格式的一個定義示例:學習

message user{ optional string name = 1; required int32 id = 2; repeated string email = 3; }

Bazel是從谷歌開源的自動化構建工具,谷歌內部絕大部分的應用都是經過它來編譯的。相比傳統的Makefile、Ant或者Maven,Bazel在速度、可伸縮性、靈活性以及對不一樣程序語言和平臺的支持上都要更加出色。TensorFlow自己以及谷歌給出的不少官方樣例都是經過Bazel來編譯的。

 

 


第3章 TensorFlow入門

TensorFlow的名字中已經說明了它最重要的兩個概念——Tensor和Flow。Tensor就是張量,能夠被簡單地理解爲多維數組。Flow翻譯成中文就是「流」,它直觀地表達了張量之間經過計算相互轉化的過程。TensorFlow是一個經過計算圖的形式來表述計算的編程系統,每個計算都是計算圖上的一個節點,而節點之間的邊描述了計算之間的依賴關係。計算圖不只僅能夠用來隔離張量和計算,它還提供了管理張量和計算的機制。

 

在TensorFlow程序中,全部的數據均可以經過張量的形式來表示。從功能的角度來看,張量能夠被簡單理解爲多維數組。其中零階張量表示標量(scalar),也就是一個數;第一階張量爲向量(vector),也就是一個一維數組;第n階張量能夠理解爲一個n維數組。在張量中並無真正保存數字,它保存的是如何獲得這些數字的計算過程。例如如下輸出結果:

Tensor("add:0", shape=(2,), dtype=float32)

會話擁有並管理TensorFlow程序運行時的全部資源,全部計算完成以後須要關閉會話來幫助系統回收資源,不然就可能出現資源泄露問題。如下代碼顯示其中一個會話使用模式:

with tf.Session() as sess:
    print(sess.run(result))

TensorFlow遊樂場使用連接:http://playground.tensorflow.org

 

在TensorFlow中,變量(tf.Variable)的做用就是保存和更新神經網絡中的參數,和其餘編程語言相似,TensorFlow中的變量也須要指定初始值。由於在神經網絡中,給參數賦予隨機初始值最爲常見,因此通常也使用隨機數給TensorFlow中的變量初始化。

 

如下代碼給出了一個完整神經網絡實現樣例,包含一個隱藏層。

import tensorflow as tf
from numpy.random import RandomState

batch_size = 8
w1= tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2= tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
x = tf.placeholder(tf.float32, shape=(None, 2), name="x-input")
y_= tf.placeholder(tf.float32, shape=(None, 1), name='y-input')

a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
y = tf.sigmoid(y)
cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0))
                                + (1 - y_) * tf.log(tf.clip_by_value(1 - y, 1e-10, 1.0)))
train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)
rdm = RandomState(1)
X = rdm.rand(128,2)
Y = [[int(x1+x2 < 1)] for (x1, x2) in X]

 

with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
   
    # 輸出目前(未經訓練)的參數取值。
    print(sess.run(w1))
    print(sess.run(w2))
    print("\n")
   
    # 訓練模型。
    STEPS = 5000
    for i in range(STEPS):
        start = (i*batch_size) % 128
        end = (i*batch_size) % 128 + batch_size
        sess.run([train_step, y, y_], feed_dict={x: X[start:end], y_: Y[start:end]})
        if i % 1000 == 0:
            total_cross_entropy = sess.run(cross_entropy, feed_dict={x: X, y_: Y})
            print("After %d training step(s), cross entropy on all data is %g" % (i, total_cross_entropy))
 
    # 輸出訓練後的參數取值。
    print("\n")
    print(sess.run(w1))
    print(sess.run(w2))

輸出結果:

[[-0.8113182   1.4845988   0.06532937]
 [-2.4427042   0.0992484   0.5912243 ]]
[[-0.8113182 ]
 [ 1.4845988 ]
 [ 0.06532937]]
 
After 0 training step(s), cross entropy on all data is 1.89805
After 1000 training step(s), cross entropy on all data is 0.655075
After 2000 training step(s), cross entropy on all data is 0.626172
After 3000 training step(s), cross entropy on all data is 0.615096
After 4000 training step(s), cross entropy on all data is 0.610309
 
[[ 0.02476983  0.56948674  1.6921941 ]
 [-2.1977348  -0.23668921  1.1143895 ]]
[[-0.45544702]
 [ 0.49110925]
 [-0.98110336]]

以上程序實現了訓練神經網絡的所有過程。這段程序能夠總結出訓練神經網絡的過程能夠分爲如下三個步驟:

(1)定義神經網絡的結構和前向傳播的輸出結果

(2)定義損失函數以及選擇反向傳播優化的算法

(3)生成會話(tf.Session),而且在訓練數據上反覆運行反向傳播優化算法

不管神經網絡的結構如何變化嗎,這三個步驟都是不變的。

 

 


第4章 深層神經網絡

維基百科對深度學習的精度定義爲「一類經過多層非線性變換對高複雜性數據建模算法的合集」。由於深層神經網絡是實現「多層非線性變換」最經常使用的一種方法,因此在實際中基本上能夠認爲深度學習就是深層神經網絡的代名詞。從維基百科給出的定義能夠看出,深度學習有兩個很是重要的特性——多層和非線性。

 

若是在深層神經網絡中,前向傳播使用線性模型,那麼經過線性變換,任意層的全鏈接神經網絡和單層的神經網絡並無區別,並且他們都是線性模型。這就是線性模型最大的侷限性,也是爲何深度學習要強調非線性。

 

分類問題和迴歸問題是監督學習的兩大種類。分類問題但願解決的是將不一樣的樣本分到事先定義好的類別中。交叉熵刻畫了兩個機率分佈之間的距離,它是分類問題中使用比較普遍的一種損失函數。

 

交叉熵是一個信息論中的概念,它本來是用來估計平均編碼長度的。給定兩個機率分佈p和q,經過q來表示p的交叉熵爲:

如何將神經網絡前向傳播獲得的結果變成機率分佈呢?SOftmax迴歸是一個很是經常使用的方法。假設原始的神經網絡輸出爲

,那麼通過Softmax迴歸處理以後的輸出爲:

與分類問題不一樣,迴歸問題解決的是對具體數值的預測。好比房價預測、銷量預測等都是迴歸問題。對於迴歸問題,最經常使用的損失函數是均方偏差(MSE,mean squared error)。它的定義以下:

梯度降低算法主要用於優化單個參數的取值,而反向傳播算法給出了一個高效的方式在全部參數上使用梯度降低算法,從而使神經網絡模型在訓練數據上的損失函數儘量小。反向傳播算法是訓練神經網絡的核心算法,它能夠根據定義好的損失函數優化神經網絡中參數的取值,從而使神經網絡模型在訓練數據集上的損失函數達到一個較小值。

 

須要注意的是,梯度降低算法並不能保證被優化的函數達到全局最優解。並且,參數的初始值會很大程度影響最後獲得的結果。只有當損失函數爲凸函數時,梯度降低算法才能保證達到全局最優解。梯度降低算法另外一個問題就是計算時間太長,由於要在所有訓練數據上最小化損失,因此損失函數J( )是在全部訓練數據上的損失和。

 

在訓練神經網絡時,須要設置學習率(learning rate)控制參數更新的速度。若是學習率設置過大,更新的幅度就比那大,那麼可能致使參數在極優值的兩側來回移動。若是學習率設置太小,會致使訓練的時間變長。爲了解決設定學習率的我呢提,TensorFlow提供了一種更加靈活的學習率設置方法——指數衰減法。tf.train.exponential_decay函數實現了指數衰減學習率。如下代碼給出了尋找 的最小值,使用梯度降低法來實現:

TRAINING_STEPS = 100
global_step = tf.Variable(0)
LEARNING_RATE = tf.train.exponential_decay(0.1, global_step, 1, 0.96, staircase=True)

 
x = tf.Variable(tf.constant(5, dtype=tf.float32), name="x")
y = tf.square(x)
train_op = tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(y, global_step=global_step)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(TRAINING_STEPS):
        sess.run(train_op)
        if i % 10 == 0:
            LEARNING_RATE_value = sess.run(LEARNING_RATE)
            x_value = sess.run(x)
            print ("After %s iteration(s): x%s is %f, learning rate is %f."% (i+1, i+1, x_value, LEARNING_RATE_value))

運行結果:

After 1 iteration(s): x1 is 4.000000, learning rate is 0.096000.
After 11 iteration(s): x11 is 0.690561, learning rate is 0.063824.
After 21 iteration(s): x21 is 0.222583, learning rate is 0.042432.
After 31 iteration(s): x31 is 0.106405, learning rate is 0.028210.
After 41 iteration(s): x41 is 0.065548, learning rate is 0.018755.
After 51 iteration(s): x51 is 0.047625, learning rate is 0.012469.
After 61 iteration(s): x61 is 0.038558, learning rate is 0.008290.
After 71 iteration(s): x71 is 0.033523, learning rate is 0.005511.
After 81 iteration(s): x81 is 0.030553, learning rate is 0.003664.
After 91 iteration(s): x91 is 0.028727, learning rate is 0.002436.

 

在真實應用中想要的並非讓模型儘可能模擬訓練數據的行爲,而是但願經過訓練出來的模型對未知的數據給出判斷。模型在訓練數據上的表現並不必定表明了它在未知數據上的表現。過擬合,指的是當一個模型過爲複雜以後,它能夠很好地」記憶「每個訓練數據中隨機噪音的部分而忘記了要去「學習」訓練數據中通用的趨勢。

爲了不過擬合問題,一個很是經常使用的方法時正則化(regularization)。正則化的思想就是在損失函數中加入刻畫模型複雜程度的指標。經常使用的刻畫模型複雜度的函數R(w)有兩種,一種時L1正則化,計算公式是:

另外一種是L2正則化,計算公式是:

不管是哪種正則化方法,基本的思想都是但願經過限制權重的大小,使得模型不能任意擬合訓練數據中的隨機噪音。但這兩種正則化的方法也有很大的區別。首先,L1正則化會讓參數變得更稀疏,而L2正則化不會讓參數變得稀疏的緣由是當參數很小時,例如0.001,這個參數的平方基本上就能夠忽略了。

 

在採用隨機梯度降低算法訓練神經網絡時,使用滑動平均模型在不少應用中均可以在必定程度提升最終模型在測試數據上的表現。在TensorFlow中提供了tf.train.ExponentialMovingAverage來實現滑動平均模型。在初始化ExponentialMovingAverage時,須要提供一個衰減率(decay)。這個衰減率將用於控制模型的更新速度。在實際應用中,decay通常會設置成很是接近1的數(例如0.999或者0.9999)。

相關文章
相關標籤/搜索