TENSORS
Warm-up: numpy
手工计算梯度
PyTorch: Tensors
- pytorch可以使用GPU进行加速,50倍以上。
- pytorch-Tensor:n维数组,提供个各种操作,并且追踪计算图和梯度。
- h.clamp(min=0)。help(torch.clamp)对Tensor进行上下限的截断。
- h_relu.mm(w2)。 torch.mm与torch.matmul都是矩阵相乘的操作,但是mm不支持broadcast。
AUTOGRAD
PyTorch: Tensors and autograd
- 如果使用autograd,则在前向计算中会定义一个计算图,其中Tensor是节点,functions是边(输入、输出)。
- 只要定义x.requires_grad=True,就会产生另外一个Tensor(x.grad)来存储对应的梯度。
- autograd只需要定义前向计算就好,后面的是自动求导。
- 调用loss.backward()就开始自动求导了,但是没有实际进行更新。
- 在不必追踪梯度历史的时候,或者使用torch.no_grad,或者使用weight.grad.data。
PyTorch: Defining new autograd functions
- 继承torch.autograd.Function类,然后实现forward和backward函数。定义它的实例,进行调用。
- 感觉这个自定义autograd就是自定义graph中的layer。
- forward中可以使用save_for_backward对(backward需要的)中间变量进行存储。
TensorFlow: Static Graphs
- pytorch使用动态图,易用但是不易于优化(比如对图进行并行化的优化)。
- 动态图和静态图的区别是control flow,比如对于循环,tensorflow要把loop作为图的一部分,而对于pytorch,loop和图可以分离开
NN MODULE
PyTorch: nn
- autograd过于简陋,我们要使用nn。nn使得我们可以把计算流程抽象为一个具有多个层的图。
- nn中包含多个Modules,相当于neural network中的layers。nn还包含了loss functions。
- nn.Sequential可以对Modules进行顺序组合。
- 经典代码摘抄,注意torch.no_grad和model.parameters():
1 | with torch.no_grad(): |
PyTorch: optim
- 使用目的:可以使用多种优化器,并且简化对模型权重的更新步骤。(因为autograd只是自动计算了梯度,如果使用adam,还需要手动维护一阶矩和二阶矩)。
- 要将模型参数传递给optimizer。并且是使用optimizer.zero_grad()来清除历史梯度的。
PyTorch: Custom nn Modules
- 继承nn.Module,并且定义forward。(不再需要自定义backward)注意对于forward是有要求的,比如要返回一个Tensor。
PyTorch: Control Flow + Weight Sharing
- 这个应该是和前面的”TensorFlow: Static Graphs”相对应,我们可以直接将torch.Module和python的控制流结合起来,而不必将loop定义在图里面,这样就很灵活,比如可以随机loop的个数。
- Pytorch可以重复使用同一个Module,但是Lua Torch不可以。
- 这个例子还包含了权重共享(Weight Sharing
)的概念。