美文网首页
通过改造BERT实现ERNIE并比较两者差异

通过改造BERT实现ERNIE并比较两者差异

作者: wipen | 来源:发表于2019-03-19 17:13 被阅读0次

    作者:WipenHan

    由于BERT与ERNIE的预训练数据存在非常大的差异,因而无法知晓ERNIE在5个NLP任务上得到的提升是源于数据还是模型。

    引用ERNIE的github主页关于预训练数据的介绍

    训练数据方面,除百科类、资讯类中文语料外,ERNIE 还引入了论坛对话类数据,利用 DLM(Dialogue Language Model)建模 Query-Response 对话结构,将对话 Pair 对作为输入,引入 Dialogue Embedding 标识对话的角色,利用 Dialogue Response Loss 学习对话的隐式关系,进一步提升模型的语义表示能力。

    引用BERT项目Issues中关于中文预训练数据的讨论

    htw2012 commented on 21 Nov 2018 •
    Is the model trained base on entire Chinese wikipedia raw text ?
    jacobdevlin-google commented on 25 Nov 2018
    Yes, a processed version of that which only keeps the text portions without formatting. In both traditional and simplified.

    其实我们可以看出ERNIE与BERT非常相似,区别主要是在pretrain中选择[MASK]字符的逻辑。那么我们就可以通过改造BERT的 create_pretraining_data.py 实现ERNIE的逻辑。再使用同样的预训练数据进行实验,便可了解连续字符MASK(ERNIE)随机字符MASK(BERT)的差异。

    clone代码:wipen/bert

    使用create_ernie_pretraining_data.py 处理预训练数据,数据样例:

    INFO:tensorflow:*** Example ***
    INFO:tensorflow:tokens: [CLS] [MASK] [MASK] , 具 有 可 鉴 别 症 状 者 却 很 少 , 60 ~ 70 岁 的 男 子 具 有 明 显 前 列 腺 戈 ##窗 者 , 也 ##荷 吵 [MASK] [MASK] 而 已 。 [SEP] 时 [MASK] [MASK] [MASK] [MASK] [MASK] [MASK] 肿 瘤 [MASK] [MASK] ce ##a ( 癌 胚 抗 原 ) 轻 度 增 高 , 按 照 常 理 , [MASK] [MASK] 检 查 指 标 异 常 是 和 消 化 系 统 肿 瘤 有 关 。 此 后 , 在 一 年 半 的 随 访 [MASK] [MASK] 里 , 张 先 生 主 动 配 合 检 查 , 他 坚 持 着 做 了 3 次 [MASK] [MASK] ct 检 [SEP]
    INFO:tensorflow:input_ids: 101 103 103 8024 1072 3300 1377 7063 1166 4568 4307 5442 1316 2523 2208 8024 8183 172 8203 2259 4638 4511 2094 1072 3300 3209 3227 1184 1154 5593 2762 18027 5442 8024 738 18849 1427 103 103 5445 2347 511 102 3198 103 103 103 103 103 103 5514 4606 103 103 10399 8139 8020 4617 5524 2834 1333 8021 6768 2428 1872 7770 117 2902 4212 2382 4415 8024 103 103 3466 3389 2900 3403 2460 2382 3221 1469 3867 1265 5143 5320 5514 4606 3300 1068 511 3634 1400 8024 1762 671 2399 1288 4638 7390 6393 103 103 7027 8024 2476 1044 4495 712 1220 6981 1394 3466 3389 8024 800 1780 2898 4708 976 749 124 3613 103 103 9162 3466 102
    INFO:tensorflow:input_mask: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    INFO:tensorflow:segment_ids: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    INFO:tensorflow:masked_lm_positions: 2 31 36 38 45 47 49 53 70 73 102 124 0 0 0 0 0 0 0 0
    INFO:tensorflow:masked_lm_ids: 5445 4606 3300 110 3890 7741 4385 3403 4415 7555 7313 6956 0 0 0 0 0 0 0 0
    INFO:tensorflow:masked_lm_weights: 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    INFO:tensorflow:next_sentence_labels: 1
    INFO:tensorflow:*** Example ***
    INFO:tensorflow:tokens: [CLS] 区 ! [SEP] 过 [MASK] [MASK] 患 者 , 被 查 出 胸 部 有 肿 块 之 后 , 第 一 反 应 是 去 美 容 店 通 过 [MASK] [MASK] 的 方 式 疏 解 胸 部 肿 块 , 在 手 法 按 摩 、 [UNK] 刮 痧 板 [UNK] 等 各 种 手 法 的 [MASK] [MASK] [MASK] [MASK] 下 , 造 成 了 癌 细 胞 扩 散 。 [MASK] [MASK] 乳 腺 癌 从 二 期 到 了 [MASK] [MASK] 。 此 外 , 李 大 夫 还 见 [MASK] [MASK] 嚐 ##刺 、 芦 荟 、 [MASK] [MASK] 、 頭 ##手 、 擀 面 杖 、 土 豆 片 等 各 种 [MASK] [MASK] 治 疗 乳 房 [SEP]
    INFO:tensorflow:input_ids: 101 1277 8013 102 6814 103 103 2642 5442 8024 6158 3389 1139 5541 6956 3300 5514 1779 722 1400 8024 5018 671 1353 2418 3221 1343 5401 2159 2421 6858 6814 103 103 4638 3175 2466 4541 6237 5541 6956 5514 1779 8024 1762 2797 3791 2902 3040 510 100 1167 4584 3352 100 5023 1392 4905 2797 3791 4638 103 103 103 103 678 8024 6863 2768 749 4617 5301 5528 2810 3141 511 103 103 745 5593 4617 794 753 3309 1168 749 103 103 511 3634 1912 8024 3330 1920 1923 6820 6224 103 103 1705 14230 510 5701 5780 510 103 103 510 7531 15854 510 3074 7481 3335 510 1759 6486 4275 5023 1392 4905 103 103 3780 4545 745 2791 102
    INFO:tensorflow:input_mask: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    INFO:tensorflow:segment_ids: 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    INFO:tensorflow:masked_lm_positions: 6 33 64 77 87 98 100 106 109 122 124 0 0 0 0 0 0 0 0 0
    INFO:tensorflow:masked_lm_ids: 855 3040 4073 5442 3309 4500 5790 2094 4132 3175 4545 0 0 0 0 0 0 0 0 0
    INFO:tensorflow:masked_lm_weights: 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    INFO:tensorflow:next_sentence_labels: 0
    

    根据BERT github上的介绍,预训练数据来源是wiki开放数据源的中文内容:https://dumps.wikimedia.org/

    处理方法参见:http://www.cnblogs.com/chenbjin/p/5635853.html

    本文使用的数据是:https://dumps.wikimedia.org/zhwiki/latest/zhwiki-latest-pages-articles.xml.bz2

    接下来使用run_pretraining.py进行预训练。

    同一数据源分别以BERT原生的预处理方式和ERNIE提出的预处理方式处理后进行pretrain,pretrain的超参数配置见下方, 文本数据量约1300w行。

    {
      "attention_probs_dropout_prob": 0.1,
      "directionality": "bidi",
      "hidden_act": "gelu",
      "hidden_dropout_prob": 0.1,
      "hidden_size": 768,
      "initializer_range": 0.02,
      "intermediate_size": 3072,
      "max_position_embeddings": 512,
      "num_attention_heads": 12,
      "num_hidden_layers": 12,
      "pooler_fc_size": 768,
      "pooler_num_attention_heads": 12,
      "pooler_num_fc_layers": 3,
      "pooler_size_per_head": 128,
      "pooler_type": "first_token_transform",
      "type_vocab_size": 2,
      "vocab_size": 21128
    }
    
    

    BERT原生pretrain eval结果:

    global_step = 500000
    loss = 1.624029
    masked_lm_accuracy = 0.6669912
    masked_lm_loss = 1.5633817
    next_sentence_accuracy = 0.975
    next_sentence_loss = 0.06493104
    

    ERNIE预处理pretrain eval结果:

    global_step = 500000
    loss = 3.0637412
    masked_lm_accuracy = 0.44055784
    masked_lm_loss = 2.973307
    next_sentence_accuracy = 0.965
    next_sentence_loss = 0.09641378
    

    可以发现采用ERNIE的预处理方式进行pretrain后,MASK任务的训练效果并不好,acc仅能达到0.44的水平,并且loss很高。推测造成MASK任务存在差距可能的原因主要是:通过上下文预测一个完整词的难度显然高于预测单个字符。next sentence任务水平差不多,不过这个任务比较简单,并且对多数具体的NLP任务来说没有意义。

    接下来在具体NLP任务上实验,采用ERNIE使用的任务数据。为方便起见,下文直接用ERNIE指代本文中经过连续字符MASK改造后pretrain的BERT模型。

    首先是自然语言推断任务 XNLI:

    XNLI 由 Facebook 和纽约大学的研究者联合构建,旨在评测模型多语言的句子理解能力。目标是判断两个句子的关系(矛盾、中立、蕴含)。[链接: https://github.com/facebookresearch/XNLI]
    

    BERT结果(dev set):

    eval_accuracy = 0.71686745
    eval_loss = 0.7184297
    global_step = 21001
    loss = 0.7185437
    

    ERNIE结果(dev set):

    eval_accuracy = 0.72208834
    eval_loss = 0.7035865
    global_step = 21001
    loss = 0.7030562
    

    惊喜的发现,虽然ERNIE在pretrain中的masked_lm_accuracy比较低,但在XNLI任务中eval_accuracy 提高了0.5% 虽然提升不大,但是至少证明了这个工作的确可能带来一些改进。为了更加严谨,后续还会在同一任务上使用不同的random seed进行多次实验验证结果。并继续再更多NLP任务上进行实验。

    相关文章

      网友评论

          本文标题:通过改造BERT实现ERNIE并比较两者差异

          本文链接:https://www.haomeiwen.com/subject/clhnmqtx.html