概念: Pytorch 或者 Tensorflow 中的 T e n s o r Tensor Tensor 类型(张量),可以理解成是数学中的 n n n 维数组,与 NumPy 中的 n d a r r a y ndarray ndarray 类型类似。
区别是:
张量表示由一个数值组成的数组,这个数组可能有多个维度。具有一个轴的张量对应数学上的向量( v e c t o r vector vector); 具有两个轴的张量对应数学上的矩阵( m a t r i x matrix matrix); 具有两个轴以上的张量没有特殊的数学名称。
torch.arange
可以用来创建行向量,默认创建的是整数(也可以指定创建类型为浮点型)。
张量中的每个值都成为张量的元素( e l e m e n t element element)。除非额外指定,新的张量将存储在内存中,并采用基于CPU的计算。
代码:
# 导入pytorch
import torch
# 创建一个行向量x,向量中有12个元素(整数),元素是从0-11
x = torch.arange(12)
print(x)
# 输出:
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
# 查看张量中元素的个数
y = x.numel()
print(y)
# 输出:
12
要想改变一个张量的形状而不改变元素数量和元素值,可以调用reshape函数。
# 将向量x变成3行4列的张量z
z = x.reshape(3, 4)
print(z)
# 输出:
tensor([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
我们可以创建一个形状为(2,3,4)的张量,其中所有元素都设置为0。
注意:具有两个轴以上的张量没有特殊的数学名称
,就不用去解读2,3,4分别代表什么了,知道是这样的一个形状就可以。
# 使用zeros,表示该张量中的所有元素都为0(zero)
torch.zeros((2,3,4))
# 输出:
tensor([[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]]])
我们可以创建一个形状为(2,3,4)的张量,其中所有元素都设置为1。
# 使用ones,表示该张量中的所有元素都为1(one)
torch.ones((2,3,4))
# 输出:
tensor([[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]],
[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]]])
创建一个形状为(2,3,4)的张量。 其中的每个元素都从均值为0、标准差为1的标准高斯分布(正态分布)中随机采样。
torch.randn(2,3,4)
# 输出:
tensor([[[ 0.2409, -0.1582, 0.4382, -1.0087],
[-0.3676, 0.3038, -0.9411, 0.0746],
[ 1.7080, -0.7177, -0.4913, 0.7167]],
[[-0.2134, -0.3533, 0.0383, -1.6476],
[ 0.6329, -0.4788, -0.8633, -0.8998],
[ 1.6637, -1.3705, 0.6495, 0.0498]]])
使用torch.tensor()
手动创建张量,如:
torch.tensor([[2,3,4],[4,5,6],[7,8,9]])
# 输出:
tensor([[2, 3, 4],
[4, 5, 6],
[7, 8, 9]])
技巧: 可以根据[
的数量来判断是几维的张量,如:
# 1个[,1维张量
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
# 2个[,2维张量
tensor([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
# 3个[,3维张量
tensor([[[ 0.2409, -0.1582, 0.4382, -1.0087],
[-0.3676, 0.3038, -0.9411, 0.0746],
[ 1.7080, -0.7177, -0.4913, 0.7167]],
[[-0.2134, -0.3533, 0.0383, -1.6476],
[ 0.6329, -0.4788, -0.8633, -0.8998],
[ 1.6637, -1.3705, 0.6495, 0.0498]]])
在数学表示法中,用 f : R → R f: \mathbb{R} \rightarrow \mathbb{R} f:R→R 来表示一元标量运算符,意味着该函数从任何一个实数 R \mathbb{R} R 映射到了另一个实数 R \mathbb{R} R。
其中,
所以上式表示一个一元函数,而 f : R , R → R f: \mathbb{R}, \mathbb{R} \rightarrow \mathbb{R} f:R,R→R 则表示一个二元函数(即:有两个自变量,有一个因变量)。
注意: 张量的运算符,是指张量中,元素
与元素
之间的运算。
x = torch.tensor([1, 2, 4, 8])
y = torch.tensor([2, 3, 4, 5])
print(x+y)
# 输出:
tensor([ 3, 4, 8, 13])
#即: 3 = 1+2 第一个tensor中的
4 = 2+3
8 = 4+4
13= 8+5
广播机制:通过适当复制元素来扩展一个或两个数组,以便在转换之后,两个张量具有相同的形状(两个张量就可以进行运算了)。
a = torch.arange(3).reshape((3, 1)) # 创建一个3行1列的张量
b = torch.arange(2).reshape((1, 2)) # 创建一个1行2列的张量
print(a)
print(b)
print(a+b)
# 输出:
tensor([[0],
[1],
[2]])
tensor([[0, 1]])
tensor([[0, 1],
[1, 2],
[2, 3]])
理解: 一个是3行1列,一个是1行2列,二者没法直接进行运算。所以需要将3行1列的广播成3行2列,1行2列的广播成3行2列,即:2个张量维度相同时再进行运算。广播机制整个过程如下所示。
# 第一步:两个张量触发广播机制,进行转换
[0] [0, 0]
[1] => [1, 1] # 3行1列,变成3行2列
[2] [2, 2]
[0, 1]
[0, 1] => [0, 1] # 1行2列,变成3行2列
[0, 1]
# 第二步:两个张量进行运算
[0, 1] [0, 0] [0, 1]
[0, 1] + [1, 1] = [1, 2]
[0, 1] [2, 2] [2, 3]