Transformer模型开发从0到1——原理深入与项目实践

news/2025/10/6 10:19:38/文章来源:https://www.cnblogs.com/dslw0820/p/19127346

第1~5章详细介绍了Transformer模型的框架及各个功能模块的代码实现,而Transformer模型最初也是为机器翻译打造的。那么如何使用Transformer模型训练一个机器翻译的模型,又是如何使用Transformer模型进行机器翻译的?

15.1.1 基于Transformer模型的机器翻译模型训练
在实现机器翻译(中英翻译为例)前,首先需要搜集大量的中英文对照数据,并进行机器翻译模型的训练,其模型训练代码如下:

第15章/15.1.1/基于Transformer模型的机器翻译模型训练-第一部分

导入相关的库

import math
import torch
import numpy as np
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as Data
import torch.nn.functional as F
device = 'cpu' #使用cpu还是 GPU进行加速推理训练 #device = 'cuda'
epochs = 100 #transformer模型训练的步数

训练集

这里为了演示随机输入了3个句子,当然真正的模型训练是需要大量的数据

sentences = [
#中文和英语的句子,单词个数不一定相同
#编码器输入 解码器输入 解码器输出
['我 爱 你 P', 'S i love you .', 'i love you . E'],
['你 好 吗 P', 'S how are you .', 'how are you . E'],
['人 工 智 能 P', 'S artificial intelligence .', 'artificial intelligence . E']
]

Padding 字符一般定义为0,其他的单词可以自行定义

中文词库

src_vocab = {'P': 0, '我': 1, '爱': 2, '你': 3, '好': 4, '吗': 5, '人':6, '工':7, '智':8, '能':9}
src_idx2word = {i: w for i, w in enumerate(src_vocab)} #把单词的字典变成

{0: 'P', 1: '我', 2: '爱', 3: '你', 4: '好', 5: '吗', 6: '人', 7: '工',

8: '智', 9: '能'}

src_vocab_size = len(src_vocab) #输入编码器的词库数据长度

英文词库

tgt_vocab = {'P': 0, 'i': 1, 'love': 2, 'you': 3, 'how': 4, 'are': 5, 'artificial':6,'intelligence':7, 'S': 8, 'E': 9, '.': 10}
idx2word = {i: w for i, w in enumerate(tgt_vocab)} #把单词的字典变成

tgt_vocab_size = len(tgt_vocab) #输入解码器的词库数据长度

src_len = 8 #编码器输入最大句子长度,长度不够的使用pad 代替
tgt_len = 7 #解码器输入最大句子长度,长度不够的使用pad 代替

Transformer 超参数

d_model = 512 #词嵌入维度
d_ff = 2048 #前馈神经网络的维度
d_k = d_v = 64 #多头注意力机制维度
n_layers = 6 #模型搭建的层数
n_heads = 8 #多头注意力机制的头数
在初始化部分,主要是定义Transformer模型的一些超参数及输入给模型的数据集。当然要想真正训练一个机器翻译的大模型,需要搜集大量的训练数据集,而这里为了演示代码的运行过程,定义了几个中英翻译的句子。每个句子的中英文的数据按照列表类型保存起来,其每列表有三部分组成,例如['我 爱 你 P', 'S i love you .', 'i love you . E']
(1)第一部分是中文数据“我 爱 你 P”,此数据会传递给Transformer模型的编码器,作为中文输入数据,其中字母“P”代表掩码字符。
(2)第二部分是对应的英文数据“S i love you .”,此数据会传递给Transformer模型的解码器,作为英文输入数据,其字母“S”代表单词start,Transformer模型碰到此单词“S”则说明模型需要开始预测下一个单词了。
(3)第三部分是英文数据“i love you . E”,此数据作为Transformer模型解码器的输出,其字母“E”,代表单词end,Transformer模型一旦碰到字母“E”,则说明模型需要结束预测。
得到训练集数据后,需要把每个汉字及每个英文单词都使用阿拉伯数字来代替以便后期进行词嵌入操作,例如“0”代表“P”,中文数据集中“1”代表“我”,英文数据集中“1”代表“i”等。需要把数据集按照数字依次排列,当然每个数字代表的数据集单词并不是固定的,只要确保不重复使用即可,其代码如下:

