零基礎入門深度學習(二):用一個案例掌握深度學習方法

授課講師 | 畢然 百度深度學習技術平臺部主任架構師 html

授課時間 | 每週2、週四晚20:00-21:00 web

編輯整理 | 劉威威 算法

內容來源 | 百度飛槳深度學習集訓營json

下載安裝命令

## CPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

導讀服務器

本課程是百度官方開設的零基礎入門深度學習課程,主要面向沒有深度學習技術基礎或者基礎薄弱的同窗,幫助你們在深度學習領域實現從0到1+的跨越。從本課程中,你將學習到:網絡

  1. 深度學習基礎知識架構

  2. numpy實現神經網絡構建和梯度降低算法app

  3. 計算機視覺領域主要方向的原理、實踐框架

  4. 天然語言處理領域主要方向的原理、實踐異步

  5. 個性化推薦算法的原理、實踐

本週爲開講第二週,百度深度學習技術平臺部主任架構師畢然老師,繼續開始零基礎入門深度學習的授課。

畢老師發現,在實際工業實踐中,面對新問題套用已有方案一般不會取得好效果,須要從初步建模的baseline出發,在建模的每一個步驟尋求優化思路。本次課程即以此作演示,將適用於房價預測任務的線性迴歸模型,挪用到手寫數字識別任務後,如何一步步的進行優化,實現最好的分類效果,讓學員能夠得到工業實踐的真實體驗。基於此,畢老師爲你們精心準備了由淺入深,由點及面的教學課程。

本次講課內容主要包括:

  1. 數據處理和異步數據讀取

  2. 網絡結構設計及背後思想

  3. 損失函數介紹及使用方式

  4. 模型優化算法介紹和選擇

  5. 分佈式訓練方法及實踐

  6. 模型訓練調試與優化

  7. 訓練中斷後恢復訓練

下圖歸納了本次課程的主要授課知識點,課程內容涵蓋深度學習的數據處理、模型設計、模型訓練、模型優化等部分,另外擴展了異步數據讀取,分佈式訓練、恢復訓練等知識點。

圖:本次課程授課知識框架

本文總結了畢然老師的講課要點,難免疏漏一些生動的講課案例,感興趣的同窗可從文末連接中直接觀看課程。

 

01 第一節:數據處理與數據讀取

深度學習算法工程師多被稱爲「煉丹師」,訓練深度學習模型則等同於「煉丹」。卻不知,在煉丹以前,重要的一步就是「採藥」。採藥是煉丹的第一步,同訓練深度模型須要準備訓練數據。

官方給出的數據集好比ImageNet,MSCOCO,VOC等,這些數據都比較乾淨,沒有標註錯誤或者漏標註的問題。可是若是是本身的業務數據集,數據可能存在各類問題,須要本身去實現數據處理的函數,構建數據讀取器。

在本節課程中,畢老師以本地讀取的mnist數據集爲例,順序講解並用代碼實現了:

  1. 從文件中讀取到數據;

  2. 劃分數據集爲訓練集,驗證集;

  3. 構建數據讀取器(data_loader)

圖:mnist數據處理

不一樣的數據保存的文件格式和存儲形式不盡相同,正確讀到數據每每是開始訓練的第一步。課程案例中,本地存儲的mnist數據是壓縮後的json文件,畢老師用簡潔的代碼,不只爲學員介紹了讀取數據、校驗數據正確性、數據劃分和使用yield構建數據讀取器等知識,還介紹了使用飛槳實現數據的異步讀取,在讀取數據較慢,數據處理複雜時更爲適用。

 

02 第二節:神經網絡模型設計

第二節裏,畢老師講解了深度神經網絡的設計原理,並分別實現了基於卷積神經網絡和全鏈接神經網絡的深度網絡模型。

主要內容以下:

  1. 深度神經網絡的設計原理。深度神經網絡相比較淺層深度神經網絡的區別是:網絡足夠深,足夠複雜,非線性程度更高。前面的課程介紹到,複雜的模型能夠擬合更復雜的函數,對現實世界的表徵能力也會加強。非線性程度的增長經過模型的深度和非線性函數來實現,若是沒有非線性函數,即便最深的神經網絡也只不過是一種線性函數表達。組建網絡時,通常考慮到訓練數據的數量,決定設計模型的複雜度,若是訓練數據不足,很難把一個參數衆多的模型訓練好。

  2. 如何設計深度神經網絡。神經網絡的基本層不外乎全鏈接層FC,卷積層CNN,循環神經網絡RNN。不一樣的網絡層有不一樣的適應任務,好比,CNN適合處理2D圖像數據,CNN能更好的捕捉到空間位置信息,這是FC和LSTM顧及不到的,可是LSTM和FC也有其應用的場景。在本次的手寫字符識別中,分別實現了基於FC和CNN的深度神經網絡,經過對比實現,學員能夠很輕鬆的學會如何使用卷積和全鏈接層構建深度網絡。

