1. 程式人生 > >21個專案玩轉深度學習 學習筆記(2)

21個專案玩轉深度學習 學習筆記(2)

Tensorflow中資料讀取的基本機制。

事實上,必須先讀入資料後才能進行計算,假設讀入用時0.1s,計算用時0.9秒,那麼沒過1s,GPU都會有0.1s無事可做,大大降低了運算的效率。

解決這個問題的方法將讀入資料和計算分別放在兩個執行緒中,讀取執行緒不斷地將檔案系統中的圖片讀入一個記憶體的佇列中,而負責計算的是另一個執行緒,計算需要資料時,直接從記憶體佇列中讀取就可以了。這樣可以解決GPU因為I/O而空閒的問題。

在Tensorflow中,為了方便管理,在記憶體佇列前又添加了一層所謂的“檔名佇列”

機器學習中一個概念是epoch,對於一個數據集來講,執行一個epoch就是將這個資料集中的圖片全部計算一遍。如果一個數據集中有三張圖片A.JPG、B.JPG、C.JPG,那麼對執行一個epoch就是指對A、B、C三張圖片都計算一遍。兩個epoch就是指先對A、B、C各計算一遍,然後再全部計算一遍,也就是說每張圖片都計算了兩遍。

Tensorflow使用“檔名佇列+記憶體佇列”雙佇列的形式讀入檔案,可以很好地管理epoch。假定要執行一個epoch,那麼在檔名佇列中把A、B、C各放入一次,在之後標註佇列結束。程式執行後,記憶體佇列依次讀入A、B、C,再嘗試讀入,就檢測到了結束,自動丟擲一個異常,結束程式。這是Tensorflow種讀取資料的基本機制。如果要執行2個epoch而不是1個epoch,在檔名佇列中將A、B、C依次放入兩次再標記結束就可以了。

對於檔名佇列,使用tf.train.string_input_producer函式,這個函式需要傳入一個檔名list,系統會自動將它轉為一個檔名佇列。

此外,tf.train.string_input_producer還有兩個重要引數,一個是num_epochs,它就是之前提到的epoch數,另外一個shuffle,shuffle是指在一個epoch內檔案的順序是否被打亂,若設定shuffle=False,每個epoch中資料仍然按照A、B、C的順序進入檔名佇列。如果設定shuffle=True,那麼在一個epoch內,資料的前後順序就會被打亂。

在Tensorflow中,記憶體佇列不需要自己建立,只需要使用reader物件從檔名佇列中讀取資料就可以了。

還有另一個函式tf.train.start_queue_runners。在使用tf.train.string_input_prodecer建立檔名佇列後,整個系統其實還處於停滯狀態,也就是說檔名並沒有真正被加入佇列中,如果此時開始計算,因為記憶體佇列中什麼也沒有,計算單元就會一直等待,導致整個系統被阻塞。

使用tf.train.start_queue_runners之後,才會啟動填充佇列的執行緒,這時系統就不會再停滯了。此後,計算單元就可以拿到資料並進行計算,整個程式執行起來。

資料增強

深度學習通常會要求擁有充足數量的訓練樣本,一般來說,資料的總量越多,訓練得到的模型效果會越好。

對於影象型別的訓練資料,所謂的資料增強(Data Augmentation)方法是指利用平移、縮放、顏色等變換,人工增大訓練集樣本的個數,從而獲得更充足的訓練資料,使得模型訓練的效果更好。

常見的影象資料增強的方法如下:

  • 平移:將影象在一定尺度範圍內平移
  • 旋轉:將影象在一定角度範圍內旋轉
  • 翻轉:水平翻轉或者上下翻轉影象
  • 裁剪:在原有影象上裁剪出一塊
  • 縮放:將影象在一定尺度內放大或縮小
  • 顏色變換:對影象的RGB顏色空間進行一些變換
  • 噪聲擾動:給影象加入一些人工生成的噪聲

使用資料增強的方法的前提是,這些資料增強方法不會改變影象的原有標籤。

在訓練的時候,常常想知道損失的變化,以及各層的訓練狀況。Tensorflow提供了一個視覺化工具TensorBoard可以非常方便地觀察損失的變化曲線,還可以觀察訓練速度等其他日誌資訊,達到實時監控訓練過程的目的。

深度殘差模型的優勢在於使用了跳過連結,讓神經網路從擬合F(x)變成擬合F(x)-x。殘差比原始函式更容易學習,也更適合深層模型迭代,因此,即使訓練非常深的神經網路也不會發生非常嚴重的過擬合。