笔记作者:王博Kings

(本文笔记pdf版本可在【人工智能算法与Python大数据】后台回复8003 )

一、整体学习的建议

1.1 如何成为Pytorch大神?

  • 打好深度学习基础
  • 学习Pytorch的官方tutorial
  • 打开Github,多看看教程
  • 使用 https://discuss.pytorch.org, 阅读文档
  • 跑代码,项目,论文代码
  • 复现,实现模型,自己创造

1.2 如何读Github代码?

  1. 首先读简单的代码,比如三四个文件
  2. 然后十个文件
  3. 然后多个文件夹
  4. 整体套路是一样的

1.3 代码能力太弱怎么办?

  • 最简单的办法就行训练
  • 抄代码,抄个100行,然后再写,再抄
  • 刚开始会不理解,后面要思考为什么这么写
  • 写代码的时候不要反复重复!Repeat no!

二、Pytorch与TensorFlow概述

2.1 什么是Pytorch?

  • Facebook开源,2017年,论文《PyTorch 中的自动微分》,地址: https://openreview.net/pdf?id=BJJsrmfCZ
  • 类似于Numpy,可以使用GPU,运行在CUDA上
  • PyTorch框架和Python语言的整合更加紧密
  • Pytorch动态图内置,可以定义深度学习模型,可灵活的进行训练和应用
  • 分布式训练并行化时,利用Python对异步执行的本地支持

2.1.1 Pytorch两个核心模块

  1. 计算图,按照需求动态构建,图会随着执行过程而改变
  2. Autograd,执行动态图的自动微分

2.1.2 Pytorch可视化:Visdom

  • 管理整体环境
  • 处理回调
  • 绘制图表细节

2.1.3 Pytorch的优缺点

优点:

  • 类似Python的代码
  • 动态图
  • 轻松编辑
  • 良好的文档和社区支持
  • 开源
  • 很多项目都在使用

缺点:

  • 可视化需要第三方
  • 生产部署需要使用API服务器

2.2 什么是TensorFlow

  • 谷歌开源,2015年,论文《TensorFlow:异构分布式系统上的大规模机器学习》,地址: http://download.tensorflow.org/paper/whitepaper2015.pdf
  • 使用GPU增强训练,使用的是内置的GPU进行加速
  • 分布式训练并行化时,必须手动编写代码,并微调每个操作
  • 使用TensorFlow Fold库实现动态图
  • 可实现并行化或依赖驱动式调度,训练更快更有效率

2.2.1 TensorFlow两个核心模块

  1. 一个用于定义计算图以及在各种不同硬件上执行这些图的运行时间的软件库
  2. 一个计算图,计算图是以静态方式定义。与外部通信通过tf.Sessionobject和tf.Placeholder

2.2.2 TensorFlow可视化:TensorBoard

  • 分析程序
  • 展示数据(图像,文本,音频)
  • 可视化计算图的操作和层数信息
  • 跟踪和实时可视化损失和准确度等相关指标
  • 查看权重、偏差、张量等随时间变化的直方图

2.2.3 TensorFlow的优缺点

优点:

  • 简单的内置高级API
  • 使用TensorBoard可视化训练
  • 通过TensorFlow serving容易实现生产部署
  • 很容易的移动平台支持
  • 开源
  • 良好的文档和社区支持

缺点:

  • 静态图
  • 调试方法
  • 难以快速修改

2.3 Pytorch和TensorFlow对比

1.学术界PyTorch已经全面超越TensorFlow,上手快,容易实现,验证想法

2.工业界TensorFlow仍然广泛应用,GPU部署方便

三、Pytorch的一些简单命令

第一步,导入torch:

import torch

构造一个未被初始化的3x5的矩阵

x = torch.empty(3,5)
x

生成一个随机初始化的3x5矩阵

x = torch.rand(3,5)
x

生成一个全部为0的矩阵

x = torch.zeros(3,5)
x
x.dtype
torch.float32

生成一个全部为0的矩阵,long的矩阵

x = torch.zeros(3,5,dtype = torch.long)
x
x.dtype
torch.int64
# 或者
x = torch.zeros(3,5).long()

直接通过数据构建tensor

x = torch.tensor([1.2,4])
x
tensor([1.2000,4.0000])

也可以通过已有tensor构建一个新的tensor

x = x.new_ones(3,5)
# 或者改变类型
x = x.new_ones(3,5,dtype=torch.double)

