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

45 深度学习(九):transformer

文章目录

  • transformer
    • 原理
    • 代码的基础准备
    • 位置编码
    • Encoder block
      • multi-head attention
      • Feed Forward
      • 自定义encoder block
    • Deconder block
    • Encoder
    • Decoder
    • transformer
    • 自定义loss 和 学习率
    • mask生成函数
    • 训练
    • 翻译

transformer

这边讲一下这几年如日中天的新的seq2seq模式的transformer,这个模型解决了RNN训练时不能并行训练的慢,提出了self-attention机制,并关注到了注意力机制,也为之后的发展引领了新的时尚。

原理

我们首先看一下transformer这个的结构图,然后根据这个结构图进行实现代码

在这里插入图片描述

代码的基础准备

import numpy as np
import pandas as pd
import tensorflow as tf
import unicodedata
import re
from sklearn.model_selection import train_test_split
# 数据处理,主要和业务相关,当工作的时候绝大多数也就是将业务和代码相连接,这是十分重要的
# -----------------------------------------------------------------------------
# 数据预处理 去除重读的因子 和带空格以及特殊标点符号的东西
def preprocess_sentence(i):# NFD是转换方法,把每一个字节拆开,Mn是重音,所以去除i = ''.join(c for c in unicodedata.normalize('NFD',i) if unicodedata.category(c)!='Mn')# 把英文或者西班牙文变成纯小写,翻译与大写小写无关,降低影响,并且去掉头尾的空格i = i.lower().strip()# 在单词与跟在其后的标点符号之间插入一个空格i = re.sub(r"([?.!,¿])", r" \1 ", i)# 因为可能有多余空格,所以处理一下i = re.sub(r'[" "]+', " ", i)# 除了 (a-z, A-Z, ".", "?", "!", ","),将所有字符替换为空格i = re.sub(r"[^a-zA-Z?.!,¿]+", " ", i)i = i.rstrip().strip()i = '<start> ' + i + ' <end>'return idef load_dataset(path, num_examples):# lines就是读取之后的每一行的数据列表lines = open(path, encoding='UTF-8').read().strip().split('\n')# i就是一个样本,一个英文样本或者一个西班牙的样本word_pairs = [[preprocess_sentence(i) for i in line.split('\t')]for line in lines[:num_examples]]# 我们这边想要拿英文翻译成西班牙文,而我们查看data当中发现英语在左侧 西班牙语在右侧,所以英语左边应该是inputinputs,targets =zip(*word_pairs)# Tokenizer帮我们把词语式的转换为id式的,filters是黑名单 英语和西班牙语的需要额外自己分别训练inputs_tokenizer = tf.keras.preprocessing.text.Tokenizer(filters='')targets_tokenizer = tf.keras.preprocessing.text.Tokenizer(filters='')# 训练词袋inputs_tokenizer.fit_on_texts(inputs)targets_tokenizer.fit_on_texts(targets)# 把英文或西班牙文转化为数字 sparseinputs_tensor = inputs_tokenizer.texts_to_sequences(inputs)targets_tensor = targets_tokenizer.texts_to_sequences(targets)# 还需要补长或者截断 没有maxlen 就是自动取最长的进行补0inputs_tensor = tf.keras.preprocessing.sequence.pad_sequences(inputs_tensor, padding='post')targets_tensor = tf.keras.preprocessing.sequence.pad_sequences(targets_tensor, padding='post')return inputs_tensor, targets_tensor, inputs_tokenizer, targets_tokenizerdata_path = './data_spa_en/spa.txt'
# 需要训练的数据量 这边取全部,如果觉得训练太久,这边就选小一点
num_examples = 118964
# inp_lang targ_lang 是tokenizer
input_tensor, target_tensor, input_tokenizer, target_tokenizer = load_dataset(data_path, num_examples)
# 这边就不定义测试集了,对于nlp领域来说准确性一般没有什么作用
input_tensor_train, input_tensor_val, target_tensor_train, target_tensor_val = train_test_split(input_tensor, target_tensor, test_size=0.2)
batch_size = 64
embedding_dim = 256
units = 1024
# 训练集
dataset = tf.data.Dataset.from_tensor_slices((input_tensor_train,target_tensor_train)).shuffle(len(input_tensor_train))
dataset = dataset.batch(batch_size,drop_remainder=True)max_input_length = max(len(t) for t in input_tensor)
max_target_length = max(len(t) for t in target_tensor)
input_tokenizer_length = len(input_tokenizer.word_index)
target_tokenizer_length = len(target_tokenizer.word_index)
# -----------------------------------------------------------------------------

