Pytorch的Tensor

1. 张量是什么

张量是一个多维数组,它是标量、向量、矩阵的高维拓展

image-20200720140731459

Pytorch0.4.0版开始,Variable并入Tensor

  • dtype:张量的数据类型,如torch.FloatTensor,torch.cuda.FloatTensor

  • shape:张量的形状,如(64,3,224,224)

  • device:张量所在设备,GPU/CPU,是加速的关键

image-20200720141349926 image-20200720142848284

2. 张量的创建

创建Tensor

2.1 从ndarray创建

2.1.1 通过torch.tensor创建张量

1
2
3
4
5
torch.tensor(data, 
dtype=None,
device=None,
requires_grad=False,
pin_memory=False) → Tensor

功能:从data创建tensor

  • data: 数据, 可以是list, numpy

  • dtype : 数据类型,默认与data的一致

  • device : 所在设备, cuda/cpu

  • requires_grad:是否需要梯度

  • pin_memory:是否存于锁页内存

1
2
3
4
5
6
7
8
9
import torch
import numpy as np

arr = np.ones((3, 3))
print("ndarray的数据类型:", arr.dtype)

# t = torch.tensor(arr, device='cuda')
t = torch.tensor(arr)
print(t)
1
2
3
4
ndarray的数据类型: float64
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)

2.1.2 通过torch.from_numpy创建张量

1
torch.from_numpy(ndarray) → Tensor

功能:从numpy创建tensor
注意事项:从torch.from_numpy创建的tensor于原ndarray共享内存,当修改其中一个的数据,另外一个也将会被改动

image-20200720142410333
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import torch
import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6]])
t = torch.from_numpy(arr)
print("numpy array: \n", arr)
print("tensor : \n", t)

print("\n修改arr")
arr[0, 0] = 0
print("numpy array: ", arr)
print("tensor : ", t)

print("\n修改tensor")
t[0, 0] = -1
print("numpy array: ", arr)
print("tensor : ", t)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
numpy array: 
[[1 2 3]
[4 5 6]]
tensor :
tensor([[1, 2, 3],
[4, 5, 6]], dtype=torch.int32)

修改arr
numpy array: [[0 2 3]
[4 5 6]]
tensor : tensor([[0, 2, 3],
[4, 5, 6]], dtype=torch.int32)

修改tensor
numpy array: [[-1 2 3]
[ 4 5 6]]
tensor : tensor([[-1, 2, 3],
[ 4, 5, 6]], dtype=torch.int32)

2.2 依据数值创建

2.2.1 通过torch.zeros创建张量

1
2
3
4
5
6
torch.zeros(*size, 
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False)

功能:依size创建全0张量

  • size: 张量的形状, 如(3, 3)、(3, 224,224)

  • out : 输出的张量

  • layout : 内存中布局形式, 有strided,sparse_coo等

  • device : 所在设备, gpu/cpu

  • requires_grad:是否需要梯度

1
2
3
4
5
6
7
8
import torch
import numpy as np

out_t = torch.tensor([1])
t = torch.zeros((3, 3), out=out_t)

print(t, '\n', out_t)
print(id(t), id(out_t), id(t) == id(out_t))
1
2
3
4
5
6
7
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
2028621356232 2028621356232 True

两种输出方式:直接复制,或者通过参数out

2.2.2 通过torch.zeros_like创建张量

1
2
3
4
5
6
torch.zeros_like(input, 
dtype=None,
layout=None,
device=None,
requires_grad=False,
memory_format=torch.preserve_format) → Tensor

功能:依input形状创建全0张量

  • intput: 创建与input同形状的全0张量
  • dtype : 数据类型
  • layout : 内存中布局形式
1
2
3
4
5
import torch
import numpy as np

input_ = torch.empty(2, 3)
print(torch.zeros_like(input_))
1
2
tensor([[0., 0., 0.],
[0., 0., 0.]])

2.2.3 通过torch.ones创建张量

1
2
3
4
5
6
torch.ones(*size, 
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False) → Tensor

功能:依input形状创建全1张量

  • size: 定义输出张量形状的整数序列。可以是可变数量的参数,也可以是列表或元组。
  • dtype : 数据类型
  • layout : 内存中布局形式
  • device : 所在设备, gpu/cpu
  • requires_grad:是否需要梯度

2.2.4 通过torch.ones_like创建张量

1
2
3
4
5
6
torch.ones_like(input, 
dtype=None,
layout=None,
device=None,
requires_grad=False,
memory_format=torch.preserve_format) → Tensor
  • input (Tensor) – the size of input will determine size of the output tensor.
  • dtype (torch.dtype, optional) – the desired data type of returned Tensor. Default: if None, defaults to the dtype of input.
  • layout (torch.layout, optional) – the desired layout of returned tensor. Default: if None, defaults to the layout of input.
  • device (torch.device, optional) – the desired device of returned tensor. Default: if None, defaults to the device of input.
  • requires_grad (bool, optional) – If autograd should record operations on the returned tensor. Default: False.
  • memory_format (torch.memory_format, optional) – the desired memory format of returned Tensor. Default: torch.preserve_format.

