李沐《动手学深度学习》深度学习计算

这篇具有很好参考价值的文章主要介绍了李沐《动手学深度学习》深度学习计算。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章

李沐《动手学深度学习》预备知识 张量操作及数据处理
李沐《动手学深度学习》预备知识 线性代数及微积分
李沐《动手学深度学习》线性神经网络 线性回归
李沐《动手学深度学习》线性神经网络 softmax回归
李沐《动手学深度学习》多层感知机 模型概念和代码实现
李沐《动手学深度学习》多层感知机 深度学习相关概念


教材:李沐《动手学深度学习》

一、层和块

(一)块的概念

块(block):可以描述单个层、由多个层组成的组件或整个模型本身

  • 使用块进行抽象的一个好处是可以将一些块组合成更大的组件, 这一过程通常是递归的;
  • 通过定义代码来按需生成任意复杂度的块, 我们可以通过简洁的代码实现复杂的神经网络。

李沐《动手学深度学习》深度学习计算,李沐《动手学深度学习》学习笔记,深度学习,人工智能,pytorch,算法

(二)块的实现

  1. 从编程的角度来看,块由类表示。每个块必须提供的基本功能:
    • 将输入数据作为其前向传播函数的参数
    • 通过前向传播函数来生成输出
    • 计算其输出关于输入的梯度,可通过其反向传播函数进行访问,通常这是自动发生的;
    • 存储和访问前向传播计算所需的参数;
    • 根据需要初始化模型参数。
  2. 层和块的顺序连接由Sequential块处理:
    • nn.Sequential定义了一种特殊的Module, 即在PyTorch中表示一个块的类, 它维护了一个由Module组成的有序列表;
    • 通过net(X)调用模型来获得模型的输出,这实际上是net.call(X)的简写。 这个前向传播函数非常简单: 它将列表中的每个块连接在一起,将每个块的输出作为下一个块的输入。
net = nn.Sequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))
X = torch.rand(2, 20)
net(X)
  1. 一个块可以由许多层组成;一个块可以由许多块组成。
class NestMLP(nn.Module):
    def __init__(self):
        super().__init__()
        self.net = nn.Sequential(nn.Linear(20, 64), nn.ReLU(),
                                 nn.Linear(64, 32), nn.ReLU())
        self.linear = nn.Linear(32, 16)

    def forward(self, X):
        return self.linear(self.net(X))

chimera = nn.Sequential(NestMLP(), nn.Linear(16, 20), FixedHiddenMLP())
chimera(X)

二、参数管理

具有单隐藏层的多层感知机:

import torch
from torch import nn

net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1))
X = torch.rand(size=(2, 4))
net(X)

(一)参数访问:用于调试、诊断和可视化

当通过Sequential类定义模型时,可以通过索引来访问模型的任意层。
参数访问方式一:

print(net[2].state_dict()) #获得第二个全连接层的参数 
print(type(net[2].bias)) #第二个全连接层偏置的类型
print(net[2].bias) #第二个全连接层的偏置 (参数是复合的对象,包含值、梯度和额外信息。)
print(net[2].bias.data) #第二个全连接层偏置的数值

参数访问方式二:

net.state_dict()['2.bias'].data

从嵌套块收集参数时,也可以像通过嵌套列表索引一样访问它们

#获得第一个主要的块中、第二个子块的第一层的偏置项。
rgnet[0][1][0].bias.data

(二)参数初始化(内置初始化、自定义初始化)

深度学习框架提供默认随机初始化, 也允许我们创建自定义初始化方法, 满足我们通过其他规则实现初始化权重。

  1. 内置初始化:PyTorch的nn.init模块提供了多种预置初始化方法

调用内置初始化器,将所有权重参数初始化为标准差为0.01的高斯随机变量,偏置参数初始化为0:

def init_normal(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, mean=0, std=0.01)
        nn.init.zeros_(m.bias)
net.apply(init_normal)
net[0].weight.data[0], net[0].bias.data[0]

调用内置初始化器,将参数初始化为1:

