Pytorch 實現變量類型轉換
Pytorch的數據類型為各式各樣的Tensor,Tensor可以理解為高維矩陣。
與Numpy中的Array類似。Pytorch中的tensor又包括CPU上的數據類型和GPU上的數據類型,一般GPU上的Tensor是CPU上的Tensor加cuda()函數得到。通過使用Type函數可以查看變量類型。
一般系統默認是torch.FloatTensor類型。
例如data = torch.Tensor(2,3)是一個2*3的張量,類型為FloatTensor; data.cuda()就轉換為GPU的張量類型,torch.cuda.FloatTensor類型。
下面簡單介紹一下Pytorch中變量之間的相互轉換
(1)CPU或GPU張量之間的轉換
一般隻要在Tensor後加long(), int(), double(),float(),byte()等函數就能將Tensor進行類型轉換;
例如:Torch.LongTensor—>Torch.FloatTensor, 直接使用data.float()即可
還可以使用type()函數,data為Tensor數據類型,data.type()為給出data的類型,如果使用data.type(torch.FloatTensor)則強制轉換為torch.FloatTensor類型張量。
當你不知道要轉換為什麼類型時,但需要求a1,a2兩個張量的乘積,可以使用a1.type_as(a2)將a1轉換為a2同類型。
(2)CPU張量 —-> GPU張量, 使用data.cuda()
(3)GPU張量 —-> CPU張量 使用data.cpu()
(4)Variable變量轉換成普通的Tensor,其實可以理解Variable為一個Wrapper,裡頭的data就是Tensor. 如果Var是Variable變量,使用Var.data獲得Tensor變量
(5)Tensor與Numpy Array之間的轉換
Tensor—->Numpy 可以使用 data.numpy(),data為Tensor變量
Numpy —-> Tensor 可以使用torch.from_numpy(data),data為numpy變量
補充:Numpy/Pytorch之數據類型與強制類型轉換
1.數據類型簡介
Numpy
NumPy 支持比 Python 更多種類的數值類型。 下表顯示瞭 NumPy 中定義的不同標量數據類型。
序號 | 數據類型及描述 |
---|---|
1. | bool_存儲為一個字節的佈爾值(真或假) |
2. | int_默認整數,相當於 C 的long,通常為int32或int64 |
3. | intc相當於 C 的int,通常為int32或int64 |
4. | intp用於索引的整數,相當於 C 的size_t,通常為int32或int64 |
5. | int8字節(-128 ~ 127) |
6. | int1616 位整數(-32768 ~ 32767) |
7. | int3232 位整數(-2147483648 ~ 2147483647) |
8. | int6464 位整數(-9223372036854775808 ~ 9223372036854775807) |
9. | uint88 位無符號整數(0 ~ 255) |
10. | uint1616 位無符號整數(0 ~ 65535) |
11. | uint3232 位無符號整數(0 ~ 4294967295) |
12. | uint6464 位無符號整數(0 ~ 18446744073709551615) |
13. | float_float64的簡寫 |
14. | float16半精度浮點:符號位,5 位指數,10 位尾數 |
15. | float32單精度浮點:符號位,8 位指數,23 位尾數 |
16. | float64雙精度浮點:符號位,11 位指數,52 位尾數 |
17. | complex_complex128的簡寫 |
18. | complex64復數,由兩個 32 位浮點表示(實部和虛部) |
19. |
complex128復數,由兩個 64 位浮點表示(實部和虛部) |
直接使用類型名很可能會報錯,正確的使用方式是np.調用,eg, np.uint8
Pytorch
Torch定義瞭七種CPU張量類型和八種GPU張量類型,這裡我們就隻講解一下CPU中的,其實GPU中隻是中間加一個cuda即可,如torch.cuda.FloatTensor:
torch.FloatTensor(2,3) 構建一個2*3 Float類型的張量
torch.DoubleTensor(2,3) 構建一個2*3 Double類型的張量
torch.ByteTensor(2,3) 構建一個2*3 Byte類型的張量
torch.CharTensor(2,3) 構建一個2*3 Char類型的張量
torch.ShortTensor(2,3) 構建一個2*3 Short類型的張量
torch.IntTensor(2,3) 構建一個2*3 Int類型的張量
torch.LongTensor(2,3) 構建一個2*3 Long類型的張量
同樣,直接使用類型名很可能會報錯,正確的使用方式是torch.調用,eg,torch.FloatTensor()
2.Python的type()函數
type函數可以由變量調用,或者把變量作為參數傳入。
返回的是該變量的類型,而非數據類型。
data = np.random.randint(0, 255, 300) print(type(data))
輸出
<class ‘numpy.ndarray’>
3.Numpy/Pytorch的dtype屬性
返回值為變量的數據類型
t_out = torch.Tensor(1,2,3) print(t_out.dtype)
輸出
torch.float32
t_out = torch.Tensor(1,2,3)
print(t_out.numpy().dtype)
輸出
float32
4.Numpy中的類型轉換
先聊聊我為什麼會用到這個函數(不看跳過)
為瞭實施trochvision.transforms.ToPILImage()函數
於是我想從numpy的ndarray類型轉成PILImage類型
我做瞭以下嘗試
data = np.random.randint(0, 255, 300) n_out = data.reshape(10,10,3) print(n_out.dtype) img = transforms.ToPILImage()(n_out) img.show()
但是很遺憾,報錯瞭
raise TypeError(‘Input type {} is not supported’.format(npimg.dtype))
TypeError: Input type int32 is not supported
因為要將ndarray轉成PILImage要求ndarray是uint8類型的。
於是我認輸瞭。。。
使用瞭
n_out = np.linspace(0,255,300,dtype=np.uint8) n_out = n_out.reshape(10,10,3) print(n_out.dtype) img = torchvision.transforms.ToPILImage()(n_out) img.show()
得到瞭輸出
uint8
嗯,顯示瞭一張圖片
但是呢,就很憋屈,和想要的隨機數效果不一樣。
於是我用瞭astype函數
astype()函數
由變量調用,但是直接調用不會改變原變量的數據類型,是返回值是改變類型後的新變量,所以要賦值回去。
n_out = n_out.astype(np.uint8)
#初始化隨機數種子 np.random.seed(0) data = np.random.randint(0, 255, 300) print(data.dtype) n_out = data.reshape(10,10,3) #強制類型轉換 n_out = n_out.astype(np.uint8) print(n_out.dtype) img = transforms.ToPILImage()(n_out) img.show()
輸出
int32
uint8
5.Pytorch中的類型轉換
pytorch中沒有astype函數,正確的轉換方法是
Way1 : 變量直接調用類型
tensor = torch.Tensor(3, 5)
torch.long() 將tensor投射為long類型
newtensor = tensor.long()
torch.half()將tensor投射為半精度浮點類型
newtensor = tensor.half()
torch.int()將該tensor投射為int類型
newtensor = tensor.int()
torch.double()將該tensor投射為double類型
newtensor = tensor.double()
torch.float()將該tensor投射為float類型
newtensor = tensor.float()
torch.char()將該tensor投射為char類型
newtensor = tensor.char()
torch.byte()將該tensor投射為byte類型
newtensor = tensor.byte()
torch.short()將該tensor投射為short類型
newtensor = tensor.short()
同樣,和numpy中的astype函數一樣,是返回值才是改變類型後的結果,調用的變量類型不變
Way2 : 變量調用pytorch中的type函數
type(new_type=None, async=False)如果未提供new_type,則返回類型,否則將此對象轉換為指定的類型。 如果已經是正確的類型,則不會執行且返回原對象。
用法如下:
self = torch.LongTensor(3, 5) # 轉換為其他類型 print self.type(torch.FloatTensor)
Way3 : 變量調用pytorch中的type_as函數
如果張量已經是正確的類型,則不會執行操作。具體操作方法如下:
self = torch.Tensor(3, 5) tesnor = torch.IntTensor(2,3) print self.type_as(tesnor)
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Pytorch數據類型與轉換(torch.tensor,torch.FloatTensor)
- pytorch常用數據類型所占字節數對照表一覽
- 解決numpy和torch數據類型轉化的問題
- pytorch教程之Tensor的值及操作使用學習
- PyTorch中Tensor和tensor的區別及說明