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

建筑设计网站大全网站网站建设是什么专业里的科目

建筑设计网站大全网站,网站建设是什么专业里的科目,做网站首页图的规格,网站建设对企业的好处Transformer和BERT可谓是LLM的基础模型#xff0c;彻底搞懂极其必要。Transformer最初设想是作为文本翻译模型使用的#xff0c;而BERT模型构建使用了Transformer的部分组件#xff0c;如果理解了Transformer#xff0c;则能很轻松地理解BERT。 一.Transformer模型架构 1…  Transformer和BERT可谓是LLM的基础模型彻底搞懂极其必要。Transformer最初设想是作为文本翻译模型使用的而BERT模型构建使用了Transformer的部分组件如果理解了Transformer则能很轻松地理解BERT。 一.Transformer模型架构 1.编码器 1Multi-Head Attention多头注意力机制   首先将输入x进行embedding编码然后通过WQ、WK和WV矩阵转换为Q、K和V然后输入Scaled Dot-Product Attention中最后经过Feed Forward输出作为解码器第2层的输入Q。 2Feed Forward前馈神经网络 2.解码器 1Masked Multi-Head Attention掩码多头注意力机制   Masked包括上三角矩阵Mask不包含对角线和PAD MASK的叠加目的是在计算自注意力过程中不会注意当前词的下一个词只会注意当前词与当前词之前的词。在模型训练的时候为了防止误差积累和并行训练使用Teacher Forcing机制。 2Encoder-Decoder Multi-Head Attention编解码多头注意力机制   把Encoder的输出作为解码器第2层的Q把Decoder第1层的输出作为K和V。 3Feed Forward前馈神经网络 二.简单翻译任务 1.定义数据集   这块简要介绍主要是通过数据生成器模拟了一些数据将原文翻译为译文实现代码如下所示 # 定义字典 vocab_x SOS,EOS,PAD,0,1,2,3,4,5,6,7,8,9,q,w,e,r,t,y,u,i,o,p,a,s,d,f,g,h,j,k,l,z,x,c,v,b,n,m vocab_x {word: i for i, word in enumerate(vocab_x.split(,))} vocab_xr [k for k, v in vocab_x.items()] vocab_y {k.upper(): v for k, v in vocab_x.items()} vocab_yr [k for k, v in vocab_y.items()] print(vocab_x, vocab_x) print(vocab_y, vocab_y)# 定义生成数据的函数 def get_data():# 定义词集合words [0,1,2,3,4,5,6,7,8,9,q,w,e,r,t,y,u,i,o,p,a,s,d,f,g,h,j,k,l,z,x,c,v,b,n,m]# 定义每个词被选中的概率p np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26])p p / p.sum()# 随机选n个词n random.randint(30, 48) # 生成30-48个词x np.random.choice(words, sizen, replaceTrue, pp) # words中选n个词每个词被选中的概率为preplaceTrue表示可以重复选择# 采样的结果就是xx x.tolist()# y是由对x的变换得到的# 字母大写数字取9以内的互补数def f(i):i i.upper()if not i.isdigit():return ii 9 - int(i)return str(i)y [f(i) for i in x]# 逆序y y[::-1]# y中的首字母双写y [y[0]] y# 加上首尾符号x [SOS] x [EOS]y [SOS] y [EOS]# 补PAD直到固定长度x x [PAD] * 50y y [PAD] * 51x x[:50]y y[:51]# 编码成数据x [vocab_x[i] for i in x]y [vocab_y[i] for i in y]# 转Tensorx torch.LongTensor(x)y torch.LongTensor(y)return x, y# 定义数据集 class Dataset(torch.utils.data.Dataset):def __init__(self): # 初始化super(Dataset, self).__init__()def __len__(self): # 返回数据集的长度return 1000def __getitem__(self, i): # 根据索引返回数据return get_data()然后通过loader torch.utils.data.DataLoader(datasetDataset(), batch_size8, drop_lastTrue, shuffleTrue, collate_fnNone)定义了数据加载器数据样例如下所示 2.定义PAD MASK函数   PAD MASK主要目的是减少计算量如下所示 def mask_pad(data):# b句话每句话50个词这里是还没embed的# data [b, 50]# 判断每个词是不是PADmask data vocab_x[PAD]# [b, 50] - [b, 1, 1, 50]mask mask.reshape(-1, 1, 1, 50)# 在计算注意力时计算50个词和50个词相互之间的注意力所以是个50*50的矩阵# PAD的列为True意味着任何词对PAD的注意力都是0但是PAD本身对其它词的注意力并不是0所以是PAD的行不为True# 复制n次# [b, 1, 1, 50] - [b, 1, 50, 50]mask mask.expand(-1, 1, 50, 50) # 根据指定的维度扩展return mask if __name__ __main__:# 测试mask_pad函数print(mask_pad(x[:1]))输出结果shape为(1,1,50,50)如下所示 tensor([[[[False, False, False, ..., False, False, True],[False, False, False, ..., False, False, True],[False, False, False, ..., False, False, True],...,[False, False, False, ..., False, False, True],[False, False, False, ..., False, False, True],[False, False, False, ..., False, False, True]]]])3.定义上三角MASK函数   将上三角和PAD MASK相加最终输出的shape和PAD MASK函数相同均为(b, 1, 50, 50) # 定义mask_tril函数 def mask_tril(data):# b句话每句话50个词这里是还没embed的# data [b, 50]# 50*50的矩阵表示每个词对其它词是否可见# 上三角矩阵不包括对角线意味着对每个词而言它只能看到它自己和它之前的词而看不到之后的词# [1, 50, 50][[0, 1, 1, 1, 1],[0, 0, 1, 1, 1],[0, 0, 0, 1, 1],[0, 0, 0, 0, 1],[0, 0, 0, 0, 0]]tril 1 - torch.tril(torch.ones(1, 50, 50, dtypetorch.long)) # torch.tril返回下三角矩阵则1-tril返回上三角矩阵# 判断y当中每个词是不是PAD, 如果是PAD, 则不可见# [b, 50]mask data vocab_y[PAD] # mask的shape为[b, 50]# 变形转型为了之后的计算# [b, 1, 50]mask mask.unsqueeze(1).long() # 在指定位置插入维度mask的shape为[b, 1, 50]# mask和tril求并集# [b, 1, 50] [1, 50, 50] - [b, 50, 50]mask mask tril# 转布尔型mask mask 0 # mask的shape为[b, 50, 50]# 转布尔型增加一个维度便于后续的计算mask (mask 1).unsqueeze(dim1) # mask的shape为[b, 1, 50, 50]return mask if __name__ __main__:# 测试mask_tril函数print(mask_tril(x[:1]))输出结果shape为(b,1,50,50)如下所示 tensor([[[[False, True, True, ..., True, True, True],[False, False, True, ..., True, True, True],[False, False, False, ..., True, True, True],...,[False, False, False, ..., True, True, True],[False, False, False, ..., True, True, True],[False, False, False, ..., True, True, True]]]])4.定义注意力计算层   这里的注意力计算层是Scaled Dot-Product Attention计算方程为 A t t e n t i o n ( Q , K , V ) s o f t m a x ( Q K T d k ) V {\rm{Attention}}(Q,K,V) {\rm{softmax}}(\frac{{Q{K^T}}}{{\sqrt {{d_k}} }})V Attention(Q,K,V)softmax(dk​ ​QKT​)V其中 d k d_k dk​等于Embedding的维度除以注意力机制的头数比如64 512 / 8如下所示 # 定义注意力计算函数 def attention(Q, K, V, mask):Qtorch.randn(8, 4, 50, 8)Ktorch.randn(8, 4, 50, 8)Vtorch.randn(8, 4, 50, 8)masktorch.zeros(8, 1, 50, 50)# b句话每句话50个词每个词编码成32维向量4个头每个头分到8维向量# Q、K、V [b, 4, 50, 8]# [b, 4, 50, 8] * [b, 4, 8, 50] - [b, 4, 50, 50]# Q、K矩阵相乘求每个词相对其它所有词的注意力score torch.matmul(Q, K.permute(0, 1, 3, 2)) # K.permute(0, 1, 3, 2)表示将K的第3维和第4维交换# 除以每个头维数的平方根做数值缩放score / 8**0.5# mask遮盖mask是True的地方都被替换成-inf这样在计算softmax时-inf会被压缩到0# mask [b, 1, 50, 50]score score.masked_fill_(mask, -float(inf)) # masked_fill_()函数的作用是将mask中为1的位置用value填充score torch.softmax(score, dim-1) # 在最后一个维度上做softmax# 以注意力分数乘以V得到最终的注意力结果# [b, 4, 50, 50] * [b, 4, 50, 8] - [b, 4, 50, 8]score torch.matmul(score, V)# 每个头计算的结果合一# [b, 4, 50, 8] - [b, 50, 32]score score.permute(0, 2, 1, 3).reshape(-1, 50, 32)return score if __name__ __main__:# 测试attention函数print(attention(torch.randn(8, 4, 50, 8), torch.randn(8, 4, 50, 8), torch.randn(8, 4, 50, 8), torch.zeros(8, 1, 50, 50)).shape) #(8, 50, 32)5.BatchNorm和LayerNorm对比   在PyTorch中主要提供了两种批量标准化的网络层分别是BatchNorm和LayerNorm其中BatchNorm按照处理的数据维度分为BatchNorm1d、BatchNorm2d、BatchNorm3d。BatchNorm1d和LayerNorm之间的区别在于BatchNorm1d是取不同样本做标准化而LayerNorm是取不同通道做标准化。 # BatchNorm1d和LayerNorm的对比 # 标准化之后均值是0, 标准差是1 # BN是取不同样本做标准化 # LN是取不同通道做标准化 # affineTrue,elementwise_affineTrue指定标准化后再计算一个线性映射 norm torch.nn.BatchNorm1d(num_features4, affineTrue) print(norm(torch.arange(32, dtypetorch.float32).reshape(2, 4, 4))) norm torch.nn.LayerNorm(normalized_shape4, elementwise_affineTrue) print(norm(torch.arange(32, dtypetorch.float32).reshape(2, 4, 4)))输出结果如下所示 tensor([[[-1.1761, -1.0523, -0.9285, -0.8047],[-1.1761, -1.0523, -0.9285, -0.8047],[-1.1761, -1.0523, -0.9285, -0.8047],[-1.1761, -1.0523, -0.9285, -0.8047]],[[ 0.8047, 0.9285, 1.0523, 1.1761],[ 0.8047, 0.9285, 1.0523, 1.1761],[ 0.8047, 0.9285, 1.0523, 1.1761],[ 0.8047, 0.9285, 1.0523, 1.1761]]],grad_fnNativeBatchNormBackward0) tensor([[[-1.3416, -0.4472, 0.4472, 1.3416],[-1.3416, -0.4472, 0.4472, 1.3416],[-1.3416, -0.4472, 0.4472, 1.3416],[-1.3416, -0.4472, 0.4472, 1.3416]],[[-1.3416, -0.4472, 0.4472, 1.3416],[-1.3416, -0.4472, 0.4472, 1.3416],[-1.3416, -0.4472, 0.4472, 1.3416],[-1.3416, -0.4472, 0.4472, 1.3416]]],grad_fnNativeLayerNormBackward0)6.定义多头注意力计算层   本文中的多头注意力计算层包括转换矩阵WK、WV和WQ以及多头注意力机制的计算过程还有层归一化、残差链接和Dropout。如下所示 # 多头注意力计算层 class MultiHead(torch.nn.Module):def __init__(self):super().__init__()self.fc_Q torch.nn.Linear(32, 32) # 线性运算维度不变self.fc_K torch.nn.Linear(32, 32) # 线性运算维度不变self.fc_V torch.nn.Linear(32, 32) # 线性运算维度不变self.out_fc torch.nn.Linear(32, 32) # 线性运算维度不变self.norm torch.nn.LayerNorm(normalized_shape32, elementwise_affineTrue) # 标准化self.DropOut torch.nn.Dropout(p0.1) # Dropout丢弃概率为0.1def forward(self, Q, K, V, mask):# b句话每句话50个词每个词编码成32维向量# Q、K、V[b,50,32]b Q.shape[0] # 取出batch_size# 保留下原始的Q后面要做短接残差思想用clone_Q Q.clone()# 标准化Q self.norm(Q)K self.norm(K)V self.norm(V)# 线性运算维度不变# [b,50,32] - [b,50,32]K self.fc_K(K) # 权重就是WKV self.fc_V(V) # 权重就是WVQ self.fc_Q(Q) # 权重就是WQ# 拆分成多个头# b句话每句话50个词每个词编码成32维向量4个头每个头分到8维向量# [b,50,32] - [b,4,50,8]Q Q.reshape(b, 50, 4, 8).permute(0, 2, 1, 3)K K.reshape(b, 50, 4, 8).permute(0, 2, 1, 3)V V.reshape(b, 50, 4, 8).permute(0, 2, 1, 3)# 计算注意力# [b,4,50,8]- [b,50,32]score attention(Q, K, V, mask)# 计算输出维度不变# [b,50,32]-[b,50,32]score self.DropOut(self.out_fc(score)) # Dropout丢弃概率为0.1# 短接残差思想score clone_Q scorereturn score7.定义位置编码层   位置编码计算方程如下所示其中 d m o d e l {d_{model}} dmodel​表示Embedding的维度比如512 P E ( p o s , 2 i ) s i n ( p o s / 10000 2 i / d m o d e l ) P E ( p o s , 2 i 1 ) c o s ( p o s / 10000 2 i / d m o d e l ) \begin{array}{l} PE\left( {pos,2i} \right) sin\left( {pos/{{10000}^{2i/{d_{model}}}}} \right) \\ PE\left( {pos,2i 1} \right) cos\left( {pos/{{10000}^{2i/{d_{model}}}}} \right) \\ \end{array} PE(pos,2i)sin(pos/100002i/dmodel​)PE(pos,2i1)cos(pos/100002i/dmodel​)​ # 定义位置编码层 class PositionEmbedding(torch.nn.Module) :def __init__(self):super().__init__()# pos是第几个词i是第几个词向量维度d_model是编码维度总数def get_pe(pos, i, d_model):d 1e4**(i / d_model)pe pos / dif i % 2 0:return math.sin(pe) # 偶数维度用sinreturn math.cos(pe) # 奇数维度用cos# 初始化位置编码矩阵pe torch.empty(50, 32)for i in range(50):for j in range(32):pe[i, j] get_pe(i, j, 32)pe pe. unsqueeze(0) # 增加一个维度shape变为[1,50,32]# 定义为不更新的常量self.register_buffer(pe, pe)# 词编码层self.embed torch.nn.Embedding(39, 32) # 39个词每个词编码成32维向量# 用正太分布初始化参数self.embed.weight.data.normal_(0, 0.1)def forward(self, x):# [8,50]-[8,50,32]embed self.embed(x)# 词编码和位置编码相加# [8,50,32][1,50,32]-[8,50,32]embed embed self.pereturn embed8.定义全连接输出层   与标准Transformer相比这里定义的全连接输出层对层归一化norm进行了提前如下所示 # 定义全连接输出层 class FullyConnectedOutput(torch.nn.Module):def __init__(self):super().__init__()self.fc torch.nn.Sequential( # 线性全连接运算torch.nn.Linear(in_features32, out_features64),torch.nn.ReLU(),torch.nn.Linear(in_features64, out_features32),torch.nn.Dropout(p0.1),)self.norm torch.nn.LayerNorm(normalized_shape32, elementwise_affineTrue)def forward(self, x):# 保留下原始的x后面要做短接残差思想用clone_x x.clone()# 标准化x self.norm(x)# 线性全连接运算# [b,50,32]-[b,50,32]out self.fc(x)# 做短接残差思想out clone_x outreturn out9.定义编码器   编码器包含多个编码层下面代码为5个1个编码层包含1个多头注意力计算层和1个全连接输出层如下所示 # 定义编码器 # 编码器层 class EncoderLayer(torch.nn.Module):def __init__(self):super().__init__()self.mh MultiHead() # 多头注意力计算层self.fc FullyConnectedOutput() # 全连接输出层def forward(self, x, mask):# 计算自注意力维度不变# [b,50,32]-[b,50,32]score self.mh(x, x, x, mask) # QKV# 全连接输出维度不变# [b,50,32]-[b,50,32]out self.fc(score)return out # 编码器 class Encoder(torch.nn.Module):def __init__(self):super().__init__()self.layer_l EncoderLayer() # 编码器层self.layer_2 EncoderLayer() # 编码器层self.layer_3 EncoderLayer() # 编码器层def forward(self, x, mask):x self.layer_l(x, mask)x self.layer_2(x, mask)x self.layer_3(x, mask)return x10.定义解码器   解码器包含多个解码层下面代码为3个1个解码层包含2个多头注意力计算层1个掩码多头注意力计算层和1个编解码多头注意力计算层和1个全连接输出层如下所示 class DecoderLayer(torch.nn.Module):def __init__(self):super().__init__()self.mhl MultiHead() # 多头注意力计算层self.mh2 MultiHead() # 多头注意力计算层self.fc FullyConnectedOutput() # 全连接输出层def forward(self, x, y, mask_pad_x, mask_tril_y):# 先计算y的自注意力维度不变# [b,50,32] - [b,50,32]y self.mhl(y, y, y, mask_tril_y)# 结合x和y的注意力计算维度不变# [b,50,32],[b,50,32]-[b,50,32]y self.mh2(y, x, x, mask_pad_x)# 全连接输出维度不变# [b,50,32]-[b,50,32]y self.fc(y)return y # 解码器 class Decoder(torch.nn.Module) :def __init__(self):super().__init__()self.layer_1 DecoderLayer() # 解码器层self.layer_2 DecoderLayer() # 解码器层self.layer_3 DecoderLayer() # 解码器层def forward(self, x, y, mask_pad_x, mask_tril_y):y self.layer_1(x, y, mask_pad_x, mask_tril_y)y self.layer_2(x, y, mask_pad_x, mask_tril_y)y self.layer_3(x, y, mask_pad_x, mask_tril_y)return y11.定义Transformer主模型   Transformer主模型计算流程包括获取一批x和y之后对x计算PAD MASK对y计算上三角MASK对x和y分别编码把x输入编码器计算输出把编码器的输出和y同时输入解码器计算输出将解码器的输出输入全连接输出层计算输出。具体实现代码如下所示 # 定义主模型 class Transformer(torch.nn.Module):def __init__(self):super().__init__()self.embed_x PositionEmbedding() # 位置编码层self.embed_y PositionEmbedding() # 位置编码层self.encoder Encoder() # 编码器self.decoder Decoder() # 解码器self.fc_out torch.nn.Linear(32, 39) # 全连接输出层def forward(self, x, y):# [b,1,50,50]mask_pad_x mask_pad(x) # PAD遮盖mask_tril_y mask_tril(y) # 上三角遮盖# 编码添加位置信息# x[b,50]-[b,50,32]# y[b,50]-[b,50,32]x, y self.embed_x(x), self.embed_y(y)# 编码层计算# [b,50,32]-[b,50,32]x self.encoder(x, mask_pad_x)# 解码层计算# [b,50,32],[b,50,32]-[b,50,32]y self.decoder(x, y, mask_pad_x, mask_tril_y)# 全连接输出维度不变# [b,50,32]-[b,50,39]y self.fc_out(y)return y12.定义预测函数   预测函数本质就是根据x得到y的过程在预测过程中解码器是串行工作的从SOS开始生成直到结束 # 定义预测函数 def predict(x):# x[1,50]model.eval()# [1,1,50,50]mask_pad_x mask_pad(x)# 初始化输出这个是固定值# [1,50]# [[0,2,2,2...]]target [vocab_y[SOS]] [vocab_y[PAD]] * 49 # 初始化输出这个是固定值target torch.LongTensor(target).unsqueeze(0) # 增加一个维度shape变为[1,50]# x编码添加位置信息# [1,50] - [1,50,32]x model.embed_x(x)# 编码层计算维度不变# [1,50,32] - [1,50,32]x model.encoder(x, mask_pad_x)# 遍历生成第1个词到第49个词for i in range(49):# [1,50]y target# [1, 1, 50, 50]mask_tril_y mask_tril(y) # 上三角遮盖# y编码添加位置信息# [1, 50] - [1, 50, 32]y model.embed_y(y)# 解码层计算维度不变# [1, 50, 32],[1, 50, 32] - [1, 50, 32]y model.decoder(x, y, mask_pad_x, mask_tril_y)# 全连接输出39分类#[1,50,32]- [1,50,39]out model.fc_out(y)# 取出当前词的输出# [1,50,39]-[1,39]out out[:,i,:]# 取出分类结果# [1,39]-[1]out out.argmax(dim1).detach()# 以当前词预测下一个词填到结果中target[:,i 1] outreturn target13.定义训练函数   训练函数的过程通常比较套路了主要是损失函数和优化器然后就是逐个epoch和batch遍历计算和输出当前epoch、当前batch、当前学习率、当前损失、当前正确率。如下所示 # 定义训练函数 def train():loss_func torch.nn.CrossEntropyLoss() # 定义交叉熵损失函数optim torch.optim.Adam(model.parameters(), lr2e-3) # 定义优化器sched torch.optim.lr_scheduler.StepLR(optim, step_size3, gamma0.5) # 定义学习率衰减策略for epoch in range(1):for i, (x, y) in enumerate(loader):# x[8,50]# y[8,51]# 在训练时用y的每个字符作为输入预测下一个字符所以不需要最后一个字# [8,50,39]pred model(x, y[:, :-1]) # 前向计算# [8,50,39] - [400,39]pred pred.reshape(-1, 39) # 转形状# [8,51]-[400]y y[:, 1:].reshape(-1) # 转形状# 忽略PADselect y ! vocab_y[PAD]pred pred[select]y y[select]loss loss_func(pred, y) # 计算损失optim.zero_grad() # 梯度清零loss.backward() # 反向传播optim.step() # 更新参数if i % 20 0:# [select,39] - [select]pred pred.argmax(1) # 取出分类结果correct (pred y).sum().item() # 计算正确个数accuracy correct / len(pred) # 计算正确率lr optim.param_groups[0][lr] # 取出当前学习率print(epoch, i, lr, loss.item(), accuracy) # 打印结果分别为当前epoch、当前batch、当前学习率、当前损失、当前正确率sched.step() # 更新学习率其中y和预测结果间的对应关系如下所示 参考文献 [1]HuggingFace自然语言处理详解基于BERT中文模型的任务实战 [2]第13章手动实现Transformer-简单翻译任务 [3]第13章手动实现Transformer-两数相加任务
http://www.zqtcl.cn/news/498945/

