自注意力架构大成者_Transformer(Pytorch 17)

1 模型简介

在上节比较了 卷积神经网络(CNN)循环神经网络(RNN)和 自注意力(self‐attention)。值得注意的是, 自注意力同时具有并行计算和最短的最大路径长度这两个优势。因此,使用自注意力来 设计深度架构 是很有 吸引力的。对比之前仍然依赖循环神经网络实现输入表示的自注意力模型 (Cheng et al., 2016, Lin et al., 2017, Paulus et al., 2017),Transformer模型完全基于注意力机制,没有任何卷积层或循环神经网络层 (Vaswani et al., 2017)。尽管Transformer最初是应用于在文本数据上的序列到序列学习,但 现在已经推广到各种现代的深度学习中,例如 语言、视觉、语音 和 强化学习 领域。

2 模型架构

Transformer作为编码器-解码器架构的一个实例,其整体架构图在下图中展示。正如所见到的,Trans‐ former是由编码器和解码器组成的。与基于Bahdanau注意力实现的序列到序列的学习相比,Trans‐ former的编码器和解码器是基于自注意力的模块叠加而成的,源(输入)序列和目标(输出)序列的嵌入 (embedding)表示将加上位置编码(positional encoding),再分别输入到编码器和解码器中。

上图概述了Transformer的架构。从宏观角度来看,Transformer的编码器是 由多个相同的层叠加而 成的每个层都有两个子层(子层表示为sublayer)。第一个子层是多头自注意力(multi‐head self‐attention) 汇聚;第二个子层是基于位置的前馈网络(positionwise feed‐forward network)。具体来说,在计算编码器 的自注意力时,查询、键和值都来自前一个编码器层的输出。受残差网络的启发,每个子层都采用了残差连接(residual connection)。在Transformer中,对于序列中任何位置的任何输入x ∈ R^d,都要求满 足sublayer(x) ∈ R^d,以便残差连接满足x + sublayer(x) ∈ R^d。在残差连接的加法计算之后,紧接着应用层规范化(layer normalization)(Ba et al., 2016)。因此,输入序列对应的每个位置,Transformer编码器都将输出一个d维表示向量。

Transformer 解码器也是由多个相同的层叠加而成的,并且 层中使用了残差连接和层规范化。除了编码器中 描述的两个子层之外,解码器 还在这两个子层之间插入了第三个子层,称为编码器-解码器注意力(encoder‐ decoder attention)层。在编码器-解码器注意力中,查询来自前一个解码器层的输出,而键和值来自整个 编码器的输出。在解码器自注意力中,查询、键和值都来自上一个解码器层的输出。但是,解码器中的每个位置只能考虑该位置之前的所有位置。这种掩蔽(masked)注意力保留了自回归(auto‐regressive)属性,确保预测仅依赖于已生成的输出词元。

在 此 之 前 已 经 描 述 并 实 现 了 基 于 缩 放 点 积 多 头 注 意 力和 位 置 编 码。 接 下 来 将 实 现Transformer模型的剩余部分。

3 基于位置的前馈网络

基于位置的前馈网络对序列中的所有位置的表示 进行变换时使用的是同一个多层感知机(MLP),这就是称 前馈网络是基于位置的(positionwise)的原因。在下面的实现中,输入X的形状(批量大小,时间步数或序列 长度,隐单元数或特征维度)将被一个两层的感知机转换成形状为(批量大小,时间步数,ffn_num_outputs) 的输出张量。

import math
import pandas as pd
import torch
from torch import nn
from d2l import torch as d2l#@save
class PositionWiseFFN(nn.Module):"""基于位置的前馈网络"""def __init__(self, ffn_num_input, ffn_num_hiddens, ffn_num_outputs,**kwargs):super(PositionWiseFFN, self).__init__(**kwargs)self.dense1 = nn.Linear(ffn_num_input, ffn_num_hiddens)self.relu = nn.ReLU()self.dense2 = nn.Linear(ffn_num_hiddens, ffn_num_outputs)def forward(self, X):return self.dense2(self.relu(self.dense1(X)))

下面的例子显示,改变张量的最里层维度的尺寸,会改变成基于位置的前馈网络的输出尺寸。因为用同一个 多层感知机对所有位置上的输入进行变换,所以当所有这些位置的输入相同时,它们的输出也是相同的。