第15章/15.1.1/基于Transformer模型的机器翻译模型训练-第二部分

def make_data(sentences):
#把单词序列转换为数字序列
enc_inputs, dec_inputs, dec_outputs = [], [], []
for i in range(len(sentences)):
enc_input = [src_vocab[n] for n in sentences[i][0].split()]
#每次生成这一行sentence中encoder_input对应的id编码
for _ in range(src_len-len(enc_input)):
enc_input.append(0)
dec_input = [tgt_vocab[n] for n in sentences[i][1].split()]
#每次生成这一行sentence中decoder_input对应的id编码
for _ in range(tgt_len-len(dec_input)):
dec_input.append(0)

    dec_output = [tgt_vocab[n] for n in sentences[i][2].split()]#每次生成这一行sentence中decoder_output对应的id编码for _ in range(tgt_len-len(dec_output)):dec_output.append(0)enc_inputs.append(enc_input) dec_inputs.append(dec_input)dec_outputs.append(dec_output)

return torch.LongTensor(enc_inputs), torch.LongTensor(dec_inputs), torch.LongTensor(dec_outputs)

格式化输入的数据,把单词序列转换为数字序列,数据长度不够的使用0填充

enc_inputs, dec_inputs, dec_outputs = make_data(sentences)

定义 data loader,方便模型的训练

class MyDataSet(Data.Dataset):
def init(self, enc_inputs, dec_inputs, dec_outputs):
super(MyDataSet, self).init()
self.enc_inputs = enc_inputs
self.dec_inputs = dec_inputs
self.dec_outputs = dec_outputs
def len(self):
return self.enc_inputs.shape[0]
def getitem(self, idx):
return self.enc_inputs[idx], self.dec_inputs[idx], self.dec_outputs[idx]

加载数据集

loader = Data.DataLoader(MyDataSet(enc_inputs, dec_inputs, dec_outputs),batch_size=3, shuffle=True)
数据集处理完成后,还需要把数据集中英文与中文单词都删除,以便获取完全数字的数据。make_data函数的功能便是输入中英文数据集,获取编码器的数字输入数据及解码器的输入输出数字数据。由于定义了编码器与解码器最大句子长度,因此此函数执行完成后,其输入数据长度不足定义的句子长度的,需要使用数字“0”进行填充。代码执行完成后,输出如下:
enc_inputs:
tensor([[1, 2, 3, 0, 0, 0, 0, 0],
[3, 4, 5, 0, 0, 0, 0, 0],
[6, 7, 8, 9, 0, 0, 0, 0]])
dec_inputs:
tensor([[ 8, 1, 2, 3, 10, 0, 0],
[ 8, 4, 5, 3, 10, 0, 0],
[ 8, 6, 7, 10, 0, 0, 0]])
dec_outputs:
tensor([[ 1, 2, 3, 10, 9, 0, 0],
[ 4, 5, 3, 10, 9, 0, 0],
[ 6, 7, 10, 9, 0, 0, 0]])
可以看到编码器与解码器的输入数据都被格式化成了数字数据,使用此数据就可以执行Transformer模型相关的功能模块代码了,其代码如下:

第15章/15.1.1/基于Transformer模型的机器翻译模型训练-第三部分

词嵌入

class Embeddings(nn.Module): #定义一个Embeddings类,继承自nn.Module
def init(self, vocab_size, d_model):

初始化函数,输入词汇表大小和词向量维度

    super(Embeddings, self).__init__()  #调用父类的初始化函数self.emb = nn.Embedding(vocab_size,d_model)#定义一个nn.Embedding对象,用于词向量映射 
def forward(self,x):  #前向传播函数,输入xreturn self.emb(x)  #返回x的词向量映射结果

