<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【論文閱讀】Mixed Precision Traning

          共 3581字,需瀏覽 8分鐘

           ·

          2020-12-13 09:44

          【GiantPandaCV導語】混合精度是一個非常簡單并且實用的技術,由百度和谷歌聯(lián)合發(fā)表于ICLR2018,可以讓模型以半精度的方式訓練模型,既能夠降低顯存占用,又可以保持精度。這篇文章不是最先提出使用更低精度來進行訓練,但是其影響力比較深遠,很多現(xiàn)在的方案都是基于這篇文章設計的。

          1. 摘要

          提高網(wǎng)絡模型的大小可以有效提升準確了,但是也增加了內存的壓力和計算力的需求。本論文引入了半精度來訓練深度神經(jīng)網(wǎng)絡,在不損失精度、不需要更改超參數(shù)的情況下,幾乎可以減半內存占用。

          權重、激活、梯度都是以IEEE半精度的方式存儲的,由于半精度的表示范圍要比單精度要小,本文提出了三種方法來防止關鍵信息的丟失。

          • 推薦維護一個單精度版本的權重weights,用于累積梯度。
          • 提出使用Loss scale來保證小的梯度值不會下溢出。
          • 在加載到內存之前,就將模型轉化到半精度來進行加速。

          2. 介紹

          大的模型往往需要更多的計算量、更多的內存資源來訓練,如果想要降低使用的資源,可以通過降低精度的方法。通常情況下,一個程序運行速度的快慢主要取決于三個因素:

          • 算法帶寬
          • 內存帶寬
          • 時延

          使用半精度減少了一半bit,可以影響算法帶寬和內存帶寬,好處有:

          • 由于是用更少的bit代替,占用空間會減小差不多一半
          • 對于處理器來說也是一個好消息,使用半精度可以提高處理器吞吐量;在當時的GPU上,半精度的吞吐量可以達到單精度的2-8倍。

          現(xiàn)在大部分深度學習訓練系統(tǒng)使用單精度FP32的格式進行存儲和訓練。本文采用了IEEE的半精度格式(FP16)。但是由于FP16可以表示的范圍要比FP32更為狹窄,所以引入了一些技術來規(guī)避模型的精度損失。

          • 保留一份FP32的主備份。
          • 使用loss scale來避免梯度過小。
          • FP16計算但是用FP32進行累加。

          3. 實現(xiàn)

          Mixed Precision

          下面詳細講解第二節(jié)提到的三種技術。

          3.1 FP32的主備份

          這部分示意圖

          在混合精度訓練中,權重、激活、梯度都采用的是半精度存儲的。為了匹配單精度網(wǎng)絡的精度,在優(yōu)化的整個過程中,需要拷貝一份單精度模型FP32作為主備份,而訓練過程中使用的是FP16進行計算。

          這樣做的原因有兩個:

          第一:溢出錯誤:更新的時候是學習率乘以梯度,這個值可能非常小,超過半精度最小范圍(),就會導致下溢出。如下圖展示了梯度和FP16的表示范圍,大約有5%的梯度已經(jīng)下溢出,如果直接對半精度表示的模型更新,這樣模型的精度肯定有所損失;而對單精度的模型進行更新,就就可以規(guī)避下溢出的問題。

          梯度和半精度范圍
          • 第二:舍入誤差:指的是當梯度過小,小于當前區(qū)間內的最小間隔,那么梯度更新可能會失敗。想要詳細了解可以自行查看wiki上的詳解。同樣的,使用FP32單精度可以盡可能減少舍入誤差的影響。
          圖源知乎@瓦礫

          3.2 Loss Scale

          下圖展示的是激活值的范圍和FP16表示范圍之間的差異,50%以上的值都集中在不可表示的范圍中,而右側FP16可表示范圍卻空蕩蕩的,那么一個簡單的想法就是向右平移,將激活平移到FP16可表示范圍內。比如說可以將激活乘以8,這樣可以平移3位,這樣表示最低范圍就從到了, 因為激活值低于的部分對模型訓練來說不重要,所以這樣操作就可以達到FP32的精度。

          Loss Scale

          那實際上是如何實現(xiàn)平移呢?很簡單,就是在loss基礎上乘以一個很大的系數(shù)loss scale, 那么由于鏈式法則,可以確保梯度更新的時候也采用相同的尺度進行縮放,最后在更新梯度之前再除以loss scale, 對FP32的單精度備份進行更新,就完成了。

          圖源NVIDIA PPT

          還有一個問題,就是loss scale值的選取,最簡單的方法就是選擇一個固定值作為loss scale,可以訓練一系列網(wǎng)絡縮放因子的設置可以從8到32k。固定的放縮因子選取是需要一定經(jīng)驗的,如果梯度的數(shù)據(jù)可以獲取,那就選取一個值可以讓其梯度的值小于65504(FP16可以表示的最大值)。如果選取loss scale值過大,可能會上溢出,這種情況可以通過檢查梯度來判斷,如果發(fā)生溢出,跳過權重更新,進行下一次迭代。

          3.3 運算精度

          在神經(jīng)網(wǎng)絡中的運算可以劃分為三類:向量點乘(dot-products)、reduction和逐點操作。這三種操作在遇到半精度的時候,會有不同的處理方法。

          為了保持模型精度,需要將向量點乘的部分乘積累加為FP32,然后再轉換為FP16。如果直接用FP16會導致精度損失,不能達到和原來一樣的精度?,F(xiàn)在很多支持Tensor Cores的GPU中已經(jīng)實現(xiàn)了這樣的操作。

          Reduction操作(比如求很多向量元素的和)需要先轉為FP32, 這樣的操作大部分出現(xiàn)在batch norm或者softmax層中。這兩個層都是從內存中讀寫FP16的向量,執(zhí)行運算的時候要使用FP32格式。

          逐點操作,如非線性和元素間矩陣乘法,內存占用有限,運算精度不影響這些操作的速度。

          4. 結果

          在分類任務(ILSVRC/ImageNet)、檢測任務(VOC2007)、語音識別(English-Mandarin)、機器翻譯(English-Frech)、語言模型(1 billion word)、DCGAN這幾個任務進行了實驗,這篇解讀僅展示分類任務和檢測任務的結果。

          實驗的時候每個任務都會設置一個兩個對比試驗

          • Baseline (FP32): 單精度的激活、權重、梯度得到的模型,運算使用的也是FP32。
          • Mixed Precision(MP): FP16用來存儲和數(shù)值運算;權重、激活、梯度都是用的是FP16,其中主備份權重是FP32的。在一些任務中使用了Loss-scaling的技術。運算過程中使用Tensor Cores將累加過程(卷積層、全連接層、矩陣相乘)轉為FP32來計算。

          4.1 分類

          分類任務上選擇了AlexNet、Vgg-D、GoogLeNet、Inceptionv2、Inceptionv3 和 預激活ResNet50幾個模型進行測試,主要滿足以下條件:

          • 使用相同的超參數(shù)比較top-1 準確率。
          • 訓練方法采用的是開源庫中默認的方法。
          • 數(shù)據(jù)增強方法使用的是最簡單的,并沒有采用開源庫中復雜的方法。主要包括:
            • 隨機水平翻轉
            • 隨機剪裁crop
          top-1實驗結果對比

          可以看到Mixed Precision方法能夠和Baseline方法差不多準確率,有時候甚至會略高于Baseline。

          在訓練以上網(wǎng)絡的時候,不需要使用Loss Scale方法,因為這些方法前向傳播和反向傳播的值都在FP16范圍內。

          4.2 檢測

          這里選擇了Faster RCNN和Multibox-SSD兩種方法在VOC2007數(shù)據(jù)集上進行訓練,兩個方法都是用來VGG-16作為骨干網(wǎng)絡。模型和訓練腳本都來自于開源庫。

          VOC2007上實驗結果

          可以看到,如果使用Mixed Precision方法,在訓練Multibox SSD的時候可能會由于下溢出導致模型不收斂,但是當使用了Loss Scale技術以后,就可以正常收斂,達到與Baseline相同的結果。

          5. 總結

          Mixed Precision混合精度是處于一個非常簡單的想法,使用低精度的表示可以節(jié)約顯存、內存同時增加處理器的吞吐量。雖然有以上的種種好處,直接使用半精度會出現(xiàn)一定的問題,比如:下溢出、精度損失等。所以這篇論文核心就是解決使用半精度過程中出現(xiàn)的問題,提出了三個方法達到了非常理想的效果。如果你使用的是有Tensor Core的GPU,那就非常推薦使用混合精度來訓練,只需要安裝NVIDIA提供的Apex庫,然后在你的PyTorch or TensorFlow代碼中加幾行代碼就可以實現(xiàn)。

          6. 參考

          • https://arxiv.org/pdf/1710.03740v3

          • https://blogs.nvidia.com/blog/2019/11/15/whats-the-difference-between-single-double-multi-and-mixed-precision-computing/

          • https://zhuanlan.zhihu.com/p/163493798

          • https://zhuanlan.zhihu.com/p/79887894


          為了感謝讀者的長期支持,今天我們將送出三本由 北京大學出版社 提供的:《Python神經(jīng)網(wǎng)絡入門與實戰(zhàn)》 。點擊下方抽獎助手參與抽獎。

          python神經(jīng)網(wǎng)絡入門與實戰(zhàn)抽獎鏈接


          瀏覽 30
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产一级18 片视频 | 亚洲免费黄 | 日韩无码日韩有码 | 日本一级免费视频 | 精品乱子伦一区二区三区免费播放 |