def init_constant(m):
    if type(m) == nn.Linear:
        nn.init.constant_(m.weight, 1)
        nn.init.zeros_(m.bias)
net.apply(init_constant)
net[0].weight.data[0], net[0].bias.data[0]

使用Xavier初始化第一个神经网络层,将第三个神经网络层初始化为常量值42:

def init_xavier(m):
    if type(m) == nn.Linear:
        nn.init.xavier_uniform_(m.weight)
def init_42(m):
    if type(m) == nn.Linear:
        nn.init.constant_(m.weight, 42)

net[0].apply(init_xavier)
net[2].apply(init_42)
print(net[0].weight.data[0])
print(net[2].weight.data)
  1. 自定义初始化
    使用以下的分布为任意权重参数 w w w定义初始化方法:
    w { U ( 5 , 10 ) 可能性 0.25  0 可能性 0.5 U ( − 10 , − 5 ) 可能性 0.25 w \begin{cases} U(5,10) & \text{可能性 0.25 } \\ 0 & \text{可能性 0.5}\\ U(-10,-5) & \text{可能性 0.25} \end{cases} w U(5,10)0U(10,5)可能性 0.25 可能性 0.5可能性 0.25
def my_init(m):
    if type(m) == nn.Linear:
        print("Init", *[(name, param.shape)
                        for name, param in m.named_parameters()][0])
        nn.init.uniform_(m.weight, -10, 10)
        m.weight.data *= m.weight.data.abs() >= 5

net.apply(my_init)
net[0].weight[:2]
  1. 也可以直接设置参数值
net[0].weight.data[:] += 1
net[0].weight.data[0, 0] = 42
net[0].weight.data[0]

(三)参数绑定:在不同模型组件间共享参数

为了在多个层间共享参数,可以定义一个稠密层,然后使用它的参数来设置另一个层的参数

  • 第三个和第五个神经网络层的参数是绑定的,不仅值相等,而且由相同的张量表示;
  • 改变其中一个参数,另一个参数也会改变;
  • 反向传播期间第二个隐藏层 (即第三个神经网络层)和第三个隐藏层(即第五个神经网络层)的梯度会加在一起。
# 我们需要给共享层一个名称,以便可以引用它的参数
shared = nn.Linear(8, 8)
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(),
                    shared, nn.ReLU(),
                    shared, nn.ReLU(),
                    nn.Linear(8, 1))
net(X)
# 检查参数是否相同
print(net[2].weight.data[0] == net[4].weight.data[0])
net[2].weight.data[0, 0] = 100
# 确保它们实际上是同一个对象,而不只是有相同的值
print(net[2].weight.data[0] == net[4].weight.data[0])

三、延后初始化

  • 框架的延后初始化:直到数据第一次通过模型传递时,框架才会动态地推断出每个层的大小。

四、自定义层

(一)不带参数的层

构建一个CenteredLayer类,要从其输入中减去均值:

import torch
import torch.nn.functional as F
from torch import nn


class CenteredLayer(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, X):
        return X - X.mean()

(二)带参数的层

实现自定义版本的全连接层:

  • 需要两个参数,一个用于表示权重,另一个用于表示偏置项;
  • 使用修正线性单元作为激活函数;
  • in_units和units分别表示输入数和输出数。
class MyLinear(nn.Module):
    def __init__(self, in_units, units):
        super().__init__()
        self.weight = nn.Parameter(torch.randn(in_units, units))
        self.bias = nn.Parameter(torch.randn(units,))
    def forward(self, X):
        linear = torch.matmul(X, self.weight.data) + self.bias.data
        return F.relu(linear)

五、读写文件

(一)加载和保存张量

save和load函数可用于张量对象的文件读写:

import torch
from torch import nn
from torch.nn import functional as F

x = torch.arange(4)
torch.save(x, 'x-file')

x2 = torch.load('x-file')
x2

(二)加载和保存模型参数

class MLP(nn.Module):
    def __init__(self):
        super().__init__()
        self.hidden = nn.Linear(20, 256)
        self.output = nn.Linear(256, 10)

    def forward(self, x):
        return self.output(F.relu(self.hidden(x)))

