最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解決pytorch下只打印tensor的數(shù)值不打印出device等信息的問題

 更新時間:2021年05月20日 14:21:59   作者:sjtu_leexx  
這篇文章主要介紹了解決pytorch下只打印tensor的數(shù)值不打印出device等信息的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

torch.Tensor類型的數(shù)據(jù)loss和acc打印時

如果寫成以下寫法

print('batch_loss: '+str(loss.data)+'batch acc: '+str(acc.data))

則不僅會打印出loss和acc的值,還會打印出device信息和 tensor字樣,如下:

在這里插入圖片描述

如果僅想打印出數(shù)值,使得打印出的信息更加簡潔

則要用以下寫法

print('batch_loss: {:.3f} batch acc: {:.3f}'.format(loss.data, acc.data))

該寫法還可控制輸出格式,結(jié)果類似如下:

在這里插入圖片描述

補(bǔ)充:關(guān)于pytorch中用plt顯示tensor的問題(tensor轉(zhuǎn)numpy)

問題

圖像的張量結(jié)構(gòu)為(C,H,W),而plt可以顯示的圖片格式要求(H,W,C),C為顏色通道數(shù),可以沒有。

所以問題就是將Tensor(C,H,W)=> numpy(H,W,C)

解決辦法

def transimg(img):
    img = img / 2 + 0.5 # unnormalize
    npimg = img.numpy()
    npimg1 = np.transpose(npimg,(1,2,0)) # C*H*W => H*W*C
    return npimg1

補(bǔ)充:PyTorch代碼調(diào)試?yán)? 自動print每行代碼的Tensor信息

本文介紹一個用于 PyTorch 代碼的實用工具 TorchSnooper。作者是TorchSnooper的作者,也是PyTorch開發(fā)者之一。

GitHub 項目地址: https://github.com/zasdfgbnm/TorchSnooper

大家可能遇到這樣子的困擾:比如說運(yùn)行自己編寫的 PyTorch 代碼的時候,PyTorch 提示你說數(shù)據(jù)類型不匹配,需要一個 double 的 tensor 但是你給的卻是 float;再或者就是需要一個 CUDA tensor, 你給的卻是個 CPU tensor。

比如下面這種:

RuntimeError: Expected object of scalar type Double but got scalar type Float

這種問題調(diào)試起來很麻煩,因為你不知道從哪里開始出問題的。比如你可能在代碼的第三行用 torch.zeros 新建了一個 CPU tensor, 然后這個 tensor 進(jìn)行了若干運(yùn)算,全是在 CPU 上進(jìn)行的,一直沒有報錯,直到第十行需要跟你作為輸入傳進(jìn)來的 CUDA tensor 進(jìn)行運(yùn)算的時候,才報錯。要調(diào)試這種錯誤,有時候就不得不一行行地手寫 print 語句,非常麻煩。

再或者,你可能腦子里想象著將一個 tensor 進(jìn)行什么樣子的操作,就會得到什么樣子的結(jié)果,但是 PyTorch 中途報錯說 tensor 的形狀不匹配,或者壓根沒報錯但是最終出來的形狀不是我們想要的。這個時候,我們往往也不知道是什么地方開始跟我們「預(yù)期的發(fā)生偏離的」。我們有時候也得需要插入一大堆 print 語句才能找到原因。

TorchSnooper 就是一個設(shè)計了用來解決這個問題的工具。TorchSnooper 的安裝非常簡單,只需要執(zhí)行標(biāo)準(zhǔn)的 Python 包安裝指令就好:

pip install torchsnooper

安裝完了以后,只需要用 @torchsnooper.snoop() 裝飾一下要調(diào)試的函數(shù),這個函數(shù)在執(zhí)行的時候,就會自動 print 出來每一行的執(zhí)行結(jié)果的 tensor 的形狀、數(shù)據(jù)類型、設(shè)備、是否需要梯度的信息。

安裝完了以后,下面就用兩個例子來說明一下怎么使用。

例子1

比如說我們寫了一個非常簡單的函數(shù):

def myfunc(mask, x):
    y = torch.zeros(6)
    y.masked_scatter_(mask, x)
    return y