位置编码 #定义一个PositionalEncoding类,继承自nn.Module

class PositionalEncoding(nn.Module):
#初始化函数,输入词向量维度、DropOut率和最大序列长度
def init(self, d_model, DropOut=0.1, max_len=5000):
super(PositionalEncoding, self).init() #调用父类的初始化函数
#定义一个nn.DropOut对象,用于DropOut操作
self.DropOut = nn.DropOut(p=DropOut)
#初始化一个全零矩阵,用于位置编码
pe = torch.zeros(max_len, d_model)
#创建一个从0到max_len-1的位置向量
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
#计算每个维度上的频率因子
div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
#每个偶数维度上应用正弦函数
pe[:, 0::2] = torch.sin(position * div_term)
#每个奇数维度上应用余弦函数
pe[:, 1::2] = torch.cos(position * div_term)
#将位置编码矩阵转置并添加一个批次维度
pe = pe.unsqueeze(0).transpose(0, 1)
#将位置编码矩阵注册为一个缓冲区,不需要梯度更新
self.register_buffer('pe', pe)
def forward(self, x): #前向传播函数,输入x
x = x + self.pe[:x.size(0), :] #将位置编码添加到x上
return self.DropOut(x) #应用DropOut操作并返回结果

获取attention的pad mask,输入query序列和key序列 pad mask

def get_attn_pad_mask(seq_q, seq_k):
batch_size, len_q = seq_q.size() #获取query序列的批次大小和序列长度
batch_size, len_k = seq_k.size() #获取key序列的批次大小和序列长度

创建一个pad mask,1表示pad位置,0表示非pad位置

pad_attn_mask = seq_k.data.eq(0).unsqueeze(1)

扩展pad mask到[batch_size, len_q, len_k]的形状

return pad_attn_mask.expand(batch_size, len_q, len_k)  

获取attention的subsequence mask,输入序列 sequence mask

def get_attn_subsequence_mask(seq):
#获取attention的形状
attn_shape = [seq.size(0), seq.size(1), seq.size(1)]

创建一个上三角矩阵,1表示可以attention,0表示不可以attention

subsequence_mask = np.triu(np.ones(attn_shape), k=1)

将上三角矩阵转换为byte类型的tensor并返回

return torch.from_numpy(subsequence_mask).byte()
输入数据首先需要经过词嵌入与位置编码后,才可以传递给Transformer模型进行注意力机制的计算,这里并定义了pad_mask与sequence_mask矩阵的计算函数,方便计算编码器与解码器的掩码矩阵,然后搭建注意力机制计算代码,代码如下:

第15章/15.1.1/基于Transformer模型的机器翻译模型训练-第四部分

self attention 注意力机制,根据注意力机制的计算公式计算注意力机制

class ScaledDotProductAttention(nn.Module):
def init(self):
super(ScaledDotProductAttention, self).init()
def forward(self, Q, K, V, attn_mask):
#Q: [batch_size, len_q, d_k] #[2,5,512]
#K: [batch_size, len_k, d_k] #[2,5,512]
#V: [batch_size, len_v(=len_k), d_v] #[ 2,5,512]
#attn_mask: [batch_size, seq_len, seq_len] #[2,5,5]
#scores:[batch_size,len_q,len_k] #[2,5,5]
#计算注意力机制矩阵
scores = torch.matmul(Q, K.transpose(-1, -2)) / np.sqrt(d_k)
if attn_mask is not None: 判断是否存在掩码矩阵
#[2,5,5]若有掩码矩阵,需要置为一个很小的数
scores.masked_fill_(attn_mask, -1e9)
attn = nn.Softmax(dim=-1)(scores)#对最后一个维度(v)做softmax
#result: [batch_size, len_q, d_v] #[2,5,512]
result = torch.matmul(attn, V) #[2,5,512] 计算最终的注意力数据
return result, attn #attn注意力矩阵(用于可视化)

multi-head attention 多头注意力,分开8个头,分别做注意力机制

