【问题标题】:torchtext BucketIterator minimum paddingtorchtext BucketIterator 最小填充
【发布时间】:2020-04-29 06:09:34
【问题描述】:

我正在尝试使用 torchtext 中的 BucketIterator.splits 函数从 csv 文件中加载数据以在 CNN 中使用。除非我有一批最长的句子比最大的过滤器尺寸短,否则一切正常。

在我的示例中,我有大小为 3、4 和 5 的过滤器,因此如果最长的句子没有至少 5 个单词,我会收到错误消息。有没有办法让 BucketIterator 为批次动态设置填充,同时也设置最小填充长度?

这是我用于 BucketIterator 的代码:

train_iter, val_iter, test_iter = BucketIterator.splits((train, val, test), sort_key=lambda x: len(x.text), batch_size=batch_size, repeat=False, device=device)

我希望有一种方法可以在 sort_key 或类似的东西上设置最小长度?

我试过了,但它不起作用:

FILTER_SIZES = [3,4,5]
train_iter, val_iter, test_iter = BucketIterator.splits((train, val, test), sort_key=lambda x: len(x.text) if len(x.text) >= FILTER_SIZES[-1] else FILTER_SIZES[-1], batch_size=batch_size, repeat=False, device=device) 

【问题讨论】:

    标签: python pytorch torchtext


    【解决方案1】:

    我查看了 torchtext 源代码以更好地了解 sort_key 的作用,并了解了为什么我最初的想法行不通。

    我不确定这是否是最佳解决方案,但我想出了一个可行的解决方案。我创建了一个标记器函数,如果它比最长的过滤器长度短,则填充文本,然后从那里创建 BucketIterator。

    FILTER_SIZES = [3,4,5]
    spacy_en = spacy.load('en')
    
    def tokenizer(text):
        token = [t.text for t in spacy_en.tokenizer(text)]
        if len(token) < FILTER_SIZES[-1]:
            for i in range(0, FILTER_SIZES[-1] - len(token)):
                token.append('<PAD>')
        return token
    
    TEXT = Field(sequential=True, tokenize=tokenizer, lower=True, tensor_type=torch.cuda.LongTensor)
    
    train_iter, val_iter, test_iter = BucketIterator.splits((train, val, test), sort_key=lambda x: len(x.text), batch_size=batch_size, repeat=False, device=device)
    

    【讨论】:

      【解决方案2】:

      虽然@paul41 的方法有效,但它有点误用。正确的做法是使用preprocessingpostprocessing(相应地在数值化之前或之后)。以下是postprocessing 的示例:

      def get_pad_to_min_len_fn(min_length):
          def pad_to_min_len(batch, vocab, min_length=min_length):
              pad_idx = vocab.stoi['<pad>']
              for idx, ex in enumerate(batch):
                  if len(ex) < min_length:
                      batch[idx] = ex + [pad_idx] * (min_length - len(ex))
              return batch
          return pad_to_min_len
      
      FILTER_SIZES = [3,4,5]
      min_len_padding = get_pad_to_min_len_fn(min_length=max(FILTER_SIZES))
      
      TEXT = Field(sequential=True, use_vocab=True, lower=True, batch_first=True, 
                   postprocessing=min_len_padding)
      

      如果是在主循环中定义的(例如min_length = max(FILTER_SIZES)),则需要将参数传递给内部函数的嵌套函数,但如果可行,参数可以在函数内部进行硬编码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-06-15
        • 1970-01-01
        • 1970-01-01
        • 2014-11-05
        • 2023-01-18
        • 1970-01-01
        • 2019-08-21
        相关资源
        最近更新 更多