总结助手?
801
2022-05-29
目录
一、整体学习的建议
1.1 如何成为Pytorch大神?
1.2 如何读Github代码?
1.3 代码能力太弱怎么办?
二、Pytorch与TensorFlow概述
2.1 什么是Pytorch?
2.1.1 Pytorch两个核心模块
2.1.2 Pytorch可视化:Visdom
2.1.3 Pytorch的优缺点
2.2 什么是TensorFlow
2.2.1 TensorFlow两个核心模块
2.2.2 TensorFlow可视化:TensorBoard
2.2.3 TensorFlow的优缺点
2.3 Pytorch和TensorFlow对比
三、Pytorch的一些简单命令
四、实现两层神经网络
4.1 如何用numpy实现两层神经网络
4.2 如何用torch实现两层神经网络
4.3 简单的autograd
如何使用autograd简化上面的两层神经网络?
最后pytorch的简单代码
五、Pytorch常用库
5.1 Pytorch:nn
5.2 Pytorch:optim
5.3 Pytorch:nn Module
(本文笔记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 + 3y.backward()# dy/dw=xprint(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进行初始化
modelmodel[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, Din, H, D_out = 64, 1000, 100, 10x = torch.randn(N, D_in)y = torch.randn(N, D_out)class TwoLayerNet(torch.nn.Module): def _init(self, Din, 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-4optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)learning_rate = 1e-6for 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 深度学习
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。