构建一个和上一个形状相同的tensor

x = torch.randn_like(x, dtype=torch.float)
x

得到tensor的形状

x.shape
torch.Size([3,5])

加法准则:

x + y
torch.add(x,y)
result = torch.empty(3,5)
torch.add(x,y, out = result)
result
# 效果与下面类似
result = x + y

in-place加法

注意,任何in-place的运算都会以_结尾,比如x.copy_(y) , x.t_() ,这些都会改变x

y.add_(x)
y
# 注意,这里加了下划线,就把y直接进行更改了,效果等价于 y=y+x

类似于Numpy的索引在Pytorch 的 tensor上面都可以使用,类比matlab

x[1:,1:]

Resizing,想要resize、reshape一个tensor,可以使用torch.view

x = torch.randn(4,4)
y = x.view(16)
y = x.view(2,8)
# 也可以用-1代表其中一个,它会自动计算
y = x.view(2,-1)和 x.view(2,8)功能类似

dir(x)可以看看x包含哪些功能

data
grad

怎么使用?

x.data
x.grad
x.item 把tensor变成数字

Numpy和tensor之间的相互转换

a = tensor([1,1,1,1,1])
b = a.numpy()
b
array([1.,1.,1.,1.,1.], dtype=float32)

注意,这里a和b是共享空间的,其中一个变,整体都会变

把Numpy array 转换成 Torch Tensor

import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
b

如果我们有GPU,可以转换为 CUDA Tensors

if torch.cuda.is_available()
device = torch.device("cuda")
y = torch.ones_like(x, device=device)
x = x.to(device)
z = x + y
# 注意,这里是GPU的
print(z)
# 转换成CPU进行输出的话
print(z.to("cpu", torch.double))

注意,如果是GPU的tensor,是没办法直接用.data这类操作,必须先转换再操作

y.cpu().data.numpy()

numpy是CPU的库,并没有GPU的库,所以如果想使用numpy,但是你默认GPU产生的是tensor

四、实现两层神经网络

4.1 如何用numpy实现两层神经网络

一个全连接ReLU神经网络,一个隐藏层,没有bias。用来从x预测y,使用L2 Loss。

# 定义一些基本的信息,64个输入,每个输入是1000维,hidden是100维,输出是10维
N, D_in, H, D_out = 64, 1000, 100, 10
# 随机创建一些训练数据
# x是64个1000维,x是64x1000矩阵
# y是64个10维,y是64x10矩阵
x = np.random.randn(N, D_in)
y = np.random.randn(N, D_out)
# 随机初始化权重
# w1是1000个100维,w1是1000x100矩阵
# w2是100个10维,w2是100x10矩阵
w1 = np.random.randn(D_in, H)
w2 = np.random.randn(H, D_out)
learning_rate = 1e-6
for t in range(500):
# 前向传播,h是64x1000x1000x100=64x100
# h_relu是看哪个激活了,还是64x100
# y_pred是64x100x100x10=64x10
h = x.dot(w1) # N * H
h_relu = np.maximum(h, 0) # N * H
y_pred = h_relu.dot(w2) # N * D_out # compute loss
loss = np.square(y_pred - y).sum()
print(it, loss) # Backward pass
# 计算梯度,链式法则,挨个求导相乘
grad_y_pred = 2.0 * (y_pred - y)
grad_w2 = h_relu.T.dot(grad_y_pred)
grad_h_relu = grad_y_pred.dot(w2.T)
grad_h = grad_h_relu.copy()
grad_h[h<0] = 0
grad_w1 = x.T.dot(grad_h)
# 更新w1和w2的权重
w1 -=learning_rate * grad_w1
w2 -=learning_rate * grad_w2

4.2 如何用torch实现两层神经网络

这里将numpy修改为pytorch做这件事

pytorch用的是tensors

