深度學習筆記整理

近期工作:

1.對車輛碰撞、駕駛行爲分析方面論文彙總,並選擇性的閱讀了幾篇。

2.學習深度學習相關知識,Python數據處理知識。

3.學習TensorFlow神經網絡庫,並搭建了開發環境。


一、深度學習簡介



1.什麼是深度學習

深度學習(Deep Learning)機器學習的一種形式,概念源於人工神經網絡的研究。含多隱層的多層感知器就是一種深度學習結構。深度學習通過組合低層特徵形成更加抽象的高層表示屬性類別或特徵,以發現數據的分佈式特徵表示。  

深度學習是機器學習研究中的一個新的領域,其動機在於建立、模擬人腦進行分析學習的神經網絡,它模仿人腦的機制來解釋數據,例如圖像,聲音和文本。




2.基本變換:層

神經網絡是由一層一層構建的,那麼每究竟在做什麼?

  • 數學式子\vec{y}= a(W\cdot\vec{x} + {b}),其中\vec{x}是輸入向量,\vec{y}是輸出向量,\vec{b}是偏移向量,W是權重矩陣,a()是激活函數。每一層僅僅是把輸入\vec x經過如此簡單的操作得到\vec y
  • 數學理解:通過如下5種對輸入空間(輸入向量的集合)的操作,完成 輸入空間 —> 輸出空間 的變換 (矩陣的行空間到列空間)。 注:用“空間”二字的原因是被分類的並不是單個事物,而是一類事物。空間是指這類事物所有個體的集合。
    • 1. 升維/降維
    • 2. 放大/縮小
    • 3. 旋轉
    • 4. 平移
    • 5. “彎曲” 這5種操作中,1,2,3的操作由W\cdot\vec{x}完成,4的操作是由+\vec{b}完成,5的操作則是由a()來實現。

每層神經網絡的數學理解:用線性變換跟隨着非線性變化,將輸入空間投向另一個空間

線性可分視角:神經網絡的學習就是學習如何利用矩陣的線性變換加激活函數的非線性變換,將原始輸入空間投向線性可分/稀疏的空間去分類/迴歸。 
增加節點數:增加維度,即增加線性轉換能力。 
增加層數:增加激活函數的次數,即增加非線性轉換次數。


3.神經網絡的訓練

知道了神經網絡的學習過程就是學習控制着空間變換方式(物質組成方式)的權重矩陣後,接下來的問題就是如何學習每一層的權重矩陣 W 。


如何訓練:

既然我們希望網絡的輸出儘可能的接近真正想要預測的值。那麼就可以通過比較當前網絡的預測值和我們真正想要的目標值,再根據兩者的差異情況來更新每一層的權重矩陣(比如,如果網絡的預測值高了,就調整權重讓它預測低一些,不斷調整,直到能夠預測出目標值)。因此就需要先定義“如何比較預測值和目標值的差異”,這便是損失函數或目標函數(loss function or objective function),用於衡量預測值和目標值的差異的方程。loss function的輸出值(loss)越高表示差異性越大。那神經網絡的訓練就變成了儘可能的縮小loss的過程。所用的方法是梯度下降(Gradient descent):通過使loss值向當前點對應梯度的反方向不斷移動,來降低loss。一次移動多少是由學習速率(learning rate)來控制的。

梯度下降的問題:

然而使用梯度下降訓練神經網絡擁有兩個主要難題。


局部極小值

梯度下降尋找的是loss function的局部極小值,而我們想要全局最小值。如下圖所示,我們希望loss值可以降低到右側深藍色的最低點,但loss有可能“卡”在左側的局部極小值中。