class MultiHeadAttention(nn.Module):
def init(self):
super(MultiHeadAttention, self).init()
#定义 Wq, Wk, Wv, Wo 四个矩阵
self.W_Q = nn.Linear(d_model, d_k * n_heads, bias=False)#512512
self.W_K = nn.Linear(d_model, d_k * n_heads, bias=False)#512
512
self.W_V = nn.Linear(d_model, d_v * n_heads, bias=False)#512512
self.W_O = nn.Linear(n_heads * d_v, d_model, bias=False)#512
512
def forward(self, input_Q, input_K, input_V, attn_mask):
#input_Q: [batch_size, len_q, d_model] #[2, 5, 512]
#input_K: [batch_size, len_k, d_model] #[2, 5, 512]
#input_V: [batch_size, len_v(=len_k), d_model] #[2, 5, 512]
#attn_mask: [batch_size, seq_len, seq_len] #[2, 5, 5]
residual, batch_size = input_Q, input_Q.size(0)

[ 25512]保存输入数据,便于计算残差

    #B: batch_size, S:seq_len, D: dim#(B,S,D)-proj-> (B,S,D_new)-split->(B,S,Head,W)-trans->(B,Head,S,W)#Q: [batch_size, n_heads, len_q, d_k] #[2, 8, 5, 64]#计算多头注意力机制的QKV矩Q = self.W_Q(input_Q).view(batch_size, -1, n_heads, d_k).transpose(1, 2) #K: [batch_size, n_heads, len_k, d_k]  #[2, 8, 5, 64]K = self.W_K(input_K).view(batch_size, -1, n_heads, d_k).transpose(1, 2)#V: [batch_size, n_heads, len_v(=len_k), d_v] #[2, 8, 5, 64]V = self.W_V(input_V).view(batch_size, -1, n_heads, d_v).transpose(1, 2)#attn_mask:[batch_size,seq_len,seq_len] ->->->->#->->->->->[batch_size,n_heads,seq_len,seq_len]计算掩码矩阵attn_mask = attn_mask.unsqueeze(1).repeat(1, n_heads, 1, 1)#[2,8,5,5]#result:[batch_size,n_heads,len_q,d_v]                   #[2,8,5,64]#attn:[batch_size,n_heads,len_q, len_k]                  #[2,8,5,5]#计算多头注意力机制result, attn = ScaledDotProductAttention()(Q, K, V, attn_mask)#result:[batch_size,n_heads,len_q,d_v]->[batch_size,len_q,n_heads*d_v]#contat heads  #result [2,5,512] #合并8个头的数据result = result.transpose(1, 2).reshape(batch_size, -1, n_heads * d_v)#[batch_size, len_q, d_model]#[2,5,512]#Wo线性变换output = self.W_O(result)#[2,5,512]残差连接与数据归一化return nn.LayerNorm(d_model)(output + residual), attn  

feed forward前馈神经网络

class PoswiseFeedForwardNet(nn.Module):
def init(self):
super(PoswiseFeedForwardNet, self).init()
self.fc = nn.Sequential(
nn.Linear(d_model, d_ff, bias=False), #W1 [512,2048]
nn.ReLU(), #max(0,w1*x+b1)
nn.Linear(d_ff, d_model, bias=False)) #W2 [2048,512]
def forward(self, inputs):
#inputs: [batch_size, seq_len, d_model]

根据前馈神经网络的公式计算前馈神经网络数据

    residual = inputsoutput = self.fc(inputs)#[batch_size, seq_len, d_model]return nn.LayerNorm(d_model)(output + residual)  

搭建编码器与解码器的功能模块代码,主要包含注意力机制与多头注意力机制的代码实现及前馈神经网络的代码实现,有了以上的功能代码模块,便可以搭建整个Transformer模型了,代码如下:

第15章/15.1.1/基于Transformer模型的机器翻译模型训练-第五部分

解码器搭建