ffn = PositionWiseFFN(4, 4, 8)
ffn.eval()
ffn(torch.ones((2, 3, 4)))[0]# tensor([[ 0.0885,  0.2403, -0.2861, -0.4473,  0.8829, -0.2787, -0.3253, -1.2090],
#         [ 0.0885,  0.2403, -0.2861, -0.4473,  0.8829, -0.2787, -0.3253, -1.2090],
#         [ 0.0885,  0.2403, -0.2861, -0.4473,  0.8829, -0.2787, -0.3253, -1.2090]],
#        grad_fn=<SelectBackward0>)

 

4 残差连接和层规范化

现在让我们关注 Transformer 的加法和规范化(add&norm)组件。正如在本节开头所述,这是由残差连接和紧随其后的层规范化组成的。两者都是构建有效的深度架构的关键。 之前解释了 在一个小批量的样本内基于批量规范化对数据进行重新中心化和重新缩放的调整。层规范化和批量规范化的目标相同,但层规范化是基于特征维度进行规范化。尽管批量规范化在计算机视觉中被广泛 应用,但在自然语言处理任务中(输入通常是变长序列)批量规范化通常不如层规范化的效果好。 以下代码对比不同维度的层规范化和批量规范化的效果。

ln = nn.LayerNorm(2)
bn = nn.BatchNorm1d(2)
X = torch.tensor([[1, 2], [2, 3]], dtype=torch.float32)
# 在训练模式下计算X的均值和方差
print('layer norm:', ln(X), '\nbatch norm:', bn(X))# layer norm: tensor([[-1.0000,  1.0000],
#         [-1.0000,  1.0000]], grad_fn=<NativeLayerNormBackward0>) 
# batch norm: tensor([[-1.0000, -1.0000],
#         [ 1.0000,  1.0000]], grad_fn=<NativeBatchNormBackward0>)

现在可以 使用残差连接和层规范化 来实现AddNorm类。暂退法也被作为正则化方法 使用。

#@save
class AddNorm(nn.Module):"""残差连接后进行层规范化"""def __init__(self, normalized_shape, dropout, **kwargs):super(AddNorm, self).__init__(**kwargs)self.dropout = nn.Dropout(dropout)self.ln = nn.LayerNorm(normalized_shape)def forward(self, X, Y):return self.ln(self.dropout(Y) + X)

残差连接要求两个输入的形状相同,以便加法操作后输出张量的形状相同。

add_norm = AddNorm([3, 4], 0.5)
add_norm.eval()
add_norm(torch.ones((2, 3, 4)), torch.ones((2, 3, 4))).shape
# torch.Size([2, 3, 4])

5 编码器

有了组成Transformer编码器的基础组件,现在可以先实现编码器中的一个层。下面的EncoderBlock类包含 两个子层:多头自注意力和基于位置的前馈网络,这两个子层都使用了残差连接和紧随的层规范化

#@save
class EncoderBlock(nn.Module):"""Transformer编码器块"""def __init__(self, key_size, query_size, value_size, num_hiddens,norm_shape, ffn_num_input, ffn_num_hiddens, num_heads,dropout, use_bias=False, **kwargs):super(EncoderBlock, self).__init__(**kwargs)self.attention = d2l.MultiHeadAttention(key_size, query_size, value_size, num_hiddens, num_heads, dropout,use_bias)self.addnorm1 = AddNorm(norm_shape, dropout)self.ffn = PositionWiseFFN(ffn_num_input, ffn_num_hiddens, num_hiddens)self.addnorm2 = AddNorm(norm_shape, dropout)def forward(self, X, valid_lens):Y = self.addnorm1(X, self.attention(X, X, X, valid_lens))return self.addnorm2(Y, self.ffn(Y))

正如从代码中所看到的,Transformer编码器中的任何层都不会改变其输入的形状

X = torch.ones((2, 100, 24))
valid_lens = torch.tensor([3, 2])
encoder_blk = EncoderBlock(24, 24, 24, 24, [100, 24], 24, 48, 8, 0.5)
encoder_blk.eval()
encoder_blk(X, valid_lens).shape  # torch.Size([2, 100, 24])