我們是這樣子使用這個函數(shù)的:

mask = torch.tensor([0, 1, 0, 1, 1, 0], device='cuda')
source = torch.tensor([1.0, 2.0, 3.0], device='cuda')
y = myfunc(mask, source)

上面的代碼看起來似乎沒啥問題,然而實際上跑起來,卻報錯了:

RuntimeError: Expected object of backend CPU but got backend CUDA for argument #2 'mask'

問題在哪里呢?讓我們 snoop 一下!用 @torchsnooper.snoop() 裝飾一下 myfunc 函數(shù):

import torch
import torchsnooper
@torchsnooper.snoop()
def myfunc(mask, x):
    y = torch.zeros(6)
    y.masked_scatter_(mask, x)
    return y

mask = torch.tensor([0, 1, 0, 1, 1, 0], device='cuda')
source = torch.tensor([1.0, 2.0, 3.0], device='cuda')
y = myfunc(mask, source)

然后運(yùn)行我們的腳本,我們看到了這樣的輸出:

Starting var:.. mask = tensor<(6,), int64, cuda:0>
Starting var:.. x = tensor<(3,), float32, cuda:0>
21:41:42.941668 call 5 def myfunc(mask, x):
21:41:42.941834 line 6 y = torch.zeros(6)
New var:....... y = tensor<(6,), float32, cpu>
21:41:42.943443 line 7 y.masked_scatter_(mask, x)
21:41:42.944404 exception 7 y.masked_scatter_(mask, x)

結(jié)合我們的錯誤,我們主要去看輸出的每個變量的設(shè)備,找找最早從哪個變量開始是在 CPU 上的。我們注意到這一行:

New var:....... y = tensor<(6,), float32, cpu>

這一行直接告訴我們,我們創(chuàng)建了一個新變量 y, 并把一個 CPU tensor 賦值給了這個變量。這一行對應(yīng)代碼中的 y = torch.zeros(6)。于是我們意識到,在使用 torch.zeros 的時候,如果不人為指定設(shè)備的話,默認(rèn)創(chuàng)建的 tensor 是在 CPU 上的。我們把這一行改成 y = torch.zeros(6, device='cuda'),這一行的問題就修復(fù)了。

這一行的問題雖然修復(fù)了,我們的問題并沒有解決完整,再跑修改過的代碼還是報錯,但是這個時候錯誤變成了:

RuntimeError: Expected object of scalar type Byte but got scalar type Long for argument #2 'mask'

好吧,這次錯誤出在了數(shù)據(jù)類型上。這次錯誤報告比較有提示性,我們大概能知道是我們的 mask 的數(shù)據(jù)類型錯了。再看一遍 TorchSnooper 的輸出,我們注意到:

Starting var:.. mask = tensor<(6,), int64, cuda:0>

果然,我們的 mask 的類型是 int64, 而不應(yīng)該是應(yīng)有的 uint8。我們把 mask 的定義修改好:

mask = torch.tensor([0, 1, 0, 1, 1, 0], device='cuda', dtype=torch.uint8)

然后就可以運(yùn)行了。

例子 2

這次我們要構(gòu)建一個簡單的線性模型:

model = torch.nn.Linear(2, 1)

我們想要擬合一個平面 y = x1 + 2 * x2 + 3,于是我們創(chuàng)建了這樣一個數(shù)據(jù)集:

x = torch.tensor([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]])
y = torch.tensor([3.0, 5.0, 4.0, 6.0])

我們使用最普通的 SGD 優(yōu)化器來進(jìn)行優(yōu)化,完整的代碼如下:

import torch
model = torch.nn.Linear(2, 1)
x = torch.tensor([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]])
y = torch.tensor([3.0, 5.0, 4.0, 6.0])

optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
for _ in range(10):
    optimizer.zero_grad()
    pred = model(x)
    squared_diff = (y - pred) ** 2
    loss = squared_diff.mean()
    print(loss.item())
    loss.backward()
    optimizer.step()

