变压器库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)