transformer--编码器1(掩码张量、注意力机制、多头注意力机制)

编码器部分:

  • 由N个编码器层堆叠而成
  • 每个编码器层由两个子层连接结构组成
  • 第一个子层连接结构包括一个多头自注意力子层和规范化层以及一个残差连接。第二个子层连接结构包括一个前馈全连接子层和规范化层以及一个残差连接 

掩码张量

什么是掩码张量

掩代表遮掩,码就是我们张量中的数值,它的尺寸不定,里面一般只有1和0的元素,代表位置被遮掩或者不被遮掩,至于是0位置被遮掩还是1位置被遮掩可以自定义,因此它的作用就是让另外一个张量中的一些数值被遮掩,也可以说被替换,它的表现形式是一个张量.

掩码张量的作用:

在transformer中,掩码张量的主要作用在应用attention时,有一些生成的attention张量中的值计算有可能已知了未来信息而得到的,未来信息被看到是因为训练时会把整个输出结果都一次性进行Embedding,但是理论上解码器的的输出却不是一次就能产生最终结果的,而是一次次通过上一次结果综合得出的,因此,未来的信息可能被提前利用.所以,我们会进行遮掩.

code

from inputs import Embeddings,PositionalEncoding
import numpy as np
import torch
import matplotlib.pyplot as plt
def subsequent_mask(size):"""生成向后遮掩的掩码张量,参数size是掩码张量最后两个维度的大小,他们最好会形成一个方阵"""attn_shape = (1,size,size)# 使用np.ones方法向这个形状中添加1元素,形成上三角阵subsequent_mask = np.triu(np.ones(attn_shape),k=1).astype('uint8')# 最后将numpy类型转化为torch中的tensor,内部做一个1-的操作,# 在这个其实是做了一个三角阵的反转,subsequent_mask中的每个元素都会被1减# 如果是0,subsequent_mask中的该位置由0变成1# 如果是1,subsequent_mask中的该位置由1变成0return torch.from_numpy(1-subsequent_mask)

 输出效果分析:
通过观察可视化方阵,黄色是1的部分,这里代表被遮掩,紫色代表没有被遮掩的信息,横坐标代表目标词汇的位置,纵坐标代表可查看的位置;
我们看到,在0的位置我们一看望过去都是黄色的,都被遮住了,1的位置一眼望过去还是黄色,说明第一次词还没有产生,从第二个位置看过去,就能看到位置1的词,其他位置看不到,以此类推.

注意力机制

原理理解

原来参考文章1这篇文章已经把注意力机制讲解的很清晰了,我就不罗嗦了,大家仔细研读,后续更多的是代码实现,还可以多参考几篇,文章2,文章3

下面我使用上面文章1的图进行简要理解什么是注意力机制:

注意力说白了就是把一句话相关性的词找到,并使其更相关,弱化不相关的内容,和我们提炼一句话主要内容类似,但是如何能找到呢?现在知道的是每个词假如都是512维度的词嵌入向量构成(假如向量已经是训练好的,这个向量就是代表这个词),那么如何计算 一句话比较相关的词呢?因为每个token(词)都是一个向量表示,而向量计算相关性,直观的方法就是内积呀,所以使用内积就可以计算词与词的相关性了,虽然词宇词的相关性可以计算了,但是一句话我也不知道哪个词才是最重要的,如果不知道哪个词是重要的后续也是无法提取主要内容的,此时最直观的想法就是给词加个权重,越重要越相关,权重越大,理论上来说这个思路是可行的,但是应该怎么做呢?我现在唯一知道的就是每个词都由512维的向量构成,也知道可以计算每个词彼此之间的相似性,但是怎么加权重呢?我们可以想象数学领域的加权求和(概率论是期望),我们也可效仿,假如现在我计算第一个词和整个句子的其他词哪个最相关,最简单的做法就是把当前词的词向量和整个句子的词向量进行求内积即计算,如果和当前词的相关性很大,那计算出来的内积就会很大,同时希望权重也大,因此我们发现内积和希望的权重是正相关的,所以可以考虑直接把内积值作为权重即可,但整个权重是相对宇整个句子,权重值没有进行统一度量,因此做一个softmax就可以定性的确定比重问题。权重有了,那如何计算这个所谓的注意力呢?现在我们明确一下有哪些已知量,词嵌入向量、每个词和整个句子的其他词的权重,数学中的期望其实就相当于加权求和以此代表该物理量的平均结果,同理我们也可以求期望,这样就可以衡量当前词在所有词中的平均相关性程度,同时这个期望就是注意力值。上面的过程可以用下图表示:

上面是我的一些理解,可能会有点问题,但是不影响深入理解,同时上面只是过程,但是如何训练呢?就需要设计权重了,但是过程还是那些,设计权重通过神经网络训练可以更好的辅助整个注意力值的计算。

概率论的期望:

在物理学中,期望可以被解释为系统在一系列可能的状态中的平均预期值。它表示了在多次实验或观测中,某个物理量的平均测量结果。

考虑一个物理系统,其中某个量(例如位置、速度、能量等)是随机变量。通过对该随机变量进行多次测量或观测,可以得到一系列可能的测量结果。期望值就是对这些测量结果的加权平均,其中每个测量结果的权重是其出现的概率

物理中的期望在描述量子力学中的测量结果、统计物理中的平均性质、热力学中的热力学量等方面起着重要的作用。它提供了确定物理系统的平均行为和预期结果的数学工具。

chatgpt的回答:

当我们谈到Transformer模型中的注意力机制中的Q(Query)、K(Key)、V(Value)时,可以使用以下类比来更形象地解释:

假设你是一位学生,而你的同学是输入序列中的其他元素。你们正在进行一项任务,需要相互交流和合作。在这个场景中,你可以将自己视为查询(Q),你的同学作为键(K)和值(V)。

  • 查询(Q):你正在思考一个问题或需要某种信息。你提出了一个问题,希望得到其他同学的回答或关注。
  • 键(K):你的同学们各自拥有自己的知识和经验。他们可以提供与你问题相关的信息。这些信息可以被认为是键(K),用来衡量其他同学与你的相关性。
  • 值(V):你的同学们可以根据你的问题提供有用的答案或具体的信息。这些答案或信息可以被认为是值(V),提供给你作为参考或使用。

当你提出一个问题时,你会向你的同学们传达你的查询(Q)。然后,他们会根据自己的知识和经验,衡量他们与你的相关性,即键(K)。最后,他们会提供有用的答案或信息作为值(V),给予你参考。

在Transformer模型中,Q、K和V也是类似的。每个元素(例如词嵌入或编码器的隐藏状态)都有自己的查询(Q)、键(K)和值(V)。通过计算查询与键的相似度,可以确定每个元素对其他元素的关注程度。然后,使用这些关注权重来加权计算其他元素的值(V),以获得每个元素的上下文表示。

这个类比可以帮助我们理解注意力机制中的Q、K和V的作用,以及它们如何协同工作来建立元素之间的关联性

code