下面实现的Transformer编码器的代码中,堆叠了num_layers个EncoderBlock类 的实例。由于这里使用的是 值范围在−1和1之间的固定位置编码,因此通过学习得到的输入的嵌入表示的值需要先乘以嵌入维度的平方 根进行重新缩放,然后再与位置编码相加。

#@save
class TransformerEncoder(d2l.Encoder):"""Transformer编码器"""def __init__(self, vocab_size, key_size, query_size, value_size,num_hiddens, norm_shape, ffn_num_input, ffn_num_hiddens,num_heads, num_layers, dropout, use_bias=False, **kwargs):super(TransformerEncoder, self).__init__(**kwargs)self.num_hiddens = num_hiddensself.embedding = nn.Embedding(vocab_size, num_hiddens)self.pos_encoding = d2l.PositionalEncoding(num_hiddens, dropout)self.blks = nn.Sequential()for i in range(num_layers):self.blks.add_module("block"+str(i),EncoderBlock(key_size, query_size, value_size, num_hiddens,norm_shape, ffn_num_input, ffn_num_hiddens,num_heads, dropout, use_bias))def forward(self, X, valid_lens, *args):# 因为位置编码值在-1和1之间,# 因此嵌入值乘以嵌入维度的平方根进行缩放,# 然后再与位置编码相加。X = self.pos_encoding(self.embedding(X) * math.sqrt(self.num_hiddens))self.attention_weights = [None] * len(self.blks)for i, blk in enumerate(self.blks):X = blk(X, valid_lens)self.attention_weights[i] = blk.attention.attention.attention_weightsreturn X

下面我们指定了超参数来 创建一个两层的Transformer编码器。Transformer编码器输出的形状是(批量大小,时间步数目,num_hiddens)。

encoder = TransformerEncoder(200, 24, 24, 24, 24, [100, 24], 24, 48, 8, 2, 0.5)
encoder.eval()
encoder(torch.ones((2, 100), dtype=torch.long), valid_lens).shape
# torch.Size([2, 100, 24])

6 解码器

Transformer解码器也是由多个相同的层组成。在DecoderBlock类中实现的 每个层包含了三 个子层解码器自注意力、“编码器‐解码器”注意力和基于位置的前馈网络。这些子层也都被残差连接和紧随的层规范化围绕。

正如在本节前面所述,在掩蔽多头解码器自注意力层(第一个子层)中,查询、键和值都来自上一个解码器 层的输出。关于序列到序列模型(sequence‐to‐sequence model),在训练阶段,其输出序列的所有位置(时 间步)的词元都是已知的;然而,在预测阶段,其输出序列的词元是逐个生成的。因此,在任何解码器时间 步中,只有生成的词元才能用于解码器的自注意力计算中。为了在解码器中保留自回归的属性,其掩蔽自注意力设定了参数dec_valid_lens,以便任何查询都只会与解码器中所有已经生成词元的位置(即直到该查询 位置为止)进行注意力计算。

class DecoderBlock(nn.Module):"""解码器中第i个块"""def __init__(self, key_size, query_size, value_size, num_hiddens,norm_shape, ffn_num_input, ffn_num_hiddens, num_heads,dropout, i, **kwargs):super(DecoderBlock, self).__init__(**kwargs)self.i = iself.attention1 = d2l.MultiHeadAttention(key_size, query_size, value_size, num_hiddens, num_heads, dropout)self.addnorm1 = AddNorm(norm_shape, dropout)self.attention2 = d2l.MultiHeadAttention(key_size, query_size, value_size, num_hiddens, num_heads, dropout)self.addnorm2 = AddNorm(norm_shape, dropout)self.ffn = PositionWiseFFN(ffn_num_input, ffn_num_hiddens,num_hiddens)self.addnorm3 = AddNorm(norm_shape, dropout)def forward(self, X, state):enc_outputs, enc_valid_lens = state[0], state[1]# 训练阶段,输出序列的所有词元都在同一时间处理,# 因此state[2][self.i]初始化为None。# 预测阶段,输出序列是通过词元一个接着一个解码的,# 因此state[2][self.i]包含着直到当前时间步第i个块解码的输出表示if state[2][self.i] is None:key_values = Xelse:key_values = torch.cat((state[2][self.i], X), axis=1)state[2][self.i] = key_valuesif self.training:batch_size, num_steps, _ = X.shape# dec_valid_lens的开头:(batch_size,num_steps),# 其中每一行是[1,2,...,num_steps]dec_valid_lens = torch.arange(1, num_steps + 1, device=X.device).repeat(batch_size, 1)else:dec_valid_lens = None# 自注意力X2 = self.attention1(X, key_values, key_values, dec_valid_lens)Y = self.addnorm1(X, X2)# 编码器-解码器注意力。# enc_outputs的开头:(batch_size,num_steps,num_hiddens)Y2 = self.attention2(Y, enc_outputs, enc_outputs, enc_valid_lens)Z = self.addnorm2(Y, Y2)return self.addnorm3(Z, self.ffn(Z)), state