# 定义一些基本的信息,64个输入,每个输入是1000维,hidden是100维,输出是10维
N, D_in, H, D_out = 64, 1000, 100, 10
# 随机创建一些训练数据
# x是64个1000维,x是64x1000矩阵
# y是64个10维,y是64x10矩阵
# np.random要改为torch
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)
# 随机初始化权重
# w1是1000个100维,w1是1000x100矩阵
# w2是100个10维,w2是100x10矩阵
w1 = torch.randn(D_in, H)
w2 = torch.randn(H, D_out)
learning_rate = 1e-6
for t in range(500):
# 前向传播,h是64x1000x1000x100=64x100
# h_relu是看哪个激活了,还是64x100
# y_pred是64x100x100x10=64x10
# .dot改为mm
h = x.mm(w1) # N * H
# maximum改为clamp,夹住
h_relu = h.clamp(min=0) # N * H
y_pred = h_relu.mm(w2) # N * D_out # compute loss
# 求平方在这里也要改
# loss = np.square(y_pred - y).sum()
loss = (y_pred - y).pow(2).sum().item()
print(it, loss) # Backward pass
# 计算梯度,链式法则,挨个求导相乘
grad_y_pred = 2.0 * (y_pred - y)
grad_w2 = h_relu.t().mm(grad_y_pred)
grad_h_relu = grad_y_pred.mm(w2.t())
grad_h = grad_h_relu.clone()
grad_h[h<0] = 0
grad_w1 = x.t().mm(grad_h)
# 更新w1和w2的权重
w1 -=learning_rate * grad_w1
w2 -=learning_rate * grad_w2

4.3 简单的autograd

x = torch.tensor(1., requires_grad=True)
w = torch.tensor(2., requires_grad=True)
b = torch.tensor(3., requires_grad=True)
y = w*x + b # y = 2*1 + 3
y.backward()
# dy/dw=x
print(w.grad)
print(x.grad)
print(b.grad)
# 结果
tensor(1.)
tensor(2.)
tensor(1 . )

如何使用autograd简化上面的两层神经网络?

# 定义一些基本的信息,64个输入,每个输入是1000维,hidden是100维,输出是10维
N, D_in, H, D_out = 64, 1000, 100, 10
# 随机创建一些训练数据
# x是64个1000维,x是64x1000矩阵
# y是64个10维,y是64x10矩阵
# np.random要改为torch
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)
# 随机初始化权重
# w1是1000个100维,w1是1000x100矩阵
# w2是100个10维,w2是100x10矩阵
w1 = torch.randn(D_in, H, requires_grad=True)
w2 = torch.randn(H, D_out, requires_grad=True)
learning_rate = 1e-6
for t in range(500):
# 前向传播,h是64x1000x1000x100=64x100
# h_relu是看哪个激活了,还是64x100
# y_pred是64x100x100x10=64x10
# .dot改为mm
# h = x.mm(w1) # N * H
# h_relu = h.clamp(min=0) # N * H
# y_pred = h_relu.mm(w2) # N * D_out
# 把上面三行合并为1行
y_pred =x.mm(w1).clamp(min=0).mm(w2) # compute loss
# 求平方在这里也要改
loss = (y_pred - y).pow(2).sum() # 这是计算图
print(it, loss.item()) # Backward pass
# 计算梯度,链式法则,挨个求导相乘
# grad_y_pred = 2.0 * (y_pred - y)
# grad_w2 = h_relu.t().mm(grad_y_pred)
# grad_h_relu = grad_y_pred.mm(w2.t())
# grad_h = grad_h_relu.clone()
# grad_h[h<0] = 0
# grad_w1 = x.t().mm(grad_h)
# 这些求梯度的全部不要
loss.backward() # 更新w1和w2的权重
# 为了减少内存,取消计算图的储存
with torch.no_grad():
w1 -=learning_rate * w1.grad
w2 -=learning_rate * w2.grad
# 每次清零
w1.grad.zero_()
w2.grad.zero_()

最后pytorch的简单代码

# 定义一些基本的信息,64个输入,每个输入是1000维,hidden是100维,输出是10维
N, D_in, H, D_out = 64, 1000, 100, 10
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)
w1 = torch.randn(D_in, H, requires_grad=True)
w2 = torch.randn(H, D_out, requires_grad=True)
learning_rate = 1e-6
for t in range(500):
y_pred =x.mm(w1).clamp(min=0).mm(w2) loss = (y_pred - y).pow(2).sum() # 这是计算图
print(it, loss.item()) loss.backward() # 更新w1和w2的权重
with torch.no_grad():
w1 -=learning_rate * w1.grad
w2 -=learning_rate * w2.grad
# 每次清零
w1.grad.zero_()
w2.grad.zero_()

五、Pytorch常用库

5.1 Pytorch:nn

使用pytorch:nn库来构建网络

使用Pytorch autograd 来构建计算图和计算梯度