from inputs import Embeddings,PositionalEncoding
import numpy as np
import torch
import torch.nn.functional as F
import matplotlib.pyplot as plt
import mathdef subsequent_mask(size):"""生成向后遮掩的掩码张量,参数size是掩码张量最后两个维度的大小,他们最好会形成一个方阵"""attn_shape = (1,size,size)# 使用np.ones方法向这个形状中添加1元素,形成上三角阵subsequent_mask = np.triu(np.ones(attn_shape),k=1).astype('uint8')# 最后将numpy类型转化为torch中的tensor,内部做一个1-的操作,# 在这个其实是做了一个三角阵的反转,subsequent_mask中的每个元素都会被1减# 如果是0,subsequent_mask中的该位置由0变成1# 如果是1,subsequent_mask中的该位置由1变成0return torch.from_numpy(1-subsequent_mask)def attention(query, key, value, mask=None, dropout=None):""" 注意力机制的实现,输入分别是query、key、value,mask此时输入的query、key、value的形状应该是 batch * number_token * embeding"""# 获取词嵌入的维度d_k = query.size(-1)# 根据注意力公示,将query和key的转置相乘,然后乘上缩放系数得到评分,这里为什么需要转置?# batch * number_token * embeding X batch * embeding * number_token = batch * number_token * number_token# 结果是个方阵scores = torch.matmul(query,key.transpose(-2,-1))/math.sqrt(d_k)# 判断是否使用maskif mask is not None:scores = scores.masked_fill(mask==0,-1e9)# scores 的最后一维进行softmax操作,为什么是最后一维?# 因为scores是方阵,每行的所有列代表当前token和全体token的相似度值,# 因此需要在列维度上进行softmaxp_attn = F.softmax(scores,dim=-1) # 这个就是最终的注意力张量# 之后判断是否使用dropout 进行随机置0if dropout is not None:p_attn = dropout(p_attn)# 最后,根据公式将p_attn与value张量相乘获得最终的query注意力表示,同时返回注意力张量# 计算后的 维度是多少呢?# batch * number_token * number_token X batch * number_token * embeding = # batch * number_token * embedingreturn torch.matmul(p_attn,value), p_attnif __name__ == "__main__":# 词嵌入dim = 512vocab  =1000emb = Embeddings(dim,vocab)x = torch.LongTensor([[100,2,321,508],[321,234,456,324]])embr  =emb(x)print("embr.shape = ",embr.shape)# 位置编码pe = PositionalEncoding(dim,0.1) # 位置向量的维度是20,dropout是0pe_result = pe(embr)print("pe_result.shape = ",pe_result.shape)# 获取注意力值query = key = value = pe_result attn,p_attn = attention(query,key,value)print("attn.shape = ",attn.shape)print("p_attn.shape = ",p_attn.shape)print("attn: ",attn)print("p_attn: ",p_attn)# 带maskmask = torch.zeros(2,4,4)attn,p_attn = attention(query,key,value,mask)print("mask attn.shape = ",attn.shape)print("mask p_attn.shape = ",p_attn.shape)print("mask attn: ",attn)print("mask p_attn: ",p_attn)# size = 5# sm = subsequent_mask(size)# print("sm: \n",sm.data.numpy())# plt.figure(figsize=(5,5))# plt.imshow(subsequent_mask(20)[0])# plt.waitforbuttonpress()

输出:

embr.shape =  torch.Size([2, 4, 512])
pe_result.shape =  torch.Size([2, 4, 512])
attn.shape =  torch.Size([2, 4, 512])
p_attn.shape =  torch.Size([2, 4, 4])
attn:  tensor([[[ 11.8008,  30.6138,   3.5098,  ...,  18.5594, -32.1164, -23.8748],[ 39.1808,   0.0000,  16.5035,  ...,   5.2685,  -4.0213, -26.3394],[ -5.4832, -11.0806,  -0.9127,  ..., -22.0353,   0.6908,  18.5235],[ 25.6710, -14.6862,  39.7165,  ...,  23.6078, -17.8417,  25.0513]],[[ -6.4936,  -9.5071,   0.0000,  ..., -22.0353,   0.0000,  18.5235],[ 13.3299, -13.5200,  29.1027,  ..., -14.6726,   0.0000,  49.9336],[ 32.0995,  -8.8866,  39.6734,  ..., -14.7124,   9.7955,  69.3002],[ 18.8763,  10.9287,  17.8396,  ...,  44.9964, -43.6573, -50.0163]]],grad_fn=<UnsafeViewBackward0>)
p_attn:  tensor([[[1., 0., 0., 0.],[0., 1., 0., 0.],[0., 0., 1., 0.],[0., 0., 0., 1.]],[[1., 0., 0., 0.],[0., 1., 0., 0.],[0., 0., 1., 0.],[0., 0., 0., 1.]]], grad_fn=<SoftmaxBackward0>)
mask attn.shape =  torch.Size([2, 4, 512])
mask p_attn.shape =  torch.Size([2, 4, 4])
mask attn:  tensor([[[ 17.7923,   1.2117,  14.7043,  ...,   6.3501, -13.3221,  -1.6598],[ 17.7923,   1.2117,  14.7043,  ...,   6.3501, -13.3221,  -1.6598],[ 17.7923,   1.2117,  14.7043,  ...,   6.3501, -13.3221,  -1.6598],[ 17.7923,   1.2117,  14.7043,  ...,   6.3501, -13.3221,  -1.6598]],[[ 14.4530,  -5.2462,  21.6539,  ...,  -1.6060,  -8.4654,  21.9353],[ 14.4530,  -5.2462,  21.6539,  ...,  -1.6060,  -8.4654,  21.9353],[ 14.4530,  -5.2462,  21.6539,  ...,  -1.6060,  -8.4654,  21.9353],[ 14.4530,  -5.2462,  21.6539,  ...,  -1.6060,  -8.4654,  21.9353]]],grad_fn=<UnsafeViewBackward0>)
mask p_attn:  tensor([[[0.2500, 0.2500, 0.2500, 0.2500],[0.2500, 0.2500, 0.2500, 0.2500],[0.2500, 0.2500, 0.2500, 0.2500],[0.2500, 0.2500, 0.2500, 0.2500]],[[0.2500, 0.2500, 0.2500, 0.2500],[0.2500, 0.2500, 0.2500, 0.2500],[0.2500, 0.2500, 0.2500, 0.2500],[0.2500, 0.2500, 0.2500, 0.2500]]], grad_fn=<SoftmaxBackward0>)

