zoukankan      html  css  js  c++  java
  • bert+seq2seq 周公解梦,看AI如何解析你的梦境?【转】

    介绍

    在参与的项目和产品中,涉及到模型和算法的需求,主要以自然语言处理(NLP)和知识图谱(KG)为主。NLP涉及面太广,而聚焦在具体场景下,想要生产落地的还需要花很多功夫。
    作为NLP的主要方向,情感分析,文本多分类,实体识别等已经在项目中得到应用。例如
    通过实体识别,抽取文本中提及到的公司、个人以及金融产品等。
    通过情感分析,判别新闻资讯,对其提到的公司和个人是否利好?
    通过文本多分类,判断资讯是否是高质量?判断资讯的行业和主题?
    具体详情再找时间分享。而文本生成、序列到序列(Sequence to Sequence)在机器翻译、问答系统、聊天机器人中有较广的应用,在参与的项目中暂无涉及,本文主要通过tensorflow+bert+seq2seq实现一个简单的问答模型,旨在对seq2seq的了解和熟悉。

    数据

    关于seq2seq的demo数据有很多,例如小黄鸡聊天语料库,影视语料库,翻译语料库等等。由于最近总是做些奇怪的梦,便想着,做一个AI解梦的应用玩玩,just for fun。
    通过采集从网上采集周公解梦数据,通过清洗,形成
    dream:梦境;
    decode:梦境解析结果。
    这样的序列对,总计33000+ 条记录。数据集下载地址:后台回复“解梦”
    {
    "dream": "梦见商人或富翁",
    "decode": "是个幸运的预兆,未来自己的事业很有机会成功,不过如果梦中的富翁是自己,则是一个凶兆。。"
    }

    模型准备

    #下载 bert
    $ git clone https://github.com/google-research/bert.git
    #下载中文预训练模型
    $ wget -c https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip
    $ unzip chinese_L-12_H-768_A-12.zip 
    

    bert 的input:

    self.input_ids = tf.placeholder(
        dtype=tf.int32,
        shape=[None, None],
        name="input_ids"
    )
    self.input_mask = tf.placeholder(
        dtype=tf.int32,
        shape=[None, None],
        name="input_mask"
    )
    self.segment_ids = tf.placeholder(
        dtype=tf.int32,
        shape=[None, None],
        name="segment_ids"
    )
    self.dropout = tf.placeholder(
        dtype=tf.float32,
        shape=None,
        name="dropout"
    )
    

    bert 的model :

    self.bert_config = modeling.BertConfig.from_json_file(bert_config)
        model = modeling.BertModel(
            config=self.bert_config,
            is_training=self.is_training,
            input_ids=self.input_ids,
            input_mask=self.input_mask,
            token_type_ids=self.segment_ids,
            use_one_hot_embeddings=False
        )
    

    seq2seq 的encoder_embedding 替换:

    # 默认seq2seq model_inputs
    # self.encoder_embedding = tf.Variable(tf.random_uniform([from_dict_size, embedded_size], -1, 1),name ="encoder_embedding")
    # self.model_inputs = tf.nn.embedding_lookup(self.encoder_embedding, self.X),
    #  替换成bert
    self.embedded = model.get_sequence_output()
    self.model_inputs = tf.nn.dropout(self.embedded, self.dropout)
    

    seq2seq 的decoder_embedding 替换:

    # 默认seq2seq decoder_embedding
    # self.decoder_embedding = tf.Variable(tf.random_uniform([to_dict_size, embedded_size], -1, 1),name="decoder_embedding")
    #  替换成bert
    self.decoder_embedding = model.get_embedding_table()
    self.decoder_input = tf.nn.embedding_lookup(self.decoder_embedding, decoder_input),
    

    数据预处理

    for i in range(len(inputs)):
        tokens = inputs[i]
        inputs_ids = model.tokenizer.convert_tokens_to_ids(inputs[i])
        segment_ids = [0] * len(inputs_ids)
        input_mask = [1] * len(inputs_ids)
        tag_ids = model.tokenizer.convert_tokens_to_ids(outputs[i])
        data.append([tokens, tag_ids, inputs_ids, segment_ids, input_mask])
        
    
    def pad_data(data):
        c_data = copy.deepcopy(data)
        max_x_length = max([len(i[0]) for i in c_data])
        max_y_length = max([len(i[1]) for i in c_data]) 
        # 这里生成的序列的tag-id 和 input-id 长度要分开
        # print("max_x_length : {} ,max_y_length : {}".format( max_x_length,max_y_length))
        padded_data = []
        for i in c_data:
            tokens, tag_ids, inputs_ids, segment_ids, input_mask = i
            tag_ids = tag_ids + (max_y_length - len(tag_ids)) * [0]
            # 注意tag-ids 的长度补充,和预测的序列长度一致。
            inputs_ids = inputs_ids + (max_x_length - len(inputs_ids)) * [0]
            segment_ids = segment_ids + (max_x_length - len(segment_ids)) * [0]
            input_mask = input_mask + (max_x_length - len(input_mask)) * [0]
            assert len(inputs_ids) == len(segment_ids) == len(input_mask)
            padded_data.append(
                [tokens, tag_ids, inputs_ids, segment_ids, input_mask]
            )
        return padded_data
    
    

    训练

    $ python3 model.py --task=train 
        --is_training=True 
        --epoch=100 
        --size_layer=256 
        --bert_config=chinese_L-12_H-768_A-12/bert_config.json 
        --vocab_file=chinese_L-12_H-768_A-12/vocab.txt 
        --num_layers=2 
        --learning_rate=0.001 
        --batch_size=16 
        --checkpoint_dir=result
    

    image

    预测

    $ python3 model.py --task=predict 
            --is_training=False 
            --epoch=100 
            --size_layer=256 
            --bert_config=chinese_L-12_H-768_A-12/bert_config.json 
            --vocab_file=chinese_L-12_H-768_A-12/vocab.txt 
            --num_layers=2 
            --learning_rate=0.001 
            --batch_size=16 
            --checkpoint_dir=result
    

    image

    Just For Fun _

    本文代码: https://github.com/saiwaiyanyu/tensorflow-bert-seq2seq-dream-decoder

    作者:saiwaiyanyu
    链接:https://juejin.im/post/5dd9e07b51882572f00c4523
    来源:掘金

    8

    本文由博客一文多发平台 OpenWrite 发布!

  • 相关阅读:
    Educational Codeforces Round 86 (Rated for Div. 2) D. Multiple Testcases
    Educational Codeforces Round 86 (Rated for Div. 2) C. Yet Another Counting Problem
    HDU
    HDU
    HDU
    HDU
    Good Bye 2019 C. Make Good (异或的使用)
    Educational Codeforces Round 78 (Rated for Div. 2) C. Berry Jam
    codeforces 909C. Python Indentation
    codeforces1054 C. Candies Distribution
  • 原文地址:https://www.cnblogs.com/jpld/p/11926248.html
Copyright © 2011-2022 走看看