本文翻译的版本是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)