多头注意力机制

什么是多头注意力机制:

从多头注意力的结构图中,貌似这个所谓的多个头就是指多组线性变换层,其实并不是我只有使用了一组线性变化层,即三个变换张量对Q,K,V分别进行线性变换,这些变换不会改变原有张量的尺寸,因此每个变换矩阵都是方阵,得到输出结果后,多头的作用才开始显现,每个头开始从词义层面分割输出的张量,也就是每个头都想获得一组Q,K,V进行注意力机制的计算,但是句子中的每个词的表示只获得一部分,也就是只分割了最后一维的词嵌入向量,这就是所谓的多头,将每个头的获得的输入送到注意力机制中,就形成多头注意力机制.

多头注意力机制的作用:

这种结构设计能让每个注意力机制去优化每个词汇的不同特征部分,从而均衡同一种注意力机制可能产生的偏差,让词义拥有来自更多元的表达,实验表明可以从而提升模型效果

code

from inputs import Embeddings,PositionalEncoding
import numpy as np
import torch
import torch.nn.functional as F
import torch.nn as nn
import matplotlib.pyplot as plt
import math
import copy def subsequent_mask(size):"""生成向后遮掩的掩码张量,参数size是掩码张量最后两个维度的大小,他们最好会形成一个方阵"""attn_shape = (1,size,size)# 使用np.ones方法向这个形状中添加1元素,形成上三角阵subsequent_mask = np.triu(np.ones(attn_shape),k=1).astype('uint8')# 最后将numpy类型转化为torch中的tensor,内部做一个1-的操作,# 在这个其实是做了一个三角阵的反转,subsequent_mask中的每个元素都会被1减# 如果是0,subsequent_mask中的该位置由0变成1# 如果是1,subsequent_mask中的该位置由1变成0return torch.from_numpy(1-subsequent_mask)def attention(query, key, value, mask=None, dropout=None):""" 注意力机制的实现,输入分别是query、key、value,mask此时输入的query、key、value的形状应该是 batch * number_token * embeding"""# 获取词嵌入的维度d_k = query.size(-1)# 根据注意力公示,将query和key的转置相乘,然后乘上缩放系数得到评分,这里为什么需要转置?# batch * number_token * embeding X batch * embeding * number_token = batch * number_token * number_token# 结果是个方阵scores = torch.matmul(query,key.transpose(-2,-1))/math.sqrt(d_k)# 判断是否使用maskif mask is not None:scores = scores.masked_fill(mask==0,-1e9)# scores 的最后一维进行softmax操作,为什么是最后一维?# 因为scores是方阵,每行的所有列代表当前token和全体token的相似度值,# 因此需要在列维度上进行softmaxp_attn = F.softmax(scores,dim=-1) # 这个就是最终的注意力张量# 之后判断是否使用dropout 进行随机置0if dropout is not None:p_attn = dropout(p_attn)# 最后,根据公式将p_attn与value张量相乘获得最终的query注意力表示,同时返回注意力张量# 计算后的 维度是多少呢?# batch * number_token * number_token X batch * number_token * embeding = # batch * number_token * embedingreturn torch.matmul(p_attn,value), p_attndef clones(module, N):"""用于生成相同网络层的克隆函数,N代表克隆的数量"""return nn.ModuleList([copy.deepcopy(module) for _ in range(N)])class MultiHeadedAttention(nn.Module):def __init__(self, head,embedding_dim,dropout=0.1) -> None:""" head 代表头的数量, embedding_dim 词嵌入的维度 """super(MultiHeadedAttention,self).__init__()# 因为多头是指对embedding的向量进行切分,因此头的数量需要整除embeddingassert embedding_dim % head == 0# 计算每个头获得分割词向量维度d_kself.d_k = embedding_dim // head# 传入头数self.head = head# 获得线形层对象,因为线性层是不分割词向量的,同时需要保证线性层输出和词向量维度相同# 因此线形层权重是方阵self.linears = clones(nn.Linear(embedding_dim,embedding_dim),4)# 注意力张量self.attn = None# dropoutself.dropout = nn.Dropout(p=dropout)def forward(self,query,key,value,mask=None):if mask is not None:# 拓展维度,因为有多头了mask = mask.unsqueeze(0)batch_size = query.size(0)# 输入先经过线形层,首先使用zip将网络层和输入数据连接一起,# 模型的输出利用view和transpose进行维度和形状的变换# (query,key,value) 分别对应一个线形层,经过线形层输出后,立刻对其进行切分,注意这里切分是对query经过线形层输出后进行切分,key经过线性层进行切分,value进行线性层进行切分,在这里才是多头的由来query,key,value = \[model(x).view(batch_size, -1, self.head,self.d_k).transpose(1,2) for model,x in zip(self.linears,(query,key,value))]# 将每个头的输出传入注意力层x,self.attn = attention(query,key,value,mask,self.dropout)# 得到每个头的计算结果是4维张量,需要进行形状的转换x = x.transpose(1,2).contiguous().view(batch_size,-1,self.head*self.d_k)return self.linears[-1](x)
if __name__ == "__main__":# 词嵌入dim = 512vocab  =1000emb = Embeddings(dim,vocab)x = torch.LongTensor([[100,2,321,508],[321,234,456,324]])embr  =emb(x)print("embr.shape = ",embr.shape)# 位置编码pe = PositionalEncoding(dim,0.1) # 位置向量的维度是20,dropout是0pe_result = pe(embr)print("pe_result.shape = ",pe_result.shape)# 获取注意力值# query = key = value = pe_result # attn,p_attn = attention(query,key,value)# print("attn.shape = ",attn.shape)# print("p_attn.shape = ",p_attn.shape)# print("attn: ",attn)# print("p_attn: ",p_attn)# # 带mask# mask = torch.zeros(2,4,4)# attn,p_attn = attention(query,key,value,mask)# print("mask attn.shape = ",attn.shape)# print("mask p_attn.shape = ",p_attn.shape)# print("mask attn: ",attn)# print("mask p_attn: ",p_attn)# 多头注意力测试head = 8embedding_dim = 512dropout = 0.2query = key = value = pe_result# mask 是给计算出来的点积矩阵使用的,这个矩阵是方阵,tokenmask = torch.zeros(8,4,4) mha = MultiHeadedAttention(head,embedding_dim,dropout)mha_result = mha(query,key,value,mask)print("mha_result.shape = ",mha_result)print("mha_result: ",mha_result)# size = 5# sm = subsequent_mask(size)# print("sm: \n",sm.data.numpy())# plt.figure(figsize=(5,5))# plt.imshow(subsequent_mask(20)[0])# plt.waitforbuttonpress()
embr.shape =  torch.Size([2, 4, 512])
pe_result.shape =  torch.Size([2, 4, 512])
mha_result.shape =  torch.Size([2, 4, 512])
mha_result:  tensor([[[  7.9783,  -8.5943,   2.3163,  ...,  -6.6598,   2.4111,   1.9539],[  9.3484,  -6.2983,   3.9020,  ..., -10.6280,   1.6378,   2.5569],[  3.4545,   0.5589,   2.1463,  ...,  -3.8981,   0.9144,   1.5187],[  5.1963,  -1.6135,   2.2151,  ...,  -5.7002,   0.2560,   6.7808]],[[ -3.3818,  -2.1619,  -5.1541,  ...,  -4.1403,   6.8026,  -8.9239],[ -2.3160,   0.7179,  -5.7809,  ...,  -5.7708,   8.4911, -11.9158],[  2.8323,  -2.9125,  -3.9379,  ...,  -0.9162,   9.5047,  -6.0437],[  1.7311,  -2.5926,  -5.0537,  ...,  -3.0688,   6.8356,  -4.3697]]],grad_fn=<ViewBackward0>)

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

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

