1.Tensor张量
张量是一种特殊的数据结构,非常类似于数组和矩阵。在PyTorch中,我们使用张量来编码模型的输入和输出,以及模型的参数。
张量类似于NumPy的ndarrays,只是张量可以运行在GPU或其他硬件加速器上。
import torch
import numpy as np
# tensor可以直接通过普通数据 由torch.tensor()函数产生
# 方式1:原数据为列表
data = [[1, 2],[3, 4]]
# x_data 即是tensor类型的数据
x_data = torch.tensor(data)
# 方式2:原数据为Numpy数组 由torch.from_numpy()函数产生
np_array = np.array(data)
x_np = torch.from_numpy(np_array)
# 其他方式:通过torch自带的函数 新张量保留原张量的属性(形状、数据类型),除非被显式覆盖。
x_ones = torch.ones_like(x_data) # retains the properties of x_data
print(f"Ones Tensor: \n {x_ones} \n")
# 原来数据为torch.int型,现在改为float。注意,是torch.float。torch.int指张量中数据的类型是整型,区别于普通的一个整型的变量 int i=1
x_rand = torch.rand_like(x_data, dtype=torch.float)
print(f"Random Tensor: \n {x_rand} \n")
如果想要指定生成tensor的形状,可以做如下操作:
# 指明形状shape为2行3列
shape = (2,3,)
rand_tensor = torch.rand(shape) # 随机数在0-1之间
ones_tensor = torch.ones(shape) # 全是1
zeros_tensor = torch.zeros(shape) # 全是0
print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")
如果想要访问Tensor的形状、数据类型、以及所存在的设备,可以使用属性 tensor.shape, tensor.dtype, tensor.device。注意,属性是没有括号的,区别于tensor内部的函数,错误用法:tensor.shape()
tensor = torch.rand((3,4)) # 建立3行4列的随机数tensor , 也可以直接torch.rand(3,4)
print(f"Shape of tensor: {tensor.shape}") # 输出tensor的形状(几行几列)
print(f"Datatype of tensor: {tensor.dtype}") # 输出tensor中的数据类型
print(f"Device tensor is stored on: {tensor.device}") # 输出所采设备
默认情况下,张量是在CPU上创建的。我们需要使用 .to 方法(在检查GPU可用性之后)。请记住,从时间和内存的角度来看,跨设备复制大型张量是非常昂贵的!如果你的pytorch安装的是CPU版本,则无法将数据搬运到GPU上进行运算(pytorch对应GPU的版本叫cuda,所以代码中的cuda代表的就是GPU的意思。)
# We move our tensor to the GPU if available if torch.cuda.is_available(): tensor = tensor.to("cuda")
1.1 tensor的索引和切片操作(和numpy几乎一样):
# 从1-16产生16个整数
array = np.linspace(1,16,16,dtype=int)
print(array)
# 将array转换为 4行4列
array = np.resize(array, (4,4))
print(array)
# 利用torch.from_numpy()方法将array装换为4行4列的tensor
x_array = torch.from_numpy(array)
print(x_array)
# 这样就有了一个4行4列的tensor,下面可以进行索引和切片(注意,与c语言一样,下标从0开始):
print(f"第一行: {x_array[0]}")
print(f"第一列: {x_array[:, 0]}") # :号表示所有行,
print(f"第三行第四列的元素: {x_array[2,3]}")
print(f"最后一列: {x_array[:, -1]}")
# 把第二列所有元素置0
x_array[:,1] = 0
print(x_array)
1.2 tensor的拼接
使用 torch.cat()实现多个tensor之间的拼接,需要指定拼接的维度,即横向拼接还是纵向拼接还是深度拼接。下面的测试代码任然使用上面的x_array ,4x4的tensor。
# 第一个参数是 由要拼接的多个tensor组成的元组或列表,地位个参数是拼接的维度
t0 = torch.cat((x_array,x_array,x_array), dim=0) # dim=0纵向拼接
print(f"t0:\n{t0}")
t1 = torch.cat((x_array,x_array,x_array), dim=1) # dim=1横向拼接
print(f"t1:\n{t1}")
1.3 tensor的算术运算
data = [[1,2],[3,4]]
y1 = torch.tensor(data)
print(f"y1\n: {y1}")
y2 = y1.T # y2是y1的转置 .T实现转置
print(f"y2\n: {y2}")
y3 = torch.matmul(y1,y2) # 实现矩阵乘法
print(f"y3\n: {y3}")
# 实现矩阵点乘,对应位置元素相乘
z1 = y1*y2
z2 = torch.mul(y1,y2) # 这两种方式作用一样
print(f"z1\n: {z1}")
print(f"z2\n: {z2}")
# tensor元素求和 求和后的数据类型仍为tensor
y1_sum = torch.sum(y1)
print(y1_sum, y1_sum.dtype) # tensor(10):和为10 dtype=torch.int64
# 如果想要将tensor(10)转换为普通的10,可以使用 .item()方法。但是item()方