程式碼量少時debug:使用print
和log
偵錯程式碼;
better做法:一遍執行一遍檢查裡面的變數和方法。
pdb是python互動式的偵錯工具,其作用:
ipdb是增強版的pdb,提供了偵錯模式下的程式碼自動補全,有更好的語法高亮和程式碼溯源,與pdb介面完全相容。
結合pytorch和ipdb進行偵錯。
要使用ipdb,在需要偵錯的地方插入ipdb.set_trace
即可(還有在程式碼開頭加上try和except兩行)。
現在有栗子如下,sum和mul函數分別計算列表x中的元素的累加和累乘:
# -*- coding: utf-8 -*-
"""
Created on Sun Dec 12 16:33:07 2021
@author: 86493
"""
try:
import ipdb
except:
import pdb as ipdb
def sum(x):
r = 0
for i in x:
r += i
return r
def mul(x):
r = 1
for i in x:
r *= i
return r
ipdb.set_trace()
x = [1, 2, 3, 4, 5]
r = sum(x)
r = mul(x)
程式執行到ipdb.set_trace()
後自動進行debug模式:
ipdb> list 7,27 # 檢視第7到27行程式碼
7 try:
8 import ipdb
9 except:
10 import pdb as ipdb
11
12 def sum(x):
13 r = 0
14 for i in x:
15 r += i
16 return r
17
18 def mul(x):
19 r = 1
20 for i in x:
21 r *= i
22 return r
23
24 ipdb.set_trace()
---> 25 x = [1, 2, 3, 4, 5]
26 r = sum(x)
27 r = mul(x)
ipdb> n # next執行下一步
> d:\桌面檔案\ipdb.py(26)<module>()
ipdb> s # step的縮寫,此處進入sum函數內部
--Call--
> d:\桌面檔案\ipdb.py(12)sum()
ipdb> u # up的縮寫,調回上一層的呼叫
> d:\桌面檔案\cs224\ipdb.py(26)<module>()
ipdb> down # down的縮寫,跳到呼叫的下一層
> d:\桌面檔案\cs224\ipdb.py(15)sum()
ipdb> return # 繼續執行到函數返回,返回15即為sum的結果
--Return--
15
同時也可以檢視或者修改變數,再繼續執行程式碼也是按照修改後的變數運算,如果要退出debug模式則是q
(debug的縮寫)。
ipdb的小技巧:
<tab>
鍵能自動補齊,和IPyhton中類似j(ump)<lineno>
能夠跳過中間某些行程式碼的執行h h
檢視help命令的用法等。pytorch可以執行計算的同時定義計算圖(該定義過程是用python完成的,雖然底層是用C++完成)。
1)通過debug暫停程式:當程式進入debug模式之後,將不再執行GPU和CPU運算,但是記憶體和視訊記憶體集相應的堆疊空間不會釋放
2)通過debug分析程式,檢視每個層的輸出,檢視網路的引數情況:通過u\d\s等命令,能夠進入指定的程式碼,通過n可以進行單步執行,從而可以看見每一層的運算結果,便於分析網路的數值分佈等資訊
3)作為動態圖框架,pytorch擁有python動態語言解釋執行的優點,我們能夠在執行程式時,通過ipdb修改某些變數的值或屬性,這些修改能夠立即生效。例如可以在訓練開始不久後根據損失函數調整學習率,不必重新啟動程式
4)如果在IPython中通過%run
魔法方法執行程式,那麼在程式異常退出時,可以使用%debug命令,直接進入debug模式,通過u和d調到報錯的地方,檢視對應的變數。然後找出原因後修改相應的程式碼即可。
因為有時模型訓練好幾個小時後,卻在要儲存模型之前,因為一個小小的拼寫錯誤異常退出。這時候最好的辦法就是利用%debug進入偵錯模式,在偵錯模式中直接執行model.save()
儲存模型
在ipython中,%pdb
魔術方法能夠使得程式出現問題後,不用手動輸入%debug
而自動進入偵錯模式,建議使用
pytorch呼叫cuDNN報錯時,報錯資訊諸如CUDNN_STATUS_BAD_PARAM
,從這些報錯資訊內容很難得到有用的幫助資訊,最好先利用CPU執行程式碼,此時一般會得到相對友好的報錯資訊。
1)型別不匹配問題:如CrossEntropyLoss
的輸入target應該是一個LongTensor
,而很多人輸入FloatTensor
2)部分資料忘記從CPU轉到GPU:例如當model存放與GPU時,輸入input耶需要轉移到GPU才能輸入到model中
還有可能是把多個model存放在一個list物件,而在執行model.cuda()
時,這個list中的物件是不會被轉移到CUDA上的,正確的用法是使用ModuleList替代
3)Tensor形狀不匹配:此類問題一般是輸入資料形狀不對,或是網路結構設計有問題,一般通過u命令跳到指定程式碼,檢視輸入和模型引數的形狀即可得知
(1)pytorch官網
(2)https://www.cnblogs.com/wanghui-garcia/p/10648849.html
(3)《深度學習框架pytorch入門與實踐》