总结笔记 | 深度学习之Pytorch入门教程
笔记作者:王博Kings
(本文笔记pdf版本可在【人工智能算法与Python大数据】后台回复8003 )
一、整体学习的建议
1.1 如何成为Pytorch大神?
- 打好深度学习基础
- 学习Pytorch的官方tutorial
- 打开Github,多看看教程
- 使用 https://discuss.pytorch.org, 阅读文档
- 跑代码,项目,论文代码
- 复现,实现模型,自己创造
1.2 如何读Github代码?
- 首先读简单的代码,比如三四个文件
- 然后十个文件
- 然后多个文件夹
- 整体套路是一样的
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两个核心模块
- 计算图,按照需求动态构建,图会随着执行过程而改变
- 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两个核心模块
- 一个用于定义计算图以及在各种不同硬件上执行这些图的运行时间的软件库
- 一个计算图,计算图是以静态方式定义。与外部通信通过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入门教程的更多相关文章
- 萌新深度学习与Pytorch入门记录(一):Win10下环境安装
深度学习从入门到入土,安装软件及配置环境踩了不少坑,过程中参考了多处博主给的解决方法,遂整合一下自己的采坑记录. (若遇到不一样的错误,请参考其他博主答案解决) 笔者电脑系统为win10系统,在此环境 ...
- 《深度学习框架PyTorch:入门与实践》的Loss函数构建代码运行问题
在学习陈云的教程<深度学习框架PyTorch:入门与实践>的损失函数构建时代码如下: 可我运行如下代码: output = net(input) target = Variable(t.a ...
- 深度学习之PyTorch实战(1)——基础学习及搭建环境
最近在学习PyTorch框架,买了一本<深度学习之PyTorch实战计算机视觉>,从学习开始,小编会整理学习笔记,并博客记录,希望自己好好学完这本书,最后能熟练应用此框架. PyTorch ...
- 对比学习:《深度学习之Pytorch》《PyTorch深度学习实战》+代码
PyTorch是一个基于Python的深度学习平台,该平台简单易用上手快,从计算机视觉.自然语言处理再到强化学习,PyTorch的功能强大,支持PyTorch的工具包有用于自然语言处理的Allen N ...
- 超简单!pytorch入门教程(五):训练和测试CNN
我们按照超简单!pytorch入门教程(四):准备图片数据集准备好了图片数据以后,就来训练一下识别这10类图片的cnn神经网络吧. 按照超简单!pytorch入门教程(三):构造一个小型CNN构建好一 ...
- 腾讯QQ会员技术团队:人人都可以做深度学习应用:入门篇(下)
四.经典入门demo:识别手写数字(MNIST) 常规的编程入门有"Hello world"程序,而深度学习的入门程序则是MNIST,一个识别28*28像素的图片中的手写数字的程序 ...
- 参考《深度学习之PyTorch实战计算机视觉》PDF
计算机视觉.自然语言处理和语音识别是目前深度学习领域很热门的三大应用方向. 计算机视觉学习,推荐阅读<深度学习之PyTorch实战计算机视觉>.学到人工智能的基础概念及Python 编程技 ...
- 【深度学习】Pytorch 学习笔记
目录 Pytorch Leture 05: Linear Rregression in the Pytorch Way Logistic Regression 逻辑回归 - 二分类 Lecture07 ...
- 深度学习框架PyTorch一书的学习-第四章-神经网络工具箱nn
参考https://github.com/chenyuntc/pytorch-book/tree/v1.0 希望大家直接到上面的网址去查看代码,下面是本人的笔记 本章介绍的nn模块是构建与autogr ...
随机推荐
- Tomcat的结构
Tomcat其实就是一个容器,最顶层的容器叫Server,代表整个服务器,Server中包含至少一个Service,用于具体提供服务.Service主要包含两部分:Connector和Containe ...
- python上selenium的弹框操作
selenium之弹框操作 1,分类 弹框类型自见解分为四种: 1,页面弹框 2,警告提示框(alert) 3,确认消息框(confirm) 4,提示消息对话(prompt) 提示:selenium ...
- 6 个珍藏已久 IDEA 小技巧,这一波全部分享给你!
每周趣图 产品经理设计体验/用户实际体验 本周就不写技术分析文章了,分享几个珍藏已久的 IDEA 的「骚技巧」,助你快速完成代码. 还等什么?赶紧上车吧...... 先赞后看,养成习惯.微信搜索「程序 ...
- web自动化测试实战之生成测试报告
同志们,老铁们,继上篇文章 web自动化测试实战之批量执行测试用例 之后我们接着继续往下走,有人说我们运行了所有测试用例,控制台输入的结果,如果很多测试用例那也不能够清晰快速的知道多少用例通过率以及错 ...
- CUDA C++ Extensions
敲代码的时候总是会去CUDA官方文档中找找思路,感觉每次看英文文档都要耗费一点时间来翻译,干脆自己翻译一下便于以后查阅.官方文档:cuda-c-language-extensions 目录 函数修饰符 ...
- Python 实现图像快速傅里叶变换和离散余弦变换
图像的正交变换在数字图像的处理与分析中起着很重要的作用,被广泛应用于图像增强.去噪.压缩编码等众多领域.本文手工实现了二维离散傅里叶变换和二维离散余弦变换算法,并在多个图像样本上进行测试,以探究二者的 ...
- 【日常摘要】- RabbitMq实现延时队列
简介 什么是延时队列? 一种带有延迟功能的消息队列 过程: 使用场景 比如存在某个业务场景 发起一个订单,但是处于未支付的状态?如何及时的关闭订单并退还库存? 如何定期检查处于退款订单是否已经成功退款 ...
- Monster Audio 使用教程(一)入门教程 + 常见问题
Monster Audio支持的操作系统: windows 7 64bit 至 windows 10 64bit 受支持的VST: Vst 64bit.Vst3 64bit 受支持的声卡驱动: ASI ...
- 启动扫描闪退,因为忘了在manifest里申请手机镜头使用许可了。
启动扫描闪退,因为忘了在manifest里申请手机镜头使用许可了.
- nginx静态资源防盗链
含义: 用于阻止 Referer 头字段为无效值的请求访问站点.需记住的是,使用适当的 Referer 字段值来伪造请求非常容易,因此本模块的预期目的不是要彻底阻止此类请求,而是阻止常规浏览器发送的大 ...