这个和之前的那个seq2seq的实现是完全一致的,这边就不细说。

位置编码

在这里插入图片描述

然后我们先实现的是这个位置编码这一部分,首先我们知道的是,我们的inputs的输入会先经过embedding层形状变成(batch-size,num-steps,embedding-dim),然后我们需要加上一个关于位置的矩阵,这个位置矩阵,包含着就是位置的信息,我们这边采用比较常见的sin-cos的方法去构建:
在这里插入图片描述
pos的意思就是一句话当中的第几个字,而i代表的就是这个字我们不是经过了embedding之后的第几个维度,也就对应着我们上面的那个输入经过了embedding之后的形状,而这个位置编码实际上就是为了满足让后面的元素和前面的元素相构成关系,也就是前面几个元素的关系和可以推出下一个元素,这样的道理。

具体的数学证明见下:
在这里插入图片描述
这边就不细说了,这还是很简单的。

理解了上面,关于如何提取出位置编码,这边就需要有相关的小技巧,我们使用切片的方式进行进行调整。

# 这一步完成的是位置编码
# -----------------------------------------------------------------------------
# # PE(pos, 2i)   = sin(pos / 10000^(2i/d_model))
# # PE(pos, 2i+1)  = cos(pos / 10000^(2i/d_model))
def get_position_embedding(sentence_length, d_model):# sentense_length就是句子的长度num-step d_model就是embedding_dim# 首先我们知道位置编码生成之后需要和外面的embedding后的数据进行相加 形成带有位置信息的数据# 而外面的embedding的data的形状是(batch-size,num-step,embedding-dim)# 所以相对应的生成就可以得到# 先根据公式来写 pos就是对应的哪一个字 i对应的就是第几个embedding-dim dmodel就是embedding-dim# pos先不考虑batch-size那一维度,先扩展维度,从(num-step)变成(num-step,1)pos = np.arange(sentence_length).reshape(-1,1)i = np.arange(d_model).reshape(1,-1)x = pos / np.power(10000,(2 * (i // 2)) / np.float32(d_model))# 利用切片得到相对应的sin 和 cossinx = np.sin(x[:, 0::2])cosx = np.cos(x[:, 1::2])# 凑成sin cos sin cos 的格式position_embedding = np.zeros((sentence_length,d_model))position_embedding[:, 0::2] = sinxposition_embedding[:, 1::2] = cosx# 最后就是维度扩展,方便后续的相加position_embedding = position_embedding.reshape(1,sentence_length,d_model)return tf.cast(position_embedding, dtype=tf.float32)position_embedding = get_position_embedding(5, 4)
print(position_embedding.shape)
print(position_embedding)
# -----------------------------------------------------------------------------

当然也可以封装到一个类当中,这边你们可以自己去实现一下

然后关于评价一下这个位置编码,我们这边使用绘制热力图进行展示:

import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline# 评估位置编码
# -----------------------------------------------------------------------------
position_embedding = get_position_embedding(50, 256)
print(position_embedding.shape)
print(position_embedding)
def plot_position_embedding(position_embedding):plt.pcolormesh(position_embedding[0], cmap = 'RdBu')plt.xlabel('Depth')plt.xlim((0, 256))plt.ylabel('Position')plt.colorbar()plt.show()
# -----------------------------------------------------------------------------
plot_position_embedding(position_embedding)

输出:

(1, 50, 256)
图片1

图片1:
在这里插入图片描述
我们可以发现对于每一个字来说他的对应的值都是不一样的,这就很有效,不过对于sin cos 这种方式的实现来说,我们取的embedding的大小还会导致位置编码是否有效,这需要作为参数方程进行查看。

Encoder block

原理图:
在这里插入图片描述

multi-head attention

首先需要实现就是这个多头注意力机制,multi-head attention:

先看一下self-attention的数学实现方式:
在这里插入图片描述
在这里插入图片描述
总结:
在这里插入图片描述
而关于多头就是实现几次的样式:
在这里插入图片描述
这边的原理讲解有点复杂,之后会另开专栏进行讲解,这边理解数学即可,只需要理解我们这边的注意力机制计算的是我们的输入的词语与词语之间的关系。