圖:卷積網絡模型示意圖

 

03 第三節:損失函數介紹

完成神經網絡設計後,畢老師首先以房價預測和手寫字符識別的損失函數對比,經過比較這兩個不一樣任務損失函數在量綱和優化目標的區別,引出了迴歸損失函數和分類損失函數的不一樣,進一步講解了在不一樣任務下該如何選擇、改進損失函數。

經過演示在mnist分類任務上使用均方偏差損失函數,得出了兩個結論:

  1. 迴歸任務的損失函數難以在分類任務上取得較好精度。

  2. loss值較大,訓練過程當中loss波動明顯。

因此,這裏引出一個疑問?爲何分類任務用均方偏差爲什麼不合適?畢老師在課程中給出了兩個答案:

  1. 物理含義不合理:實數輸出和標籤相減

  2. 分類任務本質規律是「在某種特徵組合下的分類機率!「

分類任務背後是機率的思想,因此接着,畢老師利用從黑盒中取黑白球的機率爲例,,解釋了最大似然的思想,

圖:抽取黑白球到最大似然機率

最後以貝葉斯公式、交叉熵損失函數的公式介紹、以及代碼實現收尾,結束了損失函數部分的課程內容。

圖:損失函數代碼實現

 

04 第四節:優化算法與學習率

神經網絡所擬合的函數是高度非凸函數,理想的訓練目標是,優化這類函數,達到函數最小值點或接近最小值的極小值點。本部分課程中,畢老師帶代價討論優化器和學習率對訓練神經網絡的影響,並教你們如何選取最優的學習率和優化器。

學習率的選擇

在深度學習神經網絡模型中,學習率表明更新參數的更新幅度的大小。當學習率最優時,模型的有效容量最大。學習率設置和當前深度學習任務有關,合適的學習率每每須要調參經驗和大量的實驗,總結來講,學習率選取須要注意如下兩點:

  • 學習率不是越小越好。學習率越小,損失函數的變化速度越慢,意味着咱們須要花費更長的時間進行收斂。

  • 學習率不是越大越好。由於只根據總樣本集中的一個批次計算梯度,抽樣偏差會致使計算出的梯度不是全局最優的方向,且存在波動。同時,在接近最優解時,過大的學習率會致使參數在最優解附近震盪,致使損失難以收斂。

圖: 不一樣大小學習率對到達最小值的影響

優化器的選擇

學習率是優化器的一個參數,雖然參數更新都是採用梯度降低算法,可是不一樣的梯度降低算法影響着神經網絡的收斂效果。當隨機梯度降低算法SGD沒法知足咱們的需求時,能夠嘗試以下三個思路選取優化器。

  1. 加入「動量」,參數更新的方向更穩定,好比Momentum優化器。每一個批次的數據含有抽樣偏差,致使梯度更新的方向波動較大。若是咱們引入物理動量的概念,給梯度降低的過程加入必定的「慣性」累積,就能夠減小更新路徑上的震盪!即每次更新的梯度由「歷史屢次梯度的累積方向」和「當次梯度」加權相加獲得。歷史屢次梯度的累積方向每每是從全局視角更正確的方向,這與「慣性」的物理概念很像,也是爲什麼其起名爲「Momentum」的緣由。相似不一樣品牌和材質的籃球有必定的重量差異,街頭籃球隊中的投手(擅長中遠距離投籃)喜歡稍重籃球的比例較高。一個很重要的緣由是,重的籃球慣性大,更不容易受到手勢的小幅變形或風吹的影響。

  2. 根據不一樣參數距離最優解的遠近,動態調整學習率,好比AdaGrad優化器。經過調整學習率的實驗能夠發現:當某個參數的現值距離最優解較遠時(表現爲梯度的絕對值較大),咱們指望參數更新的步長大一些,以便更快收斂到最優解。當某個參數的現值距離最優解較近時(表現爲梯度的絕對值較小),咱們指望參數的更新步長小一些,以便更精細的逼近最優解。相似於打高爾夫球,專業運動員第一杆開球時,一般會大力打一個遠球,讓球儘可能落在洞口附近。當第二杆面對離洞口較近的球時,他會更輕柔而細緻的推杆,避免將球打飛。與此相似,參數更新的步長應該隨着優化過程逐漸減小,減小的程度與當前梯度的大小有關。根據這個思想編寫的優化算法稱爲「AdaGrad」,Ada是Adaptive的縮寫,表示「適應環境而變化」的意思。

  3. 由於上述兩個優化思路是正交的,因此能夠將兩個思路結合起來,這就是當前普遍應用的Adam算法。

 