为了便于在 “编码器-解码器” 注意力中进行缩放点积计算和残差连接中进行加法计算,编码器和解码器的 特征维度都是 num_hiddens

decoder_blk = DecoderBlock(24, 24, 24, 24, [100, 24], 24, 48, 8, 0.5, 0)
decoder_blk.eval()
X = torch.ones((2, 100, 24))
state = [encoder_blk(X, valid_lens), valid_lens, [None]]
decoder_blk(X, state)[0].shape
# torch.Size([2, 100, 24])

现在我们构建了 由num_layers个DecoderBlock实例组成的完整的Transformer解码器。最后,通过一个全连接层计算所有vocab_size个可能的输出词元的预测值。解码器的自注意力权重和编码器解码器注意力权重都被存储下来,方便日后可视化的需要。

class TransformerDecoder(d2l.AttentionDecoder):def __init__(self, vocab_size, key_size, query_size, value_size,num_hiddens, norm_shape, ffn_num_input, ffn_num_hiddens,num_heads, num_layers, dropout, **kwargs):super(TransformerDecoder, self).__init__(**kwargs)self.num_hiddens = num_hiddensself.num_layers = num_layersself.embedding = nn.Embedding(vocab_size, num_hiddens)self.pos_encoding = d2l.PositionalEncoding(num_hiddens, dropout)self.blks = nn.Sequential()for i in range(num_layers):self.blks.add_module("block"+str(i),DecoderBlock(key_size, query_size, value_size, num_hiddens,norm_shape, ffn_num_input, ffn_num_hiddens,num_heads, dropout, i))self.dense = nn.Linear(num_hiddens, vocab_size)def init_state(self, enc_outputs, enc_valid_lens, *args):return [enc_outputs, enc_valid_lens, [None] * self.num_layers]def forward(self, X, state):X = self.pos_encoding(self.embedding(X) * math.sqrt(self.num_hiddens))self._attention_weights = [[None] * len(self.blks) for _ in range (2)]for i, blk in enumerate(self.blks):X, state = blk(X, state)# 解码器自注意力权重self._attention_weights[0][i] = blk.attention1.attention.attention_weights# “编码器-解码器”自注意力权重self._attention_weights[1][i] = blk.attention2.attention.attention_weightsreturn self.dense(X), state@propertydef attention_weights(self):return self._attention_weights

7 执行训练

依照Transformer架构来实例化编码器-解码器模型。在这里,指定Transformer的编码器和解码器都是2层, 都使用4头注意力。为了进行序列到序列的学习,下面在“英语-法语”机器翻译数据集上 训练Transformer模型。

num_hiddens, num_layers, dropout, batch_size, num_steps = 32, 2, 0.1, 64, 10
lr, num_epochs, device = 0.005, 200, d2l.try_gpu()
ffn_num_input, ffn_num_hiddens, num_heads = 32, 64, 4
key_size, query_size, value_size = 32, 32, 32
norm_shape = [32]train_iter, src_vocab, tgt_vocab = d2l.load_data_nmt(batch_size, num_steps)
encoder = TransformerEncoder(len(src_vocab), key_size, query_size, value_size, num_hiddens,norm_shape, ffn_num_input, ffn_num_hiddens, num_heads,num_layers, dropout)
decoder = TransformerDecoder(len(tgt_vocab), key_size, query_size, value_size, num_hiddens,norm_shape, ffn_num_input, ffn_num_hiddens, num_heads,num_layers, dropout)
net = d2l.EncoderDecoder(encoder, decoder)
d2l.train_seq2seq(net, train_iter, lr, num_epochs, tgt_vocab, device)

