学习教程:《动手学深度学习 PYTORCH 版(DEMO)》
首先导入pytorch
import torch利用torch.empty()函数创建一个未被初始化的张量
x = torch.empty(5, 3, dtype=torch.float, device=GPU, requires_grad=Ture ) # dtype:数据类型,device:cpu还是gpu,requires_grad:是否要追踪梯度 print (x)输出: 创建张量还有torch.ones() torch.rand()等很多不同的函数。 通过shape 来获取张量的形状
print(x.shape) #输出:torch.Size([5, 3])常用创建tensor的函数
函数功能Tensor(*sizes)基础构造函数tensor(data,)类似np.array的构造函数ones(*sizes)全1Tensorzeros(*sizes)全0Tensoreye(*sizes)对⻆角线为1,其他为0arange(s,e,step)从s到e,步⻓长为stepinspace(s,e,steps)从s到e,均匀切分成steps份rand/randn(*sizes)均匀/标准分布normal(mean,std)/uniform(from,to)正态分布/均匀分布randperm(m)随机排列用view()改变tensor的形状
y = x.view(15) z = x.view(-1, 5) # -1所指的维度可以根据其他维度的值推出来 print(x.size(), y.size(), z.size()) # 输出:torch.Size([5, 3]) torch.Size([15]) torch.Size([3, 5]) # 注意:更改其中的一个,另外一个也会跟着改变。(顾名思义,view仅仅是改变了了对这个张量量的观察⻆角度)Pytorch还提供了了⼀一个reshape() 可 以 改 变 形 状 , 但 是 此 函 数 并 不不 能 保 证 返 回 的 是 其 拷 ⻉贝 , 所 以 不 推 荐 使 用 。 推 荐 先⽤用clone创造一个副本然后再使⽤view。
x_cp = x.clone().view(15) x -= 1 print(x) print(x_cp) # 输出: # tensor([[ 0.6035, 0.8110, -0.0451], # [ 0.8797, 1.0482, -0.0445], # [-0.7229, 2.8663, -0.5655], # [ 0.1604, -0.0254, 1.0739], # [ 2.2628, -0.9175, -0.2251]]) # tensor([1.6035, 1.8110, 0.9549, 1.8797, 2.0482, 0.9555, 0.2771,3.8663, 0.4345, 1.1604, 0.9746, 2.0739, 3.2628, 0.0825, 0.7749])使⽤用clone还有⼀一个好处是会被记录在计算图中,即梯度回传到副本时也会传到源Tensor。
常用函数直接上图:
用方法to()可以将Tensor在CPU和GPU(需要硬件⽀支持)之间相互移动。
# 以下代码只有在PyTorch GPU版本上才会执行 iftorch.cuda.is_available():device = torch.device("cuda") #GPU GPUy = torch.ones_like(x, device=device) # 直接创建⼀一个在GPU上的 Tensorx = x.to(device) # 等价于 .to("cuda") z = x+yprint(z)print(z.to("cpu", torch.double)) # to()还可以同时更更改数据类型如果将.requires_grad设 置 为True,计算机将自动追踪在这个tensor上的所有操作。完成计算后可用.backward()完成梯度计算,这个tensor的梯度将积累在.grad属性中。 在y.backward()时,如果y是标量,则不需要为backward()传入任何参数;否则,需要传入一个与y同型的tensor。
## 自动求梯度 x = torch.rand(2, 2, requires_grad=True) #开启自动求梯度 print(x) print(x.grad_fn) # 指向Function对象(用于反向传播),在这x没有对象 y = x + 2 print('y = ',y) print('y.grad_fn = ',y.grad_fn) print(x.is_leaf, y.is_leaf) # x和y是否是叶子节点 z = y * y * 3 out = z.mean() print(z, out) out.backward() # 等价于 out.backward(torch.tensor(1.))。用backward完成梯度计算 print(x.grad) 注意:每次反向传播都会累加之前的梯度,一般在反向传播之前把梯度清零 注意:在x.backward()时,如果y是张量,backward需要传入一个与y同型的参数 例: x = torch.tensor([1, 2, 3, 4], requires_grad = True, dtype=torch.float64) y = 2 * x z = y.view(2, 2) v = torch.tensor([[1, 0.1],[0.01, 0.001]], dtype=torch.float64) z.backward(v) print(x.grad) # 注意x.grad是一个与x同型的张量输出: