一、tensor的创建

  1. 初始化一个随机的tensor,数值可能很大,也可能很小
= torch.empty(5, 3)
  1. 利用​​random​​初始化tensor
= torch.rand(5, 3) 
x = torch.randint(size=[3,4], low=0, high=3) # 数值位于[0, 3)的整数
x = torch.randn(2, 3) # 满足正态分布的 2*3 的 tensor
y = torch.rand_like(x) # 生成维度与x相同的tensor
  1. 初始化一个类型为long的全零tensor
= torch.zeros(5, 3, dtype=torch.long) 
x = torch.zeros(5, 3).long()
  1. 生成全1的tensor
= torch.ones(3, 4)
x = torch.ones(2, 3, 4)
x = torch.ones(3, 4, dtype=int64) # 同时也可指定数据类型
  1. 根据数据构造tensor,这些方法会重用原来tensor的特征,例如数据类型,除非提供新的数据类型
= torch.tensor([5.5, 3])  # 根据数据构造tensor
y = x.new_ones(2, 3) # y.type沿用上面的数据类型,为torch.FloatTensor
z = x.new_ones(2, 3, dtype = torch.int32) # 指定新的数据类型
  1. 查看tensor的形状
print(x.shape)
print(x.shape[0]) # 返回第0维的大小
print(x.size())
print(x.size(0)) # 返回第0维的大小
  1. 获取维度
.dim()  # 返回 int
  1. 查看tensor的数据类型
  • tensor的数据类型包括:torch.float64,torch.float32,torch.int64,torch.int32,torch.int16
print(x.type())
  • 转换tensor的数据类型
= x.type(torch.float64)  # y的数据与x相同,数据类型为float64
  1. ​torch.Tensor()​​​和​​torch.tensor()​​区别
  • torch.Tensor()是Python类,是默认张量类型​​torch.FloatTensor()​​​的别名。参数没有​​[]​​​时​​接收维度​​​作为参数生成张量,参数有​​[]​​​时​​接收数据​​作为参数生成张量
>>> a=torch.Tensor([3,2])  # 生成数据为3,2的tensor
>>> a
tensor([3., 2.])

>>> a.type()
'torch.FloatTensor'

>>> b=torch.Tensor(3,2) # 生成3行2列的tensor
>>> b
tensor([[0.0000e+00, 0.0000e+00],
[2.8026e-45, 0.0000e+00],
[1.4013e-45, 0.0000e+00]])
  • torch.tensor()的函数原型如下(直接​​接收数据​​作为参数生成张量):
torch.tensor(data, dtype=None, device=None, requires_grad=False)

其中​​data​​可以是:list,tuple,ndarray,Python scalars等类型

torch.tensor()可以从data中的数据部分做拷贝(而不是直接引用),根据原始数据类型生成相应的​​torch.LongTensor​​​,​​torch.FloatTensor​​​,​​torch.DoubleTensor​​。

>>> a = torch.tensor([1, 2])
>>> a.type()
'torch.LongTensor'
>>> a = torch.tensor([1., 2.])
>>> a.type()
'torch.FloatTensor'
>>> a = np.zeros(2, dtype=np.float64)
>>> a = torch.tensor(a)
>>> a.type()
'torch.DoubleTensor'

Reference: 【PyTorch】Tensor和tensor的区别

二、tensor的运算

  1. 对应元素相加
= torch.ones([5, 3])  # 初始化一个随机的tensor
y = torch.rand([5, 3]) # 初始化一个数字位于(0,1)的随机tensor
print(torch.add(x, y)) # 等价于x + y
res = torch.empty([5, 3])
torch.add(x, y, out = res) # 也就等价于res = x + y

in-place 操作

任何在原地改变张量的操作都有一个 ​​_​​​ 后缀。例如​​x.copy_(y​​​), ​​x.t_()​​操作将改变x

.add_(x)  # 等价于 y += x
  1. 广播
+ 3  # x的每个元素都加3
  1. 其他相关操作
