动手学深度学习—深度学习计算(层和块、参数管理、自定义层和读写文件)

目录

  • 1. 层和块
    • 1.1 自定义块
    • 1.2 顺序块
    • 1.3 在前向传播函数中执行代码
  • 2. 参数管理
    • 2.1 参数访问
      • 2.1.1 目标参数
      • 2.1.2 一次性访问所有参数
      • 2.1.3 从嵌套块收集参数
    • 2.2 参数初始化
      • 2.2.1 内置初始化
      • 2.2.2 自定义初始化
    • 2.3 参数绑定
  • 3. 自定义层
    • 3.1 不带参数的层
    • 3.2 带参数的层
  • 4. 读写文件
    • 4.1 加载和保存张量
    • 4.2 加载和保存模型参数
  • 5. GPU

1. 层和块

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

# 生成一个网络,其中包含一个具有256个单元和ReLU激活函数的全连接隐藏层
# 然后是一个具有10个隐藏单元且不带激活函数的全连接输出层
import torch
from torch import nn
from torch.nn import functional as Fnet = nn.Sequential(nn.Linear(20,256), nn.ReLU(), nn.Linear(256,10))X = torch.rand(2, 20)
net(X)

在这里插入图片描述

1.1 自定义块

"""自定义块:1、将输入数据作为其前向传播函数的参数。2、通过前向传播函数来生成输出(输出的形状可能与输入的形状不同)。3、计算其输出关于输入的梯度,可通过其反向传播函数进行访问。4、存储和访问前向传播计算所需的参数。5、根据需要初始化模型参数。
"""
"""多层感知机:1、输入是一个20维的输入。2、具有256个隐藏单元的隐藏层和一个10维输出层。
"""
class MLP(nn.Module):# 用模型参数声明层。这里,我们声明两个全连接层def __init__(self):# 调用MLP父类Module的构造函数来执行必要的初始化# 这样,在类实例化中也可以指定其他函数的参数,例如模型参数paramssuper().__init__()self.hidden = nn.Linear(20, 256) # 隐藏层self.out = nn.Linear(256, 10) # 输出层# 定义模型的前向传播,即如何根据输入X返回所需的模型输出def forward(self, X):# 注意,这里我们使用ReLU的函数版本,其在nn.functional模块定义return self.out(F.relu(self.hidden(X)))

在这里插入图片描述

1.2 顺序块

"""顺序块(相当于Sequential类):1、一种将块逐个追加到列表中的函数;2、一种前向传播函数,用于将输入按追加块的顺序传递给块组成的“链条”。
"""
class MySequential(nn.Module):def __init__(self, *args):# __init__函数将每个模块逐个添加到有序字典_modules中super().__init__()for idx, module in enumerate(args):# 这里,module是Module子类的一个实例。我们把它保存在'Module'类的成员# _module的类型是OrderedDict,在模块的参数初始化过程中, 系统知道在_modules字典中查找需要初始化参数的子块。self._modules[str(idx)] = moduledef forward(self, X):# OrderedDict保证了按照成员添加的顺序遍历它们for block in self._modules.values():X = block(X)return X

在这里插入图片描述

1.3 在前向传播函数中执行代码

"""实现FixedHiddenMLP模型类:1、实现一个隐藏层, 其权重(self.rand_weight)在实例化时被随机初始化,之后为常量。2、这个权重不是一个模型参数,因此它永远不会被反向传播更新。3、神经网络将这个固定层的输出通过一个全连接层。4、返回输出时做一个循环操作,输出需小于1
"""
class FixedHiddenMLP(nn.Module):def __init__(self):super().__init__()# 不计算梯度的随机权重参数。因此其在训练期间保持不变self.rand_weight = torch.rand((20, 20), requires_grad=False)self.linear = nn.Linear(20 ,20)def forward(self, X):X = self.linear(X)# 使用创建的常量参数以及relu和mm函数X = F.relu(torch.mm(X, self.rand_weight) + 1)# 复用全连接层。这相当于两个全连接层共享参数X = self.linear(X)# 控制流while X.abs().sum() > 1:X /= 2return X.sum()