試圖解決“卡在局部極小值”問題的方法分兩大類:

  • 調節步伐:調節學習速率,使每一次的更新“步伐”不同。常用方法有:
  • 隨機梯度下降(Stochastic Gradient Descent (SGD):每次只更新一個樣本所計算的梯度
  • 小批量梯度下降(Mini-batch gradient descent):每次更新若干樣本所計算的梯度的平均值
  • 動量(Momentum):不僅僅考慮當前樣本所計算的梯度;Nesterov動量(Nesterov Momentum):Momentum的改進
  • Adagrad、RMSProp、Adadelta、Adam:這些方法都是訓練過程中依照規則降低學習速率,部分也綜合動量
  • 優化起點:合理初始化權重(weights initialization)、預訓練網絡(pre-train),使網絡獲得一個較好的“起始點”,如最右側的起始點就比最左側的起始點要好。常用方法有:高斯分佈初始權重(Gaussian distribution)、均勻分佈初始權重(Uniform distribution)、Glorot 初始權重、He初始權、稀疏矩陣初始權重(sparse matrix)

梯度的計算

機器學習所處理的數據都是高維數據,該如何快速計算梯度、而不是以年來計算。 其次如何更新隱藏層的權重? 解決方法是:計算圖:反向傳播算法 這裏的解釋留給非常棒的Computational Graphs: Backpropagation 需要知道的是,反向傳播算法是求梯度的一種方法。如同快速傅里葉變換(FFT)的貢獻。 而計算圖的概念又使梯度的計算更加合理方便。

基本流程圖:


二、前饋神經網絡

前饋神經網絡(feedforward neural network),簡稱前饋網絡,是人工神經網絡的一種。在此種神經網絡中,各神經元從輸入層開始,接收前一級輸入,並輸出到下一級,直至輸出層。整個網絡中無反饋,可用一個有向無環圖表示。
前饋神經網絡採用一種單向多層結構。其中每一層包含若干個神經元,同一層的神經元之間沒有互相連接,層間信息的傳送只沿一個方向進行。其中第一層稱爲輸入層。最後一層爲輸出層.中間爲隱含層,簡稱隱層。隱層可以是一層。也可以是多層。

  • 網絡結構:2維輸入 \rightarrow\rightarrow1維輸出


  • 結構表達式
    • 正向傳遞: y=M(x)=relu(W_{h} \cdot relu(W_{x} \cdot x+b_{x})+b_{h}) (1)
      • y 用於表達隨機變量 Y 的值, x 表示隨機變量 X 的值, M(x) 是我們的神經網絡模型,等號右側是具體的表達。
    • 損失函數: loss=1/2\cdot \sum\limits_i (y_i-t_i)^2
      • 該loss就是比較 y 和 t 中所有值的差別。
  • 整體結構:左側的圖表示網絡結構。綠色方框表示操作,也叫作層(layer)。該結構中,輸入 x 經過hid_layer算出隱藏層的值 h ,再傳遞給out_layer,計算出預測值 y ,隨後與真實值 t 進行比較,算出損失 loss ,再從反向求導得出梯度後對每一層的 W和 b 進行更新。



  • 正向傳遞:如果放大hid_layer內部,從下向上,會看到 W_h 先用truncated_normal的方法進行了初始化,隨後與輸入 x 進行矩陣相乘,加上 b_h ,又經過了activation後,送給了用於計算 y 的out_layer中。而 y 的計算方式和 h 完全一致,但用的是不同的權重 W_o 和偏移 b_o 。最後將算出的預測值 y 與真實值 t 一同求出 loss


  • 反向傳遞:如果放大train的內部,再放大內部中的gradients,就可以看到框架是從 loss開始一步步反向求得各個層中 W 和 b 的梯度的。


  • 權重更新:求出的各個層 W 和 b 的梯度,將會被用於更新對應的 W 和 b ,並用learning rate控制一次更新多大。(beta1_power和beta2_power是Adam更新方法中的參數,目前只需要知道權重更新的核心是各自對應的梯度。)

三、循環神經網絡(RNN)

前饋網絡:window size爲3幀的窗處理後的前饋網絡

  • 動態圖:左側是時間維度展開前,右側是展開後(單位時刻實際工作的只有灰色部分。)。前饋網絡的特點使不同時刻的預測完全是獨立的。我們只能通過窗處理的方式讓其照顧到前後相關性。


  • 數學式子h_t= \phi(W_{xh} \cdot concat(x_{t-1}, x_t, x_{t+1}) + {b}),concat表示將向量並接成一個更大維度的向量。
  • 學習參數:需要從大量的數據中學習W_{xh}b
  • 要學習各個時刻(3個)下所有維度(39維)的關係(39*3個),就需要很多數據。


遞歸網絡:不再有window size的概念,而是time step

  • 動態圖:左側是時間維度展開前,迴路方式的表達方式,其中黑方框表示時間延遲。右側展開後,可以看到當前時刻的h_t並不僅僅取決於當前時刻的輸入x_t,同時與上一時刻的h_{t-1}也相關。


  • 數學式子h_t= \phi(W_{xh} \cdot x_t + W_{hh} \cdot h_{t-1} + {b})h_t同樣也由x_tW_{xh}的變化後的信息決定,
  • 但這裏多另一份信息:W_{hh}\cdot h_{t-1},而該信息是從上一時刻的隱藏狀態h_{t-1}經過一個不同的W_{hh}變換後得出的。
  • W_{xh}的形狀是行爲dim_input,列爲dim_hidden_state,而W_{hh}是一個行列都爲dim_hidden_state的方陣。
  • 學習參數:前饋網絡需要3個時刻來幫助學習一次W_{xh},而遞歸網絡可以用3個時刻來幫助學習3次W_{xh}W_{hh}。換句話說:所有時刻的權重矩陣都是共享的。這是遞歸網絡相對於前饋網絡而言最爲突出的優勢。
遞歸神經網絡是在時間結構上存在共享特性的神經網絡變體。

時間結構共享是遞歸網絡的核心中的核心。

四、TensorFlow簡介

目前主流的TensorFlow,用tensorflow這樣工具的原因是:它允許我們用計算圖(Computational Graphs)的方式建立網絡。同時又可以非常方便的對網絡進行操作。

下面就是對計算圖的直觀講解。

比喻說明:

  • 結構:計算圖所建立的只是一個網絡框架。在編程時,並不會有任何實際值出現在框架中。所有權重和偏移都是框架中的一部分,初始時至少給定初始值才能形成框架。因此需要initialization初始化。
  • 比喻:計算圖就是一個管道。編寫網絡就是搭建一個管道結構。在投入實際使用前,不會有任何液體進入管道。而神經網絡中的權重和偏移就是管道中的閥門,可以控制液體的流動強弱和方向。在神經網絡的訓練中,閥門會根據數據進行自我調節、更新。但是使用之前至少要給所有閥門一個初始的狀態才能形成結構。用計算圖的好處是它允許我們可以從任意一個節點處取出液體。

用法說明:

請類比管道構建來理解計算圖的用法

構造階段(construction phase):組裝計算圖(管道)

  • 計算圖(graph):要組裝的結構。由許多操作組成。
  • 操作(ops):接受(流入)零個或多個輸入(液體),返回(流出)零個或多個輸出。
  • 數據類型:主要分爲張量(tensor)、變量(variable)和常量(constant)
    • 張量:多維array或list(管道中的液體)
      • 創建語句
tensor_name=tf.placeholder(type, shape, name)
    • 變量:在同一時刻對圖中所有其他操作都保持靜態的數據(管道中的閥門)
      • 創建語句
name_variable = tf.Variable(value, name)
    • 初始化語句
#個別變量
init_op=variable.initializer()
#所有變量
init_op=tf.initialize_all_variables()
#注意:init_op的類型是操作(ops),加載之前並不執行
    • 更新語句
update_op=tf.assign(variable to be updated, new_value)
    • 常量:無需初始化的變量
      • 創建語句
name_constant=tf.constant(value)


執行階段(execution phase):使用計算圖(獲取液體)

  • 會話:執行(launch)構建的計算圖。可選擇執行設備:單個電腦的CPU、GPU,或電腦分佈式甚至手機。
    • 創建語句
#常規
sess = tf.Session()
#交互
sess = tf.InteractiveSession()
#交互方式可用tensor.eval()獲取值,ops.run()執行操作
#關閉
sess.close()
  • 執行操作:使用創建的會話執行操作
    • 執行語句
sess.run(op)
    • 送值(feed):輸入操作的輸入值(輸入液體)
      • 語句
sess.run([output], feed_dict={input1:value1, input2:value1})
    • 取值(fetch):獲取操作的輸出值(得到液體)
      • 語句
#單值獲取 
sess.run(one op)
#多值獲取
sess.run([a list of ops])

更多內容參考官網文檔


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