• <bdo id='n2iPM'></bdo><ul id='n2iPM'></ul>
    1. <tfoot id='n2iPM'></tfoot>

      <legend id='n2iPM'><style id='n2iPM'><dir id='n2iPM'><q id='n2iPM'></q></dir></style></legend>

        <small id='n2iPM'></small><noframes id='n2iPM'>

        <i id='n2iPM'><tr id='n2iPM'><dt id='n2iPM'><q id='n2iPM'><span id='n2iPM'><b id='n2iPM'><form id='n2iPM'><ins id='n2iPM'></ins><ul id='n2iPM'></ul><sub id='n2iPM'></sub></form><legend id='n2iPM'></legend><bdo id='n2iPM'><pre id='n2iPM'><center id='n2iPM'></center></pre></bdo></b><th id='n2iPM'></th></span></q></dt></tr></i><div id='n2iPM'><tfoot id='n2iPM'></tfoot><dl id='n2iPM'><fieldset id='n2iPM'></fieldset></dl></div>

        pytorch实现seq2seq时对loss进行mask的方式

        在Pytorch实现seq2seq模型中,对于一个batch中的每个序列,其长度可能不一致。对于长度不一致的序列,需要进行pad操作,使其长度一致。但是,在计算loss的时候,pad部分的贡献必须要被剔除,否则会带来噪声。

          <i id='ZlgKf'><tr id='ZlgKf'><dt id='ZlgKf'><q id='ZlgKf'><span id='ZlgKf'><b id='ZlgKf'><form id='ZlgKf'><ins id='ZlgKf'></ins><ul id='ZlgKf'></ul><sub id='ZlgKf'></sub></form><legend id='ZlgKf'></legend><bdo id='ZlgKf'><pre id='ZlgKf'><center id='ZlgKf'></center></pre></bdo></b><th id='ZlgKf'></th></span></q></dt></tr></i><div id='ZlgKf'><tfoot id='ZlgKf'></tfoot><dl id='ZlgKf'><fieldset id='ZlgKf'></fieldset></dl></div>
            <tbody id='ZlgKf'></tbody>
            <bdo id='ZlgKf'></bdo><ul id='ZlgKf'></ul>

              1. <tfoot id='ZlgKf'></tfoot>

                  <legend id='ZlgKf'><style id='ZlgKf'><dir id='ZlgKf'><q id='ZlgKf'></q></dir></style></legend>

                  <small id='ZlgKf'></small><noframes id='ZlgKf'>

                  在Pytorch实现seq2seq模型中,对于一个batch中的每个序列,其长度可能不一致。对于长度不一致的序列,需要进行pad操作,使其长度一致。但是,在计算loss的时候,pad部分的贡献必须要被剔除,否则会带来噪声。

                  为了解决这一问题,可以使用mask技术,即使用一个mask张量对loss进行掩码,将pad部分设置为0,只计算有效部分的loss。

                  下面是实现seq2seq时对loss进行mask的方式的完整攻略:

                  1.创建mask张量

                  通过给定的输入序列长度,创建一个bool掩码,其中有效部分为True,pad部分为False。

                  def create_mask(seq_len, pad_idx):
                      mask = (torch.ones(seq_len) * pad_idx).unsqueeze(0) != torch.arange(seq_len).unsqueeze(1)
                      return mask.to(device)
                  

                  其中,seq_len为每个序列的长度,pad_idx为pad的token索引,此处默认使用0进行pad。

                  2.计算loss时掩码

                  在计算loss时,将mask张量与计算得到的loss张量相乘即可实现mask。

                  mask = create_mask(target_seq_len, pad_idx)  # 创建mask张量
                  loss = criterion(output, target_seqs)  # 计算loss
                  loss = (loss * mask.float()).sum() / mask.sum()  # mask掩码
                  

                  3.示例说明

                  下面给出两个示例,更好地理解如何使用mask对seq2seq模型的loss进行掩码。

                  假设我们有如下两个序列:

                  • 输入序列:['I', 'love', 'you']
                  • 目标序列:['Ich', 'liebe', 'dich']

                  其中,我们使用3个token来表示输入和输出序列,对应的pad_idx为0。那么,我们需要将输入和输出序列转换为相同的长度,这里设定为5。那么,经过pad之后,就可以得到如下矩阵:

                  # input_seq:['I', 'love', 'you']
                  input_seqs = [[1, 3, 2, 0, 0]]  # 0表示pad
                  
                  # target_seq:['Ich', 'liebe', 'dich']
                  target_seqs = [[4, 5, 6, 2, 0]]  # 0表示pad
                  

                  其中,1/3/2对应的是输入序列中的'I'/'love'/'you',4/5/6对应的是目标序列中的'Ich'/'liebe'/'dich'。

                  接下来,我们需要创建掩码张量,对于pad部分置为False,其他部分置为True。

                  pad_idx = 0
                  input_seq_len = 3  # 输入序列长度
                  target_seq_len = 3  # 目标序列长度
                  input_mask = create_mask(input_seq_len, pad_idx)
                  # input_mask: [[ True,  True,  True, False, False]]
                  target_mask = create_mask(target_seq_len, pad_idx) 
                  # target_mask: [[ True,  True,  True, False, False]]
                  

                  最后,计算loss时,使用mask张量掩码:

                  output = model(input_seqs, input_mask, target_seqs[:, :-1], target_mask[:, :-1])
                  loss = criterion(output, target_seqs[:, 1:]) 
                  # 对验证集batch中每个序列的loss进行求和并求平均
                  loss = (loss * target_mask[:, 1:].float()).sum() / target_mask[:, 1:].sum()
                  

                  这里,我们首先使用model计算模型输出,然后计算loss,最后使用target_mask掩码。需要注意的是,这里的target_seqs需要去掉最后的一个token,也就是'pad',以保证input_seqs和target_seqs的长度相同。

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Python中有三个内置函数eval()、exec()和compile()来执行动态代码。这些函数能够从字符串参数中读取Python代码并在运行时执行该代码。但是,使用这些函数时必须小心,因为它们的不当使用可能会导致安全漏洞。
                  在Python中,下载网络文本数据到本地内存是常见的操作之一。本文将介绍四种常见的下载网络文本数据到本地内存的实现方法,并提供示例说明。
                  来给你详细讲解下Python 二进制字节流数据的读取操作(bytes与bitstring)。
                  Python 3.x 是 Python 2.x 的下一个重大版本,其中有一些值得注意的区别。 Python 3.0中包含了许多不兼容的变化,这意味着在迁移到3.0之前,必须进行代码更改和测试。本文将介绍主要的差异,并给出一些实例来说明不同点。
                  要在终端里显示图片,需要使用一些Python库。其中一种流行的库是Pillow,它有一个子库PIL.Image可以加载和处理图像文件。要在终端中显示图像,可以使用如下的步骤:
                  在Python中,我们可以使用Pillow库来进行图像处理。具体实现两幅图像合成一幅图像的方法如下:
                  • <bdo id='G1cYi'></bdo><ul id='G1cYi'></ul>
                    <tfoot id='G1cYi'></tfoot>
                      <tbody id='G1cYi'></tbody>
                    • <i id='G1cYi'><tr id='G1cYi'><dt id='G1cYi'><q id='G1cYi'><span id='G1cYi'><b id='G1cYi'><form id='G1cYi'><ins id='G1cYi'></ins><ul id='G1cYi'></ul><sub id='G1cYi'></sub></form><legend id='G1cYi'></legend><bdo id='G1cYi'><pre id='G1cYi'><center id='G1cYi'></center></pre></bdo></b><th id='G1cYi'></th></span></q></dt></tr></i><div id='G1cYi'><tfoot id='G1cYi'></tfoot><dl id='G1cYi'><fieldset id='G1cYi'></fieldset></dl></div>

                          <legend id='G1cYi'><style id='G1cYi'><dir id='G1cYi'><q id='G1cYi'></q></dir></style></legend>

                          1. <small id='G1cYi'></small><noframes id='G1cYi'>