class EncoderLayer(nn.Module):
def init(self):
super(EncoderLayer, self).init()
self.enc_self_attn = MultiHeadAttention()
self.pos_ffn = PoswiseFeedForwardNet()
def forward(self, enc_inputs, enc_self_attn_mask):
#enc_inputs: [batch_size, src_len, d_model]
#mask矩阵(pad mask or sequence mask)
#enc_self_attn_mask: [batch_size, src_len, src_len]
#enc_outputs: [batch_size, src_len, d_model] [2,5,512]
#attn: [batch_size, n_heads, src_len, src_len] [2,5,5]
enc_outputs, attn = self.enc_self_attn(enc_inputs, enc_inputs,
enc_inputs,enc_self_attn_mask)
enc_outputs = self.pos_ffn(enc_outputs) #[2,5,512]
#enc_outputs: [batch_size, src_len, d_model]
return enc_outputs, attn

class Encoder(nn.Module):
def init(self):
super(Encoder, self).init()
self.src_emb = Embeddings(src_vocab_size, d_model) #Embedding
self.pos_emb = PositionalEncoding(d_model) #Transformer中位置编码
self.layers = nn.ModuleList([EncoderLayer() for _ in range(n_layers)])

def forward(self, enc_inputs):#enc_inputs: [batch_size, src_len]                       #[2,5]enc_outputs = self.src_emb(enc_inputs)                    #[2, 5, 512]#enc_outputs [batch_size, src_len, src_len]              #[2, 5, 512]enc_outputs = self.pos_emb(enc_outputs.transpose(0,1)).transpose(0, 1) #Encoder输入 pad mask矩阵 #[batch_size, src_len, src_len]    [2,5,5]enc_self_attn_mask = get_attn_pad_mask(enc_inputs, enc_inputs)  enc_self_attns = []  #这个主要是为了画热力图,用来看各个词之间的关系for layer in self.layers:  #for循环访问nn.ModuleList,进行6次循环堆叠#enc_outputs: [batch_size, src_len, d_model],         [2, 5, 512]#enc_self_attn: [batch_size, n_heads, src_len, src_len] [2,8,5,5]enc_outputs, enc_self_attn = layer(enc_outputs,enc_self_attn_mask)  enc_self_attns.append(enc_self_attn)  #可视化return enc_outputs, enc_self_attns #enc_outputs           [2, 5, 512]

解码器搭建

class DecoderLayer(nn.Module):
def init(self):
super(DecoderLayer, self).init()
#decoder 自注意力机制
self.dec_self_attn = MultiHeadAttention()
#decoder enc_dec_attention交互层
self.dec_enc_attn = MultiHeadAttention()
#decoder 前馈神经网络
self.pos_ffn = PoswiseFeedForwardNet()
def forward(self, dec_inputs, enc_outputs, dec_self_attn_mask, dec_enc_attn_mask):
#dec_inputs: [batch_size, tgt_len, d_model] #[2,5,512]
#dec_self_attn_mask: [batch_size, tgt_len, tgt_len] #[2,5,5]
#dec_outputs: [batch_size, tgt_len, d_model] #[2,5,512]
#dec_self_attn: [batch_size, n_heads, tgt_len, tgt_len] #[2,8,5,5]
#decoder 自注意力机制,Q,K,V来自Decoder的输入 #[2,5,512]
dec_outputs, dec_self_attn = self.dec_self_attn(dec_inputs, dec_inputs,
dec_inputs,dec_self_attn_mask)
#dec_outputs: [batch_size, tgt_len, d_model] #[2,5,512]
#enc_outputs: [batch_size, src_len, d_model] #[2,5,512]
#dec_enc_attn: [batch_size, h_heads, tgt_len, src_len] #[2,8,5,5]
#dec_enc_attn_mask: [batch_size, tgt_len, src_len] #[2,5,5]
#这里encoder输入长度与decoder输入句子长度不一定相等,
#dec_enc_Attention层的Q(来自decoder), K,V(来自encoder) #[2,5,512]
dec_outputs, dec_enc_attn = self.dec_enc_attn(dec_outputs, enc_outputs,
enc_outputs,dec_enc_attn_mask)
dec_outputs = self.pos_ffn(dec_outputs) #[2,5,512]
#dec_self_attn, dec_enc_attn两个矩阵是为了可视化
return dec_outputs, dec_self_attn, dec_enc_attn