# 多头注意力的实现
# -----------------------------------------------------------------------------
# 定义多头注意力机制
class MultiHeadAttention(keras.layers.Layer):def __init__(self,d_model,num_heads):super().__init__()self.d_model = d_modelself.num_heads = num_headsself.WQ = keras.layers.Dense(self.d_model)self.WK = keras.layers.Dense(self.d_model)self.WV = keras.layers.Dense(self.d_model)self.dense = keras.layers.Dense(self.d_model)# 这边下面就需要进行分头计算 为了让头变多的同时 计算代价和参数代价不会随之增长,这边采用除法的操作assert self.d_model % self.num_heads == 0self.depth = self.d_model // self.num_headsdef call(self,q,k,v,mask):# 输入的input实际上是embedding之后加上位置编码之后的数据,形状就是(batch-size,step-nums,embedding-dim)# 首先就是先生成q,k,vq = self.WQ(q)k = self.WK(k)v = self.WV(v)# 这边进行分头 然后已知qkv的形状是(batch-size,step-nums,d_model)# 然后将其形状都变成(batch-size,nums-head,step-nums,depth),也就是由于batch-size和step-num都有其含义,这边我们不能进行拆解,所以就把d_model拆解成一个代表第几个头 一个代表的就是参数# 而为什么需要拆解成(batch-size,nums-head,step-nums,depth) 而不是(batch-size,step-nums,nums-head,depth)# 原因就是我们后面的计算明显是要用相同的nums-head的情况下去运算,这样子方便# 还有这边需要使用轴滚动 不能直接使用reshape直接进行调换形状 二者的原理不一样q = tf.reshape(q,(tf.shape(q)[0],-1,self.num_heads,self.depth))q = tf.transpose(q,[0,2,1,3])k = tf.reshape(k, (tf.shape(k)[0], -1, self.num_heads, self.depth))k = tf.transpose(k, [0, 2, 1, 3])v = tf.reshape(v, (tf.shape(q)[0], -1, self.num_heads, self.depth))v = tf.transpose(v, [0, 2, 1, 3])# 开始计算缩放点积运算 此时q k 的形状(batch-size,nums-head,step-nums,depth)# 计算得到的Matrix_kq形状就是(batch-size,nums-head,step-nums,step-nums)Matrix_kq = tf.matmul(q,k,adjoint_b=True)if mask is not None:# 带有mask多头的注意力机制 后面再来解析Matrix_kq += (mask * (-1e9))# 然后这边两个数据相乘之后,数据太大了,这边可以做一个softmax 你用relu也可以# 不过需要注意的是,我们需要对于行做softmax,取决于我们对于k的理解Matrix_kq = tf.nn.softmax(Matrix_kq,axis=-1)output = tf.transpose(tf.matmul(Matrix_kq, v),[0,2,1,3])# 再对于注意力机制进行合并 生成的数据就是(batch-size,nums-step,d_model)的数据output = tf.reshape(output,(tf.shape(output)[0],-1,self.d_model))return output
# -----------------------------------------------------------------------------

Feed Forward

前馈网络:实际上就是两层全连接层,这边就只给出代码了

# 前馈网络
# -----------------------------------------------------------------------------
class FeedForward(keras.layers.Layer):def __init__(self,d_model, dim):super().__init__()self.dense1 = keras.layers.Dense(dim,activation='relu')self.dense2 = keras.layers.Dense(d_model)def call(self,x):return self.dense2(self.dense1(x))
# -----------------------------------------------------------------------------

自定义encoder block

在这里插入图片描述