训练结束后,使用Transformer模型将一些英语句子翻译成法语,并且计算它们的BLEU分数。

engs = ['go .', "i lost .", 'he\'s calm .', 'i\'m home .']
fras = ['va !', 'j\'ai perdu .', 'il est calme .', 'je suis chez moi .']
for eng, fra in zip(engs, fras):translation, dec_attention_weight_seq = d2l.predict_seq2seq(net, eng, src_vocab, tgt_vocab, num_steps, device, True)print(f'{eng} => {translation}, ',f'bleu {d2l.bleu(translation, fra, k=2):.3f}')# go . => va !, bleu 1.000
# i lost . => j'ai perdu ., bleu 1.000
# he's calm . => il est calme ., bleu 1.000
# i'm home . => je suis chez moi ., bleu 1.000

当进行最后一个英语到法语的句子翻译工作时,让我们可视化Transformer的注意力权重。编码器自注意力 权重的形状为(编码器层数,注意力头数,num_steps或查询的数目,num_steps或“键-值”对的数目)。

enc_attention_weights = torch.cat(net.encoder.attention_weights, 0).reshape((num_layers, num_heads,-1, num_steps))
enc_attention_weights.shape  # torch.Size([2, 4, 10, 10])

在编码器的自注意力中,查询和键都来自相同的输入序列。因为填充词元是不携带信息的,因此通过指定输 入序列的有效长度可以避免查询与使用填充词元的位置计算注意力。接下来,将逐行呈现两层多头注意力的 权重。每个注意力头都根据查询、键和值的不同的表示子空间来表示不同的注意力

d2l.show_heatmaps(enc_attention_weights.cpu(), xlabel='Key positions',ylabel='Query positions', titles=['Head %d' % i for i in range(1, 5)],figsize=(7, 3.5))

为了可视化解码器的自注意力权重和“编码器-解码器”的注意力权重,我们需要完成更多的数据操作工作。 例如用零填充被掩蔽住的注意力权重。值得注意的是,解码器的自注意力权重和“编码器-解码器”的注意 力权重都有相同的查询:即 以序列开始词元(beginning‐of‐sequence,BOS)打头,再与后续输出的词元共同组成序列。

dec_attention_weights_2d = [head[0].tolist()for step in dec_attention_weight_seqfor attn in step for blk in attn for head in blk]
dec_attention_weights_filled = torch.tensor(pd.DataFrame(dec_attention_weights_2d).fillna(0.0).values)
dec_attention_weights = dec_attention_weights_filled.reshape((-1, 2, num_layers, num_heads, num_steps))
dec_self_attention_weights, dec_inter_attention_weights = \dec_attention_weights.permute(1, 2, 3, 0, 4)
dec_self_attention_weights.shape, dec_inter_attention_weights.shape
# (torch.Size([2, 4, 6, 10]), torch.Size([2, 4, 6, 10]))

由于解码器自注意力的自回归属性,查询不会对当前位置之后的“键-值”对进行注意力计算。

# Plusonetoincludethebeginning-of-sequencetoken
d2l.show_heatmaps(dec_self_attention_weights[:, :, :, :len(translation.split()) + 1],xlabel='Key positions', ylabel='Query positions',titles=['Head %d' % i for i in range(1, 5)], figsize=(7, 3.5))

与编码器的自注意力的情况类似,通过指定输入序列的有效长度,输出序列的查询不会与输入序列中填充位置的词元进行注意力计算

d2l.show_heatmaps(dec_inter_attention_weights, xlabel='Key positions',ylabel='Query positions', titles=['Head %d' % i for i in range(1, 5)],figsize=(7, 3.5))

尽管Transformer架构是为了序列到序列的学习而提出的,但正如本书后面将提及的那样,Transformer编码 器或Transformer解码器通常被单独用于不同的深度学习任务中。

小结:

  • Transformer是编码器-解码器架构的一个实践,尽管 在实际情况中编码器或解码器可以单独使用
  • 在Transformer中,多头自注意力用于表示输入序列和输出序列,不过解码器必须通过掩蔽机制来保留 自回归属性
  • Transformer中的 残差连接和层规范化 是训练非常深度模型的重要工具。
  • Transformer模型中 基于位置的前馈网络使用同一个多层感知机,作用是 对所有序列位置的表示进行转换

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

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

