连接 Transformer 编码器和解码器以及掩码

我们已经实现了 Transformer 编码器解码器并分别进行了测试,现在我们可以将它们结合起来形成一个完整的模型。我们还将学习如何创建填充掩码和前瞻掩码,通过它们来抑制在编码器或解码器计算中不被考虑的输入值。我们的最终目标仍然是将完整模型应用于自然语言处理 (NLP)。

在本教程中,您将了解如何实现完整的 Transformer 模型并创建填充掩码和前瞻掩码。 

完成本教程后,您将了解:

  • 如何为编码器和解码器创建填充掩码
  • 如何为解码器创建前瞻掩码
  • 如何将 Transformer 编码器和解码器组合成一个模型
  • 如何打印出编码器和解码器层的摘要

让我们开始吧。 

Transformer 编码器和解码器的结合与掩码
照片由 John O’Nolan 拍摄,部分权利保留。

教程概述

本教程分为四个部分;它们是

  • Transformer 架构回顾
  • 掩码
    • 创建填充掩码
    • 创建前瞻掩码
  • 组合 Transformer 编码器和解码器
  • 创建 Transformer 模型实例
    • 打印出编码器和解码器层的摘要

先决条件

本教程假设您已熟悉以下内容:

Transformer 架构回顾

回想一下,Transformer 架构遵循编码器-解码器结构。左侧的编码器负责将输入序列映射到一系列连续表示;右侧的解码器接收编码器的输出以及前一个时间步的解码器输出来生成输出序列。

Transformer 架构的编码器-解码器结构
摘自“Attention Is All You Need

在生成输出序列时,Transformer 不依赖于循环和卷积。

您已经了解了如何分别实现 Transformer 编码器和解码器。在本教程中,您将把它们结合起来形成一个完整的 Transformer 模型,并对输入值应用填充和前瞻掩码。 

让我们先来了解如何应用掩码。 

通过我的书 《Transformer 模型构建》 来启动您的项目。书中提供了自学教程工作代码,指导您构建一个功能齐全的 Transformer 模型,可以
将句子从一种语言翻译成另一种语言的完整 Transformer 模型...

掩码

创建填充掩码

您应该已经熟悉在将输入值馈入编码器和解码器之前对其进行掩码处理的重要性。 

正如您在 训练 Transformer 模型时将看到的,馈入编码器和解码器的输入序列首先会被填充为零,直到达到特定的序列长度。填充掩码的重要性在于确保这些零值不会与实际输入值一起被编码器和解码器处理。 

让我们创建以下函数来为编码器和解码器生成填充掩码

此函数在接收到输入后,将生成一个张量,在输入包含零值的地方标记为“1”。 

因此,如果您输入以下数组

那么 padding_mask 函数的输出将是以下内容

创建前瞻掩码

为了防止解码器关注后续的词语,需要前瞻掩码,这样当前词语的预测只能依赖于它之前的已知输出。

为此,让我们创建以下函数来为解码器生成前瞻掩码

我们将把解码器输入的长度传递给它。作为示例,我们将此长度设置为 5

那么 lookahead_mask 函数返回的输出是以下内容

同样,1 值屏蔽了不应使用的条目。这样,每个词的预测仅依赖于它之前的词。 

想开始构建带有注意力的 Transformer 模型吗?

