摘要:為大家梳理了針對常見精度問題的除錯調優指南,將以“MindSpore模型精度調優實戰”系列文章的形式分享出來,幫助大家輕鬆定位精度問題,快速優化模型精度。
本文分享自華為雲社群《技術乾貨 | 更快定位精度問題!MindSpore模型精度調優實戰(一)》,原文作者:HWCloudAI 。
引言:
在模型的開發過程中,精度達不到預期常常讓人頭疼。為了幫助大家解決模型除錯調優的問題,我們為MindSpore量身定做了視覺化除錯調優元件:MindInsight。
還為大家梳理了針對常見精度問題的除錯調優指南,將以“MindSpore模型精度調優實戰”系列文章的形式分享出來,幫助大家輕鬆定位精度問題,快速優化模型精度。
本文是系列分享的第一篇,將簡單介紹常見精度問題,分析精度問題的常見現象和原因,並給出一個整體的調優思路。本系列分享假設您的指令碼已經能夠執行並算出loss值。如果指令碼還不能執行,請先參考相關報錯提示進行修改。在精度調優實踐中,發現異常現象是比較容易的。但是,如果我們對異常現象不夠敏感、不會解釋,還是會同問題根因失之交臂。本文對常見精度問題進行了解釋,能夠提高你對異常現象的敏感度,幫你更快定位精度問題。
01 精度問題的常見現象和原因
模型精度問題和一般的軟體問題不同,定位週期一般也更長。在通常的程式中,程式輸出和預期不符意味著存在bug(編碼錯誤)。但是對一個深度學習模型來說,模型精度達不到預期,有著更復雜的原因和更多的可能性。由於模型精度要經過長時間的訓練才能看到最終結果,定位精度問題通常會花費更長的時間。
1.1 常見現象
精度問題的直接現象一般體現在loss(模型損失值)和metrics(模型度量指標)上。loss現象一般表現為(1)loss跑飛,出現NAN,+/- INF,極大值(2)loss不收斂、收斂慢(3)loss為0等。模型metrics一般表現為模型的accuracy、precision等metric達不到預期。
精度問題的直接現象較容易觀察,藉助MindInsight等視覺化工具,還可以在梯度、權重、啟用值等張量上觀察到更多現象。常見現象如:(1)梯度消失(2)梯度爆炸(3)權重不更新(4)權重變化過小(5)權重變化過大(6)啟用值飽和等。
1.2 常見原因
有果必有因,在現象的背後,是精度問題的原因,可以簡單分為超參問題、模型結構問題、資料問題、演算法設計問題等類別:
-
1.2.1 超參問題
超參是模型和資料之間的潤滑劑,超參的選擇直接影響了模型對資料擬合效果的優劣。超參方面常見的問題如下:
1)學習率設定不合理(過大、過小)
2)loss_scale引數不合理
3)權重初始化引數不合理等
4)epoch過大或過小
5)batch size過大
學習率過大或過小。學習率可以說是模型訓練中最重要的超參了。學習率過大,會導致loss震盪,不能收斂到預期值。學習率過小,會導致loss收斂慢。應根據理論和經驗合理選擇學習率策略。
epoch過大或過小。epoch數目直接影響模型是欠擬合還是過擬合。epoch過小,模型未訓練到最優解就停止了訓練,容易欠擬合;epoch過大,模型訓練時間過長,容易在訓練集上過擬合,在測試集上達不到最優的效果。應根據訓練過程中驗證集上模型效果的變化情況,合理選擇epoch數目。batch size過大。batch size過大時,模型可能不能收斂到較優的極小值上,從而降低模型的泛化能力。
-
1.2.2 資料問題
a.資料集問題
資料集的質量決定了演算法效果的上限,如果資料質量差,再好的演算法也難以得到很好的效果。常見資料集問題如下:
1)資料缺失值過多
2)每個類別中的樣本數目不均衡
3)資料中存在異常值
4)訓練樣本不足
5)資料的標籤錯誤
資料集中存在缺失值、異常值,會導致模型學習到錯誤的資料關係。一般來說,應該從訓練集中刪除存在缺失值或異常值的資料,或者設定合理的預設值。資料標籤錯誤是異常值的一種特殊情況,但是這種情況對訓練的破壞性較大,應通過抽查輸入模型的資料等方式提前識別這類問題。
資料集中每個類別的樣本數目不均衡,是指資料集中每個類別中的樣本數目有較大差距。例如,影像分類資料集(訓練集)中,大部分類別都有1000個樣本,但是“貓”這一類別只有100個樣本,就可以認為出現了樣本數目不均衡的情況。樣本數目不均衡會導致模型在樣本數目少的類別上預測效果差。如果出現了樣本數目不均衡,應該酌情增加樣本量小的類別的樣本。一般來說,有監督深度學習演算法在每類5000個標註樣本的情況下將達到可以接受的效能,當資料集中有1000萬個以上的已標註樣本時,模型的表現將會超過人類。
訓練樣本不足則是指訓練集相對於模型容量太小。訓練樣本不足會導致訓練不穩定,且容易出現過擬合。如果模型的引數量同訓練樣本數量不成比例,應該考慮增加訓練樣本或者降低模型複雜度。
b.資料處理問題常見資料處理問題如下:
1)常見資料處理演算法問題
2)資料處理引數不正確等
3)未對資料進行歸一化或標準化
4)資料處理方式和訓練集不一致
5)沒有對資料集進行shuffle
未對資料進行歸一化或標準化,是指輸入模型的資料,各個維度不在一個尺度上。一般來說,模型要求各個維度的資料在-1到1之間,均值為0。如果某兩個維度的尺度存在數量級的差異,可能會影響模型的訓練效果,此時需要對資料進行歸一化或標準化。資料處理方式和訓練集不一致是指在使用模型進行推理時,處理方式和訓練集不一致。例如對圖片的縮放、裁切、歸一化引數和訓練集不同,會導致推理時的資料分佈和訓練時的資料分佈產生差異,可能會降低模型的推理精度。備註:一些資料增強操作(如隨機旋轉,隨機裁切等)一般只應用在訓練集,推理時無需進行資料增強。
沒有對資料集進行shuffle,是指訓練時未對資料集進行混洗。未進行shuffle,或者混洗不充分,會導致總是以相同的資料順序更新模型,嚴重限制了梯度優化方向的可選擇性,導致收斂點的選擇空間變少,容易過擬合。
-
1.2.3 演算法問題
演算法本身有缺陷導致精度無法達到預期。
a. API使用問題
常見API使用問題如下:
1.使用API沒有遵循MindSpore約束
2.構圖時未遵循MindSpore construct約束。
使用API未遵循MindSpore約束,是指使用的API和真實應用的場景不匹配。例如,在除數中可能含有零的場景,應該考慮使用DivNoNan而非Div以避免產生除零問題。又例如,MindSpore中,DropOut第一個引數為保留的概率,和其它框架正好相反(其它框架為丟掉的概率),使用時需要注意。
構圖未遵循MindSpore construct約束,是指圖模式下的網路未遵循MindSpore靜態圖語法支援中宣告的約束。例如,MindSpore目前不支援對帶鍵值對引數的函式求反向。完整約束請見:https://mindspore.cn/doc/note/zh-CN/master/static_graph_syntax_support.html
b. 計算圖結構問題
計算圖結構是模型計算的載體,計算圖結構錯誤一般是實現演算法時程式碼寫錯了。計算圖結構方面常見的問題有:
1.運算元使用錯誤(使用的運算元不適用於目標場景)
2.權重共享錯誤(共享了不應共享的權重)
3.節點連線錯誤(應該連線到計算圖中的block未連線)
4.節點模式不正確
5.權重凍結錯誤(凍結了不應凍結的權重)
6.loss函式有誤
7.優化器演算法錯誤(如果自行實現了優化器)等
權重共享錯誤,是指應該共享的權重未共享,或者不應該共享的權重共享了。通過MindInsight計算圖可視,可以檢查這一類問題。
權重凍結錯誤,是指應該凍結的權重未凍結,或者不應該凍結的權重凍結了。在MindSpore中,凍結權重可以通過控制傳入優化器的params引數來實現。未傳入優化器的Parameter將不會被更新。可以通過檢查指令碼,或者檢視MindInsight中的引數分佈圖確認權重凍結情況。
節點連線錯誤,是指計算圖中各block的連線和設計不一致。如果發現節點連線錯誤,應該仔細檢查指令碼是否編寫出錯。
節點模式不正確,是指部分割槽分訓練、推理模式的運算元,需要按照實際情況設定模式。典型的包括:(1)BatchNorm運算元,訓練時應開啟BatchNorm的訓練模式,此開關在呼叫 net.set_train(True)的時候會自動開啟(2)DropOut運算元,推理時不應使用DropOut運算元。
loss函式有誤,是指loss函式演算法實現錯誤,或者未選擇合理的loss函式。例如,BCELoss和BCEWithLogitsLoss是不同的,應根據是否需要sigmoid函式合理選擇。
c. 權重初始化問題
權重初始值是模型訓練的起點,不合理的初始值將會影響模型訓練的速度和效果。權重初始化方面常見問題如下:
1.權重初始值全部為0
2.分散式場景不同節點的權重初始值不同
權重初始值全為0,是指初始化後,權重值為0。這一般會導致權重更新問題,應使用隨機值初始化權重。
分散式場景不同節點的權重初始值不同,是指初始化後,不同節點上的同名權重初始值不同。正常來說,MindSpore會對梯度做全域性AllReduce。確保每個step結尾,權重更新量是相同的,從而保證每個step中,各個節點上的權重一致。如果初始化時各節點的權重不同,就會導致不同節點的權重在接下來的訓練中處於不同的狀態,會直接影響模型精度。分散式場景應通過固定相同的隨機數種子等方式,確保權重的初始值一致。
1.3 相同現象存在多個可能原因導致精度問題定位難
以loss不收斂為例(下圖),任何可能導致啟用值飽和、梯度消失、權重更新不正確的問題都可能導致loss不收斂。例如錯誤地凍結了部分權重,使用的啟用函式和資料不匹配(使用relu啟用函式,輸入值全部小於0),學習率過小等原因都是loss不收斂的可能原因。
02 調優思路概述
針對上述精度問題的現象和原因,常用的幾個調優思路如下:檢查程式碼和超參、檢查模型結構、檢查輸入資料、檢查loss曲線。若上述思路都未發現問題,我們可以讓訓練執行到最後,檢查精度(主要是模型metrics)是否達到預期。
其中,檢查模型結構和超參重在檢查模型的靜態特徵;檢查輸入資料和loss曲線則是將靜態特徵和動態訓練現象結合檢查;檢查精度是否達到預期則是對整體精度調優過程重新審視,並考慮調整超參、解釋模型、優化演算法等調優手段。
為了幫助使用者高效實施上述的精度調優思路,MindInsight提供了配套的能力,如下圖。在本系列的後續文章後,我們會展開介紹精度調優的準備工作,每個調優思路的細節,以及如何使用MindInsight的功能實踐這些調優思路,敬請期待。
03 精度問題checklist
最後,我們將常見的精度問題彙總到一起,以方便大家查閱:
瞭解完MindSpore的關鍵技術是不是很心動呢!趕緊【點選連結】並【立即報名】,即可在 ModelArts 平臺學習到一個經典案例掌握基於MindSpore的深度學習!