在这里插入图片描述

# 混合搭配各种组合块
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)

在这里插入图片描述

2. 参数管理

  1. 访问参数,用于调试、诊断和可视化;
  2. 参数初始化;
  3. 在不同模型组件间共享参数。
import torch 
from torch import nnnet = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1))
X = torch.rand(size=(2, 4))
net(X)

在这里插入图片描述

2.1 参数访问

"""检查第二个全连接层的参数:1、这个全连接层包含两个参数,分别是该层的权重和偏置。2、两者都存储为单精度浮点数(float32)。
"""
print(net[2].state_dict())

在这里插入图片描述

2.1.1 目标参数

# 访问目标参数
print(type(net[2].bias))
print(net[2].bias)
print(net[2].bias.data)

在这里插入图片描述

2.1.2 一次性访问所有参数

# 一次性访问所有参数
print(*[(name, param.shape) for name, param in net[0].named_parameters()])
print(*[(name, param.shape) for name, param in net.named_parameters()])

在这里插入图片描述

2.1.3 从嵌套块收集参数

# 从嵌套块收集参数
def block1():return nn.Sequential(nn.Linear(4, 8), nn.ReLU(),nn.Linear(8, 4), nn.ReLU())def block2():net = nn.Sequential()for i in range(4):# 在这里嵌套net.add_module(f'block {i}', block1())return netrgnet = nn.S

在这里插入图片描述

2.2 参数初始化

"""参数初始化:1、内置初始化2、自定义初始化
"""
# 将所有权重参数初始化为标准差为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)# model.apply(fn)会递归地将函数fn应用到父模块的每个子模块submodule,也包括model这个父模块自身
net.apply(init_normal)
net[0].weight.data[0], net[0].bias.data[0]

在这里插入图片描述

2.2.1 内置初始化

# 将所有参数初始化为给定的常数,比如初始化为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)

在这里插入图片描述

2.2.2 自定义初始化

# 自定义初始化
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() >= 5net.apply(my_init)
net[0].weight[:2]
# net[0].weight[0:]

在这里插入图片描述

2.3 参数绑定

# 在多个层间共享参数: 我们可以定义一个稠密层,然后使用它的参数来设置另一个层的参数。
# 我们需要给共享层一个名称,以便可以引用它的参数
"""参数绑定:1、第三个和第五个神经网络层的参数是绑定的。 它们不仅值相等,而且由相同的张量表示。2、如果我们改变其中一个参数,另一个参数也会改变。3、由于模型参数包含梯度,因此在反向传播期间第二个隐藏层 (即第三个神经网络层)和第三个隐藏层(即第五个神经网络层)的梯度会加在一起。
"""
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])

在这里插入图片描述

3. 自定义层

我们可以用创造性的方式组合不同的层,从而设计出适用于各种任务的架构。

3.1 不带参数的层

"""自定义CenteredLayer类:1、要从其输入中减去均值;2、要构建它,我们只需继承基础层类并实现前向传播功能。
"""
import torch
import torch.nn.functional as F
from torch import nnclass CenteredLayer(nn.Module):def __init__(self):super().__init__()def forward(self, X):return X - X.mean()

在这里插入图片描述

3.2 带参数的层

