# numpy转tensor: torch.Tensor(trainDATA)
# torch.view()==reshape()
一、张量tensor
1.1 张量的建立
# 数据建议是列表
# 如果是numpy数组则会共享内存,即修改一个,另一个也跟着改变
x = torch.tensor([5.5, 3])
# 把张量放到gpu
x = torch.tensor([5.5, 3],device='cuda')
1.2 特殊张量
# 依概率(正态分布)分布创建张量,均值0,标准差1
#tensor([ 1.2927, -1.4295, -0.2051, -0.2933])
torch.normal(0, 1, size=(4,))
# 创建xxx个tensor组成的数组,范围[0,1)
torch.rand(xxx)
# [low,high)
torch.randint()
# tensor([[ 1.1118],
# [-0.9477],
# [-1.4819],
# [-0.2331]])
torch.normal(0, 1, size=(4,1))
# tensor([[-1.2685, 0.1898, -0.4371, -1.6179]])
torch.normal(0, 1, size=(1,4))
# 全零
torch.zeros((2,3))
# 全1
torch.ones(2)
# 自定义张量数值:全5,形状2*3
torch.full((2,3),5)
# 等差:起始(包含)、结束值(不包含)、公差(默认1)
torch.arange(2,12,2)
# 等差:初值(包含)、末值(包含)、元素的个数
torch.linspace(0,5,6)
# 单位矩阵,参数是矩阵行数
torch.eye(3)
二、张量操作
2.1 张量的拼接
a = torch.normal(0, 1, size=(2,3))
# tensor([[-0.1451, -0.1637, -1.0195],
# [ 0.7834, 0.0929, -1.4234]])
b = torch.normal(0, 1, size=(2,3))
# tensor([[ 0.3362, 0.6827, 0.6141],
# [ 0.4417, 0.4749, -0.8201]])
2.1.1 将张量按维度dim进行拼接,axis=0表示外轴、axis=1表示内轴
torch.cat([a,b],dim=0)
# tensor([[-0.1451, -0.1637, -1.0195],
# [ 0.7834, 0.0929, -1.4234],
# [ 0.3362, 0.6827, 0.6141],
# [ 0.4417, 0.4749, -0.8201]])
torch.cat([a,b],dim=1)
# tensor([[-0.1451, -0.1637, -1.0195, 0.3362, 0.6827, 0.6141],
# [ 0.7834, 0.0929, -1.4234, 0.4417, 0.4749, -0.8201]])
2.2.2 在新创建的维度dim上进行拼接
torch.stack(tensors,dim)
2.2 张量的切分
a = torch.ones((2,5))
# tensor([[1., 1., 1., 1., 1.],[1., 1., 1., 1., 1.]])
2.2.1 按dim平均切分
# 若不能整除则最后一份小于其他张量
# chunks: 切分的份数
a,b = torch.chunk(a,dim=0,chunks=2)
# (tensor([[1., 1., 1., 1., 1.]]),
# tensor([[1., 1., 1., 1., 1.]]))
a,b = torch.chunk(a,dim=1,chunks=2)
# (tensor([[1., 1., 1.],[1., 1., 1.]]),
# tensor([[1., 1.],[1., 1.]]))
2.2.2 指定每份多长
1、每份长度3
torch.split(a,3,dim=1)
#(tensor([[1., 1., 1.],[1., 1., 1.]]),
# tensor([[1., 1.],[1., 1.]]))
torch.split(a,1,dim=0)
# (tensor([[1., 1., 1., 1., 1.]]),
# tensor([[1., 1., 1., 1., 1.]]))
2、按list切分
# 第一个长2,第二个长1,第三个长2
torch.split(a,[2,1,2],dim=1)
# (tensor([[1., 1.],[1., 1.]]),
# tensor([[1.],[1.]]),
# tensor([[1., 1.],[1., 1.]]))
2.3 改变形状
torch.reshape(a,(-1,2)
三、计算某一张量的梯度torch.autograd.grad
# outputs:用于求导的张量(loss)
# inputs:需要梯度的张量(w、x):loss对w或x求导
# create_graph:创建导数计算图,用于高阶求导
# retain_graph:保存计算图
# grad_outputs:多梯度权重
torch.autograd.grad(outputs,inputs,grad_outputs=None,
retain_graph=None,create_graph=False)
'''注意点:
1、梯度不会自动清零
故通过w.grad取出张量的梯度,若不清零,下次求此梯度后会加上旧梯度
用w.grad.zero_()在每次求完梯度后清零
下划线表示in-place操作,即原位操作,如add_(1),zero_()
2、叶子结点父结点的requires_grad为True
3、叶子结点不能in-place(原位操作,即后面有下划线zero_)
'''
四、 detach
x = torch.tensor([10])
x = torch.tensor([10],requires_grad=True)
x.detach() # 将requires_grad设置为False,将不再计算此张量梯度
五、backward:loss.backward():
# loss对w和b求导
# grad_tensors:多个loss损失值时使用,表示不同损失值的权重
# retain_graph:保存计算图,反向传播后清除计算图,当需要连续两次及以上反向传播时使用
# create_graph:创建导数计算图,用于高阶求导
torch.backward(tensors,grad_tensors=None,
retain_graph=None,create_graph=False)
六、unsqueeze()和squeeze()
a = torch.ones(2,3)
# tensor([[1., 1., 1.],[1., 1., 1.]])
6.1 加一维
a.unsqueeze(0)
# torch.Size([1, 2, 3])
# tensor([[[1., 1., 1.],[1., 1., 1.]]])
a.unsqueeze(1)
# torch.Size([2, 1, 3])
# tensor([[[1., 1., 1.]],[[1., 1., 1.]]])
6.2 把维度为1的去掉
a.unsqueeze(0).squeeze()
# 也可以指定第几维,默认维数为1的那一维
a.unsqueeze(0).squeeze(0)
# [1, 2, 3] -> [2, 3]),去掉第0维的1
a.unsqueeze(1).squeeze()
# [2, 1, 3] -> [2, 3],去掉第1维的1