[ELE32] 蟒炬誤

G-HL-PE.ELE32 Program-Engineering. Emerge-Logs Errors Python(3)-Torchs(2)

ss

sss


cpp_extension.py:383: UserWarning: Error checking compiler version for cl: [WinError 2] 系統(tǒng)找不到
指定的文件嘶炭。


HW-NIVIDA(cuda)

.cuda() 的因地制宜

cuda()能實現(xiàn)從 CPUGPU 的內(nèi)存遷移, 但是對于模型nn.Module.cuda和張量Tensor.cuda的作用效果不同
對于 nn.Module 兩句效果一樣: 對model自身進行的內(nèi)存遷移
對于Tensor:
調(diào)用tensor.cuda只是返回這個tensor對象在GPU內(nèi)存上的拷貝齐遵,而
不會對自身進行改變
当辐。因此必須對tensor進行重新賦值发钝,即tensor=tensor.cuda.

.cuda() 的因地制宜

cuda()能實現(xiàn)從 CPU 到 GPU 的內(nèi)存遷移, 但是對于模型nn.Module.cuda和張量Tensor.cuda的作用效果不同

對于 nn.Module 兩句效果一樣: 對model自身進行的內(nèi)存遷移

對于Tensor:

調(diào)用tensor.cuda只是返回這個tensor對象在GPU內(nèi)存上的拷貝异希,而不會對自身進行改變袭景。因此必須對tensor進行重新賦值狠角,即tensor=tensor.cuda.

2. PyTorch 0.4 計算累積損失的不同

以廣泛使用的模式total_loss += loss.data[0]為例号杠。Python0.4.0之前,loss是一個封裝了(1,)張量的Variable丰歌,但Python0.4.0的loss現(xiàn)在是一個零維的標量姨蟋。對標量進行 索引是沒有意義的(似乎會報 invalid index to scalar variable 的錯誤)。使用loss.item可以從標量中獲取Python數(shù)字立帖。所以改為:

如果在累加損失時未將其轉(zhuǎn)換為Python數(shù)字芬探,則可能出現(xiàn)程序內(nèi)存使用量增加的情況。這是因為上面表達式的右側(cè)原本是一個Python浮點數(shù)厘惦,而它現(xiàn)在是一個零維張量偷仿。因此,總損失累加了張量和它們的梯度歷史宵蕉,這可能會產(chǎn)生很大的autograd 圖酝静,耗費內(nèi)存和計算資源。

3. PyTorch 0.4 編寫不限制設備的代碼

a3819b4f5ba651e9cf8905ff101491f3.png

4. torch. Tensor.detach的使用

detach的官方說明如下:

892cb0a026489de13ec914e11eaf8025.png

假設有模型A和模型B羡玛,我們需要將A的輸出作為B的輸入别智,但訓練時我們只訓練模型B. 那么可以這樣做:

input_B = output_A.detach

它可以使兩個計算圖的梯度傳遞斷開,從而實現(xiàn)我們所需的功能稼稿。

5. ERROR: Unexpected bus error encountered in worker. This might be caused by insufficient shared memory (shm)

出現(xiàn)這個錯誤的情況是薄榛,在服務器上的docker中運行訓練代碼時讳窟,batch size設置得過大,shared memory不夠(因為docker限制了shm).解決方法是敞恋,將Dataloader的num_workers設置為0.

6. pytorch中l(wèi)oss函數(shù)的參數(shù)設置

以CrossEntropyLoss為例:

57182ee1f352959aa889815798ff35a5.png

若 reduce = False丽啡,那么 size_average 參數(shù)失效,直接返回向量形式的 loss硬猫,即batch中每個元素對應的loss.

若 reduce = True补箍,那么 loss 返回的是標量:

如果 size_average = True,返回 loss.mean.

如果 size_average = False啸蜜,返回 loss.sum.

weight : 輸入一個1D的權值向量坑雅,為各個類別的loss加權,如下公式所示:

c4646e8b1163f6627d89b4605af1ddb9.png

ignore_index : 選擇要忽視的目標值衬横,使其對輸入梯度不作貢獻裹粤。如果 size_average = True,那么只計算不被忽視的目標的loss的均值蜂林。