class Decoder(nn.Module):
def init(self):
super(Decoder, self).init()
self.tgt_emb = Embeddings(tgt_vocab_size, d_model)
self.pos_emb = PositionalEncoding(d_model)
#DecoderLayer block 一共6层,跟encoder 相同
self.layers = nn.ModuleList([DecoderLayer() for _ in range(n_layers)])
def forward(self, dec_inputs, enc_inputs, enc_outputs):
#dec_inputs: [batch_size, tgt_len] [2,5]
#enc_inputs: [batch_size, src_len] [2,5]
#enc_outputs 用在Encoder-Decoder Attention交互层
#enc_outputs: [batch_size, src_len, d_model] [2,5,512]
dec_outputs = self.tgt_emb(dec_inputs) #[2,5,512]
#dec_outputs 位置编码+embedding 词嵌入 #[2,5,512]
dec_outputs = self.pos_emb(dec_outputs.transpose(0, 1)).transpose(0, 1)
#Decoder输入序列的pad mask矩阵 #[2,5,5]
dec_self_attn_pad_mask = get_attn_pad_mask(dec_inputs, dec_inputs)
#Decoder输入序列的sequence mask矩阵 #[2,5,5]
dec_self_attn_subsequence_mask = get_attn_subsequence_mask(dec_inputs)
#Decoder中把pad mask + sequence mask
#既屏蔽了pad的信息,也屏蔽了未来的信息 #[2,5,5]
dec_self_attn_mask = torch.gt((dec_self_attn_pad_mask +
dec_self_attn_subsequence_mask),0)
#dec_enc mask主要用于encoder-decoder attention交互层
#因为dec_enc_attn输入是encoder的K,V,decoder的Q
#求Attention时是用v1,v2,..vm去加权,要把pad对应的v_i的相关系数设为0
#dec_inputs提供expand的size
#[batc_size, tgt_len, src_len]这里tgt_len与src_len不一定相等#[2,5,5]
dec_enc_attn_mask = get_attn_pad_mask(dec_inputs, enc_inputs)
#用于可视化的矩阵,一个Self-Attention 一个enc_dec_attention
dec_self_attns, dec_enc_attns = [], []
for layer in self.layers: #遍历decoder block n = 6
#dec_outputs:[batch_size,tgt_len,d_model]decoder的输入[2,5,512]
#enc_outputs:[batch_size,src_len,d_model]encoder的输入[2,5,512]
#dec_self_attn:[batch_size,n_heads,tgt_len,tgt_len] [2,8,5,5]
#dec_enc_attn:[batch_size,h_heads,tgt_len,src_len] [2,8,5,5]
#Decoder的Block是上一个Block的输出dec_outputs(变化矩阵)
#Encoder网络的输出enc_outputs(固定矩阵)
dec_outputs, dec_self_attn, dec_enc_attn = layer(dec_outputs,
enc_outputs, dec_self_attn_mask,dec_enc_attn_mask)
dec_self_attns.append(dec_self_attn) #可视化矩阵 [2,8,5,5]
dec_enc_attns.append(dec_enc_attn) #可视化矩阵 [2,8,5,5]
#dec_outputs: [batch_size, tgt_len, d_model] #[2,5,512]
return dec_outputs, dec_self_attns, dec_enc_attns

Transformer 模型搭建

class Transformer(nn.Module):
def init(self):
super(Transformer, self).init()
self.encoder = Encoder() #编码器
self.decoder = Decoder() #解码器
#最终模型的输出经过linear层进行shape转换
self.projection = nn.Linear(d_model, tgt_vocab_size, bias=False)

