【Pytorch】张量
张量(Tensor):
张量是一个 n 维数组,是 Pytorch 中经常用到的一个数据类型,我们可以这样理解:一维张量等同于向量,二维张量等同于矩阵。
创建张量:
空张量:
x = torch.empty(size)
全0张量:
# 创建一个指定形状的全0张量:
x = torch.zeros(size)
# 创建一个形状与给定张量相等的全0张量:
x = torch.zeros_like(a)
全1张量:
# 创建一个指定形状的全1张量:
x = torch.ones(size)
# 创建一个形状与给定张量相等的全1张量:
x = torch.ones_like(a)
随机数张量:
均匀分布随机:
从区间 [0,1) 的均匀随机分布中抽取一组随机数:
x = torch.rand(size)
标准正态分布随机:
从标准正态分布(均值为0,方差为1,即高斯白噪声)中抽取一组随机数:
x = torch.randn(size)
现有列表或 ndarray 数组转为张量:
# 假设 a 为现有列表或 ndarray 数组
x = torch.tensor(a)
等差张量:
x = torch.range(start,end,step)
# 输出以 start 为起始值、end 为终止值、步长为 step 的等差数组
x = torch.arange(start=0,end,step)
# 输出以 start 为起始值、end 为终止值、步长为 step 的等差数组(不包括 end)
torch.range 与 torch.arange 的区别:
torch.range:数据类型为 torch.float32,且包括终止值 end
torch.arange:数据类型为 torch.int64,且不包括终止值 end
布尔张量:
布尔张量用于判断多个形状相同的张量对应位置元素之间的大小关系,例如:
x = torch.tensor([1,2,3])
y = torch.tensor([3,2,1])
z = x == y
# z = tensor([False,True,False])
同理,其他关系运算符(<、>、<=、>=、==、!=)均可用于创建布尔张量。
张量属性:
查看/获取张量形状和元素总数:
# 张量形状(以下两种方法等效):
TensorSize = x.szie()
Tensorsize = x.shape
# 张量中元素总数:
TensorNum = x.numel()
修改张量大小:
# 以下两种方法等效:
x = x.reshape(size)
x = x.view(size)
举例:
x = torch.tensor([1,2,3,4])
# x = tensor([1,2,3,4])
y = x.reshape(2,-1)
# y = tensor([[1,2],[3,4]])
z = x.view(-1,2)
# z = tensor([[1,2],[3,4]])
其中,-1为根据size中其他数据自动计算补全的大小。
张量索引与切片:
张量中第一个元素索引为0,最后一个元素索引为-1,同一为维度下范围用 : 分开(不包括结尾值),不同维度间用 , 隔开;同维度间不指定索引即为 从一个元素开始 或 到最后一个元素结尾。
例:
# 利用切片调取张量片段:
y = x[:,:] # 相当于对 x 进行了一次复制
# 利用索引改变张量元素:
x[:,:] = 0 # 相当于把 x 变成了全 0 张量
切片常用于节省内存开销,例如:
# 已知张量 x
a = id(x)
x = x + 1
b = id(x)
我们会发现 x 运算前后在计算机中储存的位置是不同的,当迭代次数过多时,这样会增加内存开销,于是我们可以利用以下方式来保证同名称的张量内存地址不变:
# 以下两种方法等效
x[:] = x + 1 # 切片法
x += 1 # 自增法
赋值与克隆:
我们有以下两种方式来创建一个与已知张量 x 完全相同的张量:
y = x
z = x.clone()
它们的区别在于:y 与 x 共用内存空间,改变 y 的同时 x 也会随之改变;而 z 是一个完全独立于 x 的张量,对它进行的任何修改都不会影响 x 的数值
tensor格式转换:
tensor 转 ndarray:
x = torch.zeros(3)
x = x.numpy()
# x 的数据类型由 tensor 转换为 ndarray
ndarray 转 tensor:
x = np.zeros(3)
# 以下两种方法等效
y = torch.tensor(x)
y = torch.from_numpy(x)
# x 的数据类型由 ndarray 转换为 tensor
大小为1的 tensor 转张量:
x = torch.tensor(7)
a = x.item()
a = int(x)
a = float(x)
张量运算:
基本运算:
对于任意具有相同形状的张量,常见的标准算数运算符(+、-、*、/、**)都可以被升级为按元素运算:
z = x + y
z = x - y
z = x * y
z = x / y
z = x ** y
pytorch 也支持一些其他运算:
e x e^x ex:
y = x.exp()
y = torch.exp(x)
元素求和:
所有元素求和:
y = x.sum()
y = torch.sum(x)
元素按列求和:
y = x.sum(0)
y = torch.sum(x,dim=0,keepdim-False)
# keepdim = True 用于保证计算前后张量维数不变
元素按行求和:
y = x.sum(1)
y = torch.sum(x,dim=1)
前项累加和:
x = torch.tensor([0,1,2,3,4])
y = x.cumsum(0)
# y = [0,1,3,6,10]
# 沿0轴,每一项都是前面所有项的和
元素求均值:
注意:求均值时被求张量的数据类型应该为浮点型,否则会报错。
所有元素求均值:
y = x.mean()
y = torch.mean(x)
元素按列求均值:
y = x.mean(0)
y = torch.mean(x,dim=0,keepdim=False)
# keepdim = True 用于保证计算前后张量维数不变
元素按行求均值:
y = x.mean(1)
y = torch.mean(,,dim=1)
二维张量(矩阵)求转置:
y = x.T
张量扩增:
竖向扩增:
z = torch.cat((x,y),0)
# res → [x
# y]
横向扩增:
z = torch.cat((x,y),1)
# res → [x y]
广播机制:
在特定的情况下,我们可以利用广播机制对两个形状不同的张量进行运算,例如:
x = torch.tensor([1,2,3])
y = torch.tensor([[1],[2]])
z = x + y
# z = tensor([21,3,4],[3,4,5]])
# 原理:
# x [1,2,3] → [[1,2,3],
# [1,2,3]]
# y [[1], → [[1,1,1],
# [2]] [2,2,2]]