近幾年,人工智能的深度學習大熱,相關從業者的薪資水平明顯高於不少行業,這主要是因為深度學習領域對從業者的要求較高,相關人才有些供不應求——從業者要具備紮實的數學功底,還要熟悉所使用的硬件平臺特性,掌握一門紮實的編程語言,儘可能
同樣的任務,可能水平欠佳的程序員設計的算法需要幾天才能完成,而較高水準的算法幾小時就完成了。
深度學習從業者薪資水平較高
好在,愈發成熟的各種深度學習框架大大方便了從業者,從業者甚至無需再關心硬件平臺,也無需再把大量精力花費在算法設計上,就能輕易的以不錯的性能實現自己的深度學習網絡。
關於深度學習框架,我較深入的使用過 Caffe、tensorflow,但是最終還是選擇了 PyTorch。
PyTorch 是什麼
我認為,與其說 PyTorch 是一個深度學習框架,倒不如說它是一個深度學習庫,這一點可以在以後的使用中得出。按照官網上的說法,PyTorch 是一個 Python 科學計算包,有兩類受眾:
替換 NumPy 庫,更方便的使用 GPUs 高效計算充當深度學習研究平臺,最大限度的提供靈活性和效率關於 PyTorch 的安裝,可以參考官網,已經非常傻瓜式了,本文就不贅述了。
開始
開始
Tensors(張量)
PyTorch 中的 tensor 類似於 NumPy 中的 ndarray,只不過 tensor 能夠更加方便的使用 GPU 加速運算,在使用 tensor 之前,需要導入 PyTorch 包:
<code>
import
torch/<code>創建一個沒有初始化的 5x3 的矩陣:
<code>x = torch.
empty
(5
,3
)輸出如下:
<code>
tensor([[-7.1077e+12,
4.5558e-41
,
4.2319e-11
],
[
3.0942e-41
,
1.0177e+31
,
2.2017e+12
],
[
2.8488e-14
,
9.6809e+24
,
1.0880e-19
],
[
1.0874e-19
,
2.5443e+30
,
9.4727e+21
],
[
2.4835e+27
,
2.5428e+30
,
1.0877e-19
]])
/<code>創建一個隨機初始化的矩陣:
<code>x = torch.rand(5, 3)
輸出如下:
<code>
tensor([[0.6363,
0.5365
,
0.6489
],
[0.8479,
0.3439
,
0.3546
],
[0.8024,
0.7198
,
0.8319
],
[0.6590,
0.1750
,
0.7466
],
[0.8664,
0.7331
,
0.1298
]])
/<code>創建一個數據類型為 torch.long 的全零矩陣:
<code>x = torch.zeros(5, 3, dtype=torch.long)
輸出如下:
<code>
tensor([[0,
0
,
0
],
[0,
0
,
0
],
[0,
0
,
0
],
[0,
0
,
0
],
[0,
0
,
0
]])
/<code>直接從現有數據構造矩陣:
<code>x = torch.tensor([5.5, 3])
輸出如下:
<code>
tensor
([5.5000, 3.0000]
)/<code>或者基於一個現有 tensor 創建新矩陣,下面這些方法將會重用輸入 tensor 的屬性,比如數據結構等,除非用戶指定的新值:
<code>x = x.new_ones(5, 3, dtype=torch.double)
輸出如下:
<code>
tensor([[1.,
1
.,
1
.],
[1.,
1
.,
1
.],
[1.,
1
.,
1
.],
[1.,
1
.,
1
.],
[1.,
1
.,
1
.]],
dtype=torch.float64)
tensor([[
0.2295
,
0.2996
,
0.0104
],
[
0.5513
,
0.0489
,
0.3046
],
[-0.0529,
0.8116
,
-0.2754
],
[
2.3672
,
0.1456
,
-1.3679
],
[
0.4731
,
0.0102
,
0.9750
]])
/<code>獲取它的 size:
<code>
輸出如下:
<code>
torch
.Size
([5, 3]
)/<code>torch.Size 實際上是一個 tuple,所以它支持所有的 tuple 操作。
Operations(操作)
PyTorch 中的操作有多個語法,在接下來的例子中,我們將通過加法操作了解這一點:
加法:語法 1
<code>y = torch.rand(5, 3)
輸出:
<code>
tensor([[
0.7623
,
0.4833
,
0.7200
],
[
0.8453
,
0.4220
,
1.2202
],
[
0.8108
,
1.6514
,
0.3858
],
[
2.7137
,
0.1767
,
-1.2774
],
[
0.7659
,
0.4483
,
1.2968
]])
/<code>加法:語法2
<code>
輸出:
<code>
tensor([[
0.7623
,
0.4833
,
0.7200
],
[
0.8453
,
0.4220
,
1.2202
],
[
0.8108
,
1.6514
,
0.3858
],
[
2.7137
,
0.1767
,
-1.2774
],
[
0.7659
,
0.4483
,
1.2968
]])
/<code>加法:通過參數的形式把結果輸出給指定張量
<code>result = torch.empty(
5
,3
) torch.add
(x, y,out
=result) print(result)/<code>輸出:
<code>
tensor([[
0.7623
,
0.4833
,
0.7200
],
[
0.8453
,
0.4220
,
1.2202
],
[
0.8108
,
1.6514
,
0.3858
],
[
2.7137
,
0.1767
,
-1.2774
],
[
0.7659
,
0.4483
,
1.2968
]])
/<code>加法:in-place 操作
<code> y.add_(x)
輸出:
<code>
tensor([[
0.7623
,
0.4833
,
0.7200
],
[
0.8453
,
0.4220
,
1.2202
],
[
0.8108
,
1.6514
,
0.3858
],
[
2.7137
,
0.1767
,
-1.2774
],
[
0.7659
,
0.4483
,
1.2968
]])
/<code>通過_符號,PyTorch 中的操作將變為 in-place 操作,舉個例子:x.copy_(y),x.t_(),這兩個操作的最終結果會作用在 x 上。
可以像標準的 NumPy 庫那樣對 tensor 使用切片操作:
<code>
輸出:
<code>
tensor([0.2996,
0.0489
,
0.8116
,
0.1456
,
0.0102
])
/<code>resize:如果希望對 tensor 實現 resize/reshape 操作,可以使用 torch.view:
<code>x = torch.randn(4, 4) y = x.view(16) z = x.view(-1, 8) print(x.size(), y.size(), z.size())/<code>
輸出:
<code>
torch
.Size
([4, 4]
)torch
.Size
([16]
)torch
.Size
([2, 8]
)/<code>如果 tensor 中只有一個元素,可以使用 .item() 把這個元素以 Python 標準 number 的形式取出:
<code>x = torch.randn(1)
輸出:
<code>
tensor
([-1.4181]
)-1
.4181468486785889
/<code>更多的操作可以參考官方文檔。
與 NumPy 互相轉換
PyTorch 中的 Tensor 和 NumPy 中的 array 可以共享一塊內存去區域(當 tensor 位於 CPU 中時),改變其中一個,另一個也會隨之改變。
將 Tensor 轉換為 Numpy 中的 Array
<code>a = torch.ones(5)
輸出:
<code>
tensor([1.,
1
.,
1
.,
1
.,
1
.])
/<code>將張量 a 轉換為 numpy 是非常簡單的:
<code>b = a.numpy()
輸出:
<code>
[1.
1
.
1
.
1
.
1
.]
/<code>正如剛才所說,此時 a、b 共享一塊數據內存,我們改變 a,b也會隨之改變:
<code>
a
.add_
(1
)輸出:
<code>
tensor([2.,
2
.,
2
.,
2
.,
2
.])
[2.
2
.
2
.
2
.
2
.]
/<code>將 NumPy 中的 Array 轉換為 Tensor
<code>
import
numpyas
np a = np.ones(5
) b = torch.from_numpy(a) np.add(a,1
, out=a)輸出:
<code>
[2.
2
.
2
.
2
.
2
.]
tensor([2.,
2
.,
2
.,
2
.,
2
.],
dtype=torch.float64)
/<code>除了 CharTensor 類型的 Tensor,CPU 中的其他所有 Tensor 都支持與 NumPy 互相轉換。
CUDA Tensor
PyTorch 中的 Tensor 可以簡單的通過 .to() 方法移到任意的 device 中:
<code>
if
torch.cuda.is_available():
device
=torch.device("cuda")
y
=torch.ones_like(x, device=device)
x
=x.to(device)
z
=x + y
print(z)
torch.double))
/<code>輸出:
<code>
tensor
([-0.4181
], device='cuda:0'
)tensor
([-0.4181
], dtype=torch.float64)/<code>