变压器库pytorch模型中基于梯度的输入词显著性

变压器库pytorch模型中基于梯度的输入词显著性,pytorch,gradient,huggingface-transformers,Pytorch,Gradient,Huggingface Transformers,以下代码用于确定输入字对最可能输出单元的影响 def _register_embedding_list_hook(model, embeddings_list): def forward_hook(module, inputs, output): embeddings_list.append(output.squeeze(0).clone().cpu().detach().numpy()) embedding_layer = model.bert.embeddin

以下代码用于确定输入字对最可能输出单元的影响

def _register_embedding_list_hook(model, embeddings_list):
    def forward_hook(module, inputs, output):
        embeddings_list.append(output.squeeze(0).clone().cpu().detach().numpy())
    embedding_layer = model.bert.embeddings.word_embeddings
    handle = embedding_layer.register_forward_hook(forward_hook)
    return handle

def _register_embedding_gradient_hooks(model, embeddings_gradients):
    def hook_layers(module, grad_in, grad_out):
        embeddings_gradients.append(grad_out[0])
    embedding_layer = model.bert.embeddings.word_embeddings
    hook = embedding_layer.register_backward_hook(hook_layers)
    return hook

def saliency_map(model, input_ids, segment_ids, input_mask):
    torch.enable_grad()
    model.eval()
    embeddings_list = []
    handle = _register_embedding_list_hook(model, embeddings_list)
    embeddings_gradients = []
    hook = _register_embedding_gradient_hooks(model, embeddings_gradients)

    model.zero_grad()
    A = model(input_ids, token_type_ids=segment_ids, attention_mask=input_mask)
    pred_label_ids = np.argmax(A.logits[0].detach().numpy())
    A.logits[0][pred_label_ids].backward()
    handle.remove()
    hook.remove()

    saliency_grad = embeddings_gradients[0].detach().cpu().numpy()        
    saliency_grad = np.sum(saliency_grad[0] * embeddings_list[0], axis=1)
    norm = np.linalg.norm(saliency_grad, ord=1)
    saliency_grad = [e / norm for e in saliency_grad] 
    
    return saliency_grad
以以下方式使用(对于情绪分析模型):

但它会为无意义的标记生成以下分数,因为例如“bad”对预测的类有负面影响(负面)。这个代码怎么了

以下是更多的例子:


那么,为什么分数毫无意义?分数对我来说似乎很好,唯一的问题是你对梯度求和,然后应用L1范数,这不会改变任何东西,除非我遗漏了什么。编辑:如果我认为分数完全合理,那么两个最重要的标记的绝对值最高scores@user13392352我添加了一个更好的例子(用“好”替换“好”),那么为什么这些分数都是胡说八道呢?假设高梯度=高重要性?你有没有一篇论文是根据这篇论文写的,如果有,你能把它链接起来吗。我唯一想说的是,如果我想根据梯度来猜测一个单词的重要性,我会简单地将它取为L1范数/绝对值sum@user13392352这是一种被称为“输入x梯度”的方法,在一些论文中使用,比如你链接的那篇论文似乎只是提到了总体理论,而不是实际如何实现它。但是,如果你想要“输入x梯度”,你不应该只做
显著性梯度=[np.dot(e,e,g)代表e,e\g在zip中(嵌入列表,嵌入梯度)]
from transformers import AutoTokenizer, AutoModelForSequenceClassification
tokenizer = AutoTokenizer.from_pretrained("textattack/bert-base-uncased-imdb")
model = AutoModelForSequenceClassification.from_pretrained("textattack/bert-base-uncased-imdb")

tokens = tokenizer('A really bad movie')

input_ids = torch.tensor([tokens['input_ids']], dtype=torch.long)
token_type_ids = torch.tensor([tokens['token_type_ids']], dtype=torch.long)
attention_ids = torch.tensor([tokens['attention_mask']], dtype=torch.long)

saliency_scores = saliency_map(model, input_ids, 
                                token_type_ids, 
                                attention_ids)