import torch.nn as nn
# 定义一些基本的信息,64个输入,每个输入是1000维,hidden是100维,输出是10维
N, D_in, H, D_out = 64, 1000, 100, 10
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)
# 不用这么繁琐顶定义这个w1,w2
# w1 = torch.randn(D_in, H, requires_grad=True)
# w2 = torch.randn(H, D_out, requires_grad=True)
model = torch.nn.Sequential(
torch.nn.Linear(D_in,H), #w_1 * x +b_1
torch.nn.ReLU();
torch.nn.Linear(H, D_out)
)
# model = model.cuda()
loss_fn = nn.MSELoss(reduction='sum')
learning_rate = 1e-6
for t in range(500):
# y_pred =x.mm(w1).clamp(min=0).mm(w2)
y_pred = model(x) # model.forward() loss = loss_fn(y_pred,y)
print(it, loss.item()) model.zero_grad
loss.backward() # 更新w1和w2的权重
with torch.no_grad():
for param in model.parameters():
param -= learning_rate * param.grad

初始化数据,可能影响训练效果 ,这里可对weight进行初始化

model
model[0].weight
可能初始化问题会影响训练效果
可在model和loss_fn中间加:
torch.nn.init.normal_(model[0].weight) #第一层
torch.nn.init.normal_(model[2].weight) #第二层

5.2 Pytorch:optim

不用手动更新模型的weights,而是使用optim这个包来帮助我们更新参数

optim这个包提供了各种不同的模型优化方法,包括SGD+momentum,RMSProp,Adam等等

import torch.nn as nn
# 定义一些基本的信息,64个输入,每个输入是1000维,hidden是100维,输出是10维
N, D_in, H, D_out = 64, 1000, 100, 10
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)
# 不用这么繁琐顶定义这个w1,w2
# w1 = torch.randn(D_in, H, requires_grad=True)
# w2 = torch.randn(H, D_out, requires_grad=True)
model = torch.nn.Sequential(
torch.nn.Linear(D_in,H), #w_1 * x +b_1
torch.nn.ReLU();
torch.nn.Linear(H, D_out)
)
# model = model.cuda()
loss_fn = nn.MSELoss(reduction='sum')
learning_rate = 1e-4
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
# 或者优化方法
# learning_rate = 1e-6
# optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
learning_rate = 1e-6
for t in range(500): y_pred = model(x) # model.forward() loss = loss_fn(y_pred,y)
print(it, loss.item())
# 求导之前把数据清空
optimizer.zero_grad()
loss.backward() # 更新w1和w2的权重
optimizer.step()

5.3 Pytorch:nn Module

import torch.nn as nn
# 定义一些基本的信息,64个输入,每个输入是1000维,hidden是100维,输出是10维
N, D_in, H, D_out = 64, 1000, 100, 10
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)
class TwoLayerNet(torch.nn.Module):
def _init_(self, D_in, H, D_out):
super(TwoLayerNet, self)._init_()
# 定义模型框架
self.linear1 = torch.nn.Linear(D_in, H, bias=False)
self.linear2 = torch.nn.Linear(H, D_out, bias=False) def forward(self, x)
# 定义前向传播
y_pred = self.linear2(self.linear1(x).clamp(min=0))
return y_pred model = TwoLayerNet(D_in, H, D_out))
loss_fn = nn.MSELoss(reduction='sum')
learning_rate = 1e-4
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
learning_rate = 1e-6
for t in range(500): y_pred = model(x) # model.forward() loss = loss_fn(y_pred,y)
print(it, loss.item()) # 求导之前把数据清空
optimizer.zero_grad()
loss.backward() # 更新w1和w2的权重
optimizer.step()

