关系抽取

找到一个人关系的demo
感觉人人之间的关系其实推广就是一般的实体之间的关系了?

  1. unknown 0
  2. 父母 1
  3. 夫妻 2
  4. 师生 3
  5. 兄弟姐妹 4
  6. 合作 5
  7. 情侣 6
  8. 祖孙 7
  9. 好友 8
  10. 亲戚 9
  11. 同门 10
  12. 上下级 11

使用BiLSTM+Attention模型
这个模型里和之前不同的就是他似乎把位置向量计入了模型运行
也就是不仅仅计算词向量,还有位置向量,初步看是直接拼接

  1. #coding:utf8
  2. import torch
  3. import torch.nn as nn
  4. import torch.nn.functional as F
  5. torch.manual_seed(1)
  6. class BiLSTM_ATT(nn.Module):
  7. def __init__(self,config,embedding_pre):
  8. super(BiLSTM_ATT,self).__init__()
  9. self.batch = config['BATCH']
  10. self.embedding_size = config['EMBEDDING_SIZE']
  11. self.embedding_dim = config['EMBEDDING_DIM']
  12. self.hidden_dim = config['HIDDEN_DIM']
  13. self.tag_size = config['TAG_SIZE']
  14. self.pos_size = config['POS_SIZE']
  15. self.pos_dim = config['POS_DIM']
  16. self.pretrained = config['pretrained']
  17. if self.pretrained:
  18. #self.word_embeds.weight.data.copy_(torch.from_numpy(embedding_pre))
  19. self.word_embeds = nn.Embedding.from_pretrained(torch.FloatTensor(embedding_pre),freeze=False)
  20. else:
  21. self.word_embeds = nn.Embedding(self.embedding_size,self.embedding_dim)
  22. self.pos1_embeds = nn.Embedding(self.pos_size,self.pos_dim)
  23. self.pos2_embeds = nn.Embedding(self.pos_size,self.pos_dim)
  24. self.relation_embeds = nn.Embedding(self.tag_size,self.hidden_dim)
  25. self.lstm = nn.LSTM(input_size=self.embedding_dim+self.pos_dim*2,hidden_size=self.hidden_dim//2,num_layers=1, bidirectional=True)
  26. self.hidden2tag = nn.Linear(self.hidden_dim,self.tag_size)
  27. self.dropout_emb=nn.Dropout(p=0.5)
  28. self.dropout_lstm=nn.Dropout(p=0.5)
  29. self.dropout_att=nn.Dropout(p=0.5)
  30. self.hidden = self.init_hidden()
  31. self.att_weight = nn.Parameter(torch.randn(self.batch,1,self.hidden_dim))
  32. self.relation_bias = nn.Parameter(torch.randn(self.batch,self.tag_size,1))
  33. def init_hidden(self):
  34. return torch.randn(2, self.batch, self.hidden_dim // 2)
  35. def init_hidden_lstm(self):
  36. return (torch.randn(2, self.batch, self.hidden_dim // 2).cuda(),
  37. torch.randn(2, self.batch, self.hidden_dim // 2).cuda())
  38. def attention(self,H):
  39. M = F.tanh(H)
  40. a = F.softmax(torch.bmm(self.att_weight,M),2)
  41. a = torch.transpose(a,1,2)
  42. return torch.bmm(H,a)
  43. def forward(self,sentence,pos1,pos2):
  44. self.hidden = self.init_hidden_lstm()
  45. embeds = torch.cat((self.word_embeds(sentence),self.pos1_embeds(pos1),self.pos2_embeds(pos2)),2)
  46. embeds = torch.transpose(embeds,0,1)
  47. lstm_out, self.hidden = self.lstm(embeds, self.hidden)
  48. lstm_out = torch.transpose(lstm_out,0,1)
  49. lstm_out = torch.transpose(lstm_out,1,2)
  50. lstm_out = self.dropout_lstm(lstm_out)
  51. att_out = F.tanh(self.attention(lstm_out))
  52. #att_out = self.dropout_att(att_out)
  53. relation = torch.tensor([i for i in range(self.tag_size)],dtype = torch.long).repeat(self.batch, 1).cuda()
  54. relation = self.relation_embeds(relation)
  55. res = torch.add(torch.bmm(relation,att_out),self.relation_bias)
  56. res = F.softmax(res,1)
  57. return res.view(self.batch,-1)

结果

并没有复现出原文的结果
下面的是没有使用他提供的预训练词向量
image.png
加上了预训练词向量后
image.png

踩坑

问题1

RuntimeError: DataLoader worker (pid(s) 7836, 11392) exited unexpectedly
在Window里试图使用多线程加载导致
解决办法:num_workers=2, # subprocesses for loading data
注释子进程即可# num_workers=2

问题2

codecs不可用
可能是python3里没有这个?安装不成功。
原先的是codecs.open,直接替换为open即可(参数遵循open的规则)

问题3

RuntimeError: Expected object of backend CUDA but got backend CPU for argument .。。。
这个问题是部分的数据没有完全拷贝上cuda导致的
这里一直卡住是因为有一部分的数据是在forward的时候才创建的并参与计算
我猜想model.cuda的拷贝只是把init的时候创建的数据拷贝
所以在所有能加上cuda的地方全部加上即可

问题4

AttributeError: ‘dict’ object has no attribute ‘has_key’
对于这个只要换成 word in dict即可

下一步

  1. 看看有没有更好的demo可用
  2. 重新阅读一下之前ner的框架,完全看懂怎么用bert做提取文本的特征的工作

数据

Kaggle数据
https://www.kaggle.com/freeappfans/entityrelationextraction?
image.png
image.png

模型

https://zhpmatrix.github.io/2019/06/30/neural-relation-extraction/

前面的好理解,最后一层的Sigmiod到HeadRelation并没有看懂。。。

那么,看了上述三篇文章需要预先给定entity,实际上我们更希望直接从句子中抽取关系而非预先给定entity,同时也是个人更加喜欢的一个思路。这里的一个代表是《Joint entity recognition and relation extraction as a multi-head selection problem》,看下图:

Relation Extraction - 图5