当前位置: 首页 > news >正文

使用Pytorch构建自定义层并在模型中使用

使用Pytorch构建自定义层并在模型中使用

继承自nn.Module类,自定义名称为NoisyLinear的线性层,并在新模型定义过程中使用该自定义层。完整代码可以在jupyter nbviewer中在线访问。

import torch
import torch.nn as nn
from torch.utils.data import TensorDataset, DataLoaderimport numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from mlxtend.plotting import plot_decision_regions
print(torch.__version__)
print(np.__version__)
2.0.1+cu118
1.24.4
创建一个包含有噪声的线性层
class NoisyLinear(nn.Module):def __init__(self, input_size, output_size, noise_stddev=0.1):super().__init__()w = torch.Tensor(input_size, output_size)self.w = nn.Parameter(w)nn.init.xavier_uniform_(self.w)b = torch.Tensor(output_size).fill_(0)self.b = nn.Parameter(b)self.noise_stddev = noise_stddevdef forward(self, x, training=False):if training:noise = torch.normal(0.0, self.noise_stddev, x.shape)x_new = torch.add(x, noise)else:x_new = xreturn torch.add(torch.mm(x_new, self.w), self.b)

这段代码定义了一个名为 NoisyLinear 的类,它继承自 nn.Module,表示一个包含噪声的线性层。

class NoisyLinear(nn.Module):

定义一个名为 NoisyLinear 的类,它继承自 PyTorch 的 nn.Module 类。这意味着它可以被用作一种神经网络层。

    def __init__(self, input_size, output_size, noise_stddev=0.1):

初始化方法 __init__ 接受三个参数:输入大小 input_size,输出大小 output_size,以及噪声的标准差 noise_stddev(默认值为 0.1)。

        super().__init__()

调用父类 nn.Module 的初始化方法,以确保父类的相关属性和方法被正确初始化。

        w = torch.Tensor(input_size, output_size)

创建一个形状为 (input_size, output_size) 的张量 w,用于存储权重。

        self.w = nn.Parameter(w)

将权重 w 包装为 nn.Parameter,这意味着在训练过程中,PyTorch 会自动将其视为可学习参数。

        nn.init.xavier_uniform_(self.w)

使用 Xavier 均匀分布对权重 self.w 进行初始化。这是一种常用的初始化方法,有助于保持神经网络中信号的方差。

        b = torch.Tensor(output_size).fill_(0)

创建一个形状为 (output_size,) 的张量 b,并将其填充为 0,用于存储偏置。

        self.b = nn.Parameter(b)

将偏置 b 包装为 nn.Parameter,使其在训练过程中也是可学习的。

        self.noise_stddev = noise_stddev

将噪声的标准差 noise_stddev 存储为类的一个属性,用于后续的噪声计算。

    def forward(self, x, training=False):

定义前向传播方法 forward,接受输入 x 和一个布尔参数 training,指示当前是否在训练模式下。

        if training:

检查当前是否处于训练模式。

            noise = torch.normal(0.0, self.noise_stddev, x.shape)

如果是训练模式,则创建一个与输入 x 形状相同的噪声张量 noise,其服从均值为 0、标准差为 self.noise_stddev 的正态分布。

            x_new = torch.add(x, noise)

将噪声添加到输入 x 上,得到新的输入 x_new

        else:

如果不是训练模式,则执行以下代码。

            x_new = x

在非训练模式下,x_new 直接设置为输入 x,即没有添加噪声。

        return torch.add(torch.mm(x_new, self.w), self.b)

计算输出:首先用 torch.mm 进行矩阵乘法(x_new 和权重 self.w),然后将偏置 self.b 添加到结果中。最后返回计算出的输出。

总结来说,这个类实现了一个带噪声的线性变换,在线性层中可以根据训练模式选择性地添加噪声。