相关文章

【微机原理及接口技术】存储器

【微机原理及接口技术】存储器 文章目录 【微机原理及接口技术】存储器前言一、半导体存储器技术1.半导体存储器概述2.半导体存储器的分类3.半导体存储器芯片的结构 二、半导体存储器芯片1.RAM芯片2.ROM芯片 三、半导体存储器与CPU的连接1.存储芯片数据线的连接2.存储芯片地址线…

webrtc初步了解

WebRTC搭建点对点实时音视频对话&#xff0c;起始需要保证完成两点&#xff1a; 1.媒体协商&#xff0c;了解彼此支持的媒体格式。参与视频通讯的双方必须先交换SDP信息&#xff0c;交换SDP的过程。 2.网络协商&#xff0c;了解彼此的网络环境&#xff0c;找到一条相互通讯的链…

Linux学习之禁用防火墙

查看防火墙状态 systemctl status firewalld.service 第一行前面的圆圈是有颜色的就是开启状态 黑色的就是关闭状态 关闭防火墙 systemctl stop firewalld.service 输入密码认证 再次查看防火墙状态 systemctl status firewalld.service 第一行前面的圆圈变成黑色说明关闭…

ThreeJS:补间动画与Tween.JS

补间动画 补间动画指的是做FLASH动画时&#xff0c;在两个关键帧中间需要做“补间动画”&#xff0c;才能实现图画的运动&#xff1b;插入补间动画后两个关键帧之间的插补帧是由计算机自动运算而得到的。 ——摘自《百度百科&#xff1a;补间动画_百度百科》 Tween.js Tween.js…

xCode升级后: Library ‘iconv2.4.0’ not found

报错信息&#xff1a; targets 选中 xxxNotification: Build Phases ——> Link Binary With Libraries 中&#xff0c;移除 libiconv.2.4.0.tbd libiconv.2.4.0.dylib 这两个库&#xff08;只有一个的移除一个就好&#xff09;。 然后重新添加 libiconv.tbd 修改完…

(代码以上传,超级详细)面试必备算法题----Leeecode290单词规律

文章目录 概要题目要求测试and提交结果技术细节 概要 来自Leecode ​ 代码已上传&#xff09;仓库&#xff0c;需要测试实例和其他题型解决&#xff0c;可以去自行浏览 点击这里进入仓库领取代码喔&#xff01;顺便点个star给原子加油吧&#xff01; ​ 题目要求 使用哈希表 …

GD32F103RCT6/GD32F303RCT6(9)高级定时器互补PWM波输出实验

本文章基于兆易创新GD32 MCU所提供的2.2.4版本库函数开发 后续项目主要在下面该专栏中发布&#xff1a; 手把手教你嵌入式国产化_不及你的温柔的博客-CSDN博客 感兴趣的点个关注收藏一下吧! 电机驱动开发可以跳转&#xff1a; 手把手教你嵌入式国产化-实战项目-无刷电机驱动&am…

【设计模式】之观察者模式

系列文章目录 【设计模式】之装饰器模式【设计模式】之工厂模式&#xff08;三种&#xff09;【设计模式】之工厂模式&#xff08;三种&#xff09; 前言 今天给大家介绍另一种设计模式--观察者模式&#xff0c;有了解webscoket实现原理的小伙伴应该对这个设计模式不陌生。不清…

微服务核心01-Maven【项目管理工具】基础

一、Maven 简介 1.1 传统项目管理&#xff1a; 1.2 Maven 的作用 项目构建&#xff1a;提供标准的、跨平台的自动化项目构建方式。依赖管理&#xff1a;管理项目依赖的资源&#xff08;jar 包&#xff09;&#xff0c;避免资源间的版本冲突问题统一开发结构&#xff1a;提供标…

Web LLM 攻击实验:利用 LLM API 实现 SQL 注入

前言 Web LLM 攻击 各组织都在急于集成大型语言模型 (LLM)&#xff0c;以改善其在线客户体验。这使他们面临 Web LLM 攻击&#xff0c;这些攻击利用模型对攻击者无法直接访问的数据、API 或用户信息的访问权限。例如&#xff0c;攻击可能&#xff1a; 检索 LLM 有权访问的数…

【valse 2024】会议内容汇总(持续更新)