def forward(self, enc_inputs, dec_inputs):#enc_inputs: [batch_size, src_len] [2,5]#dec_inputs: [batch_size, tgt_len] [2,5]#enc_outputs: [batch_size, src_len, d_model], [2,5,512]#enc_self_attns: [n_layers, batch_size, n_heads, src_len, src_len]#经过Encoder网络后,输出[batch_size, src_len, d_model] [2,5,512]enc_outputs, enc_self_attns = self.encoder(enc_inputs)#dec_outputs: [batch_size, tgt_len, d_model]           [2,5,512]#dec_self_attns: [n_layers, batch_size, n_heads, tgt_len, tgt_len]#dec_enc_attn: [n_layers, batch_size, tgt_len, src_len][8,2,5,5]dec_outputs, dec_self_attns, dec_enc_attns = self.decoder(dec_inputs, enc_inputs, enc_outputs)#dec_outputs: [batch_size, tgt_len, d_model]       [2,5,512]-> #dec_logits: [batch_size, tgt_len, tgt_vocab_size] [2,5,10]#线性变换,把输出数据维度转换到序列长度dec_logits = self.projection(dec_outputs) #softmax输出,得到每个输出的概率,概率和为1dec_logits = F.log_softmax(dec_logits, dim=-1) return (dec_logits.view(-1, dec_logits.size(-1)), enc_self_attns, dec_self_attns, dec_enc_attns)

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

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

相关文章

常州品牌网站建设免费文字变形logo设计

在软件工程中,设计模式是为了解决常见的软件设计问题而形成的一套经典解决方案。这些模式不仅能够帮助开发者提高设计的灵活性和代码的重用性,还能使问题的解决方案更加清晰、易于理解。《设计模式精解-GoF 23种设计模式》一书中所列举的23种…

毕业设计 网站开发简单吗蘑菇街网站模板

最近偶尔有用户反馈某些 HTTP 接口出现超时问题,而 web 服务端的 Trace 监控没有出现 http 返回值为 503 等异常情况。出现这种情况一般是web容器出现问题,客户端连 Arthas是Alibaba开源的Java诊断工具,深受开发者喜爱。 Github:h…

鸿蒙OS基于UniApp的区块链钱包创建实践:打造支持鸿蒙生态的Web3应用#三方框架 #Uniapp

鸿蒙OS&基于UniApp的区块链钱包创建实践:打造支持鸿蒙生态的Web3应用#三方框架 #Uniapppre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !impor…

CF700E

