子层连接结构

目录

1、子层连接结构介绍

2、子层连接结构

3、代码实现


1、子层连接结构介绍

输入到每个子层以及规范化层的过程中,还使用了残差连接(跳跃连接),因此我们把这一部分整体结构叫子层连接(代表子层及其连接结构),在每个编码器层,都有两个子层,这两个子层加上周围的链接结构就形成了两个子层连接结构。

2、子层连接结构

3、代码实现

import numpy as np
from torch.autograd import Variable
import copy
from torch import tensor, softmax
import math
import torch.nn as nn
import torch
# 构建Embedding类来实现文本嵌入层
class Embeddings(nn.Module):def __init__(self,vocab,d_model):""":param vocab: 词表的大小:param d_model: 词嵌入的维度"""super(Embeddings,self).__init__()self.lut = nn.Embedding(vocab,d_model)self.d_model = d_modeldef forward(self,x):""":param x: 因为Embedding层是首层,所以代表输入给模型的文本通过词汇映射后的张量:return:"""return self.lut(x) * math.sqrt(self.d_model)
class PositionalEncoding(nn.Module):def __init__(self,d_model,dropout,max_len=5000):""":param d_model: 词嵌入的维度:param dropout: 随机失活,置0比率:param max_len: 每个句子的最大长度,也就是每个句子中单词的最大个数"""super(PositionalEncoding,self).__init__()self.dropout = nn.Dropout(p=dropout)pe = torch.zeros(max_len,d_model) # 初始化一个位置编码器矩阵,它是一个0矩阵,矩阵的大小是max_len * d_modelposition = torch.arange(0,max_len).unsqueeze(1) # 初始一个绝对位置矩阵 max_len * 1div_term = torch.exp(torch.arange(0,d_model,2)*-(math.log(1000.0)/d_model)) # 定义一个变换矩阵,跳跃式的初始化# 将前面定义的变换矩阵进行奇数、偶数的分别赋值pe[:,0::2] = torch.sin(position*div_term)pe[:,1::2] = torch.cos(position*div_term)pe = pe.unsqueeze(0)  # 将二维矩阵扩展为三维和embedding的输出(一个三维向量)相加self.register_buffer('pe',pe) # 把pe位置编码矩阵注册成模型的buffer,对模型是有帮助的,但是却不是模型结构中的超参数或者参数,不需要随着优化步骤进行更新的增益对象。注册之后我们就可以在模型保存后重加载时,将这个位置编码与模型参数一同加载进来def forward(self, x):""":param x: 表示文本序列的词嵌入表示:return: 最后使用self.dropout(x)对对象进行“丢弃”操作,并返回结果"""x = x + Variable(self.pe[:, :x.size(1)],requires_grad = False)   # 不需要梯度求导,而且使用切片操作,因为我们默认的max_len为5000,但是很难一个句子有5000个词汇,所以要根据传递过来的实际单词的个数对创建的位置编码矩阵进行切片操作return self.dropout(x)def subsequent_mask(size):""":param size: 生成向后遮掩的掩码张量,参数 size 是掩码张量的最后两个维度大小,它的最后两个维度形成一个方阵:return:"""attn_shape = (1,size,size) # 定义掩码张量的形状subsequent_mask = np.triu(np.ones(attn_shape),k = 1).astype('uint8') # 定义一个上三角矩阵,元素为1,再使用其中的数据类型变为无符号8位整形return torch.from_numpy(1 - subsequent_mask) # 先将numpy 类型转化为 tensor,再做三角的翻转,将位置为 0 的地方变为 1,将位置为 1 的方变为 0def attention(query, key, value, mask=None, dropout=None):""":param query: 三个张量输入:param key: 三个张量输入:param value: 三个张量输入:param mask: 掩码张量:param dropout: 传入的 dropout 实例化对象:return:"""d_model = query.size(-1)  # 得到词嵌入的维度,取 query 的最后一维大小scores = torch.matmul(query,key.transpose(-2,-1)) / math.sqrt(d_model)     # 按照注意力公式,将 query 和 key 的转置相乘,这里是将 key 的最后两个维度进行转置,再除以缩放系数,得到注意力得分张量 scoresif mask is not None:scores = torch.masked_fill(scores,mask == 0,-1e9)  # 使用 tensor 的 mask_fill 方法,将掩码张量和 scores 张量中每一个位置进行一一比较,如果掩码张量处为 0 ,则使用 -1e9 替换# scores = scores.masked_fill(mask == 0,-1e9)p_attn = softmax(scores, dim = -1) # 对 scores 的最后一维进行 softmax 操作,使用 F.softmax 方法,第一个参数是 softmax 对象,第二个参数是最后一个维度,得到注意力矩阵print('scores.shape ',scores.shape)if dropout is not None:p_attn = dropout(p_attn)return torch.matmul(p_attn,value),p_attn  # 返回注意力表示
class MultiHeadAttention(nn.Module):def __init__(self, head, embedding_dim , dropout=0.1):""":param head: 代表几个头的参数:param embedding_dim: 词向量维度:param dropout: 置零比率"""super(MultiHeadAttention, self).__init__()assert embedding_dim % head == 0     # 确认一下多头的数量可以整除词嵌入的维度 embedding_dimself.d_k = embedding_dim // head  # 每个头获得词向量的维度self.head = headself.linears = nn.ModuleList([copy.deepcopy(nn.Linear(embedding_dim, embedding_dim)) for _ in range(4)])   # 深层拷贝4个线性层,每一个层都是独立的,保证内存地址是独立的,分别是 Q、K、V以及最终的输出线性层self.attn = None   # 初始化注意力张量self.dropout = nn.Dropout(p=dropout)def forward(self, query, key, value, mask=None):""":param query: 查询query [batch size, sentence length, d_model]:param key: 待查询key [batch size, sentence length, d_model]:param value: 待查询value [batch size, sentence length, d_model]:param mask: 计算相似度得分时的掩码(设置哪些输入不计算到score中)[batch size, 1, sentence length]:return:"""if mask is not None:mask = mask.unsqueeze(1) # 将掩码张量进行维度扩充,代表多头中的第 n 个头batch_size = query.size(0)query, key, value = [l(x).view(batch_size, -1, self.head, self.d_k).transpose(1, 2) for l, x in zip(self.linears, (query, key, value))]  # 将1、2维度进行调换,目的是让句子长度维度和词向量维度靠近,这样注意力机制才能找到词义与句子之间的关系# 将每个头传递到注意力层x, self.attn = attention(query, key, value, mask=mask, dropout=self.dropout)# 得到每个头的计算结果是 4 维的张量,需要形状的转换# 前面已经将1,2两个维度进行转置了,所以这里要重新转置回来# 前面已经经历了transpose,所以要使用contiguous()方法,不然无法使用 view 方法x = x.transpose(1, 2).contiguous() \.view(batch_size, -1, self.head * self.d_k)return self.linears[-1](x)  # 在最后一个线性层中进行处理,得到最终的多头注意力结构输出
class LayerNormalization(nn.Module):def __init__(self, features, eps=1e-6):""":param features: 词嵌入的维度:param eps: 出现在规范化公式的分母中,防止分母为0"""super(LayerNormalization, self).__init__()# a 系数的默认值为1,模型的参数self.a = nn.Parameter(torch.ones(features))# b 系统的初始值为0,模型的参数self.b = nn.Parameter(torch.zeros(features))# 把 eps 传递到类中self.eps = epsdef forward(self, x):# 在最后一个维度上求 均值,并且输出维度保持不变mean = x.mean(-1, keepdim=True)std = x.std(-1, keepdim=True)return self.a * (x - mean) / (std + self.eps) + self.b
import torch.nn as nn
class SublayerConnection(nn.Module):def __init__(self, size, dropout=0.1):super(SublayerConnection,self).__init__()# 实例化了一个 LN 对象self.norm = LayerNormalization(size)self.dropout = nn.Dropout(p = dropout)def forward(self,x,sublayer):""":param x: 接受上一个层或者子层的输入作为第一个参数:param sublayer: 该子层连接中的子层函数胡作为第二个参数:return:""""首先对输出进行规范化,然后将结果交给子层处理,之后对子层进行 dropout处理" \"随机失活一些神经元,来防止过拟合,最后还有一个add操作" \"因此存在跳跃连接,所以是将输入x与dropout后的子层输出结果相加作为最终的子层连接输出"return x + self.dropout(sublayer(self.norm(x)))
# 实例化参数
d_model = 512
dropout = 0.1
max_len = 60  # 句子最大长度
#-----------------------------------------词嵌入层
# 输入 x 是 Embedding层输出的张量,形状为 2 * 4 * 512
x = Variable(torch.LongTensor([[100,2,42,508],[491,998,1,221]]))
emb = Embeddings(1000,512)   # 嵌入层
embr = emb(x)
#-----------------------------------------位置编码
pe = PositionalEncoding(d_model, dropout,max_len)
pe_result = pe(embr)
x = pe_result
#-----------------------------------------多头注意力
size = d_model = 512
head = 8
dropout = 0.2
mask = torch.zeros(2,4,4)
self_attn = MultiHeadAttention(head,d_model)
sublayer = lambda x:self_attn(x,x,x,mask)
#-----------------------------------------子层连接
sc = SublayerConnection(size,dropout)
sc_result = sc(x,sublayer)
print(sc_result)
print(sc_result.shape)
scores.shape  torch.Size([2, 8, 4, 4])
tensor([[[ 4.6194e+00, -1.0555e+01,  1.8985e+00,  ..., -4.5931e+00,-6.2920e+00, -2.1740e+01],[-2.8843e+01, -6.2767e+00,  1.6427e+01,  ..., -9.3068e+00,-3.1705e+01,  4.2651e+01],[-3.8404e+01, -5.3660e+00,  2.6868e+01,  ...,  5.8316e+01,-1.4166e+01,  4.0424e-03],[-7.4723e+00, -0.0000e+00,  5.9630e+00,  ..., -3.1421e+01,3.1544e+00, -4.5129e+01]],[[-0.0000e+00,  1.7151e+00,  1.9417e+01,  ...,  4.3568e+01,6.7298e-01, -1.2038e+01],[-6.5731e+00,  1.0342e+01, -4.5118e+00,  ..., -6.2668e+00,-2.7792e+01, -2.6723e+01],[ 2.1822e+00, -5.9824e+00, -3.2065e+00,  ..., -2.2187e-01,3.2534e+01, -6.3145e+00],[ 4.4255e+00, -1.4299e+01,  3.5308e-01,  ...,  2.6856e+01,-1.1513e+01, -1.2965e+00]]], grad_fn=<AddBackward0>)
torch.Size([2, 4, 512])

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

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