相关文章

Ansible的playbook的编写和解析

目录 什么是playbook Ansible 的脚本 --- playbook 剧本 实例部署&#xff08;使用playbook安装启动httpd服务&#xff09; 1.编写一个.yaml文件 在主机下载安装http&#xff0c;将配置文件复制到opt目录下 运行playbook 在192.168.17.77主机上查看httpd服务是否成功开启…

DolphinScheduler——蔚来汽车数据治理开发平台的应用改造

目录 一、业务痛点 二、应用现状 三、技术改造 3.1 稳定性 3.1.1 滚动重启黑名单机制精准路由 3.2 易用性 依赖节点优化 补数任务优化 多 SQL 执行 原文大佬的这篇基于调度系统的数据治理案例有借鉴意义&#xff0c;这里摘抄下来用作学习和知识沉淀。 一、业务痛点 蔚…

Dell R730 2U服务器实践2:VMWare ESXi安装

缘起 刚到手边的一台Dell R730是三块硬盘raid0 &#xff0c;把我惊出一身冷汗&#xff0c;准备把它们改组成raid1 或者raid5 。 但是舍不得里面的ESXi 8 &#xff0c;寻找能否把raid0改成raid1 还不掉WSXi的方法&#xff0c;很遗憾没有找到。那样只能重装ESXi了。 ESXi软件下…