# 上述层的使用示例.
# 1、实例化这个层,并调用三次.
torch.manual_seed(1)noisy_layer = NoisyLinear(4, 2)
x = torch.zeros((1, 4))
print(noisy_layer(x, training=True))print(noisy_layer(x, training=True))print(noisy_layer(x, training=False))
tensor([[ 0.1154, -0.0598]], grad_fn=<AddBackward0>)
tensor([[ 0.0432, -0.0375]], grad_fn=<AddBackward0>)
tensor([[0., 0.]], grad_fn=<AddBackward0>)
在一个示例数据上,构建一个包含该自定义层的模型
# 生成一个示例数据.
np.random.seed(1)
torch.manual_seed(1)
x = np.random.uniform(low=-1, high=1, size=(200, 2))
y = np.ones(len(x))
y[x[:, 0] * x[:, 1]<0] = 0n_train = 100
x_train = torch.tensor(x[:n_train, :], dtype=torch.float32)
y_train = torch.tensor(y[:n_train], dtype=torch.float32)
x_valid = torch.tensor(x[n_train:, :], dtype=torch.float32)
y_valid = torch.tensor(y[n_train:], dtype=torch.float32)fig = plt.figure(figsize=(6, 6))
plt.plot(x[y==0, 0], x[y==0, 1], 'o', alpha=0.75, markersize=10)
plt.plot(x[y==1, 0], x[y==1, 1], '<', alpha=0.75, markersize=10)
plt.xlabel(r'$x_1$', size=15)
plt.ylabel(r'$x_2$', size=15)
plt.tight_layout()
plt.show()

在这里插入图片描述

# 创建一个DataLoader.
train_ds = TensorDataset(x_train, y_train)
batch_size = 2
torch.manual_seed(1)# 使用DataLoader加载数据,batchsize为2.
train_dl = DataLoader(train_ds, batch_size, shuffle=True)
# 创建一个新的模型,并且调用上述的自定义层.
class MyNoiseModule(nn.Module):def __init__(self):super().__init__()self.l1 = NoisyLinear(2, 4, 0.07)self.a1 = nn.ReLU()self.l2 = nn.Linear(4, 4)self.a2 = nn.ReLU()self.l3 = nn.Linear(4, 1)self.a3 = nn.Sigmoid()def forward(self, x, training=False):x = self.l1(x, training)x = self.a1(x)x = self.l2(x)x = self.a2(x)x = self.l3(x)x = self.a3(x)return xdef predict(self, x):self.eval()with torch.no_grad():x = torch.tensor(x, dtype=torch.float32)pred = self.forward(x)[:, 0]return (pred>=0.5).float()
# 模型实例化.
torch.manual_seed(1)
model = MyNoiseModule()
model
MyNoiseModule((l1): NoisyLinear()(a1): ReLU()(l2): Linear(in_features=4, out_features=4, bias=True)(a2): ReLU()(l3): Linear(in_features=4, out_features=1, bias=True)(a3): Sigmoid()
)
# 3.在训练training batch上计算预测结果.
loss_fn = nn.BCELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.015)
# 模型训练,设置epochs=200
torch.manual_seed(1)
num_epochs = 200def train(model, num_epochs, train_dl, x_valid, y_valid):loss_hist_train = [0] * num_epochsacc_hist_train = [0] * num_epochsloss_hist_valid = [0] * num_epochsacc_hist_valid = [0] * num_epochsfor epoch in range(num_epochs):for x_batch, y_batch in train_dl:pred = model(x_batch, True)[:, 0]loss = loss_fn(pred, y_batch)loss.backward()optimizer.step()optimizer.zero_grad()loss_hist_train[epoch] += loss.item()is_correct = ((pred>=0.5).float() == y_batch).float()acc_hist_train[epoch] += is_correct.mean()loss_hist_train[epoch] /= n_train/batch_sizeacc_hist_train[epoch] /= n_train/batch_sizepred = model(x_valid)[:, 0]loss = loss_fn(pred, y_valid)loss_hist_valid[epoch] = loss.item()is_correct = ((pred>=0.5).float() == y_valid).float()acc_hist_valid[epoch] += is_correct.mean()return loss_hist_train, loss_hist_valid, \acc_hist_train, acc_hist_validhistory = train(model, num_epochs, train_dl, x_valid, y_valid)
# 绘制决策边界.
fig = plt.figure(figsize=(16, 4))
ax = fig.add_subplot(1, 3, 1)
plt.plot(history[0], lw=4)
plt.plot(history[1], lw=4)
plt.legend(['Train loss', 'Validation loss'], fontsize=15)
ax.set_xlabel('Epochs', size=15)ax = fig.add_subplot(1, 3, 2)
plt.plot(history[2], lw=4)
plt.plot(history[3], lw=4)
plt.legend(['Train acc.', 'Validation acc.'], fontsize=15)
ax.set_xlabel('Epochs', size=15)ax = fig.add_subplot(1, 3, 3)
plot_decision_regions(X=x_valid.numpy(), y=y_valid.numpy().astype(np.int64),clf=model)
ax.set_xlabel(r'$x_1$', size=15)
ax.xaxis.set_label_coords(1, -0.025)
ax.set_ylabel(r'$x_2$', size=15)
ax.yaxis.set_label_coords(-0.025, 1)
plt.show()