相关文章

常见Http请求形式

一、请求参数的类型 我们在做boot项目时&#xff0c;常常会向接口发起请求&#xff0c;有些请求需要附带一些参数&#xff0c;比如说分页查询&#xff0c;就需要带上pageNum(当前页)和pageSize(页面大小)等参数 有两种方式可以传递这样的参数 query类型&#xff0c;参数通过…

iPhone 15分辨率,屏幕尺寸,PPI 详细数据对比 iPhone 15 Plus、iPhone 15 Pro、iPhone 15 Pro Max

史上最全iPhone 机型分辨率&#xff0c;屏幕尺寸&#xff0c;PPI详细数据&#xff01;已更新到iPhone 15系列&#xff01; 点击放大查看高清图 &#xff01;

MDK自动生成带校验带SVN版本号的升级文件

MDK自动生成带校验带SVN版本号的升级文件 获取SVN版本信息 确保SVN安装了命令行工具&#xff0c;默认安装时不会安装命令行工具 编写一个模板头文件 svn_version.temp.h, 版本号格式为 1_0_0_SVN版本号 #ifndef __SVN_VERSION_H #define __SVN_VERSION_H#define SVN_REVISIO…

web前端面试-- js深拷贝的一些bug,特殊对象属性(RegExp,Date,Error,Symbol,Function)处理,循环引用weekmap处理