.mean()  # 求x所有元素的均值
x.sum() # 求x所有元素的和
x.max() # 获取最大值
x.min() # 获取最小值
x.transpose(0, 1) # 交换0维和1维的数据
x = x.permute(2,0,1) # 将原本0,1,2的顺序改为2,0,1
x.t() # 转置,无参方法,只能对一维和二维tensor进行转置
x.T # 转置

三、tensor的索引

可以使用所有的numpy索引操作

[:, 1:]  # 留下所有的行,从第一列往后取
x[1:, 1:] # 从第一行以及第一列往后取

resize操作

用于重塑张量的形状,使用 ​​torch.view​​。相当于把tensor拉成一长条,然后根据所给的维度进行重塑

= torch.randn([4, 4])
y = x.view([16])
z = x.view([-1, 8]) # -1的意思是不指定维度,计算机自行计算
print(x.size(), y.size(), z.size())

pytorch入门笔记_数据


当tensor为1*1时,可以用 ​​item()​​ 方法转成 python数值

= torch.rand(1)
x = x.item() # 此时x就是一个数值

关关于更多转置,索引,数学运算等操作参考:​​click​

四、Torch张量与numpy数组相互转换

相互转换的tensor和ndarray ​​共享内存空间​​,改变其中一个,另一个也改变

  1. 根据tensor创建ndarray
= torch.ones(5)  # 创建全 1 tensor
b = a.numpy() # 根据tensor构造numpy,此时a和b共享内存空间
a[0] = 100 # 改变 a,b也会跟着改变
print(b) # [100. 1. 1. 1. 1.]
  1. 根据ndarray创建tensor
= np.ones(5)
b = torch.from_numpy(a) # 直接强制类型转换torch.tensor(a)
np.add(a, 1, out=a) # 等价于 a += 1,a内所有的值加1
print(a)
print(b)

pytorch入门笔记_数据类型_02

五、张量的自动微分

  1. tensor的数据结构
  2. pytorch入门笔记_数据_03

  • ​data​​: 表示tensor的数据值
  • ​grad​​:保存了data的梯度,与data形状一致
  • ​grad_fn​​:指向Function对象,用于反向传播的梯度计算之用
= torch.ones([2, 2], requires_grad=True)
y = x + 2
print(y.data)
print(y.grad_fn)

pytorch入门笔记_数据类型_04


2. 反向传播求梯度

= torch.ones([2, 2], requires_grad=True)
y = x + 2
z = y ** 2 + 3
out = z.mean() # 到达输出层
out.backward() # 输出对输入求梯度,将梯度保存在输入的grad属性
print(x.grad)

最终会将输出对输入的梯度保存在输入的 ​​grad​​ 属性

pytorch入门笔记_数据类型_05


然而我们要是查看输出值对中间的某个变量的梯度,就会报错

pytorch入门笔记_数据类型_06


他说 正在访问非叶子Tensor的Tensor的属性,意思就是 ​​grad​​ 属性在非叶tensor上是不能访问的

  1. 不跟踪计算过程

包含在 ​​with torch.no_grad()​​ 上下文中时,计算不会被跟踪

with torch.no_grad():
is_trace = (x + 1).requires_grad # 返回False

​detach()​​ 方法也可以获得tensor不包含梯度的值

pytorch入门笔记_初始化_07


4. 改为跟踪计算过程

​requires_grad_(bool)​​​ 方法原地改变tensor 的 ​​requires_grad​​ 属性

pytorch入门笔记_数据_08

使用GPU运算

​cuda​​ 是NVIDIA推出的运算平台

可以使用 ​​to()​​ 方法将张量移动到别的设备上

if torch.cuda.is_available():
device = torch.device("cuda") # 获取GPU
y = torch.ones_like(x, device=device) # 利用GPU运算
x = x.to(device) # 将tensor搬到GPU上计算
z = x + y
print(z)
print(z.to("cpu", torch.double)) # 重新搬回CPU上运算,由于numpy的ndarray只能在cpu上运算