然而運(yùn)行的過程我們發(fā)現(xiàn),loss 降到 1.5 左右就不再降了。這是很不正常的,因為我們構(gòu)建的數(shù)據(jù)都是無誤差落在要擬合的平面上的,loss 應(yīng)該降到 0 才算正常。

乍看上去,不知道問題在哪里。抱著試試看的想法,我們來 snoop 一下子。這個例子中,我們沒有自定義函數(shù),但是我們可以使用 with 語句來激活 TorchSnooper。把訓(xùn)練的那個循環(huán)裝進(jìn) with 語句中去,代碼就變成了:

import torch
import torchsnooper
model = torch.nn.Linear(2, 1)
x = torch.tensor([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]])
y = torch.tensor([3.0, 5.0, 4.0, 6.0])
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)

with torchsnooper.snoop():
    for _ in range(10):
        optimizer.zero_grad()
        pred = model(x)
        squared_diff = (y - pred) ** 2
        loss = squared_diff.mean()
        print(loss.item())
        loss.backward()
        optimizer.step()

運(yùn)行程序,我們看到了一長串的輸出,一點一點瀏覽,我們注意到

New var:....... model = Linear(in_features=2, out_features=1, bias=True)
New var:....... x = tensor<(4, 2), float32, cpu>
New var:....... y = tensor<(4,), float32, cpu>
New var:....... optimizer = SGD (Parameter Group 0 dampening: 0 lr: 0....omentum: 0 nesterov: False weight_decay: 0)
02:38:02.016826 line 12 for _ in range(10):
New var:....... _ = 0
02:38:02.017025 line 13 optimizer.zero_grad()
02:38:02.017156 line 14 pred = model(x)
New var:....... pred = tensor<(4, 1), float32, cpu, grad>
02:38:02.018100 line 15 squared_diff = (y - pred) ** 2
New var:....... squared_diff = tensor<(4, 4), float32, cpu, grad>
02:38:02.018397 line 16 loss = squared_diff.mean()
New var:....... loss = tensor<(), float32, cpu, grad>
02:38:02.018674 line 17 print(loss.item())
02:38:02.018852 line 18 loss.backward()
26.979290008544922
02:38:02.057349 line 19 optimizer.step()

仔細(xì)觀察這里面各個 tensor 的形狀,我們不難發(fā)現(xiàn),y 的形狀是 (4,),而 pred 的形狀卻是 (4, 1),他們倆相減,由于廣播的存在,我們得到的 squared_diff 的形狀就變成了 (4, 4)。

這自然不是我們想要的結(jié)果。這個問題修復(fù)起來也很簡單,把 pred 的定義改成 pred = model(x).squeeze() 即可?,F(xiàn)在再看修改后的代碼的 TorchSnooper 的輸出:

New var:....... model = Linear(in_features=2, out_features=1, bias=True)
New var:....... x = tensor<(4, 2), float32, cpu>
New var:....... y = tensor<(4,), float32, cpu>
New var:....... optimizer = SGD (Parameter Group 0 dampening: 0 lr: 0....omentum: 0 nesterov: False weight_decay: 0)
02:46:23.545042 line 12 for _ in range(10):
New var:....... _ = 0
02:46:23.545285 line 13 optimizer.zero_grad()
02:46:23.545421 line 14 pred = model(x).squeeze()
New var:....... pred = tensor<(4,), float32, cpu, grad>
02:46:23.546362 line 15 squared_diff = (y - pred) ** 2
New var:....... squared_diff = tensor<(4,), float32, cpu, grad>
02:46:23.546645 line 16 loss = squared_diff.mean()
New var:....... loss = tensor<(), float32, cpu, grad>
02:46:23.546939 line 17 print(loss.item())
02:46:23.547133 line 18 loss.backward()
02:46:23.591090 line 19 optimizer.step()