在这里插入图片描述

相关文章:

使用Pytorch构建自定义层并在模型中使用

使用Pytorch构建自定义层并在模型中使用 继承自nn.Module类&#xff0c;自定义名称为NoisyLinear的线性层&#xff0c;并在新模型定义过程中使用该自定义层。完整代码可以在jupyter nbviewer中在线访问。 import torch import torch.nn as nn from torch.utils.data import T…...

学习记录:js算法(五十六):从前序与中序遍历序列构造二叉树

文章目录 从前序与中序遍历序列构造二叉树我的思路网上思路 总结 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示…...

qt使用QDomDocument读写xml文件

在使用QDomDocument读写xml之前需要在工程文件添加&#xff1a; QT xml 1.生成xml文件 void createXml(QString xmlName) {QFile file(xmlName);if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate |QIODevice::Text))return false;QDomDocument doc;QDomProcessin…...

Oracle架构之表空间详解

文章目录 1 表空间介绍1.1 简介1.2 表空间分类1.2.1 SYSTEM 表空间1.2.2 SYSAUX 表空间1.2.3 UNDO 表空间1.2.4 USERS 表空间 1.3 表空间字典与本地管理1.3.1 字典管理表空间&#xff08;Dictionary Management Tablespace&#xff0c;DMT&#xff09;1.3.2 本地管理方式的表空…...

springboot整合seata

一、准备 docker部署seata-server 1.5.2参考&#xff1a;docker安装各个组件的命令 二、springboot集成seata 2.1 引入依赖 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>&…...

鸿蒙开发(NEXT/API 12)【二次向用户申请授权】程序访问控制

当应用通过[requestPermissionsFromUser()]拉起弹框[请求用户授权]时&#xff0c;用户拒绝授权。应用将无法再次通过requestPermissionsFromUser拉起弹框&#xff0c;需要用户在系统应用“设置”的界面中&#xff0c;手动授予权限。 在“设置”应用中的路径&#xff1a; 路径…...

docker export/import 和 docker save/load 的区别

Docker export/import 和 docker save/load 都是用于容器和镜像的备份和迁移&#xff0c;但它们有一些关键的区别&#xff1a; docker export/import: export 作用于容器&#xff0c;import 创建镜像导出的是容器的文件系统&#xff0c;不包含镜像的元数据丢失了镜像的层级结构…...

明星周边销售网站开发:SpringBoot技术全解析

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…...

STM32+ADC+扫描模式

1 ADC简介 1 ADC(模拟到数字量的桥梁) 2 DAC(数字量到模拟的桥梁)&#xff0c;例如&#xff1a;PWM&#xff08;只有完全导通和断开的状态&#xff0c;无功率损耗的状态&#xff09; DAC主要用于波形生成&#xff08;信号发生器和音频解码器&#xff09; 3 模拟看门狗自动监…...

R语言绘制散点图

