https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html

官方推荐的一篇教程

Tensors

  1. #Construct a 5x3 matrix, uninitialized:
  2. x = torch.empty(5, 3)
  3. #Construct a randomly initialized matrix:
  4. x = torch.rand(5, 3)
  5. # Construct a matrix filled zeros and of dtype long:
  6. x = torch.zeros(5, 3, dtype=torch.long)
  7. # Construct a tensor directly from data:
  8. x = torch.tensor([5.5, 3])
  9. # create a tensor based on an existing tensor. These methods will reuse properties of the input tensor, e.g. dtype, unless new values are provided by user
  10. x = x.new_ones(5, 3, dtype=torch.double) # new_* methods take in sizes
  11. print(x)
  12. x = torch.randn_like(x, dtype=torch.float) # override dtype! #沿用了x已有的属性,只是修改dtype
  13. print(x) # result has the same size

tensor操作的语法有很多写法,以加法为例

  1. #1
  2. x = x.new_ones(5, 3, dtype=torch.double)
  3. y = torch.rand(5, 3)
  4. print(x + y)
  5. #2
  6. print(torch.add(x, y))
  7. #3
  8. result = torch.empty(5, 3)
  9. torch.add(x, y, out=result)
  10. print(result)
  11. ##注意以_做后缀的方法,都会改变原始的变量
  12. #4 Any operation that mutates a tensor in-place is post-fixed with an _. For example: x.copy_(y), x.t_(), will change x.
  13. # adds x to y
  14. y.add_(x)
  15. print(y)

改变tensor的size,使用torch.view:

  1. x = torch.randn(4, 4)
  2. y = x.view(16)
  3. z = x.view(-1, 8) # the size -1 is inferred from other dimensions
  4. print(x.size(), y.size(), z.size())
  5. 输出如下:
  6. torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])

numpy array和torch tensor的相互转换

  • torch tensor转换为numpy array
  1. a = torch.ones(5)
  2. print(a)
  3. 输出tensor([1., 1., 1., 1., 1.])
  4. #torch tensor--->numpy array
  5. b = a.numpy()
  6. print(b)
  7. 输出[1. 1. 1. 1. 1.]
  8. #注意!:a,b同时发生了变化
  9. a.add_(1)
  10. print(a)
  11. print(b)
  12. 输出tensor([2., 2., 2., 2., 2.])
  13. [2. 2. 2. 2. 2.]
  • numpy array转换为torch tensor
  1. a = np.ones(5)
  2. b = torch.from_numpy(a)
  3. np.add(a, 1, out=a)

所有的cpu上的tensor,除了chartensor,都支持和numpy之间的互相转换.

All the Tensors on the CPU except a CharTensor support converting to NumPy and back.

CUDA Tensors

Tensors can be moved onto any device using the .to method.

  1. #let us run this cell only if CUDA is available
  2. #We will use ``torch.device`` objects to move tensors in and out of GPU
  3. if torch.cuda.is_available():
  4. device = torch.device("cuda") # a CUDA device object
  5. y = torch.ones_like(x, device=device) # directly create a tensor on GPU
  6. x = x.to(device) # or just use strings ``.to("cuda")``
  7. z = x + y
  8. print(z)
  9. print(z.to("cpu", torch.double)) # ``.to`` can also change dtype together!
  10. --->
  11. tensor([0.6635], device='cuda:0')
  12. tensor([0.6635], dtype=torch.float64)

AUTOGRAD

The autograd package provides automatic differentiation for all operations on Tensors. It is a define-by-run framework, which means that your backprop is defined by how your code is run, and that every single iteration can be different.

Generally speaking, torch.autograd is an engine for computing vector-Jacobian product

.requires_grad属性设为true,则可以追踪tensor上的所有操作(比如加减乘除)

torch.Tensor is the central class of the package. If you set its attribute .requires_grad as True, it starts to track all operations on it. When you finish your computation you can call .backward() and have all the gradients computed automatically. The gradient for this tensor will be accumulated into .grad attribute.