reduction : 可選的參數(shù)有:‘none’ | ‘elementwise_mean’ | ‘sum’, 正如參數(shù)的字面意思遥诉,不解釋。7. pytorch的可重復性問題 8. 多GPU的處理機制

使用多GPU時悉尾,應該記住pytorch的處理邏輯是:

1.在各個GPU上初始化模型突那。

2.前向傳播時,把batch分配到各個GPU上進行計算构眯。

3.得到的輸出在主GPU上進行匯總愕难,計算loss并反向傳播,更新主GPU上的權值惫霸。

4.把主GPU上的模型復制到其它GPU上猫缭。

9. num_batches_tracked參數(shù)

今天讀取模型參數(shù)時出現(xiàn)了錯誤

114f54734c0b3f6310b1ff0d6403b394.png

大概可以看出,這個參數(shù)和訓練時的歸一化的計算方式有關壹店。

因此猜丹,我們可以知道該錯誤是由于訓練和測試所用的pytorch版本(0.4.1版本前后的差異)不一致引起的。具體的解決方案是:如果是模型參數(shù)(Orderdict格式硅卢,很容易修改)里少了num_batches_tracked變量射窒,就加上去,如果是多了就刪掉将塑。偷懶的做法是將load_state_dict的strict參數(shù)置為False脉顿,如下所示:

3265936229603edd60ffaba578b11049.png

還看到有人直接修改pytorch 0.4.1的源代碼把num_batches_tracked參數(shù)刪掉的,這就非常不建議了点寥。

10. 訓練時損失出現(xiàn)nan的問題

最近在訓練模型時出現(xiàn)了損失為nan的情況艾疟,發(fā)現(xiàn)是個大坑。暫時先記錄著。

可能導致梯度出現(xiàn)nan的三個原因:

1. 梯度爆炸蔽莱。也就是說梯度數(shù)值超出范圍變成nan. 通车芙可以調(diào)小學習率、加BN層或者做梯度裁剪來試試看有沒有解決盗冷。

2. 損失函數(shù)或者網(wǎng)絡設計怠苔。比方說,出現(xiàn)了除0正塌,或者出現(xiàn)一些邊界情況導致函數(shù)不可導嘀略,比方說log(0)恤溶、sqrt(0).

3. 臟數(shù)據(jù)乓诽。可以事先對輸入數(shù)據(jù)進行判斷看看是否存在nan.

補充一下nan數(shù)據(jù)的判斷方法:

注意咒程!像nan或者inf這樣的數(shù)值不能使用 == 或者 is 來判斷鸠天!為了安全起見統(tǒng)一使用 math.isnan 或者 numpy.isnan 吧。

例如:

45217bfdf5d576bd931a79fd4c373e3a.png