# 自定义encoder block
# -----------------------------------------------------------------------------
class EncoderBlock(keras.layers.Layer):def __init__(self,d_model, num_heads, feed_dim, rate=0.1):super().__init__()self.attention = MultiHeadAttention(d_model,num_heads)self.feed = FeedForward(d_model, feed_dim)# 做的是layer的标准化和之前采用的batch标准化不一样,batch针对的是不同特征的,layer针对的是相同特征的self.layer_norm1 = keras.layers.LayerNormalization(epsilon=1e-6)self.layer_norm2 = keras.layers.LayerNormalization(epsilon=1e-6)# 下面两个层次用了做dropout,每次有10%的几率被drop掉self.dropout1 = keras.layers.Dropout(rate)self.dropout2 = keras.layers.Dropout(rate)def call(self,x,training,encoding_padding_mask):# x代表的就是训练的数据# training代表的是是否对于train状态下进行dropout,填入的是true or false# encoding_padding_mask代表的是将padding标识为不重要,避免注意力机制去关心那一块out1 = self.attention(x,x,x, encoding_padding_mask)out1 = self.dropout1(out1, training=training)# Resnet相加 很重要x = self.layer_norm1(x+out1)out2 = self.feed(x)out2 = self.dropout2(out2, training=training)output = self.layer_norm2(x+out2)return output
# -----------------------------------------------------------------------------
#来测试,结果和我们最初的输入维度一致,相当于做了两次残差连接
sample_encoder_layer = EncoderBlock(512, 8, 2048)
sample_input = tf.random.uniform((64, 50, 512))
sample_output = sample_encoder_layer(sample_input, False, None)
print(sample_output.shape)

Deconder block

在这里插入图片描述
代码见下:

# 自定义decoder block
# -----------------------------------------------------------------------------
class DecoderBlock(keras.layers.Layer):def __init__(self,d_model, num_heads, feed_dim, rate = 0.1):super().__init__()self.attention1 = MultiHeadAttention(d_model, num_heads)self.attention2 = MultiHeadAttention(d_model, num_heads)self.feed = FeedForward(d_model, feed_dim)self.layer_norm1 = keras.layers.LayerNormalization(epsilon=1e-6)self.layer_norm2 = keras.layers.LayerNormalization(epsilon=1e-6)self.layer_norm3 = keras.layers.LayerNormalization(epsilon=1e-6)self.dropout1 = keras.layers.Dropout(rate)self.dropout2 = keras.layers.Dropout(rate)self.dropout3 = keras.layers.Dropout(rate)def call(self, x, encoding_outputs, training, decoder_mask, encoder_decoder_padding_mask):# x就是下面传来的东西 encoding_outputs 就是encoding的输出 training同上# decoder_mask 就是遮住前面看过的东西和遮住padding的mask# encoder_decoder_padding_mask这个就是对应的maskout1 = self.attention1(x,x,x,decoder_mask)out1 = self.dropout1(out1,training=training)x = self.layer_norm1(x+out1)out2 = self.attention2(encoding_outputs,encoding_outputs,x, encoder_decoder_padding_mask)out2 = self.dropout2(out2, training=training)x = self.layer_norm2(x+out2)out3 = self.feed(x)out3 = self.dropout3(out3,training=training)output = self.layer_norm3(x+out3)return output
# -----------------------------------------------------------------------------# 测试一下
sample_decoder_layer = DecoderBlock(512, 8, 2048)
sample_decoder_input = tf.random.uniform((64, 50, 512))
sample_decoder_output= sample_decoder_layer(sample_decoder_input, sample_output, False, None, None)
print(sample_decoder_output.shape)

Encoder

在这里插入图片描述
样例代码:

# 定义Encoder
# -----------------------------------------------------------------------------
class Encoder(keras.layers.Layer):def __init__(self,num_layers, input_vocab_size, max_length,d_model, num_heads, feed_dim, rate=0.1):super().__init__()self.d_model = d_modelself.num_layers = num_layersself.max_length = max_lengthself.embedding = keras.layers.Embedding(input_vocab_size,self.d_model)self.position_embedding = get_position_embedding(max_length,self.d_model)self.dropout = keras.layers.Dropout(rate)self.encoder_blocks = [EncoderBlock(self.d_model,num_heads,feed_dim,rate) for _ in range(self.num_layers)]def call(self, x, training, encoder_padding_mask):# 一开始输入进去x的形状是(batch-size,num-step)embedding_x = self.embedding(x)# 因为位置编码值在-1和1之间,因此嵌入值乘以嵌入维度的平方根进行缩放,然后再与位置编码相加。embedding_x *= tf.math.sqrt(tf.cast(self.d_model, tf.float32))# 因为x长度比position_embedding可能要小,因此embedding切片后和x相加posotion_and_embedding_x = embedding_x + self.position_embedding[:, :tf.shape(x)[1], :]posotion_and_embedding_x = self.dropout(posotion_and_embedding_x, training=training)# 得到的x不断作为下一层的输入for i in range(self.num_layers):posotion_and_embedding_x = self.encoder_blocks[i](posotion_and_embedding_x, training, encoder_padding_mask)# x最终shape如下# x.shape: (batch_size, input_seq_len, d_model)return posotion_and_embedding_x
# -----------------------------------------------------------------------------
# 测试
sample_encoder_model = Encoder(2,8500,50,512, 8, 2048)
sample_encoder_model_input = tf.random.uniform((64, 37))
sample_encoder_model_output = sample_encoder_model(sample_encoder_model_input, False, encoder_padding_mask = None)
print(sample_encoder_model_output.shape)

