张量对象

张量(Tensor)是一种特殊结构,出于并行计算的需要设计,可在GPU等硬件加速器上运行。类似于数组和矩阵,用于对模型的输入输出,模型参数进行编码。
Pytorch中的Tensor类似于Numpy中的ndarray,二者可相互转换,且共享底层内存,可理解为同一数据引用的不同表现形式。修改其中之一会同时修改另一方。

张量初始化

可由现有数据对象创建张量,或根据维度创建:

data = [[1, 2],[3, 4]]
x_data = torch.tensor(data)  # 从list转换得到张量,数据类型自动推断

np_array = np.array(data)
x_np = torch.from_numpy(np_array)  # 从Numpy ndarray转换得到张量
x = x_np.numpy()                   # 从张量转换得到Numpy ndarray

# 从现有张量创建张量,会默认继承张量属性(shape, dtype)
x_ones = torch.ones_like(x_data) 
x_rand = torch.rand_like(x_data, dtype=torch.float) 

# 由给定维度创建张量
shape = (2,3,)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)

张量属性

主要属性为shape,dtype和device
shape描述张量的维度
dtype描述张量的数据类型
device描述张量的存储位置

张量操作

张量默认创建在CPU上,如需在GPU上操作计算,需要显式地调用.to方法:

if torch.cuda.is_available():
    tensor = tensor.to('cuda')

所有的张量操作都可在GPU上执行,通常速度大大快于在CPU上执行。

索引切片操作

tensor = torch.ones(4, 4)
tensor[0]          # 第一行
tensor[:, 0]       # 第一列
tensor[..., -1]    # 最后一列

矩阵操作

# 张量拼接,dim为拼接的维度,在该维度增加的方向拼接张量
torch.cat([tensor, tensor, tensor], dim=1)  # cat()同concat()
# 张量拆分,dim为拆分的维度,注意最后一块可能大小不一致
torch.chunk(tensor, 3,dim=0)
# 张量转置,将对应两个维度调换
torch.transpose(tensor, 0, 1)
# 张量条件判定,返回选择后元素组成的张量
torch.where(x > 0, x, y)  # x,y须为可广播类型
# 张量元素选择,输入张量视为一维张量索引,返回张量与输入索引shape相同
torch.take(tensor, [0, 2, 5])
# 张量压缩,将大小为1的维度移除(返回张量与原张量共享内存)
torch.squeeze(tensor)
# 张量重塑,当输入shape的某一维为-1时,表示该维度由剩余元素推断得出
torch.reshape(tensor, (2, -1))
# 张量重排,返回张量重排后的视图
torch.permute(tensor, (2, 0 ,1))
# 张量压平,张量压平成一维
torch.flatten(tensor, start_dim=0, end_dim=-1)

算术操作

# 矩阵乘法,最终结果y1=y2=y3
y1 = tensor @ tensor.T
y2 = tensor.matmul(tensor.T)
y3 = torch.rand_like(tensor)
torch.matmul(tensor, tensor.T, out=y3)
# 矩阵点积,最终结果y1=y2=y3
z1 = tensor * tensor
z2 = tensor.mul(tensor)
z3 = torch.rand_like(tensor)
torch.mul(tensor, tensor, out=z3)
# 向下取整
torch.floor(tensor)
# 向上取整
torch.round(tensor)
# 求和
agg = tensor.sum()
agg_item = agg.item()  # 单元素张量转换为Python数值对象
# 求最大值的索引
torch.argmax(tensor)
# 求最大值的值
torch.max(tensor)
# 判断张量相等
torch.equal(tensor1, tensor2)