pytorch訓練出現nan是什麼意思

2021-10-13 23:03:28 字數 1871 閱讀 9242

1.背景

訓練時忽然發現某幾項loss變成了nan。

2.nan的含義

nan值在python往往可以直接與無窮大,無窮小等價。

第乙個常見例子: los

s/po

snum

loss / posnum

loss/p

osnu

m,希望根據正例個數平分loss,卻忽視pos_num可能為0,也就是中沒有正例,常見解決los

s/

(0.0001+n

um

)loss/(0.0001 + num)

loss/(

0.00

01+n

um)或者if判斷;

第二個常見例子:loss計算中帶有log( p)時,p卻為0,後果就是反傳梯度無窮大

第三個常見例子:mask = gt>0, 然後索引 pos_p = pred[mask],卻不知此時的pos_p為空;

原因:上面第二條

debug

當出現nan後在模型forward函式上打斷點,結果發現在第一步時就出現了nan,正常的x輸入後出來就有nan值。

def

forward

(self, x)

: x = self.base_layer(x)..

.

而self.base模組只是簡單的卷積模組:

self.base_layer = nn.sequential(

nn.conv2d(

3,self.channels[0]

, kernel_size=

7, stride=

1,padding=

3,bias=

false),

nn.batchnorm2d(self.channels[0]

,momentum=

0.1)

, nn.relu(inplace=

true

))

再列印出它的學習引數:

for p in self.base_layer.parameters():

print

(p)

結果發現大部分引數已經是nan了,而這裡只是整個模型第一層…

顯然梯度**了,自然檢查去loss。

重新開始,在總的loss處debug:

if

(torch.isnan(loss)

.sum()

>0)

:print

("here!"

)

當首次出現loss時在此處斷點,結果發現,nan**某一項loss,我這裡是focal loss,顯然是來自裡面的log(p ),而p,也就是網路**為0了,本該p∈[

0,1]

p\in[0, 1]

p∈[0,1

],怎麼會有0?

最後想起是sigmoid函式:

z[

'hm'

]= z[

'hm'

].sigmoid(

)* out_branch

最後調整為:

z[

'hm'

]= torch.clamp(z[

'hm'

].sigmoid(),

min=1e-

4,max=1-

1e-4)

* out_branch

hourglass訓練出現acc是nan的情形

1 在訓練hourglass和pyranet的時候都會出現訓練的時候acc會nan,why?根據acc的 只有在分母為0的時候才會出現nan的情形,以coco為例,badidxcount是17,造成nan。為什麼badidxcount會是17呢?返回的全是 1,為什麼會返回全是 1?只能是給出的17...

sphereface 訓練出現的問題

訓練了64 層卷積的模型,沒有訓出來作者 上發布的結果。現在訓練最好的結果是十重校驗的平均是99.30 上報告的精度是99.42 差的比較多。訓練了ms 的sphereface20 層的模型。迭代了2w次loss 沒有下降,我現在的想法是 500w 的資料除以batchsize 128 那麼可能所有...

訓練網路出現loss為NaN的情況

原因 在學習過程中,梯度變得非常大,使得學習的過程偏離了正常的軌跡。症狀 觀察輸出日誌中每次迭代的loss值,發現loss隨著迭代有明顯的增長,最後因為loss值太大以致於不能用浮點數去表示,所以變成nan。可採取的方法 1.降低學習率,比如solver.prototxt中base lr,降低乙個數...