Decoder

在这里插入图片描述
样例代码:

# 定义Decoder
# -----------------------------------------------------------------------------
class Decoder(keras.layers.Layer):def __init__(self, num_layers, target_vocab_size, max_length,d_model, num_heads, feed_dim, rate=0.1):super().__init__()self.d_model = d_modelself.num_layers = num_layersself.max_length = max_lengthself.embedding = keras.layers.Embedding(target_vocab_size, self.d_model)self.position_embedding = get_position_embedding(max_length, self.d_model)self.dropout = keras.layers.Dropout(rate)self.decoder_blocks = [DecoderBlock(self.d_model, num_heads, feed_dim, rate) for _ in range(self.num_layers)]def call(self, x, encoding_outputs, training,decoder_mask, encoder_decoder_padding_mask):embedding_x = self.embedding(x)embedding_x *= tf.math.sqrt(tf.cast(self.d_model, tf.float32))posotion_and_embedding_x = embedding_x + self.position_embedding[:, :tf.shape(x)[1], :]posotion_and_embedding_x = self.dropout(posotion_and_embedding_x, training=training)for i in range(self.num_layers):posotion_and_embedding_x= self.decoder_blocks[i](posotion_and_embedding_x, encoding_outputs, training,decoder_mask, encoder_decoder_padding_mask)return posotion_and_embedding_x# -----------------------------------------------------------------------------
# 测试
sample_decoder_model = Decoder(2, 8000,50,512, 8, 2048)
sample_decoder_model_input = tf.random.uniform((64, 37))
sample_decoder_model_output= sample_decoder_model(sample_decoder_model_input,sample_encoder_model_output,training = False, decoder_mask = None,encoder_decoder_padding_mask = None)print(sample_decoder_model_output.shape)

transformer

在这里插入图片描述
样例代码:

# 定义transformer
# -----------------------------------------------------------------------------
class Transformer(keras.Model):def __init__(self,num_layers, input_vocab_size, target_vocab_size,max_length, d_model, num_heads, feed_dim, rate=0.1):super().__init__()self.encoder = Encoder(num_layers,input_vocab_size,max_length,d_model,num_heads,feed_dim,rate)self.decoder = Decoder(num_layers,target_vocab_size,max_length,d_model,num_heads,feed_dim,rate)self.final_layer = keras.layers.Dense(target_vocab_size)def call(self, input, target, training, encoder_padding_mask,decoder_mask, encoder_decoder_padding_mask):encoder_output = self.encoder(input,training,encoder_padding_mask)decoder_output = self.decoder(target,encoder_output,training,decoder_mask,encoder_decoder_padding_mask)predict = self.final_layer(decoder_output)return predict# -----------------------------------------------------------------------------
# 测试
sample_transformer = Transformer(2, 8500, 8000, 50,512, 8, 2048, rate = 0.1)
temp_input = tf.random.uniform((64, 26))
temp_target = tf.random.uniform((64, 26))# 得到输出
predictions = sample_transformer(temp_input, temp_target, training = False,encoder_padding_mask = None,decoder_mask = None,encoder_decoder_padding_mask = None)
# 输出shape
print(predictions.shape)

自定义loss 和 学习率