現(xiàn)在這個結(jié)果看起來就正常了。并且經(jīng)過測試,loss 現(xiàn)在已經(jīng)可以降到很接近 0 了。大功告成。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 基于Python和PyYAML讀取yaml配置文件數(shù)據(jù)

    基于Python和PyYAML讀取yaml配置文件數(shù)據(jù)

    這篇文章主要介紹了基于Python和PyYAML讀取yaml配置文件數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • 用Python寫王者榮耀刷金幣腳本

    用Python寫王者榮耀刷金幣腳本

    今天給大家?guī)淼氖怯肞ython語言寫一個關(guān)于手游王者榮耀刷金幣的腳本,有興趣的朋友參考學(xué)習(xí)下。
    2017-12-12
  • Python獲取郵件地址的方法

    Python獲取郵件地址的方法

    這篇文章主要介紹了Python獲取郵件地址的方法,通過自定義函數(shù)分析提取字符串中郵件地址的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • Python函數(shù)中閉包和延遲綁定詳情

    Python函數(shù)中閉包和延遲綁定詳情

    這篇文章主要介紹了Python函數(shù)中閉包和延遲綁定詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • Python datatime庫語法使用詳解

    Python datatime庫語法使用詳解

    這篇文章主要介紹了Python datatime庫語法使用詳解,datetime模塊用于是date和time模塊的合集,文章圍繞相關(guān)資料展開詳情,感興趣的小伙伴可以擦參考一下
    2022-07-07
  • Python協(xié)程原理全面分析

    Python協(xié)程原理全面分析

    協(xié)程(co-routine,又稱微線程、纖程)是一種多方協(xié)同的工作方式。協(xié)程不是進(jìn)程或線程,其執(zhí)行過程類似于Python函數(shù)調(diào)用,Python的asyncio模塊實現(xiàn)的異步IO編程框架中,協(xié)程是對使用async關(guān)鍵字定義的異步函數(shù)的調(diào)用
    2023-02-02
  • Python?+?Tkinter連接本地MySQL數(shù)據(jù)庫簡單實現(xiàn)注冊登錄

    Python?+?Tkinter連接本地MySQL數(shù)據(jù)庫簡單實現(xiàn)注冊登錄

    這篇文章主要介紹了Python?+?Tkinter連接本地MySQL數(shù)據(jù)庫簡單實現(xiàn)注冊登錄。下面文章著情介紹,需要的小伙伴可以參考一下
    2022-01-01
  • 四個Python常用OCR庫的用法詳解

    四個Python常用OCR庫的用法詳解

    在接口自動化工作中,經(jīng)常需要處理文字識別的任務(wù),而OCR庫能夠幫助我們將圖像中的文字提取出來,所以本文為大家整理了四個常用的OCR庫以及它們的用法,需要的可以參考下
    2023-09-09
  • python妙用之編碼的轉(zhuǎn)換詳解

    python妙用之編碼的轉(zhuǎn)換詳解

    在日常滲透,漏洞挖掘,甚至是CTF比賽中會遇到各種編碼,常常伴隨著這些編碼之間的各種轉(zhuǎn)換。下面這篇文章主要介紹了python中編碼轉(zhuǎn)換妙用的相關(guān)資料,需要的朋友們可以參考借鑒,下面來一起看看吧。
    2017-04-04
  • 利用python檢測文本相似性的三種方法

    利用python檢測文本相似性的三種方法

    文本查重,也稱為文本去重,是一項旨在識別文本文檔之間的相似性或重復(fù)性的技術(shù)或任務(wù),它的主要目標(biāo)是確定一個文本文檔是否包含與其他文檔相似或重復(fù)的內(nèi)容,本文給大家介紹了利用python檢測文本相似性的原理和方法,需要的朋友可以參考下
    2023-11-11

最新評論

辽阳市| 茶陵县| 汉川市| 张家川| 高尔夫| 富平县| 吐鲁番市| 河北省| 宜阳县| 繁峙县| 阿瓦提县| 灌阳县| 乡城县| 运城市| 丹巴县| 扬州市| 永登县| 抚远县| 松阳县| 永顺县| 新和县| 新河县| 怀仁县| 扶余县| 常山县| 灯塔市| 太湖县| 伊川县| 双城市| 漾濞| 阳原县| 海城市| 霍城县| 玛曲县| 大理市| 聂拉木县| 贡觉县| 沂水县| 丰城市| 金门县| 公主岭市|