2.2.5 通过torch.full创建张量

1
2
3
4
5
6
7
torch.full(size, 
fill_value,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False) → Tensor
  • size (int…) – a list, tuple, or torch.Size of integers defining the shape of the output tensor.
  • fill_value – the number to fill the output tensor with.
  • out (Tensor, optional) – the output tensor.
  • dtype (torch.dtype, optional) – the desired data type of returned tensor. Default: if None, uses a global default (see torch.set_default_tensor_type()).
  • layout (torch.layout, optional) – the desired layout of returned Tensor. Default: torch.strided.
  • device (torch.device, optional) – the desired device of returned tensor. Default: if None, uses the current device for the default tensor type (see torch.set_default_tensor_type()). device will be the CPU for CPU tensor types and the current CUDA device for CUDA tensor types.
  • requires_grad (bool, optional) – If autograd should record operations on the returned tensor. Default: False.

实验:

1
2
3
4
5
import torch
import numpy as np

t = torch.full((3, 3), 1, dtype=float)
print(t)
1
2
3
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)

2.2.6 通过torch.full_like创建张量

1
2
3
4
5
6
7
8
torch.full_like(input, 
fill_value,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False,
memory_format=torch.preserve_format) → Tensor

功能:依input形状创建指定数据的张量

  • size: 张量的形状, 如(3, 3)
  • fill_value : 张量的值

2.2.7 通过torch.arange创建等差数列张量

1
2
3
4
5
6
7
8
torch.arange(start=0, 
end,
step=1,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False) → Tensor

功能:创建等差的1维张量

注意事项:数值区间为[start, end)

  • start: 数列起始值
  • end : 数列“结束值”
  • step: 数列公差,默认为1
1
2
3
4
5
import torch
import numpy as np

t = torch.arange(2, 10, 2)
print(t)
1
tensor([2, 4, 6, 8])

2.2.8 通过torch.linspace创建均分数列张量

1
2
3
4
5
6
7
8
torch.linspace(start, 
end,
steps=100,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False) → Tensor

功能:创建均分的1维张量

注意事项:数值区间为[start, end]

  • start: 数列起始值
  • end : 数列结束值
  • steps: 数列长度
1
2
3
4
5
import torch
import numpy as np

print(torch.linspace(2, 10, 5))
print(torch.linspace(2, 10, 6))
1
2
tensor([ 2.,  4.,  6.,  8., 10.])
tensor([ 2.0000, 3.6000, 5.2000, 6.8000, 8.4000, 10.0000])

2.2.9 通过torch.logspace创建对数均分数列张量

1
2
3
4
5
6
7
8
9
torch.logspace(start, 
end,
steps=100,
base=10.0,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False) → Tensor

功能:创建对数均分的1维张量;应该是取了对数以后是均分的意思

注意事项:长度为steps, 底为base

  • start: 数列起始值
  • end : 数列结束值
  • steps: 数列长度
  • base : 对数函数的底,默认为10
1
2
3
4
import torch
import numpy as np

print(torch.logspace(1, 10, 4))
1
tensor([1.0000e+01, 1.0000e+04, 1.0000e+07, 1.0000e+10])
1
2
3
4
5
import torch
import numpy as np

t = torch.logspace(1, 10, 4, 2)
print(t)
1
tensor([   2.,   16.,  128., 1024.])

其实就是一个指数等比数列,logspace对数均分的意思是,取了对数以后是均分

1
2
3
4
5
6
import torch
import numpy as np
torch.manual_seed(1)

t = torch.logspace(1, 10, 4, 2)
print(np.log2(t))
1
tensor([ 1.,  4.,  7., 10.])

2.2.10 通过torch.eye创建单位对角矩阵

1
2
3
4
5
6
7
torch.eye(n, 
m=None,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False) → Tensor

功能:创建单位对角矩阵( 2维张量)

注意事项:默认为方阵

  • n: 矩阵行数
  • m : 矩阵列数

2.3 依概率分布创建张量

2.3.1 通过torch.normal创建正态分布张量

1
2
3
4
5
torch.normal(mean, 
std,
*,
generator=None,
out=None) → Tensor

功能:生成正态分布(高斯分布)

  • mean : 均值
  • std : 标准差
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import torch
import numpy as np
torch.manual_seed(1)

# mean:张量 std: 张量
mean = torch.arange(1, 5, dtype=torch.float)
std = torch.arange(1, 5, dtype=torch.float)
t_normal = torch.normal(mean, std)
print("mean:{}\nstd:{}".format(mean, std))
print(t_normal, "\n")

# mean:标量 std: 标量
t_normal = torch.normal(0., 1., size=(4,))
print(t_normal, "\n")