# 自定义的学习率调整设计实现
# -----------------------------------------------------------------------------
class CustomizedSchedule(keras.optimizers.schedules.LearningRateSchedule):def __init__(self, d_model, warmup_steps=4000):super().__init__()self.d_model = tf.cast(d_model, tf.float32)self.warmup_steps = warmup_stepsdef __call__(self, step):step = tf.cast(step,tf.float32)arg1 = tf.math.rsqrt(step)arg2 = step * (self.warmup_steps ** (-1.5))arg3 = tf.math.rsqrt(self.d_model)return arg3 * tf.math.minimum(arg1, arg2)learning_rate = CustomizedSchedule(d_model)
optimizer = keras.optimizers.Adam(learning_rate,beta_1=0.9,beta_2=0.98,epsilon=1e-9)loss_object = keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction='none')
def loss_function(real, pred):# 损失做了掩码处理,是padding的地方不计算损失mask = tf.math.logical_not(tf.math.equal(real, 0))loss_ = loss_object(real, pred)mask = tf.cast(mask, dtype=loss_.dtype)loss_ *= maskreturn tf.reduce_mean(loss_)
# -----------------------------------------------------------------------------

mask生成函数

def create_mask(input,target):encoder_padding_mask = tf.cast(tf.math.equal(input, 0), tf.float32)[:, tf.newaxis, tf.newaxis, :]encoder_decoder_padding_mask = encoder_padding_mask# 创建下三角型look_ahead_mask = (1 - tf.linalg.band_part(tf.ones((tf.shape(target)[1], tf.shape(target)[1])), -1, 0))decoder_padding_mask = tf.cast(tf.math.equal(target, 0), tf.float32)[:, tf.newaxis, tf.newaxis, :]decoder_mask = tf.maximum(look_ahead_mask, decoder_padding_mask)return encoder_padding_mask, decoder_mask, encoder_decoder_padding_mask

训练

# 训练
# -----------------------------------------------------------------------------
train_loss = keras.metrics.Mean(name = 'train_loss')
train_accuracy = keras.metrics.SparseCategoricalAccuracy(name = 'train_accuracy')
@tf.function
def train_step(input, target):tar_inp = target[:, :-1]  # 没带endtar_real = target[:, 1:]  # 没有startencoder_padding_mask, decoder_mask, encoder_decoder_padding_mask = create_mask(input, tar_inp)with tf.GradientTape() as tape:predictions = transformer(input, tar_inp, True,encoder_padding_mask,decoder_mask,encoder_decoder_padding_mask)loss = loss_function(tar_real, predictions)gradients = tape.gradient(loss, transformer.trainable_variables)optimizer.apply_gradients(zip(gradients, transformer.trainable_variables))train_loss(loss)train_accuracy(tar_real, predictions)epochs = 200
for epoch in range(epochs):start = time.time()# reset后就会从零开始累计train_loss.reset_states()train_accuracy.reset_states()for (batch, (input, target)) in enumerate(dataset.take(batch_size)):train_step(input, target)if batch % 100 == 0:print('Epoch {} Batch {} Loss {:.4f} Accuracy {:.4f}'.format(epoch + 1, batch, train_loss.result(),train_accuracy.result()))print('Epoch {} Loss {:.4f} Accuracy {:.4f}'.format(epoch + 1, train_loss.result(), train_accuracy.result()))print('Time take for 1 epoch: {} secs\n'.format(time.time() - start))# loss是一个正常的指标,accuracy只是机器翻译的一个参考指标,可以看趋势
# -----------------------------------------------------------------------------

翻译

# 预测
# -----------------------------------------------------------------------------
def translate(inp_sentence):# 对输入的语言做和训练时同样的预处理后,再进行word转idsentence = preprocess_sentence(inp_sentence)# text到id的转换inputs = [input_tokenizer.word_index[i] for i in sentence.split(' ')]# 加paddinginputs = keras.preprocessing.sequence.pad_sequences([inputs], maxlen=50, padding='post')# 转换为tf张量encoder_input = tf.convert_to_tensor(inputs)decoder_input = tf.expand_dims([target_tokenizer.word_index['<start>']], 1)result = ''for i in range(max_length):# 产生mask并传给transformerencoder_padding_mask, decoder_mask, encoder_decoder_padding_mask = create_mask(encoder_input, decoder_input)predictions= transformer(encoder_input,decoder_input,False,encoder_padding_mask,decoder_mask,encoder_decoder_padding_mask)# print('-'*20)# print(predictions)# 预测值就是概率最大的那个的索引,那最后一个维度中最大的那个值predicted_id = tf.argmax(predictions[0][0]).numpy()result += target_tokenizer.index_word[predicted_id] + ' '# 如果等于end id,预测结束if target_tokenizer.index_word[predicted_id] == '<end>':break# 如果predicted_id不是end id,添加到新的decoder_input中decoder_input = tf.expand_dims([predicted_id], 1)print('Input: %s' % (sentence))print('Predicted translation: {}'.format(result))translate(u'happy')
# -----------------------------------------------------------------------------

