PyTorch的Debug指南
一、ipdb 介紹
很多初學(xué) python 的同學(xué)會(huì)使用 print 或 log 調(diào)試程序,但是這只在小規(guī)模的程序下調(diào)試很方便,更好的調(diào)試應(yīng)該是在一邊運(yùn)行的時(shí)候一邊檢查里面的變量和方法。
感興趣的可以去了解 pycharm 的 debug 模式,功能也很強(qiáng)大,能夠滿足一般的需求,這里不多做贅述,我們這里介紹一個(gè)更適用于 pytorch 的一個(gè)靈活的 pdb 交互式調(diào)試工具。
Pdb 是一個(gè)交互式的調(diào)試工具,集成與 Python 標(biāo)準(zhǔn)庫(kù)中,它能讓你根據(jù)需求跳轉(zhuǎn)到任意的 Python 代碼斷點(diǎn)、查看任意變量、單步執(zhí)行代碼,甚至還能修改變量的值,而沒(méi)有必要去重啟程序。
ipdb 則是一個(gè)增強(qiáng)版的 pdb,它提供了調(diào)試模式下的代碼自動(dòng)補(bǔ)全,還有更好的語(yǔ)法高亮和代碼溯源,以及更好的內(nèi)省功能,最重要的是它和 pdb 接口完全兼容,可以通過(guò) pip install ipdb 安裝。
二、ipdb 的使用
首先看一個(gè)例子,要使用 ipdb 的話,只需要在想要進(jìn)行調(diào)試的地方插入 ipdb.set_trace(),當(dāng)代碼運(yùn)行到這個(gè)地方時(shí),就會(huì)自動(dòng)進(jìn)入交互式調(diào)試模式。
import ipdb
def sum(x):
r = 0
for ii in x:
r += ii
return r
def mul(x):
r = 1
for ii in x:
r *= 11
return r
ipdb.set_trace()
x = [1, 2, 3, 4, 5]
r = sum(x)
r = mul(x)
> /Users/mac/Desktop/jupyter/test.py(19)<module>()
18 ipdb.set_trace()
---> 19 x = [1, 2, 3, 4, 5]
20 r = sum(x)
ipdb> l 1,5 # l(ist) 1,5 的縮寫(xiě),查看第 1 行到第 5 行的代碼
1 import ipdb
2
3
4 def sum(x):
5 r = 0
ipdb> n # n(ext) 的縮寫(xiě)執(zhí)行下一步
> /Users/mac/Desktop/jupyter/test.py(20)<module>()
19 x = [1, 2, 3, 4, 5]
---> 20 r = sum(x)
21 r = mul(x)
ipdb> s # s(tep) 的縮寫(xiě),進(jìn)入 sum 函數(shù)內(nèi)部
--Call--
> /Users/mac/Desktop/jupyter/test.py(4)sum()
3
----> 4 def sum(x):
5 r = 0
ipdb> n # n(ext) 單步執(zhí)行
> /Users/mac/Desktop/jupyter/test.py(5)sum()
4 def sum(x):
----> 5 r = 0
6 for ii in x:
ipdb> n
> /Users/mac/Desktop/jupyter/test.py(6)sum()
5 r = 0
----> 6 for ii in x:
7 r += ii
ipdb> u # u(p) 的縮寫(xiě),調(diào)回上一層的調(diào)用
> /Users/mac/Desktop/jupyter/test.py(20)<module>()
19 x = [1, 2, 3, 4, 5]
---> 20 r = sum(x)
21 r = mul(x)
ipdb> d # d(own) 的縮寫(xiě),跳到調(diào)用的下一層
> /Users/mac/Desktop/jupyter/test.py(6)sum()
5 r = 0
----> 6 for ii in x:
7 r += ii
ipdb> n
> /Users/mac/Desktop/jupyter/test.py(7)sum()
6 for ii in x:
----> 7 r += ii
8 return r
ipdb> !r # 查看變量 r 的值,該變量名與調(diào)試命令 `r(eturn)` 沖突
0
ipdb> return # 繼續(xù)運(yùn)行知道函數(shù)返回
--Return--
15
> /Users/mac/Desktop/jupyter/test.py(8)sum()
7 r += ii
----> 8 return r
9
ipdb> n
> /Users/mac/Desktop/jupyter/test.py(21)<module>()
19 x = [1, 2, 3, 4, 5]
20 r = sum(x)
---> 21 r = mul(x)
ipdb> x # 查看變量 x
[1, 2, 3, 4, 5]
ipdb> x[0] = 10000 # 修改變量 x
ipdb> x
[10000, 2, 3, 4, 5]
ipdb> b 12 # b(reak) 的縮寫(xiě),在第 10 行設(shè)置斷點(diǎn)
Breakpoint 1 at /Users/mac/Desktop/jupyter/test.py:12
ipdb> c # c(ontinue) 的縮寫(xiě),繼續(xù)運(yùn)行,直到遇到斷點(diǎn)
> /Users/mac/Desktop/jupyter/test.py(12)mul()
11 def mul(x):
1--> 12 r = 1
13 for ii in x:
ipdb> return # 可以看到計(jì)算的是修改之后的 x 的乘積
--Return--
1200000
> /Users/mac/Desktop/jupyter/test.py(15)mul()
14 r *= ii
---> 15 return r
16
ipdb> q # q(uit) 的縮寫(xiě),退出 debug
上述只是給出了 ipdb 的一部分使用方法,關(guān)于 ipdb 還有一些小的使用技巧:
- 鍵能夠自動(dòng)補(bǔ)齊,補(bǔ)齊用法和 IPython 中的類似
- j(ump) 能夠跳過(guò)中間某些行的代碼的執(zhí)行
- 可以直接在 ipdb 中修改變量的值
- help 能夠查看調(diào)試命令的用法,比如 h h 可以查看 help 命令的用法,h j(ump) 能夠查看 j(ump) 命令的用法
三、在 PyTorch 中 Debug
PyTorch 作為一個(gè)動(dòng)態(tài)圖框架,和 ipdb 結(jié)合使用能夠讓調(diào)試過(guò)程更加便捷,下面我們將距離說(shuō)明以下三點(diǎn):
- 如何在 PyTorch 中查看神經(jīng)網(wǎng)絡(luò)各個(gè)層的輸出
- 如何在 PyTorch 中分析各個(gè)參數(shù)的梯度
- 如何動(dòng)態(tài)修改 PyTorch 的訓(xùn)練流程
首先,運(yùn)行上一篇文章給出的“貓狗大戰(zhàn)”程序:python main.py train --debug-file='debug/debug.txt'
程序運(yùn)行一段時(shí)間后,在debug目錄下創(chuàng)建debug.txt標(biāo)識(shí)文件,當(dāng)程序檢測(cè)到這個(gè)文件存在時(shí),會(huì)自動(dòng)進(jìn)入debug模式。
99it [00:17, 6.07it/s]loss: 0.22854854568839075
119it [00:21, 5.79it/s]loss: 0.21267264398435753
139it [00:24, 5.99it/s]loss: 0.19839374726372108
> e:/Users/mac/Desktop/jupyter/mdFile/deeplearning/main.py(80)train()
79 loss_meter.reset()
---> 80 confusion_matrix.reset()
81 for ii, (data, label) in tqdm(enumerate(train_dataloader)):
ipdb> break 88 # 在第88行設(shè)置斷點(diǎn),當(dāng)程序運(yùn)行到此處進(jìn)入debug模式
Breakpoint 1 at e:/Users/mac/Desktop/jupyter/mdFile/deeplearning/main.py:88
ipdb> # 打印所有參數(shù)及其梯度的標(biāo)準(zhǔn)差
for (name,p) in model.named_parameters(): \
print(name,p.data.std(),p.grad.data.std())
model.features.0.weight tensor(0.2615, device='cuda:0') tensor(0.3769, device='cuda:0')
model.features.0.bias tensor(0.4862, device='cuda:0') tensor(0.3368, device='cuda:0')
model.features.3.squeeze.weight tensor(0.2738, device='cuda:0') tensor(0.3023, device='cuda:0')
model.features.3.squeeze.bias tensor(0.5867, device='cuda:0') tensor(0.3753, device='cuda:0')
model.features.3.expand1x1.weight tensor(0.2168, device='cuda:0') tensor(0.2883, device='cuda:0')
model.features.3.expand1x1.bias tensor(0.2256, device='cuda:0') tensor(0.1147, device='cuda:0')
model.features.3.expand3x3.weight tensor(0.0935, device='cuda:0') tensor(0.1605, device='cuda:0')
model.features.3.expand3x3.bias tensor(0.1421, device='cuda:0') tensor(0.0583, device='cuda:0')
model.features.4.squeeze.weight tensor(0.1976, device='cuda:0') tensor(0.2137, device='cuda:0')
model.features.4.squeeze.bias tensor(0.4058, device='cuda:0') tensor(0.1798, device='cuda:0')
model.features.4.expand1x1.weight tensor(0.2144, device='cuda:0') tensor(0.4214, device='cuda:0')
model.features.4.expand1x1.bias tensor(0.4994, device='cuda:0') tensor(0.0958, device='cuda:0')
model.features.4.expand3x3.weight tensor(0.1063, device='cuda:0') tensor(0.2963, device='cuda:0')
model.features.4.expand3x3.bias tensor(0.0489, device='cuda:0') tensor(0.0719, device='cuda:0')
model.features.6.squeeze.weight tensor(0.1736, device='cuda:0') tensor(0.3544, device='cuda:0')
model.features.6.squeeze.bias tensor(0.2420, device='cuda:0') tensor(0.0896, device='cuda:0')
model.features.6.expand1x1.weight tensor(0.1211, device='cuda:0') tensor(0.2428, device='cuda:0')
model.features.6.expand1x1.bias tensor(0.0670, device='cuda:0') tensor(0.0162, device='cuda:0')
model.features.6.expand3x3.weight tensor(0.0593, device='cuda:0') tensor(0.1917, device='cuda:0')
model.features.6.expand3x3.bias tensor(0.0227, device='cuda:0') tensor(0.0160, device='cuda:0')
model.features.7.squeeze.weight tensor(0.1207, device='cuda:0') tensor(0.2179, device='cuda:0')
model.features.7.squeeze.bias tensor(0.1484, device='cuda:0') tensor(0.0381, device='cuda:0')
model.features.7.expand1x1.weight tensor(0.1235, device='cuda:0') tensor(0.2279, device='cuda:0')
model.features.7.expand1x1.bias tensor(0.0450, device='cuda:0') tensor(0.0100, device='cuda:0')
model.features.7.expand3x3.weight tensor(0.0609, device='cuda:0') tensor(0.1628, device='cuda:0')
model.features.7.expand3x3.bias tensor(0.0132, device='cuda:0') tensor(0.0079, device='cuda:0')
model.features.9.squeeze.weight tensor(0.1093, device='cuda:0') tensor(0.2459, device='cuda:0')
model.features.9.squeeze.bias tensor(0.0646, device='cuda:0') tensor(0.0135, device='cuda:0')
model.features.9.expand1x1.weight tensor(0.0840, device='cuda:0') tensor(0.1860, device='cuda:0')
model.features.9.expand1x1.bias tensor(0.0177, device='cuda:0') tensor(0.0033, device='cuda:0')
model.features.9.expand3x3.weight tensor(0.0476, device='cuda:0') tensor(0.1393, device='cuda:0')
model.features.9.expand3x3.bias tensor(0.0058, device='cuda:0') tensor(0.0030, device='cuda:0')
model.features.10.squeeze.weight tensor(0.0872, device='cuda:0') tensor(0.1676, device='cuda:0')
model.features.10.squeeze.bias tensor(0.0484, device='cuda:0') tensor(0.0088, device='cuda:0')
model.features.10.expand1x1.weight tensor(0.0859, device='cuda:0') tensor(0.2145, device='cuda:0')
model.features.10.expand1x1.bias tensor(0.0160, device='cuda:0') tensor(0.0025, device='cuda:0')
model.features.10.expand3x3.weight tensor(0.0456, device='cuda:0') tensor(0.1429, device='cuda:0')
model.features.10.expand3x3.bias tensor(0.0070, device='cuda:0') tensor(0.0021, device='cuda:0')
model.features.11.squeeze.weight tensor(0.0786, device='cuda:0') tensor(0.2003, device='cuda:0')
model.features.11.squeeze.bias tensor(0.0422, device='cuda:0') tensor(0.0069, device='cuda:0')
model.features.11.expand1x1.weight tensor(0.0690, device='cuda:0') tensor(0.1400, device='cuda:0')
model.features.11.expand1x1.bias tensor(0.0138, device='cuda:0') tensor(0.0022, device='cuda:0')
model.features.11.expand3x3.weight tensor(0.0366, device='cuda:0') tensor(0.1517, device='cuda:0')
model.features.11.expand3x3.bias tensor(0.0109, device='cuda:0') tensor(0.0023, device='cuda:0')
model.features.12.squeeze.weight tensor(0.0729, device='cuda:0') tensor(0.1736, device='cuda:0')
model.features.12.squeeze.bias tensor(0.0814, device='cuda:0') tensor(0.0084, device='cuda:0')
model.features.12.expand1x1.weight tensor(0.0977, device='cuda:0') tensor(0.1385, device='cuda:0')
model.features.12.expand1x1.bias tensor(0.0102, device='cuda:0') tensor(0.0032, device='cuda:0')
model.features.12.expand3x3.weight tensor(0.0365, device='cuda:0') tensor(0.1312, device='cuda:0')
model.features.12.expand3x3.bias tensor(0.0038, device='cuda:0') tensor(0.0026, device='cuda:0')
model.classifier.1.weight tensor(0.0285, device='cuda:0') tensor(0.0865, device='cuda:0')
model.classifier.1.bias tensor(0.0362, device='cuda:0') tensor(0.0192, device='cuda:0')
ipdb> opt.lr # 查看學(xué)習(xí)率
0.001
ipdb> opt.lr = 0.002 # 更改學(xué)習(xí)率
ipdb> for p in optimizer.param_groups: \
p['lr'] = opt.lr
ipdb> model.save() # 保存模型
'checkpoints/squeezenet_20191004212249.pth'
ipdb> c # 繼續(xù)運(yùn)行,直到第88行暫停
222it [16:38, 35.62s/it]> e:/Users/mac/Desktop/jupyter/mdFile/deeplearning/main.py(88)train()
87 optimizer.zero_grad()
1--> 88 score = model(input)
89 loss = criterion(score, target)
ipdb> s # 進(jìn)入model(input)內(nèi)部,即model.__call__(input)
--Call--
> c:\programdata\anaconda3\lib\site-packages\torch\nn\modules\module.py(537)__call__()
536
--> 537 def __call__(self, *input, **kwargs):
538 for hook in self._forward_pre_hooks.values():
ipdb> n # 下一步
> c:\programdata\anaconda3\lib\site-packages\torch\nn\modules\module.py(538)__call__()
537 def __call__(self, *input, **kwargs):
--> 538 for hook in self._forward_pre_hooks.values():
539 result = hook(self, input)
ipdb> n # 下一步
> c:\programdata\anaconda3\lib\site-packages\torch\nn\modules\module.py(544)__call__()
543 input = result
--> 544 if torch._C._get_tracing_state():
545 result = self._slow_forward(*input, **kwargs)
ipdb> n # 下一步
> c:\programdata\anaconda3\lib\site-packages\torch\nn\modules\module.py(547)__call__()
546 else:
--> 547 result = self.forward(*input, **kwargs)
548 for hook in self._forward_hooks.values():
ipdb> s # 進(jìn)入forward函數(shù)內(nèi)容
--Call--
> c:\programdata\anaconda3\lib\site-packages\torch\nn\modules\loss.py(914)forward()
913
--> 914 def forward(self, input, target):
915 return F.cross_entropy(input, target, weight=self.weight,
ipdb> input # 查看input變量值
tensor([[4.5005, 2.0725],
[3.5933, 7.8643],
[2.9086, 3.4209],
[2.7740, 4.4332],
[6.0164, 2.3033],
[5.2261, 3.2189],
[2.6529, 2.0749],
[6.3259, 2.2383],
[3.0629, 3.4832],
[2.7008, 8.2818],
[5.5684, 2.1567],
[3.0689, 6.1022],
[3.4848, 5.3831],
[1.7920, 5.7709],
[6.5032, 2.8080],
[2.3071, 5.2417],
[3.7474, 5.0263],
[4.3682, 3.6707],
[2.2196, 6.9298],
[5.2201, 2.3034],
[6.4315, 1.4970],
[3.4684, 4.0371],
[3.9620, 1.7629],
[1.7069, 7.8898],
[3.0462, 1.6505],
[2.4081, 6.4456],
[2.1932, 7.4614],
[2.3405, 2.7603],
[1.9478, 8.4156],
[2.7935, 7.8331],
[1.8898, 3.8836],
[3.3008, 1.6832]], device='cuda:0', grad_fn=<AsStridedBackward>)
ipdb> input.data.mean() # 查看input的均值和標(biāo)準(zhǔn)差
tensor(3.9630, device='cuda:0')
ipdb> input.data.std()
tensor(1.9513, device='cuda:0')
ipdb> u # 跳回上一層
> c:\programdata\anaconda3\lib\site-packages\torch\nn\modules\module.py(547)__call__()
546 else:
--> 547 result = self.forward(*input, **kwargs)
548 for hook in self._forward_hooks.values():
ipdb> u # 跳回上一層
> e:/Users/mac/Desktop/jupyter/mdFile/deeplearning/main.py(88)train()
87 optimizer.zero_grad()
1--> 88 score = model(input)
89 loss = criterion(score, target)
ipdb> clear # 清除所有斷點(diǎn)
Clear all breaks? y
Deleted breakpoint 1 at e:/Users/mac/Desktop/jupyter/mdFile/deeplearning/main.py:88
ipdb> c # 繼續(xù)運(yùn)行,記得先刪除"debug/debug.txt",否則很快又會(huì)進(jìn)入調(diào)試模式
59it [06:21, 5.75it/s]loss: 0.24856307208538073
76it [06:24, 5.91it/s]
當(dāng)我們想要進(jìn)入 debug 模式,修改程序中某些參數(shù)值或者想分析程序時(shí),就可以通過(guò)創(chuàng)建 debug 標(biāo)識(shí)文件,此時(shí)程序會(huì)進(jìn)入調(diào)試模式,調(diào)試完成之后刪除這個(gè)文件并在 ipdb 調(diào)試接口輸入 c 繼續(xù)運(yùn)行程序。如果想退出程序,也可以使用這種方式,先創(chuàng)建 debug 標(biāo)識(shí)文件,然后輸入 quit 在退出 debug 的同時(shí)退出程序。這種退出程序的方式,與使用 Ctrl + C 的方式相比更安全,因?yàn)檫@能保證數(shù)據(jù)加載的多進(jìn)程程序也能正確地退出,并釋放內(nèi)存、顯存等資源。
PyTorch 和 ipdb 集合能完成很多其他框架所不能完成或很難完成的功能。根據(jù)筆者日常使用的總結(jié),主要有以下幾個(gè)部分:
- 通過(guò) debug 暫停程序。當(dāng)程序進(jìn)入 debug 模式后,將不再執(zhí)行 CPU 和 GPU 運(yùn)算,但是內(nèi)存和顯存及相應(yīng)的堆棧空間不會(huì)釋放。
- 通過(guò) debug 分析程序,查看每個(gè)層的輸出,查看網(wǎng)絡(luò)的參數(shù)情況。通過(guò) u(p) 、 d(own) 、 s(tep) 等命令,能夠進(jìn)入指定的代碼,通過(guò) n(ext) 可以單步執(zhí)行,從而看到每一層的運(yùn)算結(jié)果,便于分析網(wǎng)絡(luò)的數(shù)值分布等信息。
- 作為動(dòng)態(tài)圖框架, PyTorch 擁有 Python 動(dòng)態(tài)語(yǔ)言解釋執(zhí)行的優(yōu)點(diǎn),我們能夠在運(yùn)行程序時(shí),用過(guò) ipdb 修改某些變量的值或?qū)傩?,這些修改能夠立即生效。例如可以在訓(xùn)練開(kāi)始不久根據(jù)損失函數(shù)調(diào)整學(xué)習(xí)率,不必重啟程序。
- 如果在 IPython 中通過(guò) %run 魔法方法運(yùn)行程序,那么在程序異常退出時(shí),可以使用 %debug 命令,直接進(jìn)入 debug 模式,通過(guò) u(p) 和 d(own) 跳到報(bào)錯(cuò)的地方,查看對(duì)應(yīng)的變量,找出原因后修改相應(yīng)的代碼即可。有時(shí)我們的模式訓(xùn)練了好幾個(gè)小時(shí),卻在將要保存模式之前,因?yàn)橐粋€(gè)小小的拼寫(xiě)錯(cuò)誤異常退出。此時(shí),如果修改錯(cuò)誤再重新運(yùn)行程序又要花費(fèi)好幾個(gè)小時(shí),太浪費(fèi)時(shí)間。因此最好的方法就是看利用 %debug 進(jìn)入調(diào)試模式,在調(diào)試模式中直接運(yùn)行 model . save() 保存模型。在 IPython 中, %pdb 魔術(shù)方法能夠使得程序出現(xiàn)問(wèn)題后,不用手動(dòng)輸入 %debug 而自動(dòng)進(jìn)入 debug 模式,建議使用。
四、 通過(guò)PyTorch實(shí)現(xiàn)項(xiàng)目中容易遇到的問(wèn)題
PyTorch 調(diào)用 CuDNN 報(bào)錯(cuò)時(shí),報(bào)錯(cuò)信息諸如 CUDNN_STATUS_BAD_PARAM,從這些報(bào)錯(cuò)內(nèi)容很難得到有用的幫助信息,最后先利用 PCU 運(yùn)行代碼,此時(shí)一般會(huì)得到相對(duì)友好的報(bào)錯(cuò)信息,例如在 ipdb 中執(zhí)行 model.cpu() (input.cpu()), PyTorch 底層的 TH 庫(kù)會(huì)給出相對(duì)比較詳細(xì)的信息。
常見(jiàn)的錯(cuò)誤主要有以下幾種:
- 類型不匹配問(wèn)題。例如 CrossEntropyLoss 的輸入 target 應(yīng)該是一個(gè) LongTensor ,而很多人輸入 FloatTensor 。
- 部分?jǐn)?shù)據(jù)忘記從 CPU 轉(zhuǎn)移到 GPU 。例如,當(dāng) model 存放于 GPU 時(shí),輸入 input 也需要轉(zhuǎn)移到 GPU 才能輸入到 model 中。還有可能就是把多個(gè) model 存放于一個(gè) list 對(duì)象,而在執(zhí)行 model.cuda() 時(shí),這個(gè) list 中的對(duì)象是不會(huì)被轉(zhuǎn)移到 CUDA 上的,正確的用法是用 ModuleList 代替。
- Tensor 形狀不匹配。此類問(wèn)題一般是輸入數(shù)據(jù)形狀不對(duì),或是網(wǎng)絡(luò)結(jié)構(gòu)設(shè)計(jì)有問(wèn)題,一般通過(guò) u(p) 跳到指定代碼,查看輸入和模型參數(shù)的形狀即可得知。
此外,可能還會(huì)經(jīng)常遇到程序正常運(yùn)行、沒(méi)有報(bào)錯(cuò),但是模型無(wú)法收斂的問(wèn)題。例如對(duì)于二分類問(wèn)題,交叉熵?fù)p失一直徘徊在 0.69 附近(ln2),或者是數(shù)值出現(xiàn)溢出等問(wèn)題,此時(shí)可以進(jìn)入 debug 模式,用單步執(zhí)行查看,每一層輸出的均值和方差,觀察從哪一層的輸出開(kāi)始出現(xiàn)數(shù)值異常。還要查看每個(gè)參數(shù)梯度的均值和方差,查看是否出現(xiàn)梯度消失或者梯度爆炸等問(wèn)題。一般來(lái)說(shuō),通過(guò)再激活函數(shù)之前增加 BatchNorm 層、合理的參數(shù)初始化、使用 Adam 優(yōu)化器、學(xué)習(xí)率設(shè)為0.001,基本就能確保模型在一定程度收斂。
五、總結(jié)
本章帶同學(xué)們從頭實(shí)現(xiàn)了一個(gè) Kaggle 上的經(jīng)典競(jìng)賽,重點(diǎn)講解了如何合理地組合安排程序,同時(shí)介紹了一些在PyTorch中調(diào)試的技巧,下章將正式的進(jìn)入編程實(shí)戰(zhàn)之旅,其中一些細(xì)節(jié)不會(huì)再講的如此詳細(xì),做好心理準(zhǔn)備。
以上就是PyTorch的Debug指南的詳細(xì)內(nèi)容,更多關(guān)于PyTorch Debug的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- pytorch_detach 切斷網(wǎng)絡(luò)反傳方式
- pytorch 禁止/允許計(jì)算局部梯度的操作
- 如何利用Pytorch計(jì)算三角函數(shù)
- 聊聊PyTorch中eval和no_grad的關(guān)系
- Pytorch實(shí)現(xiàn)圖像識(shí)別之?dāng)?shù)字識(shí)別(附詳細(xì)注釋)
- Pytorch實(shí)現(xiàn)全連接層的操作
- pytorch 優(yōu)化器(optim)不同參數(shù)組,不同學(xué)習(xí)率設(shè)置的操作
- PyTorch 如何將CIFAR100數(shù)據(jù)按類標(biāo)歸類保存
- Python深度學(xué)習(xí)之使用Pytorch搭建ShuffleNetv2
- win10系統(tǒng)配置GPU版本Pytorch的詳細(xì)教程
- 淺談pytorch中的nn.Sequential(*net[3: 5])是啥意思
- pytorch visdom安裝開(kāi)啟及使用方法
- PyTorch CUDA環(huán)境配置及安裝的步驟(圖文教程)
- pytorch中的nn.ZeroPad2d()零填充函數(shù)實(shí)例詳解
- 使用pytorch實(shí)現(xiàn)線性回歸
- pytorch實(shí)現(xiàn)線性回歸以及多元回歸
- PyTorch學(xué)習(xí)之軟件準(zhǔn)備與基本操作總結(jié)
相關(guān)文章
python使用numpy讀取、保存txt數(shù)據(jù)的實(shí)例
今天小編就為大家分享一篇python使用numpy讀取、保存txt數(shù)據(jù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
在python的WEB框架Flask中使用多個(gè)配置文件的解決方法
所謂配置文件管理,就是在不改變?cè)创a的前提下,擁有兩套(甚至多套)配置文件,分別用于開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境,通過(guò)命令行選擇配置文件2014-04-04
python?scapy抓包獲取udp并轉(zhuǎn)發(fā)的操作步驟
這篇文章主要介紹了python?scapy抓包獲取udp并轉(zhuǎn)發(fā)的操作步驟,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01
caffe的python接口caffemodel參數(shù)及特征抽取示例
這篇文章主要介紹了caffe的python接口caffemodel參數(shù)及特征抽取示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
Python實(shí)現(xiàn)手機(jī)號(hào)自動(dòng)判斷男女性別(實(shí)例解析)
這篇文章主要介紹了Python實(shí)現(xiàn)手機(jī)號(hào)自動(dòng)判斷男女性別,本文性別判斷主要依靠airtest中的自動(dòng)化測(cè)試實(shí)現(xiàn),通過(guò)實(shí)例代碼給大家講解的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
Mac中PyCharm配置Anaconda環(huán)境的方法
這篇文章主要介紹了Mac中PyCharm配置Anaconda環(huán)境的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
python數(shù)字轉(zhuǎn)對(duì)應(yīng)中文的方法總結(jié)
在本篇文章里小編給大家分享的是一篇關(guān)于python數(shù)字轉(zhuǎn)對(duì)應(yīng)中文的方法總結(jié)內(nèi)容,有興趣的朋友們可以跟著猜嘗試測(cè)試下。2021-08-08

