总结笔记 | 深度学习之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 ...
随机推荐
- React js ReactDOM.render 语句后面不能加分号
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...
- 软件测试工程师应该怎样规划自己?成为年薪30W+测试工程师(乾坤未定,皆是黑马)
今天在知乎上被邀了一个问题,软件测试工程师应该怎样规划自己?16年毕业,技术方面已经渣到不行,因为之前的公司没有Python自动化测试这个要求,有些迷茫.我把我的问题回答贴出来希望可以帮助到更多有类型 ...
- java实现判断时间是否为合法时间
最近遇到一个需求,输入字符串,判断为日期的话再进行后面的比较大小之类的操作,但是合法日期的格式也是比较多的,利用正则表达式又太长了.所以后面利用的方法就是,先把输入的字符串转成一种固定的时间格式,然后 ...
- 线性dp 之 麻烦的聚餐
题目描述 为了避免餐厅过分拥挤,FJ要求奶牛们分3批就餐.每天晚饭前,奶牛们都会在餐厅前排队入内,按FJ的设想,所有第3批就餐的奶牛排在队尾,队伍的前端由设定为第1批就餐的奶牛占据,中间的位置就归第2 ...
- vue : 自定义脚手架提示
做项目做烦了就想找点乐子. 比如,我们可以自定义脚手架提示. webpack.dev.conf.js 54-78 行 module.exports = new Promise((resolve, ...
- 【真实分享】学习linux!让我工资翻5倍!从月薪3000到年薪18W!只用了六个月!
月薪3000到年薪18W,我用了六个月时间.从只会皮毛,到一家公司的运维工程师主力,我的故事蛮神奇的,今天和大家分享一下我自己的经历. 我今年26岁,之前做个体,修过电脑,卖过电脑,做过桌面运维,一直 ...
- STL Queue(队列)学习笔记 + 洛谷 P1540 机器翻译
队(Queue) 队简单来说就是一个先进先出的“栈”,但是不同于标准“栈”的先进后出. 基本操作: push(x) 将x压入队列的末端 pop() 弹出队列的第一个元素(队顶元素),注意此函数并不返回 ...
- 检查string是否有重复尝试用map
链接: 题意:输入一些单词,找出所有满足如下条件的单词:该单词不能通过字母重排,得到输入文本的另外一个单词.在判断是否满足条件时,字母不分大小写,但在输出时应保留输入的大小写,按字典序排列. 题解:先 ...
- Nexus安装与迁移
Maven registry(maven私有仓库) 配置Java export JAVA_HOME=/software/jdk1.7.0_79 export JRE_HOME=${JAVA_HOME} ...
- arcgis for js 如何用contains过滤数据
添加全部数据 // 构建map容器 var view = new MapView({ container: 'mapId', map: map }); /******************** * ...