相关文章:

45 深度学习(九):transformer

文章目录 transformer原理代码的基础准备位置编码Encoder blockmulti-head attentionFeed Forward自定义encoder block Deconder blockEncoderDecodertransformer自定义loss 和 学习率mask生成函数训练翻译 transformer 这边讲一下这几年如日中天的新的seq2seq模式的transform…...

java中用javax.servlet.ServletInputStream.readLine有什么安全问题吗?怎么解决实例?

使用 javax.servlet.ServletInputStream.readLine 方法在处理 Servlet 请求时可能存在以下安全问题&#xff0c;以及相应的解决方案&#xff1a; 缓冲区溢出&#xff1a;readLine 方法会将数据读取到一个缓冲区中&#xff0c;并根据换行符分隔成行。如果输入流中包含过长的行或…...

面试官问 Spring AOP 中两种代理模式的区别?很多面试者被问懵了

面试官问 Spring AOP 中两种代理模式的区别?很多初学者栽了跟头&#xff0c;快来一起学习吧&#xff01; 代理模式是一种结构性设计模式。为对象提供一个替身&#xff0c;以控制对这个对象的访问。即通过代理对象访问目标对象&#xff0c;并允许在将请求提交给对象前后进行一…...

MQ四大消费问题一锅端:消息不丢失 + 消息积压 + 重复消费 + 消费顺序性

RabbitMQ-如何保证消息不丢失 生产者把消息发送到 RabbitMQ Server 的过程中丢失 从生产者发送消息的角度来说&#xff0c;RabbitMQ 提供了一个 Confirm&#xff08;消息确认&#xff09;机制&#xff0c;生产者发送消息到 Server 端以后&#xff0c;如果消息处理成功&#xff…...

Python爬虫——入门爬取网页数据

目录 前言 一、Python爬虫入门 二、使用代理IP 三、反爬虫技术 1. 间隔时间 2. 随机UA 3. 使用Cookies 四、总结 前言 本文介绍Python爬虫入门教程&#xff0c;主要讲解如何使用Python爬取网页数据&#xff0c;包括基本的网页数据抓取、使用代理IP和反爬虫技术。 一、…...

爬虫,TLS指纹 剖析和绕过

当你欲爬取某网页的信息数据时&#xff0c;发现通过浏览器可正常访问&#xff0c;而通过代码请求失败&#xff0c;换了随机ua头IP等等都没什么用时&#xff0c;有可能识别了你的TLS指纹做了验证。 解决办法&#xff1a; 1、修改 源代码 2、使用第三方库 curl-cffi from curl…...

Linux shell编程学习笔记25:tty

1 tty的由来 在 1830 年代和 1840 年代&#xff0c;开发了称为电传打字机&#xff08;teletypewriters&#xff09;的机器&#xff0c;这些机器可以将发件人在键盘上输入的消息“沿着线路”发送在接收端并打印在纸上。 电传打字机的名称由teletypewriters&#xff0c; 缩短为…...

AIGC大模型-初探

大语⾔模型技术链 1. ⾃然语⾔处理 2. 神经⽹络 3. ⾃注意⼒机制 4. Transformer 架构 5. 具体模型 - GPT6. 预训练&#xff0c;微调 7. ⼤模型应⽤ - LangChain 大语⾔模型有什么用&#xff1f; 利⽤⼤语⾔模型帮助我们理解⼈类的命令&#xff0c;从⽽处理⽂本分析…...

Postman for Mac(HTTP请求发送调试工具)v10.18.10官方版

Postman for mac是一个提供在MAC设备上功能强大的开发&#xff0c;监控和测试API的绝佳工具。非常适合开发人员去使用。此版本通过Interceptor添加了对请求捕获的支持&#xff0c;修正了使用上下文菜单操作未复制响应正文的问题和预请求脚本的垂直滚动条与自动完成下拉列表重叠…...

SpringBoot 项目优雅实现读写分离 | 京东云技术团队

