App下載

numpy和torch數(shù)據(jù)類型怎么轉(zhuǎn)化?

猿友 2021-07-17 14:38:31 瀏覽數(shù) (5600)
反饋

在學(xué)習(xí)機(jī)器學(xué)習(xí)的時(shí)候我們會(huì)學(xué)習(xí)到一些矩陣的數(shù)據(jù)結(jié)構(gòu),比如說(shuō)大名鼎鼎的numpy和一些庫(kù)里面自帶的數(shù)據(jù)結(jié)構(gòu)(Tensor,torch)。但有時(shí)候需要在這些數(shù)據(jù)類型之間進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換,比如說(shuō)numpy和Tensor互轉(zhuǎn),nunpy的數(shù)據(jù)類型轉(zhuǎn)化的問(wèn)題,那么該如何進(jìn)行它們的數(shù)據(jù)類型轉(zhuǎn)化呢?接下來(lái)的這篇文章告訴你。

在實(shí)際計(jì)算過(guò)程中,float類型使用最多,因此這里重點(diǎn)介紹numpy和torch數(shù)據(jù)float類型轉(zhuǎn)化遇到的問(wèn)題,其他類型同理。

numpy數(shù)據(jù)類型轉(zhuǎn)化

numpy使用astype轉(zhuǎn)化數(shù)據(jù)類型,float默認(rèn)轉(zhuǎn)化為64位,可以使用np.float32指定為32位

#numpy轉(zhuǎn)化float類型
a= np.array([1,2,3])
a = a.astype(np.float)
print(a)
print(a.dtype)

[1. 2. 3.]

float64

不要使用a.dtype指定數(shù)據(jù)類型,會(huì)使數(shù)據(jù)丟失

#numpy轉(zhuǎn)化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,否則可能出現(xiàn)意想不到的錯(cuò)誤

不能從np.float64位轉(zhuǎn)化np.float32,會(huì)報(bào)錯(cuò)

np.float64與np.float32相乘,結(jié)果為np.float64

在實(shí)際使用過(guò)程中,可以指定為np.float,也可以指定具體的位數(shù),如np.float,不過(guò)直接指定np.float更方便。

torch數(shù)據(jù)類型轉(zhuǎn)化

torch使用torch.float()轉(zhuǎn)化數(shù)據(jù)類型,float默認(rèn)轉(zhuǎn)化為32位,torch中沒有torch.float64()這個(gè)方法

# torch轉(zhuǎn)化float類型
b = torch.tensor([4,5,6])
b = b.float()
b.dtype
torch.float32

np.float64使用torch.from_numpy轉(zhuǎn)化為torch后也是64位的

print(a.dtype)
c = torch.from_numpy(a)
c.dtype

float64

torch.float64

不要用float代替torch.float,否則可能出現(xiàn)意想不到的錯(cuò)誤

torch.float32與torch.float64數(shù)據(jù)類型相乘會(huì)出錯(cuò),因此相乘的時(shí)候注意指定或轉(zhuǎn)化數(shù)據(jù)float具體類型

np和torch數(shù)據(jù)類型轉(zhuǎn)化大體原理一樣,只有相乘的時(shí)候,torch.float不一致不可相乘,np.float不一致可以相乘,并且轉(zhuǎn)化為np.float64

numpy和tensor互轉(zhuǎn)

tensor轉(zhuǎn)化為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轉(zhuǎn)化為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默認(rèn)int型是64位的,numpy默認(rèn)int型是32位的

補(bǔ)充:torch.from_numpy VS torch.Tensor

最近在造dataset的時(shí)候,突然發(fā)現(xiàn),在輸入圖像轉(zhuǎn)tensor的時(shí)候,我可以用torch.Tensor直接強(qiáng)制轉(zhuǎn)型將numpy類轉(zhuǎn)成tensor類,也可以用torch.from_numpy這個(gè)方法將numpy類轉(zhuǎn)換成tensor類,那么,torch.Tensor和torch.from_numpy這兩個(gè)到底有什么區(qū)別呢?既然torch.Tensor能搞定,那torch.from_numpy留著不就是冗余嗎?

答案

有區(qū)別,使用torch.from_numpy更加安全,使用tensor.Tensor在非float類型下會(huì)與預(yù)期不符。

解釋

實(shí)際上,兩者的區(qū)別是大大的。打個(gè)不完全正確的比方說(shuō),torch.Tensor就如同c的int,torch.from_numpy就如同c++的static_cast,我們都知道,如果將int64強(qiáng)制轉(zhuǎn)int32,只要是高位轉(zhuǎn)低位,一定會(huì)出現(xiàn)高位被抹去的隱患的,不僅僅可能會(huì)丟失精度,甚至?xí)?fù)對(duì)調(diào)。

這里的torch.Tensor與torch.from_numpy也會(huì)存在同樣的問(wèn)題。

看看torch.Tensor的文檔,里面清楚地說(shuō)明了,

torch.Tensor is an alias for the default tensor type (torch.FloatTensor).

而torch.from_numpy的文檔則是說(shuō)明,

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.

也即是說(shuō),

1、當(dāng)轉(zhuǎn)換的源是float類型,torch.Tensor與torch.from_numpy會(huì)共享一塊內(nèi)存!且轉(zhuǎn)換后的結(jié)果的類型是torch.float32

2、當(dāng)轉(zhuǎn)換的源不是float類型,torch.Tensor得到的是torch.float32,而torch.from_numpy則是與源類型一致!

是不是很神奇,下面是一個(gè)簡(jiǎn)單的例子:

import torch
import numpy as nps1 = np.arange(10, dtype=np.float32)
s2 = np.arange(10) # 默認(rèn)的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)

小結(jié)

以上就是numpy和tensor互轉(zhuǎn),numpy數(shù)據(jù)類型轉(zhuǎn)化,torch數(shù)據(jù)類型轉(zhuǎn)化的全部?jī)?nèi)容,如有不盡之處還請(qǐng)各位讀者大佬們補(bǔ)充,也希望大家多多支持W3Cschool。



0 人點(diǎn)贊