基于串流技术的p2p共享桌面共享方案

研究远控有一定时间了&#xff0c;但真正落地运用的不多&#xff0c;所以也不太上心&#xff0c;平时也只是自己diy玩玩&#xff0c;远程共享看看电视剧。 最近生成式ai大火&#xff0c;直接带动了gpu应用的相关场景&#xff0c;相关场景&#xff0c;但gpu卡又贵&#xff0c;对…

每日一题——LeetCode1556.千位分隔符

方法一 个人方法&#xff1a; 把n转为字符串&#xff0c;逆序遍历n&#xff0c;把n的每个元素加入res&#xff0c;每三次加入.&#xff0c;最后将res翻转再转为字符串即为符合题目要求的结果 var thousandSeparator function(n) {nlet res[],lenn.length-1for(let ilen;i>…

202435读书笔记|《半小时漫画中国史》——读点经济学与历史,生活更美好,趣味烧脑土地制度、商鞅变法、华丽丽的丝绸之路这里都有

202435读书笔记|《半小时漫画中国史》——读点经济学与历史&#xff0c;生活更美好&#xff0c;趣味烧脑土地制度、商鞅变法、华丽丽的丝绸之路这里都有 1. 土地政策、度量衡及税收2. 商鞅变法3. 西汉经济4. 西汉盐铁大辩论5. 西汉丝绸之路 《半小时漫画中国史&#xff1a;经济…

Typora快捷键设置详细教程(内附每个步骤详细截图)

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号&#xff1a;程序员洲洲。 &#x1f388; 本文专栏&#xff1a;本文…

在vue2中使用饼状图

1.引入vue2和echarts <script src"https://cdn.jsdelivr.net/npm/vue2.7.14/dist/vue.js"></script> <script src"https://cdn.jsdelivr.net/npm/echarts5.4.0/dist/echarts.min.js"></script> 2.1 补充基本的body内容 <div id…

存储过程基本了解