05 第五節:模型訓練及分佈式訓練

在前幾回課程中,畢老師已經或多或少介紹瞭如何訓練神經網絡。但並無涉及分佈式訓練的內容,本部分課程中,畢老師給你們介紹了分佈式訓練的思想,尤爲是數據並行的思想,並介紹如何增長三行代碼使用飛槳實現多GPU訓練。

分佈式訓練有兩種實現模式:模型並行和數據並行。

模型並行

模型並行是將一個網絡模型拆分爲多份,拆分後的模型分到多個設備上(GPU)訓練,每一個設備的訓練數據是相同的。模型並行的方式通常適用於:

  1. 模型架構過大,完整的模型沒法放入單個GPU。2012年ImageNet大賽的冠軍模型AlexNet是模型並行的典型案例。因爲當時GPU內存較小,單個GPU不足以承擔AlexNet。研究者將AlexNet拆分爲兩部分放到兩個GPU上並行訓練。

  2. 網絡模型的設計結構能夠並行化時,採用模型並行的方式。例如在計算機視覺目標檢測任務中,一些模型(YOLO9000)的邊界框迴歸和類別預測是獨立的,能夠將獨立的部分分在不一樣的設備節點上完成分佈式訓練。

說明:當前GPU硬件技術快速發展,深度學習使用的主流GPU的內存已經足以知足大多數的網絡模型需求,因此大多數狀況下使用數據並行的方式。

數據並行

數據並行與模型並行不一樣,數據並行每次讀取多份數據,讀取到的數據輸入給多個設備(GPU)上的模型,每一個設備上的模型是徹底相同的。數據並行的方式與衆人拾柴火焰高的道理相似,若是把訓練數據比喻爲磚頭,把一個設備(GPU)比喻爲一我的,那單GPU訓練就是一我的在搬磚,多GPU訓練就是多我的同時搬磚,每次搬磚的數量倍數增長,效率呈倍數提高。可是注意到,每一個設備的模型是徹底相同的,可是輸入數據不一樣,每一個設備的模型計算出的梯度是不一樣的,若是每一個設備的梯度更新當前設備的模型就會致使下次訓練時,每一個模型的參數都不一樣了,因此咱們還須要一個梯度同步機制,保證每一個設備的梯度是徹底相同的。

數據並行中有一個參數管理服務器(parameter server)收集來自每一個設備的梯度更新信息,並計算出一個全局的梯度更新。當參數管理服務器收到來自訓練設備的梯度更新請求時,統一更新模型的梯度。

用戶只須要對程序進行簡單修改,便可實如今多GPU上並行訓練。飛槳採用數據並行的實現方式,在訓練前,須要配置以下參數:

  • 1.從環境變量獲取設備的ID,並指定給CUDAPlace

device_id = fluid.dygraph.parallel.Env().dev_id  place = fluid.CUDAPlace(device_id)
  • 2.對定義的網絡作預處理,設置爲並行模式

strategy = fluid.dygraph.parallel.prepare_context() ## 新增  model = MNIST("mnist")  model = fluid.dygraph.parallel.DataParallel(model, strategy)  ## 新增
  • 3.定義多GPU訓練的reader,將每批次的數據平分到每一個GPU上

valid_loader = paddle.batch(paddle.dataset.mnist.test(), batch_size=16, drop_last=true)  valid_loader = fluid.contrib.reader.distributed_batch_reader(valid_loader)
  • 4.收集每批次訓練數據的loss,並聚合參數的梯度

avg_loss = mnist.scale_loss(avg_loss)  ## 新增  avg_loss.backward()  mnist.apply_collective_grads()         ## 新增

若是想了解飛槳數據並行的基本思想,能夠參考官網文檔-https://www.paddlepaddle.org.cn/documentation/docs/zh/user_guides/howto/training/cluster_howto.html。

 

06 第六節:訓練調試與優化