相关文章:

  • 广西智能网站建设哪家好网红商城
  • 关于建设网站的情况说明书wordpress 在线检测
  • 帝国cms 网站迁移错版怎样做心理咨询网站
  • 烟台建网站wordpress重写规则
  • 上海网站建设怎么赚钱平顶山网站建设服务公司
  • 导航网站如何被百度收录广告设计在线设计
  • 雪域什么网站是做电影的苏州优化方式
  • 设计网站多少钱手机百度助手
  • 驾校网上约车网站开发不会做网站如何做seo
  • 企业做推广可以发哪些网站宜兴埠网站建设
  • 网站后台文章添加成功 不显示公司设计网站建设合同
  • 后端开发需要掌握哪些知识潍坊优化公司
  • 专业手机网站制作哪家好wordpress wp-polls
  • 网站建设前分析网页制作素材按钮
  • 做视频网站怎么对接云盘松江新城网站建设
  • 温州阿里巴巴网站建设企业宣传片怎么拍
  • 淮阳住房城乡建设局网站阿里巴巴做国际网站要多少钱
  • 电子商务个人网站可以备案吗短网址还原
  • 网站内容由什么组成部分组成部分电子商务网站建设主管的策划书
  • 云服务器安装win系统做网站seo三人行论坛
  • 电气网站设计机械设计软件solidworks
  • 内网网站建设所需硬件设备厦门关键词排名提升
  • 网站动态海报效果怎么做的最专业网站建
  • 学校如何建设网站北京市住房及城乡建设部网站
  • 响应式网站制作流程全国城建培训中心官网查询证书
  • 北京工程建设信息网站中国市场网
  • xml做网站源码免费网站是
  • 中国工商建设标准化协会网站织梦app网站模板
  • 怎么做好网络销售文大侠seo博客
  • wish网站应该怎么做网站建设前规划