来自pytorch官网:添加链接描述

目录

  • 1、Tensors 张量
    • (1)、导入包
    • (2)、tensor初始化
    • (3)、tensor属性attributes
    • (4)、tensor操作operation
    • (5)、和NumPy的联系
  • 2、介绍torch.autograd
  • (1)、背景background
    • (2)、在pytorch中的用法
    • (3)、Autograd
    • (4)、计算图
    • (4)、冻结参数
  • 3、神经网络
    • (1)、定义神经网络
    • (2)、loss 函数
    • (3)、更新参数

1、Tensors 张量

(1)、导入包

import torch
import numpy as np

(2)、tensor初始化

  1. 直接通过数据创建
data = [[1,2],[3,4]]
x_data = torch.tensor(data)
print(x_data)
"""
tensor([[1, 2],[3, 4]])
"""
  1. 通过numpy数组创建
np_array = np.array(data)
x_np = torch.from_numpy(np_array)
print(np_array)
print(x_np)
"""
[[1 2][3 4]]
tensor([[1, 2],[3, 4]], dtype=torch.int32)
"""
  1. 通过其他张量创建
x_ones = torch.ones_like(x_data) # 创建一个新的全是1的tensor,大小和数据类型和x_data一样
print(f"ones tenser:\n {x_ones}\n")
x_rand = torch.rand_like(x_data,dtype=torch.float)
print(f"Random Tensor: \n {x_rand} \n")
"""
ones tenser:tensor([[1, 1],[1, 1]])Random Tensor: tensor([[0.1373, 0.8053],[0.6573, 0.9279]])
"""
  1. 随机创建
shape = (2, 3) # shape is a tuple of tensor dimensions.
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")
"""
Random Tensor: tensor([[0.5519, 0.8138, 0.0425],[0.7606, 0.5727, 0.4184]]) Ones Tensor: tensor([[1., 1., 1.],[1., 1., 1.]]) Zeros Tensor: tensor([[0., 0., 0.],[0., 0., 0.]])
"""

(3)、tensor属性attributes

tensor的属性包括:shape、datatype、以及存储的设备

tensor = torch.rand(3,4)
print(f"shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")
"""
shape of tensor: torch.Size([3, 4])
Datatype of tensor: torch.float32
Device tensor is stored on: cpu
"""

(4)、tensor操作operation

包括:转置(transposing)、索引(indexing)、切片(slicing)、数学运算(mathematical oprations)、线性代数(linear algebra)、随机抽样(random sampling)等等,都在这里得到了全面的描述。

  1. 在GPU上运行
# We move our tensor to the GPU if available
if torch.cuda.is_available():tensor = tensor.to('cuda')print(f"Device tensor is stored on: {tensor.device}")
"""
Device tensor is stored on: cuda:0
"""
  1. 索引和切片
tensor = torch.ones(4, 4)
tensor[:,1] = 0
print(tensor)
"""
tensor([[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.]])
"""
  1. 连接张量torch.cat和torch.stack
tensor = torch.ones(4,4)
t1 = torch.cat([tensor,tensor],dim = 1)
print(t1)
t2 = torch.cat([tensor,tensor],dim = 0)
print(t2)
"""
tensor([[1., 1., 1., 1., 1., 1., 1., 1.],[1., 1., 1., 1., 1., 1., 1., 1.],[1., 1., 1., 1., 1., 1., 1., 1.],[1., 1., 1., 1., 1., 1., 1., 1.]])
tensor([[1., 1., 1., 1.],[1., 1., 1., 1.],[1., 1., 1., 1.],[1., 1., 1., 1.],[1., 1., 1., 1.],[1., 1., 1., 1.],[1., 1., 1., 1.],[1., 1., 1., 1.]])
"""
  1. tensor乘法
t = torch.ones(3,3)
#元素乘法
t4 = t * t
t5 = t.mul(t)
print(f"元素乘法:t * t : \n{t4}\n t.mul(t):\ng{t5}")
# 矩阵乘法
t6 = t @ t.T
t7 = t.matmul(t.T)
print(f"矩阵乘法:t @ t.T : \n{t6}\n t.matmul(t.T):\ng{t7}")
"""
元素乘法:t * t :
tensor([[1., 1., 1.],[1., 1., 1.],[1., 1., 1.]])t.mul(t):
gtensor([[1., 1., 1.],[1., 1., 1.],[1., 1., 1.]])
矩阵乘法:t @ t.T :
tensor([[3., 3., 3.],[3., 3., 3.],[3., 3., 3.]])t.matmul(t.T):
gtensor([[3., 3., 3.],[3., 3., 3.],[3., 3., 3.]])
"""
  1. 就地操作
    就地操作(In-palce):具有 _ 后缀的操作是就地操作。例如:x.copy_(y),x.t_(),将改变x。