本人是一个web前端开发工程师&#xff0c;主要是vue框架&#xff0c;整理了一些面试题&#xff0c;今后也会一直更新&#xff0c;有好题目的同学欢迎评论区分享 ;-&#xff09; web面试题专栏&#xff1a;点击此处 文章目录 深拷贝和浅拷贝的区别浅拷贝示例深拷贝示例 特殊对象…

ODrive移植keil(五)—— 开环控制和电流变换

目录 一、开环控制1.1、控制原理1.2、硬件接线1.3、代码说明1.4、程序演示1.5、程序架构的体现 二、电流变换2.1、理论说明2.2、代码说明 ODrive、VESC和SimpleFOC 教程链接汇总&#xff1a;请点击 一、开环控制 在SimpleFOC系列中有开环控制的教程&#xff0c;SimpleFOC移植S…

【C进阶】内存函数

strcpy拷贝的仅仅是字符串&#xff0c;但是内存中的数据不仅仅是字符&#xff0c;所以就有了memcpy函数 1. memcpy void *memcpy &#xff08;void * destination &#xff0c;const void * source , size_t num) 函数memcpy从source的位置开始向后拷贝num个字节的数据到desti…

基于nodejs+vue驾校预约管理系统

通过科技手段提高自身的优势&#xff1b;对于驾校预约管理系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了驾校预约管理系统&#xff0c; 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;驾校预约管理系统&am…

1.go web之gin框架

