笔记作者:王博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. Python网络编程04 /recv工作原理、展示收发问题、粘包现象

    Python网络编程04 /recv工作原理.展示收发问题.粘包现象 目录 Python网络编程04 /recv工作原理.展示收发问题.粘包现象 1. recv工作原理 2. 展示收发问题示例 发多次 ...

  2. JavaScript图形实例:阿基米德螺线

    1.阿基米德螺线 阿基米德螺线亦称“等速螺线”.当一点P沿动射线OP以等速率运动的同时,该射线又以等角速度绕点O旋转,点P的轨迹称为“阿基米德螺线”. 阿基米德螺线的笛卡尔坐标方程式为: r=10*( ...

  3. Linux基础入门(一)初识Shell

    Linux基础入门(一)初识Shell shell是什么 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell ...

  4. Ethical Hacking - Web Penetration Testing(4)

    CODE EXECUTION VULNS Allows an attacker to execute OS commands. Windows or Linux commands. Can be us ...

  5. P3379 最近公共祖先(LCA) 洛谷

    题意简单明了(这就是个模板). 就是让我们找2个节点的公共祖先而已,但我们要讲的做法不是生硬的爆搜,而且直接搜好像过不去…… 这次就讲我往后拖了n多天才开始学了倍增LCA. 嗯,这个题,如果2个节点的 ...

  6. 「美团面试系列」面试加分项,这样说你会JVM,面试官还能问什么

    Java性能调优都是老生常谈的问题,特别当“糙快猛”的开发模式大行其道时,随着系统访问量的增加.代码的臃肿,各种性能问题便会层出不穷. 比如,下面这些典型的性能问题,你肯定或多或少都遇到过: 在进行性 ...

  7. ssh配置、vscode使用及常用扩展

    1.ssh配置 1.1 进入命令行 win + r  > cmd 1.2 输入如下代码直接回车即可生成ssh  ssh-keygen -t rsa -C "xxx@qq.com&quo ...

  8. 拆招黑客!github代码库大牛们如何应对黑客攻击

    2019年05月,<个人电脑杂志>网站报道,GitHub(2018年被微软收购)代码库正遭到一名黑客的入侵(392个资源库受损,约1000名用户受到攻击,真实资料未知).据称,这名黑客先擦 ...

  9. python numpy库np.percentile用法说明

    在python中计算一个多维数组的任意百分比分位数,此处的百分位是从小到大排列,只需用np.percentile即可…… a = range(1,101) #求取a数列第90%分位的数值 np.per ...

  10. heredoc

    Heredoc在正规的PHP文档中和技术书籍中一般没有详细讲述.他是一种Perl风格的字符串输出技术.使用heredoc技术可以实现界面与代码的准分离,比如phpwind模板.规则如下:1.”< ...