"""自定义带参数的全连接层:1、该层需要两个参数,一个用于表示权重,另一个用于表示偏置项;2、使用修正线性单元作为激活函;3、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.datareturn F.relu(linear)

在这里插入图片描述

4. 读写文件

有时我们希望保存训练的模型, 以备将来在各种环境中使用(比如在部署中进行预测)。

4.1 加载和保存张量

import torch
from torch import nn
from torch.nn import functional as Fx = torch.arange(4)
torch.save(x, 'x-file')

在这里插入图片描述

# 存储一个张量列表,然后把它们读回内存。
y = torch.zeros(4)
torch.save([x, y], 'x-files')
x2, y2 = torch.load('x-files')
(x2, y2)

在这里插入图片描述

# 写入或读取从字符串映射到张量的字典
mydict = {'x': x, 'y': y}
torch.save(mydict, 'mydict')
mydict2 = torch.load('mydict')
mydict2

在这里插入图片描述

4.2 加载和保存模型参数

"""加载和保存模型参数:1、深度学习框架提供了内置函数来保存和加载整个网络;2、保存模型的参数而不是保存整个模型。
"""
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)

在这里插入图片描述

# 为了恢复模型,我们实例化了原始多层感知机模型的一个备份
clone = MLP()
clone.load_state_dict(torch.load('mlp.params'))
clone.eval()

在这里插入图片描述

5. GPU

GPU能够帮助我们更好地进行计算,使用nvidia-smi命令来查看显卡信息。

!nvidia-smi
# 定义了两个方便的函数, 这两个函数允许我们在不存在所需所有GPU的情况下运行代码
def try_gpu(i=0): #@save"""如果存在,则返回gpu(i),否则返回cpu()"""if torch.cuda.device_count() >= i + 1:return torch.device(f'cuda:{i}')return torch.device('cpu')def try_all_gpus(): #@save"""返回所有可用的GPU,如果没有GPU,则返回[cpu(),]"""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()

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/78546.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI介绍——chat gpt/文心一言/claude/bard/星火大模型/bing AI

AI体验 1. AI 介绍(注册和使用)1.1 Chat GPT1.2 文心一言1.3 Slack 上的 Claude1.3.1 Claude 介绍1.3.2 Claude 使用 1.4 Google的Bard1.4.1 Bard 介绍1.4.2 Bard 使用 1.5 科大讯飞的星火大模型1.5.1 星火大模型 介绍1.5.2 星火大模型 使用 1.6 new bin…

【100天精通python】Day23:正则表达式,基本语法与re模块详解示例

目录 专栏导读 1 正则表达式概述 2 正则表达式语法 2.1 正则表达式语法元素 2.2 正则表达式的分组操作 3 re 模块详解与示例 4 正则表达式修饰符 专栏导读 专栏订阅地址:https://blog.csdn.net/qq_35831906/category_12375510.html 1 正则表达式概述 python 的…

使用 GitHub Copilot 进行 Prompt Engineering 的初学者指南(译)

文章目录 什么是 GitHub Copilot ?GitHub Copilot 可以自己编码吗?GitHub Copilot 的底层是如何工作的?什么是 prompt engineering?这是 prompt engineering 的另一个例子 使用 GitHub Copilot 进行 prompt engineering 的最佳实践提供高级上下文&…

栈和内存溢出

7 栈 线程运行需要的内存空间。 一个栈内由多个栈帧组成,一个栈帧代表一次方法的调用。 栈帧:每个方法运行时需要的内存。 方法内:参数,局部变量,返回地址。方法执行结束,出栈。 方法一调用了方法二。 方法…

【数据挖掘torch】 基于LSTM电力系统负荷预测分析(Python代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【沁恒蓝牙mesh】CH58x系统时钟配置与计算

本文主要记录了【沁恒蓝牙mesh】CH58x系统时钟配置与计算 💖 作者简介:大家好,我是喜欢记录零碎知识点的小菜鸟。😎📝 个人主页:欢迎访问我的 Ethernet_Comm 博客主页🔥🎉 支持我&am…

[Flask]SSTI1

根据题目提示,这关应该是基于Python flask的模版注入,进入靶场环境后就是一段字符串,而且没有任何提示,有点难受,主要是没有提示注入点 随机尝试一下咯,首先尝试一下guest,GET传参 但是没有反应…

Windows上安装 jdk 环境并配置环境变量 (超详细教程)

👨‍🎓博主简介 🏅云计算领域优质创作者   🏅华为云开发者社区专家博主   🏅阿里云开发者社区专家博主 💊交流社区:运维交流社区 欢迎大家的加入! 🐋 希望大家多多支…

Kali中AWD靶机环境搭建

Kali中AWD靶机环境搭建 1、kali安装docker2、克隆项目(400多M,下载会有点久)3、进入项目4、下载镜像5、改镜像名6、比赛环境搭建6.1 启动靶机6.2 连接裁判机,启动check脚本6.3 关闭环境命令 7、 靶机访问方式7.1 web界面访问7.2 s…

C++数据结构之平衡二叉搜索树(一)——AVL的实现(zig与zag/左右双旋/3+4重构)

本文目录 00.BBST——平衡二叉搜索树01.AVL树02.AVL的插入2.1单旋——zig 与 zag2.2插入节点后的单旋实例2.3手玩小样例2.4双旋实例2.5小结 03.AVL的删除3.1单旋删除3.2双旋删除3.3小结 04.34重构05.综合评价AVL5.1优点5.2缺点 06.代码注意插入算法删除算法完整代码&#xff1a…

spring security + oauth2 使用RedisTokenStore 以json格式存储

1.项目架构 2.自己对 TokenStore 的 redis实现 package com.enterprise.auth.config;import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis…

基于SpringBoot+Vue的漫画网站设计与实现(源码+LW+部署文档等)

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

41.利用matlab 平衡方程用于图像(matlab程序)

1.简述 白平衡 白平衡的英文为White Balance,其基本概念是“不管在任何光源下,都能将白色物体还原为白色”,对在特定光源下拍摄时出现的偏色现象,通过加强对应的补色来进行补偿。 所谓的白平衡是通过对白色被摄物的颜色还原&…

opencv-34 图像平滑处理-双边滤波cv2.bilateralFilter()

双边滤波(BilateralFiltering)是一种图像处理滤波技术,用于平滑图像并同时保留边缘信息。与其他传统的线性滤波方法不同,双边滤波在考虑像素之间的空间距离之外,还考虑了像素之间的灰度值相似性。这使得双边滤波能够有…

【C语言进阶】指针的高级应用(下)

文章目录 一、指针数组与数组指针1.1 指针数组与数组指针的表达式 二、函数指针2.1 函数指针的书写方式 三、二重指针与一重指针3.1 二重指针的本质3.2 二重指针的用法3.3 二重指针与数组指针 总结 一、指针数组与数组指针 (1)指针数组的实质是一个数组,这个数组中存…

【python】使用Selenium和Chrome WebDriver来获取 【腾讯云 Cloud Studio 实战训练营】中的文章信息

文章目录 前言导入依赖库设置ChromeDriver的路径创建Chrome WebDriver对象打开网页找到结果元素创建一个空列表用于存储数据遍历结果元素并提取数据提取标题、作者、发布时间等信息判断是否为目标文章提取目标文章的描述、阅读数量、点赞数量、评论数量等信息将提取的数据存储为…

IntelliJ IDEA 2023.2 最新变化

IntelliJ IDEA 2023.2 引入 AI Assistant,通过一组由 AI 提供支持的功能助力开发。 升级的 IntelliJ 分析器现在提供编辑器内提示,使分析进程更加直观详尽。 此版本还包括有助于简化开发工作流的 GitLab 集成,以及其他多项值得关注的更新和改…

在政策+市场双轮驱动下,深眸科技助力机器视觉行业走向成熟

近年来,随着人工智能发展的不断提速,机器视觉作为其重要的前沿分支,凭借着机器代替人眼来做测量和判断的能力,广泛应用于工业领域的制造生产环节,用来保证产品质量、控制生产流程、感知环境等,并迸发出强劲…

基于新浪微博海量用户行为数据、博文数据数据分析:包括综合指数、移动指数、PC指数三个指数

基于新浪微博海量用户行为数据、博文数据数据分析:包括综合指数、移动指数、PC指数三个指数 项目介绍 微指数是基于海量用户行为数据、博文数据,采用科学计算方法统计得出的反映不同事件领域发展状况的指数产品。微指数对于收录的关键词,在指…

用Log4j 2记录日志

说明 maven工程中增加对Log4j 2的依赖 下面代码示例的maven工程中的pom.xml文件中需要增加对Log4j 2的依赖&#xff1a; <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.20.0&…