立即参加我的免费12天电子邮件速成课程(含示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

组合 Transformer 编码器和解码器

让我们开始创建 TransformerModel 类,它继承自 Keras 中的 Model 基类

创建 TransformerModel 类我们的第一步是初始化先前实现的 EncoderDecoder 类的实例,并将它们的输出分别赋值给变量 encoderdecoder。如果您将这些类保存在单独的 Python 脚本中,请不要忘记导入它们。我将代码保存在 encoder.pydecoder.py 的 Python 脚本中,因此我需要相应地导入它们。 

您还将包含最后一层密集层,该层生成最终输出,如同 Vaswani 等人 (2017) 的 Transformer 架构一样。 

接下来,您将创建类方法 call(),以将相关的输入馈入编码器和解码器。

首先生成填充掩码,以掩盖编码器输入以及解码器的编码器输出(当将其馈入解码器的第二个自注意力块时)

然后生成填充掩码和前瞻掩码来屏蔽解码器输入。将它们通过元素级的 maximum 操作组合在一起

接下来,将相关输入馈入编码器和解码器,并通过将解码器输出馈入最后一个密集层来生成 Transformer 模型输出

将所有步骤结合起来,我们得到以下完整的代码列表

请注意,我们对 padding_mask 函数返回的输出进行了一个小的更改。它的形状被调整为可以广播到训练 Transformer 模型时要掩码的注意力权重张量的形状。 

创建 Transformer 模型实例

我们将使用 Vaswani 等人 (2017) 的论文 《Attention Is All You Need》中指定的参数值。

至于与输入相关的参数,在您进入 训练完整的 Transformer 模型阶段之前,您将使用虚拟值。届时,您将使用实际的句子

现在您可以按如下方式创建 TransformerModel 类的实例

完整的代码清单如下

打印出编码器和解码器层的摘要

您还可以打印出 Transformer 模型编码器和解码器块的摘要。单独打印它们的选择将允许您查看其各个子层的详细信息。要做到这一点,请在 EncoderLayerDecoderLayer 类的 __init__() 方法中添加以下代码行

然后您需要向 EncoderLayer 类添加以下方法

以及向 DecoderLayer 类添加以下方法

这会导致 EncoderLayer 类修改如下(call() 方法下的三个点表示这与此处实现的保持不变 这里

DecoderLayer 类也可以进行类似的更改。

完成必要的更改后,您可以继续创建 EncoderLayerDecoderLayer 类的实例并打印它们的摘要,如下所示:

编码器的结果摘要如下:

而解码器的结果摘要如下:

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

书籍

论文

总结

在本教程中,您将了解如何实现完整的 Transformer 模型以及如何创建填充掩码和前瞻掩码。

具体来说,你学到了:

  • 如何为编码器和解码器创建填充掩码
  • 如何为解码器创建前瞻掩码
  • 如何将 Transformer 编码器和解码器组合成一个模型
  • 如何打印出编码器和解码器层的摘要

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

学习 Transformer 和注意力!

Building Transformer Models with Attention

教您的深度学习模型阅读句子

...使用带有注意力的 Transformer 模型

在我的新电子书中探索如何实现
使用注意力机制构建 Transformer 模型

它提供了自学教程可运行代码,指导您构建一个可以
将句子从一种语言翻译成另一种语言的完整 Transformer 模型...

为理解人类语言提供神奇力量
您的项目


查看内容

, , , , ,

32 条回复关于 “连接 Transformer 编码器和解码器以及掩码”

  1. Helen 2022年10月16日 上午3:44 #

    感谢您提供出色的教程!
    我在打印编码器和解码器结构信息时发现了一些错误。
    原因似乎在于 MultiHeadAttention/reshape_tensor 函数。具体来说,重塑对于具有 None 维度的张量不起作用。
    我通过如下更改函数来解决了这个问题。
    _________________________________________________
    def reshape_tensor(self, x, heads, flag)
    if flag
    # 重塑和转置后的张量形状:(batch_size, heads, seq_length, -1)
    x = reshape(x, shape=(shape(x)[0], shape(x)[1], heads, int(x.shape[2]/heads)))
    x = transpose(x, perm=(0, 2, 1, 3))
    else
    # 恢复重塑和转置操作:(batch_size, seq_length, d_model)
    x = transpose(x, perm=(0, 2, 1, 3))
    x = reshape(x, shape=(shape(x)[0], shape(x)[1], int(x.shape[2]*x.shape[3])))
    return x
    _________________________________________________
    这似乎有点奇怪。我想知道是否有更好的解决方案。再次感谢!

    • James Carmichael 2022年10月17日 上午10:45 #

      感谢 Helen 的反馈!您遇到了哪些具体的错误消息,以便我们记录需要审查的代码列表。

      • Helen 2022年10月17日 晚上11:00 #

        感谢您的回复!错误如下。

        in test_transformer
        encoder.build_graph().summary()
        in build_graph
        return Model(inputs=[input_layer], outputs=self.call(input_layer, None, True))
        in call
        multihead_output = self.multihead_attention(x, x, x, padding_mask)
        in call *
        return self.W_o(output)
        ValueError: The last dimension of the inputs to a Dense layer should be defined. Found None. Full input shape received: (None, 5, None)
        Call arguments received by layer “multi_head_attention_18” (type MultiHeadAttention)
        \u2022 queries=tf.Tensor(shape=(None, 5, 512), dtype=float32)
        \u2022 keys=tf.Tensor(shape=(None, 5, 512), dtype=float32)
        \u2022 values=tf.Tensor(shape=(None, 5, 512), dtype=float32)
        \u2022 mask=None

  2. Chunhua 2022年10月29日 上午8:36 #

    最后添加图输出的部分非常令人困惑。
    它涉及到许多地方的更改。
    最后,我仍然遇到一些错误。

    49
    50 def build_graph(self)
    —> 51 input_layer = Input(shape=(self.sequence_length, self.d_model))
    52 return Model(inputs=[input_layer], outputs=self.call(input_layer, None, True))
    53 def call(self, x, padding_mask, training)

    重现错误的 Colab

    NameError: name ‘Input’ is not defined

    • michel 2022年11月19日 晚上8:34 #

      我遇到了同样的错误。

      • Ivan 2023年2月26日 上午10:09 #

        Input 层未在导入部分导入。在第一行的末尾添加 Input

        from tensorflow.keras.layers import LayerNormalization, Layer, Dense, ReLU, Dropout, Input

  3. michel 2022年11月19日 晚上8:08 #

    在构建解码器摘要时,我遇到了与编码器摘要相同的错误。

    TypeError Traceback (most recent call last)
    in
    2 # encoder.build_graph().summary()
    3
    —-> 4 decoder = DecoderLayer(dec_seq_length, h, d_k, d_v, d_model, d_ff, dropout_rate)
    5 decoder.build_graph().summary()

    TypeError: __init__() takes 7 positional arguments but 8 were given

    • James Carmichael 2022年11月20日 上午11:54 #

      你好 Michel…我建议在 Google Colab 中尝试此代码。

    • Ivan 2023年2月26日 上午10:15 #

      检查 DecoderLayer 类中的 __init__ 函数。
      本书在此章节之前的版本没有 dec_seq_length(只有 7 个输入参数),但如果您仔细查看本章节中的构造函数,会发现许多文本中未提及的更改。

      class EncoderLayer(Layer)
      # ——— sequence_length 已添加
      def __init__(self, sequence_length, h, d_k, d_v, d_model, d_ff, rate, **kwargs)
      super().__init__(**kwargs)
      self.build(input_shape=[None, sequence_length, d_model])
      # ——– 以下两行已添加
      self.d_model = d_model
      self.sequence_length = sequence_length
      self.multihead_attention = MultiHeadAttention(h, d_k, d_v, d_model)
      self.dropout1 = Dropout(rate)
      self.add_norm1 = AddNormalization()
      self.feed_forward = FeedForward(d_ff, d_model)
      self.dropout2 = Dropout(rate)

      如果您进行了所有这些更改,那么 build_graph 将可以工作,但其他所有内容很可能都会损坏。

  4. Michel 2022年11月19日 晚上8:36 #

    ValueError 回溯 (最近一次调用)
    in
    2
    3 encoder = EncoderLayer(enc_seq_length, h, d_k, d_v, d_model, d_ff, dropout_rate)
    —-> 4 encoder.build_graph().summary()
    5
    6 decoder = DecoderLayer(dec_seq_length, h, d_k, d_v, d_model, d_ff, dropout_rate)

    3 frames
    /tmp/__autograph_generated_file2sd23ix_.py in tf__call(self, queries, keys, values, mask)
    15 try
    16 do_return = True
    —> 17 retval_ = ag__.converted_call(ag__.ld(self).W_o, (ag__.ld(output),), None, fscope)
    18 except
    19 do_return = False

    ValueError: Exception encountered when calling layer “multi_head_attention_155” (type MultiHeadAttention).

    in user code

    File “”, line 48, in call *
    return self.W_o(output)
    File “/usr/local/lib/python3.7/dist-packages/keras/utils/traceback_utils.py”, line 67, in error_handler **
    raise e.with_traceback(filtered_tb) from None
    File “/usr/local/lib/python3.7/dist-packages/keras/layers/core/dense.py”, line 141, in build
    raise ValueError(‘The last dimension of the inputs to a Dense layer ‘

    ValueError: The last dimension of the inputs to a Dense layer should be defined. Found None. Full input shape received: (None, 5, None)

    Call arguments received by layer “multi_head_attention_155” (type MultiHeadAttention)
    • queries=tf.Tensor(shape=(None, 5, 512), dtype=float32)
    • keys=tf.Tensor(shape=(None, 5, 512), dtype=float32)
    • values=tf.Tensor(shape=(None, 5, 512), dtype=float32)
    • mask=None

    • James Carmichael 2022年11月20日 上午11:51 #

      你好 Michel…你是在输入代码还是复制粘贴代码?您可能希望在 Google Colab 中尝试一下。

    • Ivan 2023年2月26日 上午10:18 #

      此错误是由于 EncoderLayer 类中的构造函数已更改,但 Encoder 类仍然依赖于之前的实现。为了解决这个问题,Encoder 类必须考虑新的构造函数参数 seq_length。

  5. Shivam Shrivastava 2023年2月11日 上午4:58 #

    class Transformer(tf.keras.Model)
    def __init__(self, num_layers, d_model, num_heads, dff, input_vocab_size, target_vocab_size, pe_input, pe_target, rate=0.1)
    super(Transformer, self).__init__()

    self.encoder = Encoder(num_layers, d_model, num_heads, dff, input_vocab_size, pe_input, rate)

    self.decoder = Decoder(num_layers, d_model, num_heads, dff, target_vocab_size, pe_target, rate)

    self.final_layer = tf.keras.layers.Dense(target_vocab_size)

    def call(self, inp, tar, training, enc_padding_mask, look_ahead_mask, dec_padding_mask)
    enc_output = self.encoder(inp, training, enc_padding_mask)

    dec_output, attention_weights = self.decoder(tar, enc_output, training, look_ahead_mask, dec_padding_mask)

    final_output = self.final_layer(dec_output)

    return final_output, attention_weights

    注意:Transformer/Transformer 训练的其余代码与这些博客类似
    .
    .
    .
    .
    .
    .

    这是我的 Transformer 类… 在训练这个子类模型时,每 3 个 epoch 后,我尝试使用以下代码行保存子类模型:`trainer.save(‘net’, save_format=’tf’)`

    但是我收到了这个错误:
    TypeError: tf__call() missing 3 required positional arguments: ‘enc_padding_mask’, ‘look_ahead_mask’, and ‘dec_padding_mask’

    你能给我一些解决方案吗?

  6. Vik 2023年2月23日 下午5:51 #

    你好,
    感谢您提供出色的教程!如何使用 Hugging Face 的 transformers 包来实现这一点?

  7. Ivan 2023年2月25日 下午3:05 #

    各位专家好,

    在阅读本章并进行大量实验时,我注意到一种我认为不正确的行为。想听听您的意见。

    注意:在以下解释中
    *) 松散遵循 int 与 float 类型
    *) 松散使用“token”与“word”等术语,在本例中它们是相同的。
    对此表示抱歉。

    — Padding mask —

    让我们假设
    input_seq_len = 9 # encoded sentence 中的单词数
    input_seq = [[2,3,4,5,0,0,0,0,0]]

    在类 TransformerModel.padding_mask 中
    mask = padding_mask(input_seq)
    # 张量 [[[[0,0,0,0,1,1,1,1,1]]]], 形状 (1,1,1,9)
    # 第一个“1”是 batch
    # 第二个和第三个“1”是 tf.newaxis
    # 最后一个维度是实际的掩码

    此掩码的目的是禁止“0”token 关注实际单词(2,3,4,5)。

    让我们看看 DotProductAttention.call 行中发生了什么
    scores += -1e9 * mask
    # scores.shape (1, heads, 9, 9)
    # “1”是 batch
    # 9×9 是注意力分数矩阵,它显示了每个 token 必须如何关注另一个 token。

    当 TensorFlow 将 (9, 9) 分数乘以 (1, 9) 掩码矩阵时,会应用广播规则。这会产生如下形式的分数(\* 表示 -1e9)
    [x11, x12, x13, x14, *,*,*,*,*]
    [x21, x22, x23, x24, *,*,*,*,*]
    [x31, x32, x33, x34, *,*,*,*,*]
    [x41, x42, x43, x44, *,*,*,*,*]
    [x51, x52, x53, x54, *,*,*,*,*]
    [x61, x62, x63, x64, *,*,*,*,*]
    [x71, x72, x73, x74, *,*,*,*,*]
    [x81, x82, x83, x84, *,*,*,*,*]
    [x91, x92, x93, x94, *,*,*,*,*]

    观察 1)
    上述矩阵允许第 5、6、7、8 和 9 个 token 关注第 1、2、3 和 4 个 token。我认为上述矩阵应该是
    [x11, x12, x13, x14, *,*,*,*,*]
    [x21, x22, x23, x24, *,*,*,*,*]
    [x31, x32, x33, x34, *,*,*,*,*]
    [x41, x42, x43, x44, *,*,*,*,*]
    [ *, *, *, *, *,*,*,*,*]
    [ *, *, *, *, *,*,*,*,*]
    [ *, *, *, *, *,*,*,*,*]
    [ *, *, *, *, *,*,*,*,*]
    [ *, *, *, *, *,*,*,*,*]

    解决方案 1)
    如果观察 1 是正确的
    def PaddingMask(self, input)
    mask = tf.equal(input, 0)
    mask = tf.cast(mask, tf.float32)
    mask = mask[:, tf.newaxis, tf.newaxis, :]
    new_mask = tf.maximum(mask, tf.transpose(mask, perm=(0,1,3,2)))
    return new_mask

    — Lookahead mask combined with padding mask —
    完全相同的设置。

    在 TransformerModel.call() 中
    dec_lookahead_mask = tf.maximum(dec_lookahead_mask_pre, dec_padding_mask)
    将看起来像

    [1,0,0,0,0,0,0,0,0]
    [1,1,0,0,0,0,0,0,0]
    [1,1,1,0,0,0,0,0,0]
    [1,1,1,1,0,0,0,0,0]
    [1,1,1,1,0,0,0,0,0]
    [1,1,1,1,0,0,0,0,0]
    [1,1,1,1,0,0,0,0,0]
    [1,1,1,1,0,0,0,0,0]
    [1,1,1,1,0,0,0,0,0]

    但应该是
    [1,0,0,0,0,0,0,0,0]
    [1,1,0,0,0,0,0,0,0]
    [1,1,1,0,0,0,0,0,0]
    [1,1,1,1,0,0,0,0,0]
    [0,0,0,0,0,0,0,0,0]
    [0,0,0,0,0,0,0,0,0]
    [0,0,0,0,0,0,0,0,0]
    [0,0,0,0,0,0,0,0,0]
    [0,0,0,0,0,0,0,0,0]

    观察 2)
    上述掩码允许零 token 关注实际单词。

    解决方案 2)
    如果观察 2 有效,解决方案 (1) 也能修复观察 (2)。

    • Jamol 2023年2月28日 上午2:26 #

      我完全同意您的观察。零 token 不应该被允许关注实际 token,因此分数矩阵应该是块状非零的。然而,您的解决方案会产生类似以下的内容:

      array([[[[0., 0., 1., 1.],
      [0., 0., 1., 1.],
      [1., 1., 1., 1.],
      [1., 1., 1., 1.]]]], dtype=float32)>

      例如,如果我们有一个序列 [2,4,0,0]。这个数组在下面这行不起作用:

      scores = scores + mask * -1e9

      在 dot product attention 中实现掩码。原因是显而易见的,因为 softmax 是逐行操作的:零 token 的注意力分数当然会因 -1e9 而改变,但是它们都均匀地改变,并且 softmax 最终将它们标准化为相等的值。

      • Ivan 2023年2月28日 下午2:30 #

        在我的消息中,我在 1 和 0 的使用上出了差错,但代码仍然是正确的。
        在 padding/lookahead 掩码中,1 表示“应被掩盖”。
        当 1 乘以 -1e9 时,它会变成一个非常小的数字。所以掩码应该在需要被掩盖的位置有 1。

  8. Ivan 2023年2月28日 下午2:20 #

    scores += -1e9 * mask
    # 这里是形状
    # (1, 8, 4, 4) + -1e9 * (1, 1, 4, 4) – 由于广播,工作正常。

  9. David 2023年4月13日凌晨1:19 #

    你好,Jason Brownlee博士
    我在运行整个Transformer模型时遇到一个问题
    在按batch_size处理时,
    执行“encoder_input = trainX_batch[:, 1:]”后,encoder_input的形状是[batch_size, max_len_eng – 1]
    执行“decoder_input = trainY_batch[:, :-1]”后,decoder_input的形状是[batch_size, max_len_ger – 1]
    所以当max_len_eng不等于max_len_ger时,
    使用“tensorflow.maximum(dec_in_padding_mask, dec_in_lookahead_mask)”组合两种掩码的执行会引发如下错误:
    ValueError: Dimensions must be equal, but are 64 and 23 for ‘{{node transformer_model_complete/Maximum}} = Maximum[T=DT_FLOAT](transformer_model_complete/Cast_1, transformer_model_complete/sub)’ with input shapes: [64,23], [23,23]。
    你能帮我弄清楚吗?

  10. David 2023年4月13日晚上8:48 #

    抱歉,James,我不认为这与您发布的URL有关。
    在掩码编码器输入时,我遵循了这个教程:https://machinelearning.org.cn/joining-the-transformer-encoder-and-decoder-and-masking/
    代码的关键部分是:

    # 创建并组合填充和前瞻掩码以馈入解码器
    dec_in_padding_mask = self.padding_mask(decoder_input)
    dec_in_lookahead_mask = self.lookahead_mask(decoder_input.shape[1])
    dec_in_lookahead_mask = maximum(dec_in_padding_mask, dec_in_lookahead_mask)

    在以上三行中,decoder_input的形状是[batch_size, max_len_source_lang],例如[64, 25]
    执行“dec_in_padding_mask = self.padding_mask(decoder_input)”后,
    dec_in_padding_mask的形状是[64, 25]
    decoder_input的形状是[batch_size, max_len_target_lang – 1],例如[64, 23]
    执行“dec_in_lookahead_mask = self.lookahead_mask(decoder_input.shape[1])”后,
    dec_in_lookahead_mask是一个形状为[23, 23]的方形矩阵。

    那么,为什么这两个形状不同的张量可以被发送到maximum函数,这就是我在开始训练模型时遇到的错误。

    • David 2023年4月13日晚上8:52 #

      抱歉,我之前打错了张量的形状,所以重写此回复。
      我不认为这与您发布的URL有关,或者我在那个StackOverflow问题中没有找到完全正确的评论。
      我的问题是
      在掩码编码器输入时,我遵循了这个教程:https://machinelearning.org.cn/joining-the-transformer-encoder-and-decoder-and-masking/
      代码的关键部分是:

      # 创建并组合填充和前瞻掩码以馈入解码器
      dec_in_padding_mask = self.padding_mask(decoder_input)
      dec_in_lookahead_mask = self.lookahead_mask(decoder_input.shape[1])
      dec_in_lookahead_mask = maximum(dec_in_padding_mask, dec_in_lookahead_mask)

      在以上三行中,decoder_input的形状是[batch_size, max_len_target_lang – 1],例如[64, 23]。
      执行“dec_in_padding_mask = self.padding_mask(decoder_input)”后,
      dec_in_padding_mask的形状是[64, 23]。
      decoder_input的形状是[batch_size, max_len_target_lang – 1],例如[64, 23]
      执行“dec_in_lookahead_mask = self.lookahead_mask(decoder_input.shape[1])”后,
      dec_in_lookahead_mask是一个形状为[23, 23]的方形矩阵。

      那么,为什么这两个形状不同的张量([64, 23] vs [23, 23])可以被发送到maximum函数,这就是我在开始训练模型时遇到的错误。

      • Stefania Cristina
        Stefania Cristina 2023年4月14日凌晨12:23 #

        你好David,您提到的张量形状应该是这样的:

        – decoder_input: [batch_size, dec_seq_length – 1]
        – dec_in_padding_mask: [batch_size, 1, 1, dec_seq_length – 1]
        – dec_in_lookahead_mask: [batch_size, 1, dec_seq_length – 1, dec_seq_length – 1]

        例如,我使用dec_seq_length = 12,batch_size = 64,因此我有以下张量形状:

        – decoder_input: [64, 11]
        – dec_in_padding_mask: [64, 1, 1, 11]
        – dec_in_lookahead_mask: [64, 1, 11, 11]

        您能否深入代码检查一下为什么您的张量形状与预期不符?

        • David 2023年4月14日中午12:52 #

          感谢Cristina的帮助。我发现我直接使用了本教程前面部分的演示“padding_mask”函数,该函数只返回“mask”变量,实际上,最终格式中一个同名的函数返回“[:, newaxis, newaxis, :]”,这就是我无法最大化这两个填充掩码张量的原因。

          • Stefania Cristina
            Stefania Cristina 2023年4月14日晚上9:59 #

            谢谢你的澄清,David。

  11. Florian 2023年5月17日晚上11:26 #

    我想为卡在最后阶段的人提供一个快速的解决方法:打印模型摘要。
    您可以使用我们之前章节中使用的虚拟变量。

    batch_size = 64
    my_encoder_input = np.random.random((batch_size, enc_seq_length))
    my_decoder_input = np.random.random((batch_size, dec_seq_length))
    output = training_model(my_encoder_input, my_decoder_input, True)

    –> output的形状应该是(batch_size, dec_seq_length, dec_vocab_size)

    奖励:现在training_model已经被实例化,您可以运行
    training_model.summary()
    并且可以看到我们的模型有超过2700万个参数!

    • James Carmichael 2023年5月18日早上5:56 #

      感谢Florian乐于与社区分享!

  12. Mohammad 2023年9月14日晚上11:28 #

    打扰一下,但是我的数据集是3个元素的列表,例如:[[ ],[ ],[ ]],[[ ],[ ],[ ]],……
    dataset = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    [[10, 11, 12], [13, 14, 15], [16, 17, 18]],……

    这是一个有5个类别(1,2,3,4,5)的分类问题。

    我应该如何为此序列分类问题使用Transformer模型?我想使用注意力机制。

    感谢您的帮助

Leave a Reply

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。