zoukankan      html  css  js  c++  java
  • 源码阅读笔记 BiLSTM+CRF做NER任务(二)

    源码地址:https://github.com/ZhixiuYe/NER-pytorch

    本篇正式进入源码的阅读,按照流程顺序,一一解剖。

    一、流程图

    二、详细步骤

    1、数据预处理

    1)将数据集从文件中加载出来,如果句子中出现了数字,会将其置零(可选),删除无用句。 

    2)转换标注模式,将iob1(数据集原有标注模式)转换为iob2,如果选用的是IOBES则将iob2转换成iobes选用的是IOB,则将iob2返回iob1iob2都是表示里面只有I、O、B,不同的是iob1中的B是为了隔断同类实体不同实体名的,而iob2中的B是为了作为实体名的开头的iobes中包含I(实体名内部)O(非实体)B(实体的开头)E(实体的结尾)S(单字实体名)

    下例将说明iob1、iob2、iobes的形式:

    3)创建word、char、tag、cap字典(根据训练集)。

    word字典:统计单词词频,筛选出词频大于3的单词,按照词频逆序、单词顺序对单词由0开始编号并加入字典中。除此,加入'<PAD>'、'<UNK>'这两个单词,分别表示pad和未知词汇,赋予最大的两个编号。

    char字典:统计字母频数,按照词频逆序、字母顺序对字母由0开始编号并加入字典中,除此,加入'<PAD>'并赋予最大的编号。

    tag字典:统计标签频数,按照标签频数逆序、标签顺序对标签由0开始编号并加入字典中,除此,加入'<START>''<STOP>'并分别赋予-1-2编号

    cap字典:无法创建字典,映射关系为全小写:0,全大写:1,首字母大写:2,其他:3

    4)根据3创建的字典和映射关系,分别对训练集、验证集、测试集的word、char、cap、tag等特征做数值化。得出的数据集中每一句由{'str_words': str_words,'words': words,'chars': chars,'caps': caps,'tags': tags,}字典组成,句中每个单词对应一个这样的字典。

    2、进入训练

    从上面的数据预处理中,假如我们得到这么一个句子数据:

    {'str_words': ['Amy','goes','to','Beijing','to','visit','Peking','University'],

    'words': [0,1,2,3,2,4,5,6], 

    'chars': [[0, 1, 2], [3, 4, 5, 6], [7, 4], [8, 5, 9, 10, 9, 11, 3], [7, 4], [12, 9, 6, 9, 7], [13, 5, 14, 9, 11, 3], [15, 11, 9, 12, 5, 16, 6, 9, 7, 2]],

    'caps': [2,0,0,2,0,0,2,2], 

    'tags': [0,1,1,2,1,1,3,3], }

    注:该示例的words、chars、tags并未按照1所说的根据词频进行的编码,只是按照出现的先后顺序进行的编码。

    1)char Embedding

    ① 对'chars'根据word长度进行排序,得到排序后的列表,与原列表对比生成索引映射关系。

    ② 对排序后的列表进行mask处理,即对word进行尾部填充0知道达到最长word长度。本例中,即是生成:[[15, 11, 9, 12, 5, 16, 6, 9, 7, 2],[8, 5, 9, 10, 9, 11, 3, 0, 0, 0],......],为8×10的矩阵。

    将生成的char新矩阵输入Embedding层,设置的size25,在本例中将得到8×10×25的矩阵,并进行转置,成为10×8×25的矩阵。

    对得到的矩阵进行pack操作(去除pad),成为39×25PackedSequencebatchsize(10,7,6,5,4,3,2,2)。

    ⑤ 将PackedSequence输入到双向LSTM中,然后把输出的output的pack操作还原回去,再进行转置操作。

    ⑥ 提取出output中最后一个字母的out和第一个字母的out进行拼接,并且将排序的结果还原。

    注:如果在进行pack操作时,选择batch_first=True,则不用进行转置操作;进行长度排序是pack操作必经的过程;双向lstm的结果的第三维长度为2*size,拼接时选择第一个字母的后size长度(t→1)和最后一个字母的前size长度(1→t)。

    2)word Embedding

    输入embedding层

    3)cap Embedding

    输入embedding层

    4)拼接所有的Embedding并输入LSTM中

    ① 拼接char、word、cap Embedding

    ② 对最终的Embedding增加第二维(unsqueeze)

    ③ 输入到dropout层

    ④ 输入到双向LSTM层

    ⑤ 减去第二维

    ⑥ 输入到dropout层

    ⑦ 输入到一个线性层

    5)无crf的话,使用交叉熵作为loss函数。

     

     

     

     

  • 相关阅读:
    跳转练习
    从入门到自闭之Python--Redis
    从入门到自闭之Python--Django Rest_Framework
    从入门到自闭之Python--RESTful API规范与序列化
    从入门到自闭之Python--虚拟环境如何安装
    从入门到自闭之Python集合,深浅拷贝(大坑)
    从入门到自闭之Python编码
    从入门到自闭之Python字典如何使用
    从入门到自闭之Python列表,元祖及range
    从入门到自闭之Python整型,字符串以及for循环
  • 原文地址:https://www.cnblogs.com/zhuangzi101/p/12753620.html
Copyright © 2011-2022 走看看