题目大意: 给定一个长为 \(n\) 的字符串 \(S\),你要找到最大的 \(k\),使得存在 \(s_{1} \sim s_{k}\) 使得 \(s_{1}\) 是 \(S\) 子串 且 \(s_{i}\) 在 \(s_{i - 1}\) 中作为子串至少出现两次。 \(n \le 2 \times 10…

价值弥漫:“AI元人文”的场域革命与共生之路

价值弥漫:“AI元人文”的场域革命与共生之路 本文探讨“价值弥漫”作为“AI元人文”核心实现路径的哲学基础与技术内涵,提出从“工具性AI”到“场域性AI”的范式转变。 引言:从“价值对齐”到“价值弥漫”的范式迁移…

手机app设计网站公司网站建设需要什么科目

流程图 一、前期准备 1.1 打开百度智能云官网找到管理中心创建应用 全选文字识别 1.2 保存好AppId、API Key和Secret Key 1.3 找到通用场景文字识别,立即使用 1.4 根据自己需要,选择要开通的项目 二、代码编写 以通用文字识别(高精度版&am…

k8s之pod概念

1. pod基本概念 2. pod网络概念 3. pod的生命周期和状态 4. 探针 5. 创建pod 6. 总结‍ 1. pod基本概念Kubernetes 中,Pod 是最小的网络调度单位, 每个pod可以放多个容器(例如可以放多个docke容器在同一个pod中运行…

鸿蒙版Taro 搭建开发环境 - 教程

鸿蒙版Taro 搭建开发环境 - 教程2025-10-06 10:09 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !import…

CF 1055 Div.1+Div.2

F - Triple Attack 我会了。 G - Query Jungle 我会了。 H1 - Victorious Coloring (Easy Version) 我不会。 H2 - Victorious Coloring (Hard Version) 我不会。

LUCKY STUN穿透在Windows上使用UPnP工具为BT客户端自动添加内外端口号不同的映射规则

LUCKY STUN穿透在Windows上使用UPnP工具为BT客户端自动添加内外端口号不同的映射规则2024.02.07 关于本教程 本教程基于:基于stun穿透工具LUCKY,使BT客户端绿灯、开放TCP端口的办法(进化版) 在该教程中实现了使用 …

深圳门户网站制作wordpress 鼠标特效

摘要: 4月30日,阿里云发现,俄罗斯黑客利用Hadoop Yarn资源管理系统REST API未授权访问漏洞进行攻击。 Hadoop是一款由Apache基金会推出的分布式系统框架,它通过著名的 MapReduce 算法进行分布式处理,Yarn是Hadoop集群的…

2026 NOI 做题记录(五)

推荐阅读:A、B、E、F、N、O、R、T、U、WContest Link \(\text{By DaiRuiChen007}\)*A. [CF2097F] Lost Luggage (7.5) Problem Link 先建立网络流,每层的点 \(i\) 向下一层 \(i-1,i,i+1\) 分别连权值 \(a_i,b_i,c_i\…

ARC 207 (Div.1)

A - Affinity for Artifacts 我不会。我会了。 B - Balanced Neighbors 2然后 \(n\leq 5\) 无解。 C - Combine to Make Non-decreasing 容易发现原题目等价于将原序列分成若干段,要求段之间的 \(\text{OR}\) 值 non-…

四大门户网站的区别深圳营销型网站定制

教师资格认定前需要做的准备材料 准备身份证户口本 居住证 学生证 教师考试合格证明 普通话证书 学历证书 体检合格证书 近期一寸白底证件照 网上报名 河南24下教资认定 网上报名时间:10月21日-11月1日 现场确认 网上审核未通过的宝子,需要…

“齐俊杰投资智能体”更新完了9月份的资料

“齐俊杰投资智能体”更新完了9月份的资料,本次更新包括了9月份的课程和粉丝群问答,读书更新了这几本:明斯基时刻。每日问答的语音转文字已经使用了AI进行格式优化,更加容易阅读。将新资料更新到了智能体,大家可以…

联想电脑护眼卫士与系统颜色配置(X-Rite)冲突 | 显示设置频繁变换色阶 - 解决方案 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

(转载)无人机飞行模式全面解析

(转载)无人机飞行模式全面解析原文地址: https://baijiahao.baidu.com/s?id=1822706539478215889飞行模式详解 自稳模式: 在自稳模式下,飞手通过操作roll与pitch摇杆来控制飞行器的倾斜角度。一旦飞手松开这些摇…

html官方网站建站系统cms是什么

tcp长连接和保活时间TCP协议中有长连接和短连接之分。短连接在数据包发送完成后就会自己断开,长连接在发包完毕后,会在一定的时间内保持连接,即我们通常所说的Keepalive(存活定时器)功能。 www.2cto.com 默认的Keepa…

河北雄安建设投资集团网站微网站免费搭建平台

来源:专知 摘要对话系统是一个流行的自然语言处理(NLP)任务,因为它在现实生活中应用前景广阔。这也是一个复杂的任务,因为涉及到许多需要研究的自然语言处理任务。因此,关于深度学习的对话系统研究的大量工作开展了。在这个综述中…

网站建设怎么上传数据微信小程序设计软件

写在前面 内部审计是一种独立的、客观的确认和咨询活动,包括鉴证、识别和分析问题以及提供管理建议和解决方案。狭义的数字化转型是指将企业经营管理和业务操作的各种行为、状态和结果用数字的形式来记录和存储,据此再对数据进行挖掘、分析和应用。广义…