# mean:张量 std: 标量
mean = torch.arange(1, 5, dtype=torch.float)
std = 1
t_normal = torch.normal(mean, std)
print("mean:{}\nstd:{}".format(mean, std))
print(t_normal)
mean:tensor([1., 2., 3., 4.])
std:tensor([1., 2., 3., 4.])
tensor([1.6614, 2.5338, 3.1850, 6.4853])

tensor([-0.4519, -0.1661, -1.5228,  0.3817])

mean:tensor([1., 2., 3., 4.])
std:1
tensor([-0.0276,  1.4369,  2.1077,  3.9417])

2.3.2 通过torch.randn创建标准正态分布张量

1
2
3
4
5
6
torch.randn(*size, 
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False) → Tensor
1
2
import torch
print(torch.randn((3, 3)))
1
2
3
tensor([[-0.1955, -0.9656,  0.4224],
[ 0.2673, -0.4212, -0.5107],
[-1.5727, -0.1232, 3.5870]])

2.3.3 通过torch.randn_like创建标准正态分布张量

1
2
3
4
5
6
torch.randn_like(input, 
dtype=None,
layout=None,
device=None,
requires_grad=False,
memory_format=torch.preserve_format) → Tensor
1
2
3
4
import torch
import numpy as np

print(torch.randn_like(torch.tensor(np.ones((3, 3)))))
1
2
3
tensor([[-1.8313,  1.5987, -1.2770],
[ 0.3255, -0.4791, 1.3790],
[ 2.5286, 0.4107, -0.9880]], dtype=torch.float64)

参数input必须是tensor类型,不能是其他类型,比如ndarray

2.3.4 通过 torch.rand创建均匀分布张量

1
2
3
4
5
6
torch.rand(*size, 
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False) → Tensor

功能:在区间[0, 1)上,生成均匀分布

1
2
3
import torch

print(torch.rand((3, 3)))
1
2
3
tensor([[0.9391, 0.4167, 0.7140],
[0.2676, 0.9906, 0.2885],
[0.8750, 0.5059, 0.2366]])

2.3.5 通过 torch.rand_like创建均匀分布张量

1
2
3
4
5
6
torch.rand_like(input, 
dtype=None,
layout=None,
device=None,
requires_grad=False,
memory_format=torch.preserve_format) → Tensor

功能:在区间[0, 1)上,生成均匀分布

2.3.6 通过 torch.randint创建均匀分布张量

1
2
3
4
5
6
7
8
torch.randint(low=0,
high,
size,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False)

功能:区间[low, high)生成整数均匀分布

1
2
import torch
print(torch.randint(0, 9, (3,)))
1
tensor([6, 0, 6])
1
2
import torch
print(torch.randint(0, 9, (3, 3)))
1
2
3
tensor([[2, 4, 3],
[3, 4, 6],
[0, 7, 5]])

2.3.7 通过 torch.randint_like创建均匀分布张量

1
2
3
4
5
6
7
8
torch.randint_like(input, 
low=0,
high,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False,
memory_format=torch.preserve_format) → Tensor

功能:区间[low, high)生成整数均匀分布

1
2
3
4
5
import torch
import numpy as np

t = torch.randint_like(torch.tensor(np.ones((3, 3))), 0, 10)
print(t)
1
2
3
tensor([[5., 9., 4.],
[8., 3., 3.],
[1., 1., 9.]], dtype=torch.float64)

2.3.8 通过torch.randperm创建0到n-1的随机排列张量

1
2
3
4
5
6
torch.randperm(n, 
out=None,
dtype=torch.int64,
layout=torch.strided,
device=None,
requires_grad=False) → LongTensor

功能:生成生成从0到n-1的随机排列

  • n : 张量的长度
1
2
import torch
print(torch.randperm(4))
1
tensor([1, 2, 3, 0])
1
2
import torch
print(torch.randperm(8))
1
tensor([3, 6, 4, 5, 2, 7, 0, 1])

2.3.9 通过torch.bernoulli创建0到n-1的随机排列张量

1
2
3
4
torch.bernoulli(input,
*,
generator=None,
out=None)→ Tensor

功能:以input为概率,生成伯努力分布 (0-1分布,两点分布)

  • input : 概率值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>> a = torch.empty(3, 3).uniform_(0, 1)  # generate a uniform random matrix with range [0, 1]
>>> a
tensor([[ 0.1737, 0.0950, 0.3609],
[ 0.7148, 0.0289, 0.2676],
[ 0.9456, 0.8937, 0.7202]])
>>> torch.bernoulli(a)
tensor([[ 1., 0., 0.],
[ 0., 0., 0.],
[ 1., 1., 1.]])

>>> a = torch.ones(3, 3) # probability of drawing "1" is 1
>>> torch.bernoulli(a)
tensor([[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]])
>>> a = torch.zeros(3, 3) # probability of drawing "1" is 0
>>> torch.bernoulli(a)
tensor([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])