PyTorch 深度學習:60分鐘快速入門(1) ----什麼是PyTorch
本文翻譯的版本是pytorch 1.0.0官方文件
譯自 pytorch官方文件
作者:Soumith Chintala
教程目標:
- 深入理解PyTorch張量庫和神經網路
- 訓練一個小的神經網路來分類圖片
這個教程假設你熟悉numpy的基本操作。
注意
請確保torch和torchvision包已經安裝。
一.什麼是Pytorch
它是一個基於Python的科學計算包,目標使用者有兩類:
- 為了使用GPU來替代numpy
- 一個深度學習研究平臺:提供最大的靈活性和速度
開始
張量(Tensors)
張量類似於numpy的ndarrays,不同之處在於張量可以使用GPU來加快計算。
from __future__ import print_function
import torch
構建一個未初始化的5*3的矩陣:
x = torch.empty(5, 3)
print(x)
輸出:
tensor([[6.6740e+16, 4.5850e-41, 3.3872e+18], [4.5850e-41, 3.8805e+25, 6.5096e+32], [2.9208e-11, 3.9753e+28, 2.5444e+30], [3.7893e+22, 3.9737e+28, 6.0657e+23], [2.9194e-11, 3.7906e+22, 4.1613e-41]])
構造一個隨機初始化的矩陣:
x = torch.rand(5, 3)
print(x)
輸出:
tensor([[0.5073, 0.8605, 0.0232],
[0.1122, 0.8995, 0.8835],
[0.5968, 0.5281, 0.9801],
[0.2018, 0.9549, 0.1442],
[0.3405, 0.9567, 0.7668]])
構造一個dtype為long,數值為0的矩陣
x = torch.zeros(5, 3, dtype=torch.long)
print(x)
輸出:
tensor([[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]])
直接用資料構造一個tensor
x = torch.tensor([5.5, 3])
print(x)
輸出:
tensor([5.5000, 3.0000])
或者基於一個已存在的tensor建立一個tensor。除非使用者提供新值,否則這些方法將重用輸入tensor的屬性,例如dtype
x = x.new_ones(5, 3, dtype=torch.double) # new_* methods take in sizes
print(x)
x = torch.randn_like(x, dtype=torch.float) # override dtype!
print(x) # result has the same size
輸出:
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
tensor([[-0.5228, -0.0111, 2.5073],
[ 1.1455, 1.3264, 0.2007],
[-0.1626, 0.9117, -0.2683],
[ 0.0856, 1.5781, 0.4481],
[ 0.0245, -0.2411, -0.5900]])
獲取矩陣的大小:
print(x.size())
輸出:
torch.Size([5, 3])
注意
torch.Size實際上是一個元組,所以它支援元組相同的操作。
操作
張量上的操作有多重語法形式,下面我們以加法為例進行講解。
語法1
y = torch.rand(5, 3)
print(x + y)
輸出:
tensor([[-0.3996, 0.2443, 3.1812],
[ 1.6338, 2.1747, 0.2639],
[ 0.2952, 1.3413, -0.1872],
[ 0.5001, 1.8277, 1.0364],
[ 0.8115, 0.6303, -0.1815]])
語法2
print(torch.add(x, y))
輸出:
tensor([[-0.3996, 0.2443, 3.1812],
[ 1.6338, 2.1747, 0.2639],
[ 0.2952, 1.3413, -0.1872],
[ 0.5001, 1.8277, 1.0364],
[ 0.8115, 0.6303, -0.1815]])
語法三:給出一個輸出向量
result = torch.empty(5, 3)
torch.add(x, y, out=result)
print(result)
輸出:
tensor([[-0.3996, 0.2443, 3.1812],
[ 1.6338, 2.1747, 0.2639],
[ 0.2952, 1.3413, -0.1872],
[ 0.5001, 1.8277, 1.0364],
[ 0.8115, 0.6303, -0.1815]])
語法四:原地操作
# adds x to y
y.add_(x)
print(y)
輸出:
tensor([[-0.3996, 0.2443, 3.1812],
[ 1.6338, 2.1747, 0.2639],
[ 0.2952, 1.3413, -0.1872],
[ 0.5001, 1.8277, 1.0364],
[ 0.8115, 0.6303, -0.1815]])
注意
任何在原地改變張量的操作都有一個’
_
'字尾。例如x.copy_(y)
,x.t_()
操作將改變x
.
你可以使用所有的numpy索引操作。
print(x[:, 1])
輸出:
tensor([-0.0111, 1.3264, 0.9117, 1.5781, -0.2411])
調整:如果你想resize/reshape tensor,你可以用torch.view
輸出:
x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8) # the size -1 is inferred from other dimensions
print(x.size(), y.size(), z.size())
輸出:
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])
如果你有一個一個元素的tensor,用.item()
去得到這個值
x = torch.randn(1)
print(x)
print(x.item())
輸出:
tensor([-0.1355])
-0.1354905664920807
稍後閱讀:
這裡描述了一百多種張量操作,包括轉置,索引,數學運算,線性代數,隨機數等。
numpy橋
把一個torch張量轉換為numpy陣列或者反過來都是很簡單的。
Torch張量和numpy陣列將共享潛在的記憶體,改變其中一個也將改變另一個。
把Torch張量轉換為numpy陣列
a = torch.ones(5)
print(a)
輸出:
tensor([1., 1., 1., 1., 1.])
b = a.numpy()
print(b)
輸出:
[1. 1. 1. 1. 1.]
看看numpy陣列的值如何改變。
a.add_(1)
print(a)
print(b)
輸出:
tensor([2., 2., 2., 2., 2.])
[2. 2. 2. 2. 2.]
把numpy陣列轉換為torch tensor
看看改變numpy陣列如何自動改變torch tensor。
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)
輸出:
[2. 2. 2. 2. 2.]
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
所有在CPU上的張量,除了字元張量,都支援在numpy之間轉換。
CUDA張量
使用.to
函式可以將張量移動到GPU上。
# let us run this cell only if CUDA is available
# We will use ``torch.device`` objects to move tensors in and out of GPU
if torch.cuda.is_available():
device = torch.device("cuda") # a CUDA device object
y = torch.ones_like(x, device=device) # directly create a tensor on GPU
x = x.to(device) # or just use strings ``.to("cuda")``
z = x + y
print(z)
print(z.to("cpu", torch.double)) # ``.to`` can also change dtype together!
輸出:
tensor([0.8645], device='cuda:0')
tensor([0.8645], dtype=torch.float64)