散点图是一种在直角坐标系中用数据点直观呈现两个变量之间关系、可检测异常值并探索数据分布的可视化图表。它是一种常用的数据可视化工具&#xff0c;我们通过不同的参数调整和包的使用&#xff0c;可以创建出满足各种需求的散点图。 常用绘制散点图的函数有plot()函数和ggpl…...

安装最新 MySQL 8.0 数据库(教学用)

安装 MySQL 8.0 数据库&#xff08;教学用&#xff09; 文章目录 安装 MySQL 8.0 数据库&#xff08;教学用&#xff09;前言MySQL历史一、第一步二、下载三、安装四、使用五、语法总结 前言 根据 DB-Engines 网站的数据库流行度排名&#xff08;2024年&#xff09;&#xff0…...

微信小程序开发-配置文件详解

文章目录 一&#xff0c;小程序创建的配置文件介绍二&#xff0c;配置文件-全局配置-pages 配置作用&#xff1a;注意事项&#xff1a;示例&#xff1a; 三&#xff0c;配置文件-全局配置-window 配置示例&#xff1a; 四&#xff0c;配置文件-全局配置-tabbar 配置核心作用&am…...

TCP/UDP初识

TCP是面向连接的、可靠的、基于字节流的传输层协议。 面向连接&#xff1a;一定是一对一连接&#xff0c;不能像 UDP 协议可以一个主机同时向多个主机发送消息 可靠的&#xff1a;无论的网络链路中出现了怎样的链路变化&#xff0c;TCP 都可以保证一个报文一定能够到达接收端…...

【大数据】在线分析、近线分析与离线分析

文章目录 1. 在线分析&#xff08;Online Analytics&#xff09;定义特点应用场景技术栈 2. 近线分析&#xff08;Nearline Analytics&#xff09;定义特点应用场景技术栈 3. 离线分析&#xff08;Offline Analytics&#xff09;定义特点应用场景技术栈 总结 在线分析&#xff…...

【unity进阶知识9】序列化字典,场景,vector,color,Quaternion

文章目录 前言一、可序列化字典类普通字典简单的使用可序列化字典简单的使用 二、序列化场景三、序列化vector四、序列化color五、序列化旋转Quaternion完结 前言 自定义序列化的主要原因&#xff1a; 可读性&#xff1a;使数据结构更清晰&#xff0c;便于理解和维护。优化 I…...

传奇GOM引擎架设好进游戏后提示请关闭非法外挂,重新登录,如何处理?

今天在架设一个GOM引擎的版本时&#xff0c;进游戏之后刚开始是弹出一个对话框&#xff0c;提示请关闭非法外挂&#xff0c;重新登录&#xff0c;我用的是绿盟登陆器&#xff0c;同时用的也是绿盟插件&#xff0c;刚开始我以为是绿盟登录器的问题&#xff0c;于是就换成原版gom…...

OpenCV视频I/O(15)视频写入类VideoWriter之标识视频编解码器函数fourcc()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 将 4 个字符拼接成一个 FourCC 代码。 在 OpenCV 中&#xff0c;fourcc() 函数用于生成 FourCC 代码&#xff0c;这是一种用于标识视频编解码器的…...

rust log选型

考察了最火的tracing。但是该模块不支持compact&#xff0c;仅支持根据时间进行rotate。 daily Creates a daily-rotating file appender. hourly Creates an hourly-rotating file appender. minutely Creates a minutely-rotating file appender. This will rotate the log…...

数据库-分库分表

什么是分库分表 分库分表是一种数据库优化策略。 目的&#xff1a;为了解决由于单一的库表数据量过大而导致数据库性能降低的问题 分库&#xff1a;将原来独立的数据库拆分成若干数据库组成 分表&#xff1a;将原来的大表(存储近千万数据的表)拆分成若干个小表 什么时候考虑分…...

基于SSM的校园社团管理系统的设计 社团信息管理 智慧社团管理社团预约系统 社团活动管理 社团人员管理 在线社团管理社团资源管理(源码+定制+文档)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...