pytorch官方教程

疑问

  1. 官方说pytorch的高级功能:GPU加速的张量计算;自动求导系统(反向求导技术)。其实是相对于普通CPU网络说的,对于深度网络来说,这些东西可以忽略。
  2. pytorch是动态图,可以任意改变网络的行为,而且速度快。动态图和静态图有什么区别还是不清楚
  3. 在autograd一节中,介绍了标量函数的求导方式,但是对于向量形式的求导,目前还不清楚如何设置求导参数如何设置。

记录

1. 什么是PyTorch

  1. torch是和Numpy类似的科学计算包,但是因为是小众语言Lua写的,所以不太流行。Pytorch是在torch基础上做的工作,然后最上层使用python封装了,所以叫pytroch。因此,pytorch可以作为numpy的替代品,而且支持GPU加速。同时,它也支持深度学习。当然,我们更重视后者。
  2. pytorch最核心的是autograd包,它为张量的所有操作提供了自动求导机制。
  3. Module里面定义的是各种layers,都包含可学习的参数;forword()函数定义的是整个网络完整的结构。

pytroch api

torch

  • 创建tensor
  • tensor的dtype

pytorch 60min入门

1. pytorch入门

创建tensor
import torch
torch.empty(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False, pin_memory=False)
torch.rand(5, 3)
x = torch.zeros(5, 3, dtype=torch.long)
x = torch.tensor([5.5, 3]) # 会根据入参自动推断,如果是[1,2]则,dtype是torch.int64;正常dtype是torch.float32
x = x.new_ones(5, 3, dtype=torch.double)   
x = torch.randn_like(x, dtype=torch.float)   

里面的requires_grad参数默认都是False,在网络中,只有parameters是需要grad的。

获取tensor的信息
x = torch.tensor([1,2])
x.size() # 返回torch.Size([2])
x.numpy() # 获取numpy,底层numpy和tensor共享数据
operations

同一个操作有很多种方式。

  • torch.add(x, y)
  • x.add_(y) # 把y加到x上面
  • x.view() # 相当于tf的reshape,不过第一个参数还是*args 可变参数

可以看出torch和numpy的接口基本一致,而且两者共享底部数据

import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)
cuda tensor

不知道不同device上的数据相加,是如何处理的

if torch.cuda.is_available():
    device = torch.device("cuda")          # a CUDA device object,不进行编译,有没有cuda也可以执行,但是tensor.to(device)会失败
    y = torch.ones_like(x, device=device)  # directly create a tensor on GPU
    x = x.to(device)                       # or just use strings ``.to("cuda")``
    z = x + y
    print(z)
    print(z.to("cpu", torch.double))
输出如下:
tensor([0.5480], device='cuda:0')
tensor([0.5480], dtype=torch.float64)

2. AUTOGRAD

构建可求导tensor

torch.tensor(requires_grad=True)

创建了tensor,之后所有的operation产生的tensor,都会自带一个Function。
对tensor求grad,只需要调用out.backword(grad_variables)就可以了,但是grad_variables参数非常古怪,现在也不知道设置多少才合适?

detach求grad

两种方案:

  1. with torch.no_grad():
  2. x.detach()
  3. requires_grad_(False)

3. NEURAL NETWORKS

如何训练一个神经网络,下面的流程可以说是很清晰了:

  1. Define the neural network that has some learnable parameters (or weights)
class Net(nn.Module):
  def __init__(self):
    # define layers
  
  def forword(input):
    # define network
  1. Iterate over a dataset of inputs
  2. Process input through the network
net = Net()
output = net(input)
  1. Compute the loss (how far is the output from being correct)
    所有的loss也都存放在了torch.nn包里面,接收一个(output, target)pair,产生一个loss tensor
criterion = nn.MSELoss()
loss = criterion(output, target)
  1. Propagate gradients back into the network’s parameters
loss.backward()
  1. Update the weights of the network, typically using a simple update rule: weight = weight – learning_rate * gradient
optimizer = optim.SGD(net.parameters(), lr=0.01)
optimizer.zero_grad()   # zero the gradient buffers
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step()    # Does the update

tips

  • nn.Module. 神经网络模型,直接作为定义神经网络的父类。
  • torch.optim 这个包包含了所有的optim函数
  • net.parameters() 返回的是Parameter对象,如果想获取值,需要使用list(Parameters)

4. TRAINING A CLASSIFIER

前面定义网络,定义loss和optim的阶段省略了,只记录下面计算loss和更新参数的部分:

for epoch in range(2):  # loop over the dataset multiple times
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data
        # zero the parameter gradients
        optimizer.zero_grad()
        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0
print('Finished Training')

其中loss和optim的定义如下:

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

可以看出,loss不依赖参数;optim是参数以来的,它的目的是更新所有的parameter。

save model

torch.save(net.state_dict(), PATH)

load model

net = Net()
net.load_state_dict(torch.load(PATH))

predict

在进行predict的时候,需要把predict的代码放到with torch.no_grad():里面

training on GPU

不知道为什么,默认不是GPU,需要把两类数据送到目标device中:

  1. Net的parameters
  2. 数据集的data

https://www.jianshu.com/p/48d469ba39e7

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论