一、读写分离介绍 当使用Spring Boot开发数据库应用时&#xff0c;读写分离是一种常见的优化策略。读写分离将读操作和写操作分别分配给不同的数据库实例&#xff0c;以提高系统的吞吐量和性能。 读写分离实现主要是通过动态数据源功能实现的&#xff0c;动态数据源是一种通过…...

企业如何利用好用户画像对客户进行精准营销?提高营销转化?

随着市场竞争的加剧&#xff0c;企业对于客户的需求和行为越来越关注&#xff0c;如何利用好用户画像对客户进行精准营销&#xff0c;提高营销转化&#xff0c;成为企业关注的焦点。 一、了解用户需求和行为 首先&#xff0c;企业需要了解客户的需求和行为&#xff0c;包括客户…...

acwing算法基础之搜索与图论--匈牙利算法求二分图的最大匹配数

目录 1 基础知识2 模板3 工程化 1 基础知识 二分图中的最大匹配数&#xff1a;从二分图中选择一些边&#xff08;这些边连接集合A和集合B&#xff0c;集合A中结点数目为n1&#xff0c;集合B中结点数目为n2&#xff09;&#xff0c;设为集合S&#xff0c;其中任意两条边不共用一…...

优化重复冗余代码的8种方式

文章目录 前言1、抽取公用方法2、抽工具类3、反射4、泛型5、继承与多态6、使用设计模式7、自定义注解(或者说AOP面向切面)8、函数式接口和Lambda表达式 前言 日常开发中&#xff0c;我们经常会遇到一些重复代码。大家都知道重复代码不好&#xff0c;它主要有这些缺点&#xff…...

DVWA - 3

文章目录 XSS&#xff08;Dom&#xff09;lowmediumhighimpossible XSS&#xff08;Dom&#xff09; XSS 主要基于JavaScript语言进行恶意攻击&#xff0c;常用于窃取 cookie&#xff0c;越权操作&#xff0c;传播病毒等。DOM全称为Document Object Model&#xff0c;即文档对…...

android studio离线tips

由于种种原因&#xff08;你懂的&#xff0c;导致我们使用android studio会有很多坑&#xff0c;这里记录一下遇到的问题以及解决方案 环境问题 无法下载gradle 因为android studio采用gradle作为构建工具&#xff0c;国内gradle没有镜像下载非常慢&#xff0c;并且大概率失…...

JWT概念(登录代码实现)

JWT (JSON Web Token)是一种开放标准&#xff0c;用于在网络应用程序之间安全地传输信息。JWT是一种基于JSON的轻量级令牌&#xff0c;包含了一些声明和签名&#xff0c;可以用于认证和授权。 JWT主要由三部分组成&#xff1a;头部、载荷和签名。 头部包含了使用的算法和类型…...

如何在 Windows 10/11 上高质量地将 WAV 转换为 MP3

WAV 几乎完全准确地存储了录音硬件所听到的内容&#xff0c;这使得它变得很大并占用了更多的存储空间。因此&#xff0c;WAV 格式在作为电子邮件附件发送、保存在便携式音频播放器上、通过蓝牙或互联网从一台设备传输到另一台设备等时可能无法正常工作。 如果您遇到 WAV 问题&…...

详解FreeRTOS:FreeRTOS消息队列(高级篇—1)

目录 1、队列简介 2、队列的运行机制 3、队列的阻塞机制 4、队列结构体 5、创建队列...

Vue3 + ts+ elementUi 实现后台数据渲染到下拉框选项中,滑动加载更多数据效果

前言 功能需求&#xff1a;下拉框中分页加载后端接口返回的人员数据&#xff0c;实现滑动加载更多数据效果&#xff0c;并且可以手动搜索定位数据&#xff0c;此项目使用Vue3 ts elementUi 实现 实现 把此分页滑动加载数据功能封装成vue中的hooks&#xff0c;文件命名为use…...

Elasticsearch 索引库操作与 Rest API 使用详解

1. 引入 Elasticsearch 依赖 在开始之前&#xff0c;确保你的 Maven 或 Gradle 项目中已经引入了 Elasticsearch 的 Java 客户端库。你可以使用以下 Maven 依赖&#xff1a; xml <dependency> <groupId>org.elasticsearch.client</groupId> <ar…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...