当前位置:   article > 正文

Bert模型获得词向量和句子向量表示_利用bert模型提取词向量

利用bert模型提取词向量
  1. text = "After stealing money from the bank vault, the bank robber was seen fishing on the Mississippi river bank."
  2. marked_text = "[CLS] " + text + " [SEP]"
  3. tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
  4. tokenized_text = tokenizer.tokenize(marked_text)
  5. indexed_tokens = tokenizer.convert_tokens_to_ids(tokenized_text) #得到每个词在词表中的索引
  6. segments_ids = [1] * len(tokenized_text)
  7. tokens_tensor = torch.tensor([indexed_tokens]) .to(DEVICE)
  8. segments_tensors = torch.tensor([segments_ids]).to(DEVICE)
  9. model = BertModel.from_pretrained('bert-base-uncased',
  10. output_hidden_states = True)
  11. model.to(DEVICE)
  12. model.eval()
  13. with torch.no_grad():
  14. outputs = model(tokens_tensor, segments_tensors)
  15. hidden_states = outputs[2]
  16. token_embeddings = torch.stack(hidden_states, dim=0)
  17. token_embeddings.size()
  18. token_embeddings = torch.squeeze(token_embeddings, dim=1)
  19. token_embeddings.size()
  20. token_embeddings = token_embeddings.permute(1,0,2)#调换顺序
  21. token_embeddings.size()
  22. #词向量表示
  23. token_vecs_cat = [torch.cat((layer[-1], layer[-2], layer[-3], layer[-4]), 0) for layer in token_embeddings] #连接最后四层 [number_of_tokens, 3072]
  24. token_vecs_sum = [torch.sum(layer[-4:], 0) for layer in token_embeddings] #对最后四层求和 [number_of_tokens, 768]
  25. #句子向量表示
  26. token_vecs = hidden_states[-2][0]
  27. sentence_embedding = torch.mean(token_vecs, dim=0)#一个句子就是768维度

改进:处理被切分的token,处理被分割成子单词的单词嵌入,通过平均这些子单词的嵌入向量来为原始单词生成一个近似的向量:

  1. text = "After stealing money from the bank vault the bank robber was seen fishing on the Mississippi river bank"
  2. #tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
  3. tokenized_text = tokenizer.tokenize(text)
  4. len(tokenized_text)
  5. #把分开的词进行合并
  6. text_words = text.split(' ')#list,放每一个words
  7. len(text_words)
  8. ##如果是以##开头的就将词进行合并,数一下有多少个词,对应将embedding对应进行求和平均?
  9. #后续再尝试进行处理,就是可以对应获得每个词的向量表示,而不是token,根据
  10. num_emb = []
  11. m = 1
  12. for i in range(len(tokenized_text)):
  13. if '##' in tokenized_text[i]:#合并前一个词和当前词
  14. m = m+1
  15. num_emb.append(m)
  16. else:
  17. m = 1
  18. num_emb.append(m) #仅需要当前一个emb
  19. #所以再在emb合并,即对由123,12这种的合成相应的embedding,倒序合成?获得emb,倒着排列,是1即取,是3取三个,就可以得到每个词的向量表示
  20. indexed_tokens = tokenizer.convert_tokens_to_ids(tokenized_text) #得到每个词在词表中的索引
  21. segments_ids = [1] * len(tokenized_text)
  22. tokens_tensor = torch.tensor([indexed_tokens]).to(DEVICE)
  23. segments_tensors = torch.tensor([segments_ids]).to(DEVICE)
  24. #model = BertModel.from_pretrained('bert-base-uncased',output_hidden_states = True)
  25. #model.to(DEVICE)
  26. #model.eval()
  27. with torch.no_grad():#其实这里可以直接放进去很多句子的
  28. outputs = model(tokens_tensor, segments_tensors)
  29. hidden_states = outputs[2]
  30. # print(hidden_states)#13层的tuple#好像只能获得最后一层?
  31. token_embeddings = torch.stack(hidden_states, dim=0)#将每层获得向量打包
  32. token_embeddings.size()
  33. token_embeddings = torch.squeeze(token_embeddings, dim=1)
  34. token_embeddings.size()
  35. token_embeddings = token_embeddings.permute(1,0,2)#调换顺序
  36. token_embeddings.size()
  37. #词向量表示
  38. #token_vecs_cat = [torch.cat((layer[-1], layer[-2], layer[-3], layer[-4]), 0) for layer in token_embeddings] #连接最后四层 [number_of_tokens, 3072]
  39. token_vecs_sum = [torch.sum(layer[-4:], 0).cpu().detach().numpy() for layer in token_embeddings] #对最后四层求和 [number_of_tokens, 768]
  40. token_vecs_sum = token_vecs_sum[::-1]
  41. num_embr = num_emb[::-1]
  42. text_words = text_words[::-1]
  43. token_vecs_sum_words = []
  44. m = 0
  45. for i in num_embr:
  46. if i == 1:
  47. token_vecs_sum_words.append(token_vecs_sum[m])
  48. m = m+1
  49. elif i==0:
  50. m = m+1
  51. else:
  52. #合并i个emb,并相应的删除num_emb中的词
  53. token_vecs_sum_words.append(np.asarray(token_vecs_sum[m:m+i]).mean(axis=0))#torch.mean(token_vecs_sum[m:m+i], dim=0).cpu().detach().numpy()
  54. for j in range(i-1):
  55. num_embr[m+1+j]=0
  56. m = m+1
  57. #每个词的向量表示
  58. emb_dic = {}
  59. for w,emb in zip(text_words,token_vecs_sum_words):
  60. emb_dic[w] = emb
  61. #句子向量表示
  62. token_vecs = hidden_states[-2][0]#直接取倒数第二层的CLS作为句子的向量表示?
  63. sentence_embedding = torch.mean(token_vecs, dim=0)#一个句子就是768维度

 参考:1. BERT Word Embeddings Tutorial · Chris McCormick

            2. 使用pytorch获取bert词向量_海蓝时见鲸-CSDN博客_pytorch获取bert词向量

            3. BERT中的词向量指南,非常的全面,非常的干货_AI公园-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/522045
推荐阅读
相关标签
  

闽ICP备14008679号