allennlp HotFlip无效替换索引和不同形状的错误

svgewumm  于 6个月前  发布在  其他
关注(0)|答案(1)|浏览(69)

描述错误

Hotflip 类中的第一个"bug"

def __init__(self, ...):
        ...
        self.invalid_replacement_indices: List[int] = []
        for i in self.vocab._index_to_token[self.namespace]:
            if not self.vocab._index_to_token[self.namespace][i].isalnum():
                self.invalid_replacement_indices.append(i)

isalnum() 可能不是找到 invalid_replacement_indices 的最佳方法,因为在许多情况下,tokens 包含 _ 符号(例如在 BPE 编码中)
第二个错误与使用带有 start_tokensend_tokens 的 token indexers 有关。在我的情况下,我使用以下数据集阅读器:

"dataset_reader": {
    "type": "text_classification_json",
    "token_indexers": 
      "tokens": {
        "type": "single_id",
        "start_tokens": ["<START>"],
        "end_tokens": ["<END>"],
        "token_min_padding_length": 5
     },
    "tokenizer": {
      "type": "just_spaces"
    }
}

在这种情况下,gradtext_field.tokens 将具有不同的形状,这将导致 text_field.tokens[index_of_token_to_flip] = new_tokenindex_of_token_to_flip >= len(text_field.tokens) 时失败。

def attack_from_json(self, ...):
    ...
    for instance in original_instances:
        text_field = instance[input_field_to_attack]
        ...
        grad = grads[grad_input_field][0]
        ...
        while True: 
            text_field.tokens[index_of_token_to_flip] = new_token

第三个错误与使用 token_min_padding_length > 0 参数有关。它也会导致如上所示的形状不匹配。

重现

要重现上述错误,请使用我提供的 dataset_reader 训练任何分类器,并尝试使用 HotFlip.attack_from_json() 方法。

c9qzyr3d

c9qzyr3d1#

你提出了三个问题:

  1. 对于这个问题,你是对的,当前的启发式方法并不理想。实际上,还有其他一些约束条件需要考虑得非常准确 - 例如,你不希望第一个标记是一个延续词片。如果能改进这些情况的处理方式,我们将非常欢迎。

2 和 3 都破坏了 TextFieldEmbedder API。如果你有一个添加标记的索引器,你的嵌入器应该删除它们。Hotflip API 是基于 TextField APIs 编写的,因此破坏 TextField APIs 的事情也会破坏 Hotflip API,我不确定我们能做些什么,除了建议你复制代码并根据你的特定应用进行自定义。如果你不必担心覆盖任意 TextField 输入,你可以在逻辑上更加灵活。

如果我真的想解决这个问题,我可能会在 TokenIndexer 中添加一些 API 方法来告诉哪些标记被添加。然后 Hotflip 在执行操作之前可以删除这些标记的梯度。我不认为有其他解决这个问题的方法。我也不确定是否值得添加这个 API 方法。

相关问题