描述错误
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_tokens
和 end_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"
}
}
在这种情况下,grad
和 text_field.tokens
将具有不同的形状,这将导致 text_field.tokens[index_of_token_to_flip] = new_token
在 index_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()
方法。
1条答案
按热度按时间c9qzyr3d1#
你提出了三个问题:
2 和 3 都破坏了 TextFieldEmbedder API。如果你有一个添加标记的索引器,你的嵌入器应该删除它们。Hotflip API 是基于 TextField APIs 编写的,因此破坏 TextField APIs 的事情也会破坏 Hotflip API,我不确定我们能做些什么,除了建议你复制代码并根据你的特定应用进行自定义。如果你不必担心覆盖任意 TextField 输入,你可以在逻辑上更加灵活。
如果我真的想解决这个问题,我可能会在
TokenIndexer
中添加一些 API 方法来告诉哪些标记被添加。然后 Hotflip 在执行操作之前可以删除这些标记的梯度。我不认为有其他解决这个问题的方法。我也不确定是否值得添加这个 API 方法。