笔记作者:王博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. 数据可视化实例(十二): 发散型条形图 (matplotlib,pandas)

    https://datawhalechina.github.io/pms50/#/chapter10/chapter10 如果您想根据单个指标查看项目的变化情况,并可视化此差异的顺序和数量,那么散型条 ...

  2. 数据可视化实例(十): 相关图(matplotlib,pandas)

    相关图 https://datawhalechina.github.io/pms50/#/chapter8/chapter8 导入所需要的库 import numpy as np # 导入numpy库 ...

  3. C++代码规约--命名约定

    目录 通用命名规则 文件命名 类型命名 变量命名 常量命名 函数命名 宏命名 枚举命名 命名空间命名 命名规则的特例 学习自Google C++编程规约 通用命名规则 函数命名, 变量命名, 文件命名 ...

  4. P1776 宝物筛选

    题目: 正文: 啊,多重背包真恶心... 一开始我是把多重背包改成了01背包,然鹅我当时是直接1个1个的往后摞的... 参见以下代码: for(int i=1;i<=n;++i){//平平无奇的 ...

  5. 详解UDP协议

    运输层位于网络层之上,网络层提供了主机之间的逻辑通信:而运输层为运行在不同主机上的应用进程之间提供了逻辑通信.从应用程序角度看,通过逻辑通信,运行不同进程的主机好像直接相连一样.应用进程使用运输层提供 ...

  6. 搞定 CompletableFuture,并发异步编程和编写串行程序还有什么区别?你们要的多图长文

    你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it well enough ...

  7. SQL order by语句

    关于order by: order by 语句用于根据指定的列对结果集进行排序,默认按照升序排列. 1.  select 字段名 from 表名 where 条件 order by 字段名1 asc/ ...

  8. 多云架构下,JAVA微服务技术选型实例解析

    [摘要] 本文介绍了基于开源自建和适配云厂商开发框架两种构建多云架构的思路,以及这些思路的优缺点. 微服务生态 微服务生态本质上是一种微服务架构模式的实现,包括微服务开发SDK,以及微服务基础设施. ...

  9. 【转载】基于dom的一些前端漏洞

    最直接的xss --dom xss function trackSearch(query) { document.write('<img src="/resources/images/ ...

  10. vue 修改路由

    直接放代码: this.$router.push({ path: "/login" });