net = MLP()
X = torch.randn(size=(2, 20))
Y = net(X)

深度学习框架提供了内置函数来保存和加载整个网络,但是只会保存模型的参数而不是保存整个模型。 因为模型本身可以包含任意代码,所以模型本身难以序列化。 因此,为了恢复模型,需要用代码生成架构, 然后从磁盘加载参数。

#模型保存
torch.save(net.state_dict(), 'mlp.params')
#用代码生成架构
clone = MLP()
#加载保存好的参数
clone.load_state_dict(torch.load('mlp.params'))
clone.eval()

六、GPU

(一)计算设备

  1. 可以指定用于存储和计算的设备,如CPU和GPU。 默认情况下,张量是在内存中创建的,然后使用CPU计算它。

在PyTorch中,CPU和GPU可以用torch.device(‘cpu’) 和torch.device(‘cuda’)表示。 应该注意的是,cpu设备意味着所有物理CPU和内存, 这意味着PyTorch的计算将尝试使用所有CPU核心。 然而,gpu设备只代表一个卡和相应的显存。 如果有多个GPU,我们使用torch.device(f’cuda:{i}') 来表示第 i i i 块GPU(从0开始)。 另外,cuda:0和cuda是等价的。

import torch
from torch import nn

torch.device('cpu'), torch.device('cuda'), torch.device('cuda:1')
  1. 查询可用GPU的数量:
torch.cuda.device_count()
  1. 定义函数try_gpu,如果申请的GPU存在,就返回GPU(i),不存在就使用CPU
def try_gpu(i=0):  
    if torch.cuda.device_count() >= i + 1:
        return torch.device(f'cuda:{i}')
    return torch.device('cpu')
  1. 定义函数try_all_gpus,返回所有可用的GPU,如果没有GPU,则返回[cpu(),]"
def try_all_gpus():  
    devices = [torch.device(f'cuda:{i}')
             for i in range(torch.cuda.device_count())]
    return devices if devices else [torch.device('cpu')]

try_gpu(), try_gpu(10), try_all_gpus()

(二)张量与GPU

  1. 可以查询张量所在的设备。 默认情况下,张量是在CPU上创建的
x = torch.tensor([1, 2, 3])
x.device
#返回device(type='cpu')
  1. 将张量存储在GPU上
X = torch.ones(2, 3, device=try_gpu())
X
Y = torch.rand(2, 3, device=try_gpu(1))
Y
  1. 复制:对多个项进行操作时不同项目必须在同一个设备上
Z = X.cuda(1)
print(X)
print(Z)
#返回结果显示X在cuda0,Z在cuda1

(三)神经网络与GPU

神经网络模型可以指定设备。 下面的代码将模型参数放在GPU上。文章来源地址https://www.toymoban.com/news/detail-814644.html

net = nn.Sequential(nn.Linear(3, 1))
net = net.to(device=try_gpu())

到了这里,关于李沐《动手学深度学习》深度学习计算的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 李沐-《动手学深度学习》--02-目标检测

    a . 算法步骤 使用启发式搜索算法来选择锚框(选出多个锚框大小可能不一,需要使用Rol pooling) 使用 预训练 好的模型(去掉分类层)对每个锚框进行特征抽取(如VGG,AlexNet…) 训练一个SVM来对每个类进行分类 训练一个线性回归模型来预测边缘框偏移 b . Rol Pooling ​ 每个锚框

    2024年01月25日
    浏览(47)
  • 李沐《动手学深度学习》线性神经网络 线性回归

    李沐《动手学深度学习》预备知识 张量操作及数据处理 李沐《动手学深度学习》预备知识 线性代数及微积分 教材:李沐《动手学深度学习》 线性回归基于的 假设 : 假设自变量和因变量之间的关系是线性的,这里通常允许包含观测值的一些噪声; 假设任何噪声都比较正常

    2024年01月21日
    浏览(96)
  • 【深度学习】动手学深度学习(PyTorch版)李沐 2.4.3 梯度【公式推导】

      我们可以连接一个多元函数对其所有变量的偏导数,以得到该函数的 梯度 (gradient)向量。 具体而言,设函数 f : R n → R f:mathbb{R}^{n}tomathbb{R} f : R n → R 的输入是一个 n n n 维向量 x ⃗ = [ x 1 x 2 ⋅ ⋅ ⋅ x n ] vec x=begin{bmatrix} x_1\\\\x_2\\\\···\\\\x_nend{bmatrix} x = ​ x 1 ​ x 2 ​

    2024年01月17日
    浏览(55)
  • 跟着李沐学AI(动手学深度学习 PyTorch版)学习笔记——03安装(环境配置d2l、pytorch)(python3.7版本+Windows+各种问题解决措施)

    1.下载Miniconda下载地址 2.在安装过程中需要勾选“Add Anaconda to the system PATH environment variable”选项 3.检验win+R,输入cmd,在文本框输入conda --version 1.点击该链接+点击jupyter记事本下载压缩包 2.解压该压缩包 3.在解压后的文件夹地址栏输入cmd回车进入命令模式。 1.conda和pip默认使⽤

    2024年02月12日
    浏览(57)
  • 李沐《动手学深度学习》d2l——安装和使用

    今天想要跟着沐神学习一下循环神经网络,在跑代码的时候,d2l出现了问题,这里记录一下解决的过程,方便以后查阅。 下载whl :https://www.cnpython.com/pypi/d2l/dl-d2l-0.15.1-py3-none-any.whl 将下载的文件放到这里: 在这个文件中右键,选择“在终端中打开” 在终端中输入如下命令:

    2024年01月17日
    浏览(59)
  • 李沐 《动手学深度学习》预备知识 线性代数与微积分

    李沐《动手学深度学习》预备知识 张量操作与数据处理 教材:李沐《动手学深度学习》 标量(scalar) 仅包含一个数值被称为标量,标量由只有一个元素的张量表示。 向量 向量可以被视为标量值组成的列表,向量由一维张量表示。一般来说,张量可以具有任意长度,取决于

    2024年01月20日
    浏览(67)
  • 动手学深度学习(李沐)的pytorch版本(包含代码和PDF版本)

    目录 网址(特别适合自学) 说明: 代码与PDF版 传送门 界面一览:    github上一个项目将《动手学深度学习》从mxnet改为了pytorch实现。感谢大佬们的工作。    特别说明该电子版网页是通过docsify部署生成的,详细了解点击here,自己有很多文章或者想做电子版本文档的强推

    2024年02月13日
    浏览(47)
  • 16 PyTorch 神经网络基础【李沐动手学深度学习v2】

    在构造自定义块之前,我们先回顾一下多层感知机的代码。 下面的代码生成一个网络,其中包含一个具有256个单元和ReLU激活函数的全连接隐藏层, 然后是一个具有10个隐藏单元且不带激活函数的全连接输出层。 层和块 构造单层神经网咯:线性层+RELU+线性层 生成2x20(2是批量

    2024年03月10日
    浏览(89)
  • 一篇文章搞定《动手学深度学习》-(李沐)PyTorch版本的所有内容

    目录 目录 简介 阅读指南 1. 深度学习简介 2. 预备知识 3. 深度学习基础 4. 深度学习计算 5. 卷积神经网络 6. 循环神经网络 7. 优化算法 8. 计算性能 9. 计算机视觉 10. 自然语言处理 环境 参考(大家可以在这里下载代码) 原书地址(大家可以在这里阅读电子版PDF内容) 引用 阅读

    2023年04月24日
    浏览(49)
  • 深度学习环境配置Anaconda+cuda+cudnn+PyTorch——李沐大神《动手学深度学习》环境配置(巨详细,持续迭代)

    Anaconda+cuda+cudnn+Pytorch(手把手教你安装深度学习环境)——这里是GPU+PyTorch版本 国内AI教学体系发展较晚,很多喜欢AI的同学都得不到系统的学习。当然我们也不否认国内一些优质的AI领域的课程和教学资料,这里我们主要推荐李沐大神推出的《动手学深度学习》,这门课程最初

    2024年02月15日
    浏览(79)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包