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,降低乙個數...