系列文章目录 提示&#xff1a;更新中&#xff0c;一周左右更新完毕。需要具体课件的可私信 文章目录 系列文章目录开幕式主旨报告-1:大模型时代的机遇和挑战主旨报告-2:以深度学习框架为牵引促进自主 AI生态发展主旨报告-3:从洞穴的影子到智能的光辉--连接和交互方式的改变塑造…

别出心裁的自动化网页数据采集:Chrome插件和mitmproxy

别出心裁的自动化网页数据采集&#xff1a;Chrome插件和mitmproxy 前言 在信息时代&#xff0c;数据已成为决策的关键。传统的数据采集方法往往依赖于手动操作或简单的自动化脚本&#xff0c;这限制了数据的时效性和精确性。为了克服这些限制&#xff0c;本文介绍了一种结合C…

文件批量移动:按路径名称指引,高效文件管理与批量归类实战

在数字化时代&#xff0c;文件批量移动成为了一项至关重要的技能&#xff0c;它能够帮助我们高效地管理和归类大量的文件。通过按路径名称指引进行文件批量移动&#xff0c;我们可以使文件组织更加有序&#xff0c;提高文件检索的速度&#xff0c;从而提升工作效率。 一、明确路…

多线程学习Day09

10.Tomcat线程池 LimitLatch 用来限流&#xff0c;可以控制最大连接个数&#xff0c;类似 J.U.C 中的 Semaphore 后面再讲 Acceptor 只负责【接收新的 socket 连接】 Poller 只负责监听 socket channel 是否有【可读的 I/O 事件】 一旦可读&#xff0c;封装一个任务对象&#x…

【建议收藏】CSP-J/S信奥赛,小白报名教程!

✅ 信奥介绍 信息学奥赛是五大学科&#xff08;数学、物理、化学、生物、信息学&#xff09;奥林匹克竞赛中唯一一个可以贯穿小学、初中、高中的特长生项目。由中国计算机学会主办&#xff0c;主要考察信息学&#xff0c;即编程的相关知识和能力。 ✅ 报名流程 &#x1f449;登…

智能绘画系统源码系统 后台自由设置会员套餐 带网站的安装包以及安装部署教程

在当今数字化与智能化快速发展的时代&#xff0c;艺术与技术正以前所未有的速度相互融合。为了满足广大绘画爱好者和专业艺术家的需求&#xff0c;我们精心打造了一款智能绘画系统源码系统。该系统不仅具备高度的智能化特性&#xff0c;还提供了丰富的后台管理功能&#xff0c;…

CTF-密码学基础

概述 密码学(Cryptolopy)&#xff1a;是研究信息系统安全保密的科学 密码学研究的两个方向&#xff1a; 密码编码学(Cryptography)&#xff1a;主要研究对信息进行编码&#xff0c;实现对信息的隐蔽密码分析学(Cryptanalytics)&#xff1a;主要研究加密信息的破译或消息的伪造…

多客陪玩系统源码APP小程序H5陪玩开发伴游源码游戏陪玩平台源码陪玩平台开发约单源码线下陪玩接单平台app小程序H5源码游戏陪玩app小程序H5开发

出售成品陪玩app小程序H5源码&#xff0c;免费搭建部署和售后服务&#xff0c;并提供源码二开、定制开发等相关服务。 一、陪玩app源码的功能介绍 1、语音聊天: 陪玩app小程序H5源码用户随时创建语音聊天室&#xff0c;实现多用户上麦功能&#xff0c;提高互动聊天体验。 2、游…

【Qt 开发基础体系】字符串类应用和常用的数据类型

文章目录 1. Qt 字符串类应用1.1 操作字符串1.2 QString::append()函数1.3 QString::sprintf()函数1.4 QString::arg()函数 2. 查询字符串2.1 函数 QString::startsWith()2.2 函数 QString::contains()2.3 函数 QString::toInt()2.4 函数 QString::compare()2.5 将 QString 转换…

攻克《模版进阶》 全方位了解

目录 前言&#xff1a; 非类型模板参数 按需实例化 模板的特化 概念&#xff1a; 函数模板特化&#xff1a; 类模板特化&#xff1a; 1、全特化 2、偏特化 3、类模板特化应用示例 模板分离编译 什么是分离编译 模板的分离编译 解决方法 总结 前言&#xff1a; 我…