60分鐘入門PyTorch(一)——Tensors
前言
原文翻譯自:Deep Learning with PyTorch: A 60 Minute Blitz
翻譯:林不清(https://www.zhihu.com/people/lu-guo-92-42-88)
來源:機(jī)器學(xué)習(xí)初學(xué)者
目錄
60分鐘入門PyTorch(一)——Tensors
60分鐘入門PyTorch(二)——Autograd自動(dòng)求導(dǎo)
60分鐘入門Pytorch(三)——神經(jīng)網(wǎng)絡(luò)
60分鐘入門PyTorch(四)——訓(xùn)練一個(gè)分類器
Tensors
Tensors張量是一種特殊的數(shù)據(jù)結(jié)構(gòu),它和數(shù)組還有矩陣十分相似。在Pytorch中,我們使用tensors來給模型的輸入輸出以及參數(shù)進(jìn)行編碼。Tensors除了張量可以在gpu或其他專用硬件上運(yùn)行來加速計(jì)算之外,其他用法類似于Numpy中的ndarrays。如果你熟悉ndarrays,您就會(huì)熟悉tensor的API。如果沒有,請(qǐng)按照這個(gè)教程,快速了解一遍API。
%matplotlib?inline
import?torch
import?numpy?as?np
初始化Tensor
創(chuàng)建Tensor有多種方法,如:
直接從數(shù)據(jù)創(chuàng)建
可以直接利用數(shù)據(jù)創(chuàng)建tensor,數(shù)據(jù)類型會(huì)被自動(dòng)推斷出
data?=?[[1,?2],[3,?4]]
x_data?=?torch.tensor(data)
從Numpy創(chuàng)建
Tensor 可以直接從numpy的array創(chuàng)建(反之亦然-參見bridge-to-np-label)
np_array?=?np.array(data)
x_np?=?torch.from_numpy(np_array)
從其他tensor創(chuàng)建
新的tensor保留了參數(shù)tensor的一些屬性(形狀,數(shù)據(jù)類型),除非顯式覆蓋
x_ones?=?torch.ones_like(x_data)?#?retains?the?properties?of?x_data
print(f"Ones?Tensor:?\n?{x_ones}?\n")
x_rand?=?torch.rand_like(x_data,?dtype=torch.float)?#?overrides?the?datatype?of?x_data
print(f"Random?Tensor:?\n?{x_rand}?\n")
Ones Tensor:
tensor([[1, 1],
[1, 1]])
Random Tensor:
tensor([[0.6075, 0.4581],
[0.5631, 0.1357]])
從常數(shù)或者隨機(jī)數(shù)創(chuàng)建
shape是關(guān)于tensor維度的一個(gè)元組,在下面的函數(shù)中,它決定了輸出tensor的維數(shù)。
shape?=?(2,3,)
rand_tensor?=?torch.rand(shape)
ones_tensor?=?torch.ones(shape)
zeros_tensor?=?torch.zeros(shape)
print(f"Random?Tensor:?\n?{rand_tensor}?\n")
print(f"Ones?Tensor:?\n?{ones_tensor}?\n")
print(f"Zeros?Tensor:?\n?{zeros_tensor}")
Random Tensor:
tensor([[0.7488, 0.0891, 0.8417],
[0.0783, 0.5984, 0.5709]])
Ones Tensor:
tensor([[1., 1., 1.],
[1., 1., 1.]])
Zeros Tensor:
tensor([[0., 0., 0.],
[0., 0., 0.]])
Tensor的屬性
Tensor的屬性包括形狀,數(shù)據(jù)類型以及存儲(chǔ)的設(shè)備
tensor?=?torch.rand(3,4)
print(f"Shape?of?tensor:?{tensor.shape}")
print(f"Datatype?of?tensor:?{tensor.dtype}")
print(f"Device?tensor?is?stored?on:?{tensor.device}")
Shape of tensor: torch.Size([3, 4])
Datatype of tensor: torch.float32
Device tensor is stored on: cpu
Tensor的操作
Tensor有超過100個(gè)操作,包括 transposing, indexing, slicing, mathematical operations, linear algebra, random sampling,更多詳細(xì)的介紹請(qǐng)點(diǎn)擊這里
它們都可以在GPU上運(yùn)行(速度通常比CPU快),如果你使用的是Colab,通過編輯>筆記本設(shè)置來分配一個(gè)GPU。
#?We?move?our?tensor?to?the?GPU?if?available
if?torch.cuda.is_available():
??tensor?=?tensor.to('cuda')
嘗試列表中的一些操作。如果你熟悉NumPy API,你會(huì)發(fā)現(xiàn)tensor的API很容易使用。
標(biāo)準(zhǔn)的numpy類索引和切片:
tensor?=?torch.ones(4,?4)
tensor[:,1]?=?0
print(tensor)
tensor([[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.]])
合并tensors
可以使用torch.cat來沿著特定維數(shù)連接一系列張量。torch.stack另一個(gè)加入op的張量與torch.cat有細(xì)微的不同
t1?=?torch.cat([tensor,?tensor,?tensor],?dim=1)
print(t1)
tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]])
增加tensors
#?This?computes?the?element-wise?product
print(f"tensor.mul(tensor)?\n?{tensor.mul(tensor)}?\n")
#?Alternative?syntax:
print(f"tensor?*?tensor?\n?{tensor?*?tensor}")
tensor.mul(tensor)
tensor([[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.]])
tensor * tensor
tensor([[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.]])
它計(jì)算兩個(gè)tensor之間的矩陣乘法
print(f"tensor.matmul(tensor.T)?\n?{tensor.matmul(tensor.T)}?\n")
#?Alternative?syntax:
print(f"tensor?@?tensor.T?\n?{tensor?@?tensor.T}")
tensor.matmul(tensor.T)
tensor([[3., 3., 3., 3.],
[3., 3., 3., 3.],
[3., 3., 3., 3.],
[3., 3., 3., 3.]])
tensor @ tensor.T
tensor([[3., 3., 3., 3.],
[3., 3., 3., 3.],
[3., 3., 3., 3.],
[3., 3., 3., 3.]])
原地操作
帶有后綴_的操作表示的是原地操作,例如:x.copy_(y), x.t_()將改變 x.
print(tensor,?"\n")
tensor.add_(5)
print(tensor)
tensor([[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.]])
tensor([[6., 5., 6., 6.],
[6., 5., 6., 6.],
[6., 5., 6., 6.],
[6., 5., 6., 6.]])
注意
原地操作雖然會(huì)節(jié)省許多空間,但是由于會(huì)立刻清除歷史記錄所以在計(jì)算導(dǎo)數(shù)時(shí)可能會(huì)有問題,因此不建議使用
Tensor轉(zhuǎn)換為Numpt 數(shù)組
t?=?torch.ones(5)
print(f"t:?{t}")
n?=?t.numpy()
print(f"n:?{n}")
t: tensor([1., 1., 1., 1., 1.])
n: [1. 1. 1. 1. 1.]
tensor的變化反映在NumPy數(shù)組中。
t.add_(1)
print(f"t:?{t}")
print(f"n:?{n}")
t: tensor([2., 2., 2., 2., 2.])
n: [2. 2. 2. 2. 2.]
Numpy數(shù)組轉(zhuǎn)換為Tensor
n?=?np.ones(5)
t?=?torch.from_numpy(n)
NumPy數(shù)組的變化反映在tensor中
np.add(n,?1,?out=n)
print(f"t:?{t}")
print(f"n:?{n}")
t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
n: [2. 2. 2. 2. 2.]