autograd包实现自动的求解梯度.

神经网络

torch.nn包可以用来构建神经网络.

nn依赖autogard来不断地更新model中各层的参数. nn.Module包含layers,forward方法.

典型的神经网络的训练过程如下:

  • 定义一个神经网络,含learnable parameters或者叫weights
  • 对数据集的所有数据作为Input输入网络
  • 计算loss
  • 反向传播计算weights的梯度
  • 更新weights,一个典型的简单规则:weight = weight - learning_rate * gradient

定义网络

  1. import torch
  2. import torch.nn as nn
  3. import torch.nn.functional as F
  4. class Net(nn.Module):
  5. def __init__(self):
  6. super(Net, self).__init__()
  7. # 1 input image channel, 6 output channels, 5x5 square convolution
  8. # kernel
  9. self.conv1 = nn.Conv2d(1, 6, 5) #输入是1个矩阵,输出6个矩阵,filter是5*5矩阵.即卷积层1使用6个filter.
  10. self.conv2 = nn.Conv2d(6, 16, 5) #输入是6个矩阵,输出16个矩阵,filter是5*5矩阵.即卷积层2使用16个filter.
  11. # an affine operation: y = Wx + b
  12. self.fc1 = nn.Linear(16 * 5 * 5, 120) #全连接层,fc=fullconnect 作用是分类
  13. self.fc2 = nn.Linear(120, 84)
  14. self.fc3 = nn.Linear(84, 10)
  15. def forward(self, x):
  16. # Max pooling over a (2, 2) window
  17. x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
  18. # If the size is a square you can only specify a single number
  19. x = F.max_pool2d(F.relu(self.conv2(x)), 2)
  20. x = x.view(-1, self.num_flat_features(x))
  21. x = F.relu(self.fc1(x))
  22. x = F.relu(self.fc2(x))
  23. x = self.fc3(x)
  24. return x
  25. def num_flat_features(self, x):
  26. size = x.size()[1:] # all dimensions except the batch dimension
  27. num_features = 1
  28. for s in size:
  29. num_features *= s
  30. return num_features
  31. net = Net()
  32. print(net)
  33. 输出如下:
  34. Net(
  35. (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
  36. (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
  37. (fc1): Linear(in_features=400, out_features=120, bias=True)
  38. (fc2): Linear(in_features=120, out_features=84, bias=True)
  39. (fc3): Linear(in_features=84, out_features=10, bias=True)
  40. )

你只需要定义forward函数,backward函数(即计算梯度的函数)是autograd包自动定义的.你可以在forward函数里使用任何tensor操作.

model的参数获取.

  1. params = list(net.parameters())
  2. print(len(params))
  3. print(params[0].size()) # conv1's .weight
  4. 输出如下:
  5. 10
  6. torch.Size([6, 1, 5, 5])

以MNIST识别为例,输入图像为3232.我们用一个随机的3232输入演示一下.

  1. input = torch.randn(1, 1, 32, 32)
  2. out = net(input)
  3. print(out)
  4. 输出如下:
  5. tensor([[ 0.0659, -0.0456, 0.1248, -0.1571, -0.0991, -0.0494, 0.0046, -0.0767,
  6. -0.0345, 0.1010]], grad_fn=<AddmmBackward>)
  7. #清空所有的parameter的gradient buffer.用随机的梯度反向传播。
  8. #Zero the gradient buffers of all parameters and backprops with random gradients:
  9. net.zero_grad()
  10. out.backward(torch.randn(1, 10))

回忆一下部分概念

  • torch.Tensor - A multi-dimensional array with support for autograd operations like backward(). Also holds the gradient w.r.t. the tensor.
  • nn.Module - Neural network module. Convenient way of encapsulating parameters, with helpers for moving them to GPU, exporting, loading, etc.
  • nn.Parameter - A kind of Tensor, that is automatically registered as a parameter when assigned as an attribute to a Module.
  • autograd.Function - Implements forward and backward definitions of an autograd operation. Every Tensor operation creates at least a single Function node that connects to functions that created a Tensor and encodes its history.

损失函数

nn package有好几种损失函数.以nn.MSELoss为例

  1. output = net(input)
  2. target = torch.randn(10) # a dummy target, for example
  3. target = target.view(1, -1) # make it the same shape as output
  4. criterion = nn.MSELoss()
  5. loss = criterion(output, target)
  6. print(loss)
  7. 输出
  8. tensor(0.6918, grad_fn=<MseLossBackward>)

Now, if you follow loss in the backward direction, using its .grad_fn attribute, you will see a graph of computations that looks like this:

input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d

-> view -> linear -> relu -> linear -> relu -> linear

-> MSELoss

-> loss

  1. print(loss.grad_fn) # MSELoss
  2. print(loss.grad_fn.next_functions[0][0]) # Linear
  3. print(loss.grad_fn.next_functions[0][0].next_functions[0][0]) # ReLU
  4. 输出如下:
  5. <MseLossBackward object at 0x7ff3406e1be0>
  6. <AddmmBackward object at 0x7ff3406e1da0>
  7. <AccumulateGrad object at 0x7ff3406e1da0>

反向传播

调用loss.backward()重新计算梯度

  1. #首先清空现有的gradient buffer
  2. net.zero_grad() # zeroes the gradient buffers of all parameters
  3. print('conv1.bias.grad before backward')
  4. print(net.conv1.bias.grad)
  5. loss.backward()
  6. print('conv1.bias.grad after backward')
  7. print(net.conv1.bias.grad)
  8. 输出如下:
  9. conv1.bias.grad before backward
  10. tensor([0., 0., 0., 0., 0., 0.])
  11. conv1.bias.grad after backward
  12. tensor([-0.0080, 0.0043, -0.0006, 0.0142, -0.0017, -0.0082])

更新权重

最常见的是使用随机梯度下降法更新权重:

weight = weight - learning_rate * gradient

简单实现如下

  1. learning_rate = 0.01
  2. for f in net.parameters():
  3. f.data.sub_(f.grad.data * learning_rate)

torch.optim包封装了各种各样的优化方法, SGD, Nesterov-SGD, Adam, RMSProp等等.

  1. import torch.optim as optim
  2. # create your optimizer
  3. optimizer = optim.SGD(net.parameters(), lr=0.01)
  4. # in your training loop:
  5. optimizer.zero_grad() # zero the gradient buffers
  6. output = net(input)
  7. loss = criterion(output, target)
  8. loss.backward()
  9. optimizer.step() # Does the update

训练一个分类器

并行计算

pytorch深度学习60分钟闪电战的更多相关文章

  1. 【PyTorch深度学习60分钟快速入门 】Part1:PyTorch是什么?

      0x00 PyTorch是什么? PyTorch是一个基于Python的科学计算工具包,它主要面向两种场景: 用于替代NumPy,可以使用GPU的计算力 一种深度学习研究平台,可以提供最大的灵活性 ...

  2. 【PyTorch深度学习60分钟快速入门 】Part4:训练一个分类器

      太棒啦!到目前为止,你已经了解了如何定义神经网络.计算损失,以及更新网络权重.不过,现在你可能会思考以下几个方面: 0x01 数据集 通常,当你需要处理图像.文本.音频或视频数据时,你可以使用标准 ...

  3. 【PyTorch深度学习60分钟快速入门 】Part5:数据并行化

      在本节中,我们将学习如何利用DataParallel使用多个GPU. 在PyTorch中使用多个GPU非常容易,你可以使用下面代码将模型放在GPU上: model.gpu() 然后,你可以将所有张 ...

  4. 【PyTorch深度学习60分钟快速入门 】Part3:神经网络

      神经网络可以通过使用torch.nn包来构建. 既然你已经了解了autograd,而nn依赖于autograd来定义模型并对其求微分.一个nn.Module包含多个网络层,以及一个返回输出的方法f ...

  5. 【PyTorch深度学习60分钟快速入门 】Part0:系列介绍

      说明:本系列教程翻译自PyTorch官方教程<Deep Learning with PyTorch: A 60 Minute Blitz>,基于PyTorch 0.3.0.post4 ...

  6. 【PyTorch深度学习60分钟快速入门 】Part2:Autograd自动化微分

      在PyTorch中,集中于所有神经网络的是autograd包.首先,我们简要地看一下此工具包,然后我们将训练第一个神经网络. autograd包为张量的所有操作提供了自动微分.它是一个运行式定义的 ...

  7. [PyTorch入门之60分钟入门闪击战]之入门

    深度学习60分钟入门 来源于这里. 本文目标: 在高层次上理解PyTorch的Tensor库和神经网络 训练一个小型的图形分类神经网络 本文示例运行在ipython中. 什么是PyTorch PyTo ...

  8. 对比学习:《深度学习之Pytorch》《PyTorch深度学习实战》+代码

    PyTorch是一个基于Python的深度学习平台,该平台简单易用上手快,从计算机视觉.自然语言处理再到强化学习,PyTorch的功能强大,支持PyTorch的工具包有用于自然语言处理的Allen N ...

  9. PyTorch深度学习实践——反向传播

    反向传播 课程来源:PyTorch深度学习实践--河北工业大学 <PyTorch深度学习实践>完结合集_哔哩哔哩_bilibili 目录 反向传播 笔记 作业 笔记 在之前课程中介绍的线性 ...

随机推荐

  1. Python3 ——斐波那契数列(经典)

    刚刚学习了 斐波那契数列,整理一下思路,写个博文给未来的学弟学妹参考一下,希望能够帮助到他们 永远爱你们的 ----新宝宝 经历过简单的学习之后,写出一个比较简单的代码,斐波那契数列:具体程序如下: ...

  2. selenium IDE工具页面介绍!

    selenium IDE工具页面,常用功能点介绍

  3. Python-常用 Linux 命令的基本使用

    常用 Linux 命令的基本使用 操作系统 作用:管理好硬件设备,让软件可以和硬件发生交互类型 桌面操作系统 Windows macos linux 服务器操作系统 linux Windows ser ...

  4. 循环神经网络之LSTM和GRU

    看了一些LSTM的博客,都推荐看colah写的博客<Understanding LSTM Networks> 来学习LSTM,我也找来看了,写得还是比较好懂的,它把LSTM的工作流程从输入 ...

  5. Haskell学习-monad

    原文地址:Haskell学习-monad 什么是Monad Haskell是一门纯函数式的语言,纯函数的优点是安全可靠.函数输出完全取决于输入,不存在任何隐式依赖,它的存在如同数学公式般完美无缺.可是 ...

  6. SpringBoot | 第六章:常用注解介绍及简单使用

    前言 之前几个章节,大部分都是算介绍springboot的一些外围配置,比如日志配置等.这章节开始,开始总结一些关于springboot的综合开发的知识点.由于SpringBoot本身是基于Sprin ...

  7. 数据库原理 - 序列3 - 事务是如何实现的? - Redo Log解析

    6.5 事务实现原理之1:Redo Log 介绍事务怎么用后,下面探讨事务的实现原理.事务有ACID四个核心属性:A:原子性.事务要么不执行,要么完全执行.如果执行到一半,宕机重启,已执行的一半要回滚 ...

  8. 关于a[i]++和a[i++]说明

    1.a[i]++:表示对当前数组元素值自增,此时可以把a[i]简单看做一个变量x,操作后,x的值加1: int main() { ]; ; a[i] = ; a[i]++; printf(" ...

  9. golang中的defer

    1.defer的作用 defer 语句会将函数推迟到外层函数返回之后执行. 即defer后面的函数在defer语句所在的函数执行结束的时候会被调用 2.defer的语法 defer后面必须是函数调用语 ...

  10. DNS服务详解

    DNS服务 目录: 一.DNS原理 二.DNS服务的安装与配置 三.DNS信息收集 一.DNS原理 1.hosts文件与DNS服务器 1.1hosts文件 目录:C:\WINDOWS\system32 ...