文章目录 介绍存储过程示例1. 目的2. 输入参数3. 输出参数4. 执行逻辑5. 返回值6. 示例用法7. 注意事项 存储过程的关键字有哪些简单实操 介绍 存储过程是一组预编译的SQL语句&#xff0c;以及流程控制语句&#xff0c;封装在数据库服务器中并可以被重复调用。它们可以接收参数…

5G 网络建设【华为OD机试-JAVAPythonC++JS】

题目描述 现需要在某城市进行5G网络建设&#xff0c;已经选取N个地点设置5G基站&#xff0c;编号固定为1到N&#xff0c;接下来需要各个基站之间使用光纤进行连接以确保基站能互联互通&#xff0c;不同基站之间架设光纤的成本各不相同&#xff0c;且有些节点之间已经存在光纤相…

CentOS7安装MySQL5.7

查看并卸载系统自带的 Mariadb rpm -qa|grep mariadb rpm -e --nodeps mariadb-libs-5.5.68-1.el7.x86_64 检查系统是否安装过MySQL rpm -qa | grep mysql 检查有无MySQL用户组 cat /etc/group | grep mysql cat /etc/passwd | grep mysql 创建MySQL用户组和用户 groupadd m…

特斯拉一面算法原题

来自太空的 X 帖子 埃隆马斯克&#xff08;Elon Musk&#xff09;旗下太空探索技术公司 SpaceX 于 2 月 26 号&#xff0c;从太空往社交平台 X&#xff08;前身为推特&#xff0c;已被马斯克全资收购并改名&#xff09;发布帖子。 这是 SpaceX 官号首次通过星链来发送 X 帖子&a…

SpringBoot+Vue实战:打造企业级项目管理神器

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

水豚鼠标助手 强大的鼠标美化工具

水豚鼠标助手 水豚鼠标助手是一款 鼠标换肤、屏幕画笔、放大镜、聚光灯、屏幕放大、倒计时功能的强大屏幕演示工具。 软件助手获取 水豚鼠标助手1.0.0 安装教程 第一步&#xff1a;下载后&#xff0c;双击软件安装包 第二步&#xff1a;Windows可能会出现提示弹窗&#xff…

【已亲测有效】如何彻底删除nodejs,避免影响安装新版本

第一步开始菜单搜索uninstall node.js&#xff0c;点击之后等待删除&#xff08;删除node_modules文件夹以及以下这些文件&#xff09; 第二步手动删除nodejs下载位置的其他文件夹。&#xff08;就是另外自己新建的两个文件夹node_cache和node_global&#xff09; 到这里其实应…

网络安全课程VIP介绍(比同行便宜)

免责声明 本文发布的工具和脚本&#xff0c;仅用作测试和学习研究&#xff0c;禁止用于商业用途&#xff0c;不能保证其合法性&#xff0c;准确性&#xff0c;完整性和有效性&#xff0c;请根据情况自行判断。如果任何单位或个人认为该项目的脚本可能涉嫌侵犯其权利&#xff0c…

Javaweb day7

前后端分类开发 Yapi 环境配置 vue项目简介 项目启动 更改端口号 vue项目开发流程

【c++设计模式05】创建型3:抽象工厂模式(Abstact Factory Pattern)

【c设计模式05】创建型3&#xff1a;抽象工厂模式&#xff08;Abstact Factory Pattern&#xff09; 一、工厂模式二、抽象工厂模式三、UML类图四、demo五、总结 原创作者&#xff1a;郑同学的笔记 原创地址&#xff1a;https://zhengjunxue.blog.csdn.net/article/details/132…

Spring 源码解析

文章目录 前言相关Spring的定义接口整体代码StartupStep contextRefresh this.applicationStartup.start("spring.context.refresh")prepareRefresh()obtainFreshBeanFactory()registerBeanPostProcessors(beanFactory)SpringAOP原码流程EnableAspectJAutoProxyAnno…

Linux调试器-gdb使用与冯诺依曼体系结构

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 Linux调试器-gdb使用 1. 背景 2. 开始使用 冯诺依曼体系结构 总结 前言 世上有两种耀眼的光芒&#xff0c;一种是正在升起的太阳&#xff0c;一种是正在努力学…