10 分钟理解 PyTorch 代码
来源:互联网 发布:淘宝论坛app官方下载 编辑:程序博客网 时间:2024/05/22 00:49
本文译自: Understand PyTorch code in 10 minutes
PyTorch 是一个新的深度学习框架. 本文的内容基于 Justin Johnson 的 教程, 如果想要有更多了解或有更多时间的话建议仔细研究一下.
PyTorch 主要包含 4 个包 (package):
torch
: 一个通用性的数组库, 与 Numpy 类似, 当 tensor 类型被转化(torch.cuda.TensorFloat)的时候可以在 GPU 上进行计算.torch.autograd
: 一个用来构建计算图来自动求梯度的包.torch.nn
: 一个包含常见 layer 和 cost function 的 神经网络库.torch.optim
: 包含像 SGD, Adam 这样常见优化算法的一个优化包.
导入工作
你可以像下面这样导入 PyTorch:
import torch # arrays on GPUimport torch.autograd as autograd #build a computational graphimport torch.nn as nn ## neural net libraryimport torch.nn.functional as F ## most non-linearities are hereimport torch.optim as optim # optimization package
使用 torch array 代替 numpy ndarray -> 提供在 GPU 上的线性代数运算支持
PyTorch 提供了类似 Numpy array 的多维数组, 当数据类型可以被转化为 (torch.cuda.TensorFloat
) 时就可以放到 GPU 上进行处理. 多维数组和它相关的一些函数都是通用的科学计算工具.
Torch for numpy users 可以查看它是如何与 numpy 相关联的:
# 2 matrices of size 2x3 into a 3d tensor 2x2x3d=[[[1., 2.,3.],[4.,5.,6.]],[[7.,8.,9.],[11.,12.,13.]]]d=torch.Tensor(d) # array from python listprint "shape of the tensor:",d.size()# the first index is the depthz=d[0]+d[1]print "adding up the two matrices of the 3d tensor:",z
shape of the tensor: torch.Size([2, 2, 3])adding up the two matrices of the 3d tensor: 8 10 12 15 17 19[torch.FloatTensor of size 2x3]
# a heavily used operation is reshaping of tensors using .view()print d.view(2,-1) #-1 makes torch infer the second dim
1 2 3 4 5 6 7 8 9 11 12 13[torch.FloatTensor of size 2x6]
torch.autograd
-> 创建一个计算图并自动计算梯度
第二个特性是 autograd 包, 它能够定义一个计算图以便于我们能够自动计算梯度. 在计算图中, 一个节点就是一个数组, 一条边就是在数组上的一个操作. 为了创建一个计算图, 我们需要在函数里面封装一个数组来创建一个节点 (torch.autograd.Variable()
). 然后在该节点上的所有操作将会被定义为边, 操作的结果将会成为计算图中新的节点. 计算图中的每个节点都有一个 node.data
属性, 它是一个多维数组. 还有一个 node.grad
属性, 它是某个标量的梯度 (node.grad
同时也是一个 .Variable()). 在定义好图以后, 只需一个命令 (loss.backward()
) 就可以计算图中所有节点的 loss 梯度.
- 使用
torch.autograd.Variable()
可以将一个 Tensor 转化成为计算图中一个节点.- 通过
x.data
来获取它的值 - 通过
x.grad
来获取的梯度
- 通过
- 在 .Variable() 上施加操作来生成图中的边
# d is a tensor not a node, to create a node based on it:x= autograd.Variable(d, requires_grad=True)print "the node's data is the tensor:", x.data.size()print "the node's gradient is empty at creation:", x.grad # the grad is empty right now
the node's data is the tensor: torch.Size([2, 2, 3])the node's gradient is empty at creation: None
# do operation on the node to make a computational graphy= x+1z=x+ys=z.sum()print s.creator
<torch.autograd._functions.reduce.Sum object at 0x7f1e59988790>
# calculate gradientss.backward()print "the variable now has gradients:",x.grad
the variable now has gradients: Variable containing:(0 ,.,.) = 2 2 2 2 2 2(1 ,.,.) = 2 2 2 2 2 2[torch.FloatTensor of size 2x2x3]
torch.nn
包含了各种神经网络的 layer (对一个 tensor 行的线性映射) + (非线性) -> 无须手动控制 tensor 和参数即可构建一个神经网络计算图
第三个特性是一个高层次的神经网络库 (torch.nn
), 它抽象出了神经网络的 layer 中所有的参数处理, 使得能够几个命令就可以定义一个神经网络 (比如, torch.nn.conv
). 这个包同样也带有常用的 loss function (比如, torch.nn.MSEloss
). 我们以定义一个模型容器开始, 比如使用 (torch.nn.Sequential
) 有一系列层的模型, 并且按顺序列出我们想要的层. 这个库处理其他的所有事情; 我们可以通过 model.parameters()
来获取参数 (Variables()).
# linear transformation of a 2x5 matrix into a 2x3 matrixlinear_map=nn.Linear(5,3)print "using randomly initialized params:", linear_map.parameters
using randomly initialized params: <bound method Linear.parameters of Linear (5 -> 3)>
# data has 2 examples with 5 features and 3 targetdata=torch.randn(2,5) # trainingy=autograd.Variable(torch.randn(2,3)) # target# make a nodex=autograd.Variable(data, requires_grad=True)# apply transformation to a node creates a computational grapha=linear_map(x)z=F.relu(a)o=F.softmax(z)print "output of softmax as a probability distribution:", o.data.view(1,-1)# loss functionloss_func=nn.MSELoss() #instantiate loss functionL=loss_func(z,y) # calculateMSE loss between output and targetprint "Loss:", L
output of softmax as a probability distribution: 0.2092 0.1979 0.5929 0.4343 0.3038 0.2619[torch.FloatTensor of size 1x6]Loss: Variable containing: 2.9838[torch.FloatTensor of size 1]
我们也可以通过子集 torch.nn.Module 自定义 layer, 实现一个接受一个 Variable()
作为输入, 并输出一个 Variable()
的 forward()
函数. 我们也可以定义一个随时间变化的 layer 来创建一个动态网络!
- 当自定义一个 layer, 需要实现 2 个函数:
- 首先需要继承 init 函数, 然后 layer 中的所有参数必须被定义为类变量 (self.x)
- 在 forward 函数里面, 我们传递输入, 在输入上施加操作并进行输出. 输入需要时一个 autograd.Variable() 以便于 pytorch 能够构建 layer 的计算图.
class Log_reg_classifier(nn.Module): def __init__(self, in_size,out_size): super(Log_reg_classifier,self).__init__() #always call parent's init self.linear=nn.Linear(in_size, out_size) #layer parameters def forward(self,vect): return F.log_softmax(self.linear(vect)) #
torch.optim
可以进行优化 -> 我们通过 torch.nn
构建一个计算图, 通过 torch.autograd
来计算梯度, 然后输入到 torch.optim
来更新网络参数
第四个特性是一个配合 NN 库使用的优化包 (torch.optim). 这个库包含了一些像 Adam, RMSprop 的 optimizer. 我们定义一个 optimizer 并传入网络参数和学习率 (opt = torch.optim.Adam(model.parameters(), lr=learning_rate
), 然后我们可以调用 opt.step()
对于我们的参数做一步更新.
optimizer=optim.SGD(linear_map.parameters(),lr=1e-2) # instantiate optimizer with model params + learning rate# epoch loop: we run following until convergenceoptimizer.zero_grad() # make gradients zeroL.backward(retain_variables=True)optimizer.step()print L
Variable containing: 2.9838[torch.FloatTensor of size 1]
构建一个神经网络十分容易, 下面是一个完整示例:
# define modelmodel = Log_reg_classifier(10,2)# define loss functionloss_func=nn.MSELoss()# define optimizeroptimizer=optim.SGD(model.parameters(),lr=1e-1)# send data through model in minibatches for 10 epochsfor epoch in range(10): for minibatch, target in data: model.zero_grad() # pytorch accumulates gradients, making them zero for each minibatch #forward pass out=model(autograd.Variable(minibatch)) #backward pass L=loss_func(out,target) #calculate loss L.backward() # calculate gradients optimizer.step() # make an update step
- 10 分钟理解 PyTorch 代码
- PyTorch代码学习-dataloader
- 强大的PyTorch:10分钟让你了解深度学习领域新流行的框架
- 强大的PyTorch:10分钟让你了解深度学习领域新流行的框架
- 强大的PyTorch:10分钟让你了解深度学习领域新流行的框架
- PyTorch深度学习:60分钟入门(Translation)
- PyTorch 深度学习:60分钟快速入门
- 10分钟理解依赖注入
- 10分钟理解依赖注入
- 10 分钟理解 BFC 原理
- 10 分钟理解 BFC 原理
- Pytorch的backward()相关理解
- 10分钟理解Android数据库的创建与使用(附详解和示例代码)
- PyTorch深度学习:60分钟入门(Translation) PyTorch深度学习:60分钟入门(Translation)
- PyTorch代码学习-ImageNET训练
- pytorch学习笔记(七):pytorch hook 和 关于pytorch backward过程的理解
- pytorch学习笔记(七):pytorch hook 和 关于pytorch backward过程的理解
- Ubuntu16.10安装Pytorch
- [LeetCode] 450. Delete Node in a BST
- 在C语言中什么是语义错误??
- flush privileges 什么意思?
- 求SG函数的值(模板)
- 抓包工具fiddler安装和使用
- 10 分钟理解 PyTorch 代码
- 内存溢出 out of memory与内存泄露 memory leak
- 位操作-leetcode 338 Counting Bits
- 安装Python
- 解决 Communications link failure due to underlying exception
- java的4种代码块
- Activiti HelloWorld流程实现及原理
- java8 in action 学习笔记 一
- POJ 2504 Bounding box 笔记