raiseValueError('Expected more than 1 value per channel when training, got input size {}'.format(size)

沒有什么特別好的解決辦法帐姻,在訓練前用 num_of_samples % batch_size 算一下會不會正好剩下一個樣本稠集。

可以考慮將DataLoaderdrop_last選項設為True,這樣的話饥瓷,當最后一個batch湊不滿時剥纷,就會舍棄掉。

12. 優(yōu)化器的weight_decay項導致的隱蔽bug

我們都知道weight_decay指的是權值衰減呢铆,即在原損失的基礎上加上一個L2懲罰項晦鞋,使得模型趨向于選擇更小的權重參數(shù),起到正則化的效果棺克。但是我經(jīng)常會忽略掉這一項的存在悠垛,從而引發(fā)了意想不到的問題。

這次的坑是這樣的娜谊,在訓練一個ResNet50的時候确买,網(wǎng)絡的高層部分layer4暫時沒有用到,因此也并不會有梯度回傳纱皆,于是我就放心地將ResNet50的所有參數(shù)都傳遞給Optimizer進行更新了湾趾,想著layer4應該能保持原來的權重不變才對。 但是實際上派草,盡管layer4沒有梯度回傳搀缠,但是weight_decay的作用仍然存在,它使得layer4權值越來越小澳眷,趨向于0胡嘿。后面需要用到layer4的時候,發(fā)現(xiàn)輸出異常(接近于0)钳踊,才注意到這個問題的存在衷敌。

雖然這樣的情況可能不容易遇到勿侯,但是還是要謹慎:暫時不需要更新的權值,一定不要傳遞給Optimizer缴罗,避免不必要的麻煩助琐。

13. TensorDataset 數(shù)據(jù)加載速度

TensorDataset 提供了已經(jīng)完全加載到內(nèi)存中的矩陣的數(shù)據(jù)讀取接口。在使用 TensorDataset的時候面氓,如果直接用DataLoader兵钮,會導致數(shù)據(jù)加載速度非常緩慢,嚴重拖慢訓練速度舌界,分析和解決方案詳見

https://huangbiubiu.github.io/2019/BEST-PRACTICE-PyTorch-TensorDataset

SW- jit\tensorboard..

AttributeError

module 'distutils' has no attribute 'version'

pytorch 的 tensorboard: torch.utils.tensorboard和 setuptools 版本不匹配

pip install tensorboardX

DT - type, feature, loss,

讀取模型參數(shù)錯誤

num_batches_tracked 參數(shù): 和訓練時的歸一化的計算方式有關掘譬。

因此,我們可以知道該錯誤是由于訓練和測試所用的pytorch版本(0.4.1版本前后的差異)不一致引起的呻拌。具體的解決方案是:如果是模型參數(shù)(Orderdict格式葱轩,很容易修改)里少了num_batches_tracked變量,就加上去藐握,如果是多了就刪掉靴拱。偷懶的做法是將load_state_dict的strict參數(shù)置為False,如下所示:

不建議直接修改源代碼 (把num_batches_tracked參數(shù)刪掉)

ERROR: Unexpected bus error encountered in worker. This might be caused by insufficient shared memory (shm) 出現(xiàn)這個錯誤的情況是猾普,在服務器上的docker中運行訓練代碼時袜炕,batch size設置得過大,shared memory不夠(因為docker限制了shm).

解決方法是初家,將Dataloader的num_workers設置為0.

隱層出現(xiàn) nan

RuntimeWarning

[nan] = self._nnLnrm(x)

RuntimeWarning: invalid value encountered in subtract

gae += vag - val    # core[enbRppo.py:222]

RuntimeWarning: invalid value encountered in subtract

_np.subtract(arr, avg, out=arr, casting='unsafe', where=where) # numpy[nanfunctions.py:1740]

RuntimeWarning: invalid value encountered in subtract

return (valAqsa - valAmea) / (valAstd + 1e-5)   # 3*2:1 core[ent_mpo.py:179]

[ENBrSPR] : getrDet

FutureWarning x2: Non-finite norm encountered in torch.nn.utils.clip_grad_norm_; continuing anyway.

Note that the default behavior will change in a future release to error out if a non-finite total norm is encountered. At that point, setting error_if_nonfinite=false will be required to retain the old behavior.

return _nn.utils.clip_grad_norm_(self._or_act.parameters(), nrmMgrd, error_if_nonfinite=False)
# core[enp_mpo.py:277][enp_mpo.py:279]

檢查用的什么層: _nn.LayerNorm

batch 部分輸入是全 0, 把這種 batch 提前屏蔽掉

FutureWarning:
Non-finite norm encountered in torch.nn.utils.clip_grad_norm_; continuing anyway.
Note that the default behavior will change in a future release to error out
if a non-finite total norm is encountered.
At that point, setting nn.utils.clip_grad_norm:
error_if_nonfinite = false
will be required to retain the old behavior.

Pytorch梯度截斷:torch.nn.utils.clip_grad_norm_

梯度裁剪

既然在BP過程中會產(chǎn)生梯度消失(即偏導無限接近0偎窘,導致長時記憶無法更新),那么最簡單粗暴的方法笤成,設定閾值评架,當梯度小于閾值時,更新的梯度為閾值(梯度裁剪解決的是梯度消失或爆炸的問題炕泳,即設定閾值)

訓練時候的drop out的方法纵诞,用于解決神經(jīng)網(wǎng)絡訓練過擬合的方法

輸入是(NN參數(shù),最大梯度范數(shù)培遵,范數(shù)類型=2) 一般默認為L2 范數(shù)浙芙。

讓每一次訓練的結果都不過分的依賴某一部分神經(jīng)元,在訓練的時候隨機忽略一些神經(jīng)元和神經(jīng)的鏈接籽腕,使得神經(jīng)網(wǎng)絡變得不完整嗡呼, 是解決過擬合的一種方法。y =wx皇耗,W為所要學習的各種參數(shù)南窗,在過擬合中,W往往變化率比較大,這個時候 用clip_grad_norm 控制W 變化的不那么大万伤,把原來的cost =(Wx-realY)^2 -->cost=(Wx-realY)^2 +L2 正則

在訓練模型的過程中窒悔,我們有可能發(fā)生梯度爆炸的情況,這樣會導致我們模型訓練的失敗敌买。

我們可以采取一個簡單的策略來避免梯度的爆炸简珠,那就是梯度截斷Clip, 將梯度約束在某一個區(qū)間之內(nèi),在訓練的過程中虹钮,在優(yōu)化器更新之前進行梯度截斷操作聋庵。

損失出現(xiàn) nan

ddd

梯度出現(xiàn) nan

可能原因:

  1. 梯度爆炸。也就是說梯度數(shù)值超出范圍變成nan. 通耻搅唬可以調(diào)小學習率祭玉、加BN層或者做梯度裁剪來試試看有沒有解決。
  2. 損失函數(shù)或者網(wǎng)絡設計宅倒。比方說攘宙,出現(xiàn)了除0屯耸,或者出現(xiàn)一些邊界情況導致函數(shù)不可導拐迁,比方說log(0)、sqrt(0).
  3. 臟數(shù)據(jù)疗绣∠哒伲可以事先對輸入數(shù)據(jù)進行判斷看看是否存在nan.

raiseValueError

('Expected more than 1 value per channel when training, got input size {}'.format(size)

訓練前用 num_of_samples % batch_size 算一下會不會正好剩下一個樣本。

DataLoaderdrop_last選項設為True多矮,這樣的話缓淹,當最后一個batch湊不滿時,就會舍棄掉塔逃。

計算累積損失

栗子: total_loss += loss.data[0] loss 是一個封裝了(1,)張量的 Variable

應使用loss.item可以從標量中獲取Python數(shù)字

如果在累加損失時未將其轉(zhuǎn)換為Python數(shù)字讯壶,則可能出現(xiàn)程序內(nèi)存使用量增加的情況。這是因為上面表達式的右側(cè)原本是一個Python浮點數(shù)湾盗,而它現(xiàn)在是一個零維張量伏蚊。因此,總損失累加了張量和它們的梯度歷史格粪,這可能會產(chǎn)生很大的autograd 圖躏吊,耗費內(nèi)存和計算資源。

權值衰減 weight_decay

原損失的基礎上加上一個L2懲罰項起到正則化的效果

訓練一個多層網(wǎng)絡, 直接將所有參數(shù)都 Optimize, 高層部分暫時沒用(沒有梯度回傳)但權重變小了?

盡管沒有梯度回傳帐萎,但是 weight_decay 依然起效使得不用層權值越來越小(趨于0)

不需更新的權值不要傳遞給 Optimizer

數(shù)據(jù)加載速度非常緩慢 TensorDataset

TensorDataset 提供了已經(jīng)完全加載到內(nèi)存中的矩陣的數(shù)據(jù)讀取接口

直接用 DataLoader比伏,數(shù)據(jù)加載速度慢

https://huangbiubiu.github.io/2019/BEST-PRACTICE-PyTorch-TensorDatasethuangbiubiu.github.io/2019/BEST-PRACTICE-PyTorch-TensorDataset

Grad Norm

  1. Future Warning: Non-finite norm encountered in torch.nn.utils.clip_grad_norm_;

continuing anyway.

  • 學習率過大:
    使用了 ReLU 激活函數(shù) 以后, 某一步跨入了一個點, 出現(xiàn)了dead neuron 現(xiàn)象, 前面的參數(shù)全部不更新, 最后的結果變成了定值.

  • base_lr,至少減小一個數(shù)量級疆导。如果有多個loss layer赁项,需要找出哪個損失層導致了梯度爆炸,并減小該層的loss_weight,而非是減小通用的base_lr悠菜。

  • 設置clip gradient紫新,用于限制過大的diff。

  • 壞樣本存在

  • 樣本的全是0李剖,減去均值除以方差以后就變成了nan

  • 并行mask設置失誤, 遺漏了一些導致padding傳入

  • 希望模型輸出為0芒率,結果又用了log輸出來作為損失的方式。這就導致篙顺,在輸出可以做到為0的情況下偶芍,log之后就會nan

neg_outputs=model(x)
loss=torch.log(neg_outputs + 6e-7)  # 6e-7 保證了最小值 損失就會飽和
  • 自己定義的某個Tensor沒有初始化
    比如代碼中實現(xiàn)一些簡單的weight matrix的時候,你直接使用 torch.FloatTensor 作為訓練參數(shù)德玫,但是FloatTensor 本身的初始化是不適用于深度神經(jīng)網(wǎng)絡的匪蟀,此時最好用 nn.init. 初始化

  • 損失函數(shù)的Bug

  • 原因:有時候損失層中l(wèi)oss的計算可能導致NaN的出現(xiàn)。比如宰僧,給InfogainLoss層(信息熵損失)輸入沒有歸一化的值材彪,使用帶有bug的自定義損失層等等。

  • 現(xiàn)象:觀測訓練產(chǎn)生的log時一開始并不能看到異常琴儿,loss也在逐步的降低段化,但突然之間NaN就出現(xiàn)了

  • 檢查 loss 計算公式。一定要使用那種飽和類型的損失造成,例如你希望模型二分類显熏,loss不應該設置為,對于類別1晒屎,希望模型輸出為正無窮大喘蟆,對于類別0,希望模型輸出為負無窮大鼓鲁,這樣loss不會飽和蕴轨,模型會一直訓練下去,很容易nan骇吭。應該改為橙弱,對模型輸出的結果,加一層sigmoid绵跷,從而對于類別1膘螟,希望模型輸出為1,對于類別0碾局,模型輸出為0荆残。而對于sigmoid這種飽和函數(shù),輸出為1净当,輸入不需要是正無窮大内斯,6蕴潦,7,8這種數(shù)字就可以差不多輸出為1了俘闯。

注: the default behavior will change in a future release to error out if a non-finite total norm is encountered. At that point, setting error_if_nonfinite=false will be required to retain the old behavior.

RuntimeError: [enforce fail at http://inline_container.cc:145

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末潭苞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子真朗,更是在濱河造成了極大的恐慌此疹,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遮婶,死亡現(xiàn)場離奇詭異蝗碎,居然都是意外死亡,警方通過查閱死者的電腦和手機旗扑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門蹦骑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人臀防,你說我怎么就攤上這事眠菇。” “怎么了袱衷?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵捎废,是天一觀的道長。 經(jīng)常有香客問我祟昭,道長缕坎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任篡悟,我火速辦了婚禮,結果婚禮上匾寝,老公的妹妹穿的比我還像新娘搬葬。我一直安慰自己,他們只是感情好艳悔,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布急凰。 她就那樣靜靜地躺著,像睡著了一般猜年。 火紅的嫁衣襯著肌膚如雪抡锈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天乔外,我揣著相機與錄音床三,去河邊找鬼。 笑死杨幼,一個胖子當著我的面吹牛撇簿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼忍抽,長吁一口氣:“原來是場噩夢啊……” “哼因妇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起找蜜,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤饼暑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后洗做,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體撵孤,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年竭望,在試婚紗的時候發(fā)現(xiàn)自己被綠了邪码。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡咬清,死狀恐怖闭专,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情旧烧,我是刑警寧澤影钉,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站掘剪,受9級特大地震影響平委,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜夺谁,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一廉赔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧匾鸥,春花似錦蜡塌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至奴愉,卻和暖如春琅摩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锭硼。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工房资, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人账忘。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓志膀,卻偏偏與公主長得像熙宇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子溉浙,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容