总结笔记 | 深度学习之Pytorch入门教程的更多相关文章

  1. 萌新深度学习与Pytorch入门记录(一):Win10下环境安装

    深度学习从入门到入土,安装软件及配置环境踩了不少坑,过程中参考了多处博主给的解决方法,遂整合一下自己的采坑记录. (若遇到不一样的错误,请参考其他博主答案解决) 笔者电脑系统为win10系统,在此环境 ...

  2. 《深度学习框架PyTorch:入门与实践》的Loss函数构建代码运行问题

    在学习陈云的教程<深度学习框架PyTorch:入门与实践>的损失函数构建时代码如下: 可我运行如下代码: output = net(input) target = Variable(t.a ...

  3. 深度学习之PyTorch实战(1)——基础学习及搭建环境

    最近在学习PyTorch框架,买了一本<深度学习之PyTorch实战计算机视觉>,从学习开始,小编会整理学习笔记,并博客记录,希望自己好好学完这本书,最后能熟练应用此框架. PyTorch ...

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

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

  5. 超简单!pytorch入门教程(五):训练和测试CNN

    我们按照超简单!pytorch入门教程(四):准备图片数据集准备好了图片数据以后,就来训练一下识别这10类图片的cnn神经网络吧. 按照超简单!pytorch入门教程(三):构造一个小型CNN构建好一 ...

  6. 腾讯QQ会员技术团队:人人都可以做深度学习应用:入门篇(下)

    四.经典入门demo:识别手写数字(MNIST) 常规的编程入门有"Hello world"程序,而深度学习的入门程序则是MNIST,一个识别28*28像素的图片中的手写数字的程序 ...

  7. 参考《深度学习之PyTorch实战计算机视觉》PDF

    计算机视觉.自然语言处理和语音识别是目前深度学习领域很热门的三大应用方向. 计算机视觉学习,推荐阅读<深度学习之PyTorch实战计算机视觉>.学到人工智能的基础概念及Python 编程技 ...

  8. 【深度学习】Pytorch 学习笔记

    目录 Pytorch Leture 05: Linear Rregression in the Pytorch Way Logistic Regression 逻辑回归 - 二分类 Lecture07 ...

  9. 深度学习框架PyTorch一书的学习-第四章-神经网络工具箱nn

    参考https://github.com/chenyuntc/pytorch-book/tree/v1.0 希望大家直接到上面的网址去查看代码,下面是本人的笔记 本章介绍的nn模块是构建与autogr ...

随机推荐

  1. redis(十二):Redis 集合(Set)

    Redis 集合(Set) Redis 的 Set 是 String 类型的无序集合.集合成员是唯一的,这就意味着集合中不能出现重复的数据. Redis 中集合是通过哈希表实现的,所以添加,删除,查找 ...

  2. bzoj3436小K的农场

    bzoj3436小K的农场 题意: n个数,知道m条关系:a-b≥c.a-b≤c或a==b.问是否存在满足所有关系的情况.n≤10000,m≤10000. 题解: 差分约束.因为只要求是否满足,因此最 ...

  3. drf频率源码、自动生成接口文档、JWT

    目录 一.drf频率源码分析 二.自动生成接口文档 1 安装依赖 2 设置接口文档访问路径 3 文档描述说明的定义位置 4 访问接口文档网页 三.JWT 1 JWT基本原理 1.1 header 1. ...

  4. OSCP Learning Notes - Enumeration(2)

    HTTP Enumeration Target Host IP: 10.0.0.20 Brute Forcing using DirBuster 1. Start the dirbuster and ...

  5. Ethical Hacking - GAINING ACCESS(22)

    CLIENT SIDE ATTACKS - BeEf Framework Browser Exploitation Framework allowing us to launch a number o ...

  6. 手写SpringBoot自动配置及自定义注解搭配Aop,实现升级版@Value()功能

    背景 项目中为了统一管理项目的配置,比如接口地址,操作类别等信息,需要一个统一的配置管理中心,类似nacos. 我根据项目的需求写了一套分布式配置中心,测试无误后,改为单体应用并耦合到项目中.项目中使 ...

  7. Onedrive分享型网盘搭建 - OneManager

    注册账号 部署OneManager 注册完账号后打开网址:https://heroku.com/deploy?template=https://github.com/qkqpttgf/OneManag ...

  8. scratch编程体感游戏

    体感游戏有很多种,最常见的就是摄像头和声控了,今天我们要用scratch编写一系列的体感游戏!!!是不是很激动呢? 首先我们来编摄像头类的: No.1拳头打幽灵 挥动头就能打到幽灵了哟! 具体程序如下 ...

  9. 搭建高可用kubernetes集群(keepalived+haproxy)

    序 由于单master节点的kubernetes集群,存在master节点异常之后无法继续使用的缺陷.本文参考网管流程搭建一套多master节点负载均衡的kubernetes集群.官网给出了两种拓扑结 ...

  10. STL源码剖析:迭代器

    准备知识 什么是迭代器? 迭代器是链接容器和算法的桥梁,所有的算法都通过迭代器操作容器中的数据 迭代器是一种智能指针,最重要的操作符重载就是operator*,operator-> 迭代器的实现 ...