解決numpy和torch數據類型轉化的問題
在實際計算過程中,float類型使用最多,因此這裡重點介紹numpy和torch數據float類型轉化遇到的問題,其他類型同理。
numpy數據類型轉化
numpy使用astype轉化數據類型,float默認轉化為64位,可以使用np.float32指定為32位
#numpy轉化float類型 a= np.array([1,2,3]) a = a.astype(np.float) print(a) print(a.dtype)
[1. 2. 3.]
float64
不要使用a.dtype指定數據類型,會使數據丟失
#numpy轉化float類型 b= np.array([1,2,3]) b.dtype= np.float32 print(b) print(b.dtype)
[1.e-45 3.e-45 4.e-45]
float32
不要用float代替np.float,否則可能出現意想不到的錯誤
不能從np.float64位轉化np.float32,會報錯
np.float64與np.float32相乘,結果為np.float64
在實際使用過程中,可以指定為np.float,也可以指定具體的位數,如np.float,不過直接指定np.float更方便。
torch數據類型轉化
torch使用torch.float()轉化數據類型,float默認轉化為32位,torch中沒有torch.float64()這個方法
# torch轉化float類型 b = torch.tensor([4,5,6]) b = b.float() b.dtype
torch.float32
np.float64使用torch.from_numpy轉化為torch後也是64位的
print(a.dtype) c = torch.from_numpy(a) c.dtype
float64
torch.float64
不要用float代替torch.float,否則可能出現意想不到的錯誤
torch.float32與torch.float64數據類型相乘會出錯,因此相乘的時候註意指定或轉化數據float具體類型
np和torch數據類型轉化大體原理一樣,隻有相乘的時候,torch.float不一致不可相乘,np.float不一致可以相乘,並且轉化為np.float64
numpy和tensor互轉
tensor轉化為numpy
import torch b = torch.tensor([4.0,6]) # b = b.float() print(b.dtype) c = b.numpy() print(c.dtype)
torch.int64
int64
numpy轉化為tensor
import torch import numpy as np b= np.array([1,2,3]) # b = b.astype(np.float) print(b.dtype) c = torch.from_numpy(b) print(c.dtype)
int32
torch.int32
可以看到,torch默認int型是64位的,numpy默認int型是32位的
補充:torch.from_numpy VS torch.Tensor
最近在造dataset的時候,突然發現,在輸入圖像轉tensor的時候,我可以用torch.Tensor直接強制轉型將numpy類轉成tensor類,也可以用torch.from_numpy這個方法將numpy類轉換成tensor類,那麼,torch.Tensor和torch.from_numpy這兩個到底有什麼區別呢?既然torch.Tensor能搞定,那torch.from_numpy留著不就是冗餘嗎?
答案
有區別,使用torch.from_numpy更加安全,使用tensor.Tensor在非float類型下會與預期不符。
解釋
實際上,兩者的區別是大大的。打個不完全正確的比方說,torch.Tensor就如同c的int,torch.from_numpy就如同c++的static_cast,我們都知道,如果將int64強制轉int32,隻要是高位轉低位,一定會出現高位被抹去的隱患的,不僅僅可能會丟失精度,甚至會正負對調。
這裡的torch.Tensor與torch.from_numpy也會存在同樣的問題。
看看torch.Tensor的文檔,裡面清楚地說明瞭,
torch.Tensor is an alias for the default tensor type (torch.FloatTensor).
而torch.from_numpy的文檔則是說明,
The returned tensor and ndarray share the same memory. Modifications to the tensor will be reflected in the ndarray and vice versa. The returned tensor is not resizable.
也即是說,
1、當轉換的源是float類型,torch.Tensor與torch.from_numpy會共享一塊內存!且轉換後的結果的類型是torch.float32
2、當轉換的源不是float類型,torch.Tensor得到的是torch.float32,而torch.from_numpy則是與源類型一致!
是不是很神奇,下面是一個簡單的例子:
import torch import numpy as nps1 = np.arange(10, dtype=np.float32) s2 = np.arange(10) # 默認的dtype是int64# 例一 o11 = torch.Tensor(s1) o12 = torch.from_numpy(s1) o11.dtype # torch.float32 o12.dtype # torch.float32 # 修改值 o11[0] = 12 o12[0] # tensor(12.)# 例二 o21 = torch.Tensor(s2) o22 = torch.from_numpy(s2) o21.dtype # torch.float32 o22.dtype # torch.int64 # 修改值 o21[0] = 12 o22[0] # tensor(0)
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- NumPy-ndarray 的數據類型用法說明
- Python Numpy中ndarray的常見操作
- Pytorch 實現變量類型轉換
- pytorch教程之Tensor的值及操作使用學習
- PyTorch一小時掌握之基本操作篇