Gin框架 一、准备 1.下载依赖 go get -u github.com/gin-gonic/gin2.引入依赖 import "github.com/gin-gonic/gin"3. &#xff08;可选&#xff09;如果使用诸如 http.StatusOK 之类的常量&#xff0c;则需要引入 net/http 包 import "net/http"二、基…

python之K线模式识别

1、晨星 晨星也称作早晨之星&#xff0c;它是一种三日形态的K线组合&#xff0c;第一日是阴线&#xff0c;第二日价格振幅较小&#xff0c;第三日出现阳线&#xff0c;它的一般形态如下图所示。晨星的K线组合形态一般出现在下跌的趋势之后&#xff0c;预示着价格的上升回调。其…

Java架构师缓存架构设计

目录 1 导学2 高性能概述2.1 高性能的定义和衡量指标2.2 如何实现高性能的计算机系统或软件程序2.3 木桶理论2.4 如何实现计算机系统或软件程序的高性能3 多级缓存设计3.1 浏览器缓存3.2 CDN缓存3.3 负载均衡的缓存3.4 进程内缓存3.5 分布式缓存4 缓存技术方案5 如何进行缓存拆…

C++学习day5

目录 作业&#xff1a; 1> 思维导图 2> 多继承代码实现沙发床 1>思维导图 2> 多继承代码实现沙发床 #include <iostream>using namespace std; //创建沙发类 class sofa { private:string sitting; public:sofa(){cout << "sofa的无参构造函数…

Docker系列--网络的配置

原文网址&#xff1a;Docker系列--网络的配置_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Docker的网络的配置。 官网网址 https://docs.docker.com/engine/reference/commandline/network/ 网络的默认设置 Docker启动之后&#xff0c;系统中会产生一个名为docker0的…

如何调整 Kubernetes StatefulSet 卷的大小

Kubernetes StatefulSet用于在集群内部署有状态应用程序。StatefulSet 中的每个 Pod 都可以访问即使在重新调度后仍坚持使用的本地持久卷。这使得 Pod 能够维护与其集合中的邻居不同的单独状态。 不幸的是,这些卷有一个很大的限制:Kubernetes 没有提供从 StatefulSet 对象调整…

【AI】Interesting Applications

文章目录 【盘古】【嗜睡检测】【3D AI 生成】多模态——指哪打哪【AlphaDev&#xff1a;汇编版 AlphaZero】【ChatExcel】 【盘古】 2023年7月&#xff0c;华为正式发布盘古大模型3.0&#xff0c;并提出3层模型架构。 L0&#xff1a;基础大模型&#xff0c;包括自然语言、视觉…

塑胶材料检测对激光焊机的作用

塑胶材料的激光焊接已经普遍用于各种零配件&#xff0c;而塑料的透光率是焊接工艺质量的一个重要指标。针对这类塑胶材料推出这款专门检测塑胶材料近红外透光率特性的透光率检测仪&#xff0c;对注塑件的透光率进行全画面扫描。 全球工业致力于贯彻绿色环保、节能减排发展理念&…

Selenium+Pytest自动化测试框架

前言 selenium自动化 pytest测试框架 本章你需要 一定的python基础——至少明白类与对象&#xff0c;封装继承 一定的selenium基础——本篇不讲selenium&#xff0c;不会的可以自己去看selenium中文翻译网 测试框架简介 测试框架有什么优点呢&#xff1a; 代码复用率高&…

16+sci,多重免疫组织化学+CIBERSORTx 鉴定成纤维细胞亚群。

今天给同学们分享一篇单细胞多重免疫组织化学数字细胞学&#xff08;CIBERSORTx&#xff09;的生信文章“Single-cell analysis reveals prognostic fibroblast subpopulations linked to molecular and immunological subtypes of lung cancer”&#xff0c;这篇文章于2023年1…

springboot就业信息管理系统springboot32

大家好✌&#xff01;我是CZ淡陌。一名专注以理论为基础实战为主的技术博主&#xff0c;将再这里为大家分享优质的实战项目&#xff0c;本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路…

nodejs+vue宠物店管理系统

例如&#xff1a;如何在工作琐碎,记录繁多的情况下将宠物店管理的当前情况反应给管理员决策,等等。在此情况下开发一款宠物店管理系统小程序&#xff0c; 困扰管理层的许多问题当中,宠物店管理也是不敢忽视的一块。但是管理好宠物店又面临很多麻烦需要解决,于是乎变得非常合乎时…

conda: error: argument COMMAND: invalid choice: ‘activate‘

参考:https://github.com/conda/conda/issues/13022 输入后重启terminal即可