在模型訓練部分,爲了保證模型的真實效果,須要對模型進行一些調試和優化,畢老師在課程中把訓練調試優化分五個環節來說:

  • 計算分類準確率,觀測模型訓練效果。

    交叉熵損失函數只能做爲優化目標,沒法直接準確衡量模型的訓練效果。準確率能夠直接衡量訓練效果,但因爲其離散性質,不適合作爲損失函數優化神經網絡。

  • 檢查模型訓練過程,識別潛在問題。

    若是模型的損失或者評估指標表現異常,咱們一般須要打印模型每一層的輸入和輸出來定位問題,分析每一層的內容來獲取錯誤的緣由。

  • 加入校驗或測試,更好評價模型效果。

    理想的模型訓練結果是在訓練集和驗證集上均有較高的準確率,若是訓練集上的準確率高於驗證集,說明網絡訓練程度不夠;若是驗證集的準確率高於訓練集,多是發生了 過擬合現象。經過在優化目標中加入正則化項的辦法,能夠解決過擬合的問題。

  • 加入正則化項,避免模型過擬合。

  • 可視化分析。

    用戶不只能夠經過打印或使用matplotlib庫做圖,飛槳還集成了更專業的第三方繪圖庫tb-paddle,提供便捷的可視化分析。

 

07 第七節:恢復訓練

在快速入門中,咱們已經介紹了將訓練好的模型保存到磁盤文件的方法。應用程序能夠隨時加載模型,完成預測任務。可是在平常訓練工做中咱們會遇到一些突發狀況,致使訓練過程主動或被動的中斷。若是訓練一個模型須要花費幾天的訓練時間,中斷後從初始狀態從新訓練是不可接受的。

萬幸的是,飛槳支持從上一次保存狀態繼續訓練,只要咱們隨時保存訓練過程當中的模型狀態,就不用從初始狀態從新訓練。保存模型的代碼以下:

# 保存模型參數和優化器的參數    fluid.save_dygraph(model.state_dict(), './checkpoint/mnist_epoch{}'.format(epoch_id))    fluid.save_dygraph(optimizer.state_dict(), './checkpoint/mnist_epoch{}'.format(epoch_id))

訓練不只保存模型參數,並且保存優化器、學習率有關的參數,好比Adam, Adagrad優化器在訓練時會建立一些新的變量輔助訓練;動態變化的學習率須要保存訓練中止時的訓練步數。這些參數對於恢復訓練相當重要。

恢復訓練只須要恢復保存的模型和優化器相關參數便可。

# 加載模型參數到模型中    params_dict, opt_dict = fluid.load_dygraph(params_path)    model = MNIST("mnist")    model.load_dict(params_dict)
    # 使用Adam優化器,並加載保存的Adam優化器相關參數    optimizer = fluid.optimizer.AdamOptimizer(learning_rate=lr)    optimizer.set_dict(opt_dict)

總結

本次課程內容豐富,畢老師經過一個案例講解了深度學習的通常方法,全方面涵蓋了數據處理,模型設計,訓練配置,分佈式訓練,訓練優化與調試,恢復訓練等。以一個簡單的例子幫助學員們掌握了深度學習方法,真正實現了從0到1+的跨越。在後期課程中,將繼續爲你們帶來內容更豐富的課程,幫助學員快速掌握深度學習方法。

【如何學習】

1. 如何觀看配套視頻?如何代碼實踐?

視頻+代碼已經發布在AI Studio實踐平臺上,視頻支持PC端/手機端同步觀看,也鼓勵你們親手體驗運行代碼哦。掃碼或者打開如下連接:

https://aistudio.baidu.com/aistudio/course/introduce/888

2. 學習過程當中,有疑問怎麼辦?

加入深度學習集訓營QQ羣:726887660,班主任與飛槳研發會在羣裏進行答疑與學習資料發放。

3. 如何學習更多內容?

百度飛槳將經過飛槳深度學習集訓營的形式,繼續更新《零基礎入門深度學習》課程,由百度深度學習高級研發工程師親自授課,每週2、每週四8:00-9:00不見不散,採用直播+錄播+實踐+答疑的形式,歡迎關注~ 

請搜索AI Studio,點擊課程-百度架構師手把手教深度學習,或者點擊https://aistudio.baidu.com/aistudio/course/introduce/888收看。

下載安裝命令

## CPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

>> 訪問 PaddlePaddle 官網,瞭解更多相關內容

相關文章
相關標籤/搜索