print(t,"\n")
t.add_(5)
print(t)
"""
tensor([[1., 1., 1.],[1., 1., 1.],[1., 1., 1.]]) tensor([[6., 6., 6.],[6., 6., 6.],[6., 6., 6.]])
"""

(5)、和NumPy的联系

Tensors on the CPU and NumPy arrays can share their underlying memory locations, and changing one will change the other.
在CPU上的张量和NumPy共享相同的存储位置,改变一个也会改变另一个

k = torch.ones(4)
print(f"k: {k}")
print(k.dtype)
# 将tensor类型改成numpy
n = k.numpy()
print(f"n: {n}")
print(n.dtype)
# 改变k,n也会改变
k.add_(1)
print(f"change k:{k}")
print(f"change n:{n}")# 将numpy类型改成tensor
n = np.ones(5)
k = torch.from_numpy(n)
print(f"n: {n}")
print(n.dtype)
print(f"k: {k}")
print(k.dtype)#改变n,k也会改变,略
"""
k: tensor([1., 1., 1., 1.])
torch.float32
n: [1. 1. 1. 1.]
float32
change k:tensor([2., 2., 2., 2.])
change n:[2. 2. 2. 2.]
n: [1. 1. 1. 1. 1.]
float64
k: tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
torch.float64
"""
"""

2、介绍torch.autograd

torch.autograd是PyTorch的自动微分引擎,为神经网络训练提供动力。在本节中,您将从概念上了解autograd如何帮助神经网络训练。

(1)、背景background

神经网络是对输入数据进行映射的嵌套函数的集合
这些函数通过参数来定义(包括权重weights和偏置biases)。
在pytorch中这些参数都是储存在tensors
训练神经网络NN包括两步:
1、正向传播神经网络对输出进行最佳猜测。它通过输入训练样本然后执行每个函数来进行猜测。
2、反向传播在反向运算中,神经网络通过其猜测的输出和真实输出的误差,按比例调整其参数。它通过从输出向前遍历,收集误差相对于函数参数(梯度)的导数,并使用梯度下降优化参数来实现这一点。

(2)、在pytorch中的用法

目标:通过torchvision加载一个与训练好的resnet 18 模型。创造一个随机数据张量来表示图片(3通道、长64、宽64),对应的标签随意的初始化。在预训练模型中的标签尺寸为(1,1000)

"""
目标:通过torchvision加载一个与训练好的resnet 18 模型。
创造一个随机数据张量来表示图片(3通道、长64、宽64),对应的标签随意的初始化。
在预训练模型中的标签尺寸为(1,1000)
"""
import torch
from torchvision.models import resnet18, ResNet18_Weights
model = resnet18(weights=ResNet18_Weights.DEFAULT)
data = torch.rand(1, 3, 64, 64)
labels = torch.rand(1, 1000)
"""
Downloading: "https://download.pytorch.org/models/resnet18-f37072fd.pth" to /var/lib/jenkins/.cache/torch/hub/checkpoints/resnet18-f37072fd.pth0%|          | 0.00/44.7M [00:00<?, ?B/s]50%|####9     | 22.3M/44.7M [00:00<00:00, 234MB/s]
100%|##########| 44.7M/44.7M [00:00<00:00, 241MB/s]
"""
# 正向传播:把训练样本输入到模型中的到模型中
prediction = model(data)# 计算损失函数:预测结果 - 真实结果(标签)
loss = (prediction - labels)# 反向传播:将损失函数通过神经网络反向传播来调整网络参数(权重、偏置)
# .backward()反向传播误差张量loss,Autograd在其中计算每一层参数的梯度,并粗存在参数属性中的.grad里面
loss.backward()# 优化器:这里使用SGD(学习率0.01,动量0.9),在优化其中优化模型中所有的参数
optim = torch.optim.SGD(model.parameters(), lr=1e-2, momentum=0.9)# 启动梯度下降:调用.step()来启动梯度下降。优化器通过存储在.grad中的梯度来调整每个参数。
optim.step() #gradient descent

(3)、Autograd

"""
具体看autograd是如何收集梯度。"""
import torch# 创建两个张量a和b。requires_grad=True:意味着autograd应该跟踪对它们的每一次操作。
a = torch.tensor([2., 3.], requires_grad=True)
b = torch.tensor([6., 4.], requires_grad=True)
Q = 3*a**3 - b**2
# 假设a,b是神经网络的参数,Q是误差。在神经网络训练中我们想要计算误差对于参数的梯度
# ∂Q/∂a = 9*a^2
# ∂Q/∂b = -2*b
# 对误差张量Q调用.backward(),autograd就会计算Q对a和n的偏导,存储在a.grad和b.grad中
# 我们需要传入一个梯度参数到.backward()中,这个参数就是Q自身的梯度,所以和Q有相同的形状
# ∂Q/∂Q = 1
external_grad = torch.tensor([1., 1.])
Q.backward(gradient=external_grad)
# 查看autograd计算的梯度是否正确
print(9*a**2 == a.grad)
print(-2*b == b.grad)
"""
tensor([True, True])
tensor([True, True])
"""

补充1:通过autograd实现向量计算 我有点没搞懂,之后再写

(4)、计算图

autograd实际上是有Function 对象组成的有向无环图(directed acyclic graph, DAG )包括数据(tensors)和一些可执行的操作(生成新的tensors)。在这个DAG中,叶是输入张量,根是输出张量。通过从根到叶跟踪该图,可以使用链式规则自动计算梯度。
在前向传播中,autograd同时做两件事:

  1. 运行forward操作计算结果张量
  2. 在DAG中维护forward操作的梯度函数(gradient function)
    当调用.backward()之后,反向传播从DAG的root开始:
  3. 根据每个.grad_fn计算梯度
  4. 将计算结果存储到参数张量的.grad属性中
  5. 使用链式法则,将损失函数一直传递到叶张量

下面是我们示例中DAG的可视化表示。在图中,箭头指向正向传播过程的方向。节点表示正向传播过程中每个操作的backward函数。蓝色的叶节点表示我们的叶张量a和b。

(4)、冻结参数

有时候有一些参数不需要再进行计算梯度了,就可以将其重计算梯度的DAG图中删除掉。具体的操作就是将requires_grad设置为False。
即使只有一个输入张量requires_grad=True,运算的输出张量也需要梯度。

x = torch.rand(5, 5)
y = torch.rand(5, 5)
z = torch.rand((5, 5), requires_grad=True)a = x + y
print(f"Does `a` require gradients? : {a.requires_grad}")
b = x + z # 即使只有一个输入张量requires_grad=True,运算的输出张量也需要梯度。
print(f"Does `b` require gradients?: {b.requires_grad}")
"""
Does `a` require gradients? : False
Does `b` require gradients?: True
"""

在NN中,不计算梯度的参数通常被称为冻结参数。如果您事先知道不需要这些参数的梯度,那么“冻结”部分模型是很有用的(这通过减少自动梯度计算提供了一些性能优势)。

3、神经网络

(1)、定义神经网络

神经网络通过torch.nn包来构建。
torch.nn依赖autograd来构建模型
nn.Module包括layers和forward(input)

下面是一个网络分类图片的例子:

这是一个简单的前馈网络。它将输入数据一个接一个地传入layers中,然后最终给出输出结果。

典型的神经网络训练流程:

  1. 首先定义神经网络,其中包括科学系的参数(权重和偏置)
  2. 创建输入数据集
  3. 将输入数据传入到神经网络中,得到输出结果
  4. 计算损失(这个输出令和正确结果之间的差值)
  5. 将损失函数的梯度gradient传回神经网络的各层参数上
  6. 更新神经网络的参数:最简单的更新规则:weight = weight - learning_rate * gradient
# 一个例子
# 定义network
import torch
import torch.nn as nn
import torch.nn.functional as Fclass Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(1, 6, 5) # 1个输入图像通道,6个输出通道,5x5卷积核self.conv2 = nn.Conv2d(6, 16, 5) # 6个输入图像通道,16个输出通道,5x5卷积核# 仿射运算: y = Wx + bself.fc1 = nn.Linear(16 * 5 * 5, 120)  # 5*5 from image dimensionself.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 10)def forward(self, x):# Max pooling over a (2, 2) windowx = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))# If the size is a square, you can specify with a single numberx = F.max_pool2d(F.relu(self.conv2(x)), 2)x = torch.flatten(x, 1) # flatten all dimensions except the batch dimensionx = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)return xnet = Net()
print(net)
"""
Net((conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))(conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))(fc1): Linear(in_features=400, out_features=120, bias=True)(fc2): Linear(in_features=120, out_features=84, bias=True)(fc3): Linear(in_features=84, out_features=10, bias=True)
)
"""
# 只需要定义正向函数,反向函数(计算梯度的地方)是使用autograd自动定义的。
# 所以可以在正向函数中使用任何张量运算。# 这个模型的可学习参数可以通过net.parameters()得到
params = list(net.parameters())
print(len(params))
print(params[0].size())  # conv1's .weight
"""
10
torch.Size([6, 1, 5, 5])
"""
# 尝试一个随机的32x32输入。注:此网络(LeNet)的预期输入大小为32x32。
# 要在MNIST数据集上使用此网络,请将数据集中的图像大小调整为32x32。
input = torch.randn(1, 1, 32, 32)
out = net(input)
print(out)
"""
tensor([[ 0.1453, -0.0590, -0.0065,  0.0905,  0.0146, -0.0805, -0.1211, -0.0394,-0.0181, -0.0136]], grad_fn=<AddmmBackward0>)
"""
# 将所有参数的梯度缓冲区归零,并使用随机梯度进行反向运算:
net.zero_grad()
out.backward(torch.randn(1, 10))

小贴士:
torch.nn只处理小批次的数据(miini-batches),所以输入应该是小批次的样本而不是一个样本。比如nn.Conv2d需要输入的张量的形状是:nSamples x nChannels x Height x Width
如果只输入一个样本,就只是用input.unsqueeze(0)来添加一个虚假的批次数。

(2)、loss 函数

nn包下有几个不同的损失函数。一个简单的损失是:nn.MSELoss,它计算输出和目标之间的均方误差。

output = net(input)
target = torch.randn(10) # 虚假的目标(只是举个例子)
target = target.view(1,-1) # reshape这个目标,让其行为1,列随意,使其和输出一样的尺寸
criterion = nn.MSELoss()
loss = criterion(output, target)# 计算实际输出output和目标target之间的均方差
print(loss)
"""
tensor(1.3581, grad_fn=<MseLossBackward0>)
"""
"""
input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d-> flatten -> linear -> relu -> linear -> relu -> linear-> MSELoss-> loss
"""
print(loss.grad_fn)  # MSELoss
print(loss.grad_fn.next_functions[0][0])  # Linear
print(loss.grad_fn.next_functions[0][0].next_functions[0][0])  # ReLU
"""
<MseLossBackward0 object at 0x7f0749d60940>
<AddmmBackward0 object at 0x7f0749d602e0>
<AccumulateGrad object at 0x7f0749d60190>
"""
# 之后反向传播损失,首先需要清除梯度
net.zero_grad()     # zeroes the gradient buffers of all parametersprint('conv1.bias.grad before backward')
print(net.conv1.bias.grad)loss.backward()print('conv1.bias.grad after backward')
print(net.conv1.bias.grad)
"""
conv1.bias.grad before backward
tensor([0., 0., 0., 0., 0., 0.])
conv1.bias.grad after backward
tensor([ 0.0117,  0.0175,  0.0045,  0.0142, -0.0022, -0.0187])
"""

注:view()函数:添加链接描述

(3)、更新参数

实践中使用的最简单的更新规则是随机梯度下降(SGD):
weight = weight - learning_rate * gradient

# 代码实现:weight = weight - learning_rate * gradient
learning_rate = 0.01
for f in net.parameters():f.data.sub_(f.grad.data * learning_rate)

然而,当你使用神经网络时,你想使用各种不同的更新规则,如SGD、Nesterov SGD、Adam、RMSProp等。为了实现这一点,我们构建了一个小程序包:torch.optim,它实现了所有这些方法。使用它非常简单:

import torch.optim as optim# create your optimizer
optimizer = optim.SGD(net.parameters(), lr=0.01)# in your training loop:
optimizer.zero_grad()   # zero the gradient buffers
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step()    # Does the update

用pytorch实现深度学习;60分钟闪电战相关推荐

  1. PyTorch深度学习60分钟闪电战:03 神经网络

    本系列是PyTorch官网Tutorial Deep Learning with PyTorch: A 60 Minute Blitz 的翻译和总结. PyTorch概览 Autograd - 自动微 ...

  2. PyTorch深度学习60分钟闪电战:04 训练一个分类器

    本系列是PyTorch官网Tutorial Deep Learning with PyTorch: A 60 Minute Blitz 的翻译和总结. PyTorch概览 Autograd - 自动微 ...

  3. PyTorch深度学习60分钟闪电战:01 PyTorch概览

    本系列是PyTorch官网Tutorial Deep Learning with PyTorch: A 60 Minute Blitz 的翻译和总结. PyTorch概览 Autograd - 自动微 ...

  4. PyTorch深度学习60分钟闪电战:02 Autograd - 自动微分

    本系列是PyTorch官网Tutorial Deep Learning with PyTorch: A 60 Minute Blitz 的翻译和总结. PyTorch概览 Autograd - 自动微 ...

  5. PyTorch 深度学习: 60 分钟极速入门

    PyTorch 深度学习: 60 分钟极速入门 2019年年初,ApacheCN组织志愿者翻译了PyTorch1.2版本中文文档(github地址),同时也获得了PyTorch官方授权,我相信已经有许 ...

  6. PyTorch深度学习60分钟入门与实战(四)训练分类器

    原文:github link,最新版会首先更新在github上 有误的地方拜托大家指出~ 训练分类器 目前为止,我们以及看到了如何定义网络,计算损失,并更新网络的权重. 现在可能会想, 数据呢? 通常 ...

  7. PyTorch深度学习:60分钟闪电战

    使用PYTORCH进行深度学习:60分钟的闪电战 本教程的目标: 全面了解PyTorch的Tensor库和神经网络. 训练一个小型神经网络对图像进行分类 请确保您有 torch 和 torchvisi ...

  8. 大佬原创 | 深度学习60讲453页pdf下载

    关注公众号 后台回复 深度学习 即可下载深度学习60讲 作者简介 机器学习实验室的号主作为一名统计专业的硕士毕业生,一路从数据分析师进阶到深度学习算法工程师.现于杭州一家AI初创公司担任深度学习算法工 ...

  9. DL框架之PyTorch:深度学习框架PyTorch的简介、安装、使用方法之详细攻略

    DL框架之PyTorch:PyTorch的简介.安装.使用方法之详细攻略 DL框架之PyTorch:深度学习框架PyTorch的简介.安装.使用方法之详细攻略 目录 PyTorch的简介 1.pyto ...

  10. 【项目实战课】从零掌握安卓端Pytorch原生深度学习模型部署

    欢迎大家来到我们的项目实战课,本期内容是<从零掌握安卓端Pytorch原生深度学习模型部署>.所谓项目课,就是以简单的原理回顾+详细的项目实战的模式,针对具体的某一个主题,进行代码级的实战 ...

最新文章

  1. MPB:中科院城环所杨军组-​​​基于DNA宏条形码的水体浮游细菌群落测序建库方法...
  2. Android MVC,MVP,MVVM模式入门——重构登陆注册功能
  3. Android10.0 Binder通信原理(四)-Native-C\C++实例分析
  4. ASP.NET 2.0中轻松实现网站换肤
  5. 禁止 pdf 下载、打印的方法
  6. 【学亮IT手记】HashMap集合精讲
  7. MyEclipse 10 之下Web Service 的创建和实现
  8. ASP.NET Core和json请求这样用真简单,axios、微信小程序得救了
  9. C#的类修饰符和成员修饰符
  10. 中文电子病例命名实体识别项目
  11. 有问有答 | 算法和数据结构精华问答
  12. NHibernate.3.0.Cookbook第三章第8节的翻译
  13. 我佛了!用 KNN 实现验证码识别,又 Get 到一招
  14. hdu 6088 Rikka with Rock-paper-scissors (2017 多校第五场 1004) 【组合数学 + 数论 + 模意义下的FFT】...
  15. 【Unity3D】摇杆
  16. 《数字化决策》连载 | 七:探索并建立决策模型(3)
  17. Navicat Premium的下载及安装
  18. 文案撰写技巧,感人文案的4大技巧
  19. ALV中的回车事件相应及添加F4帮助
  20. python 爬取财经新闻_如何用 100 行 Python 代码实现新闻爬虫?

热门文章

  1. 钢模块化结构的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  2. 北京大学ACM---poj3750---小孩报数问题(循环链表求解法)
  3. 大周期转换小周期的入场交易策略
  4. 美团实习刚入职就连开3小时会,但是工作氛围超好超和谐
  5. 今日学习在线编程题:波兰国旗问题
  6. hi nginx java_hi-nginx-java并发性能一窥
  7. python3 爬取上海预付卡备案企业信息
  8. JavaScript实现星空背景
  9. python图片处理库_Python图像处理库(1)
  10. 学习python基础(三)