scalar vector matrix tensor(维度是无限的)
tensor参数:
dtype,device,requires_grad,pin_memory(拿空间换时间)
import torch #创建tensor,dtype指定类型(强制转换) a=torch.tensor(1,dtype=torch.long) #使用指定类型函数随机初始化指定大小的Tensor d=torch.FloatTensor(2,3) e=torch.IntTensor(2) f=torch.IntTensor([1,2,3,4])#对于列表转成Tensor #numpy转Tensor torch.tensor(g) torch.from_numpy(g) #Tensor转numpy h.numpy() #构造Tensor函数(参数是大小) k=torch.rand(2,3) l=torch.ones(2,3) m=torch.zeros(2,3) n=torch.arange(0,10,2)#左闭右开 #查看维度信息,注意括号 k.shape k.size() #Tensor的运算,对应元素相加 o=torch.add(k,l) #索引与numpy类似 o[:,1] #改变Tensor形状函数view o.view(3,2) o.view(-1,2)#-1自动填补 #Tensor广播机制,维度不一样,运算时自动配齐 p=torch.arange(1,3).view(1,2) q=torch.arange(1,4).view(3,1) p+q #>>3行2列 #Tensor维数扩展 unsqueeze #Tensor维数压缩 squeeze ,只能删掉维数是1的Tensor,若不是就保持原样 r=o.unsqueeze(1) r.squeeze(0)#不变 r.squeeze(1)2.2自动求导
雅克比矩阵:向量求导向量是矩阵 + 链式法则
动态计算图(DCG)
import torch x1 = torch.tensor(1.0,requires_grad=True) x2 = torch.tensor(2.0,requires_grad=True) y= x1 + 2*x2 y.backward() #查看导数的值 x1.grad.data #导数会累积,再做梯度回传,梯度会相加,每次计算前要清零导数值 #若x1 = torch.tensor(1.0,requires_grad=False),x2 = torch.tensor(2.0,requires_grad=False) #那y.backward()会报错,不能自动去求导,反向传播不能完成2.3并行计算 基础知识补充
pytorch补充函数clone(),copy(),detach()
clone()与copy()的用法是一样的,只是写法不同
创建一个tensor与源tensor有相同的shape,dtype和device,不共享内存地址,但新tensor的梯度会叠加在源tensor上。下面例子可以说明上述特点:
import torch a = torch.tensor([1.,2.,3.],requires_grad=True) b = a.clone() print(a.data_ptr()) # 3004830353216 print(b.data_ptr()) # 3004830353344 内存地址不同 print(a) # tensor([1., 2., 3.], requires_grad=True) print(b) # tensor([1., 2., 3.], grad_fn=) 复制成功 print('-'*30) c = a * 2 d = b * 3 c.sum().backward() print(a.grad) # tensor([2., 2., 2.]) d.sum().backward() print(a.grad) # tensor([5., 5., 5.]) # 源tensor的梯度叠加了新tensor的梯度 print(b.grad) # None # 此时复制出来的节点已经不属于叶子节点,因此不能直接得到其梯度
需要注意的是,b = a.clone()之后,b并非叶子节点(最后输出b的梯度时warning会提醒我们)。b节点更像是a经过一个恒等函数之后得到的输出。
a = torch.tensor([1., 2., 3.],requires_grad=True) b = torch.empty_like(a).copy_(a)
detach()函数返回与调用对象tensor相关的一个tensor,此新tensor与源tensor共享数据内存(那么tensor的数据必然是相同的),但其requires_grad为False,并且不包含源tensor的计算图信息。当定义两个网络A、B时,把A的输出给B,只改变B的参数,不改变A的参数。
a = A(input) a = a.deatch() # 或者a.detach_()进行in_place操作 out = B(a) loss = criterion(out, labels) loss.backward()



