# nlp_project3 **Repository Path**: coracoding/nlp_project3 ## Basic Information - **Project Name**: nlp_project3 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-03-26 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # NLP作业3:自然语言通顺判定 ## 1. 问题描述与分析 ​ **自然语言通顺判定** ,即给定一个句子,要求判定所给的句子是否通顺; 除了提供的训练集之外,可以使用外部数据(如无标注的文本语料); ​ 这是一个典型的二分类问题,并且这个问题和通用语言理解评估基准(GLUE)中的语料库句子合理性(CoLA)类似,可以使用分类的方法进行判定。 ​ 实验中存在最严重的问题是数据不平衡问题,通过对标签为0的数据进行随机裁剪得到标签为1的数据,然而实验结果比较差。 ## 2. 数据描述 总共有 146950个训练数据 - raw_train.txt - 每个训练样例包含id、句子、标签三个元素,分别对应句子的id、句子内容以及句子是否通顺,用'\t'分隔 - 0-表示通顺, 1-表示不通顺 - 训练集高度不平衡:标签0的个数为135931(92.50%),标签为1的个数为11019(7.50%) - 因此分类阈值为0.925015 - test_v3.txt - 测试集,每个测试样例包含id、句子两个元素 - 总共有 19990 条测试数据 ## 3. 实验环境 - python3.6 - tensorflow-gpu==1.12.0 ## 4. 模型选择 ### 4.1使用LSTM对文本进行二分类 ![1547463250713](assets/1547463250713.png) ​ 在初始实验方案中,使用两层LSTM对文本进行分类,实验中使用的是sogou新闻的sgns.sogounews.bigram-char.bz2词向量,https://github.com/Embedding/Chinese-Word-Vectors ​ 然而最后得到的效果比较差,低于随机模型,因此最后放弃了对模型的调参和改进 ### 4.2 使用BERT预训练模型进行finetune - pre-trained model: - google BERT code:https://github.com/google-research/bert - TensorFlow code and pre-trained models for BERT ![1547787115487](assets/1547787115487.png) ![1547787232049](assets/1547787232049.png) ​ BERT 可以视为结合了 OpenAI GPT 和 ELMo 优势的新模型。其中 ELMo 使用两条独立训练的 LSTM 获取双向信息,而 OpenAI GPT 使用新型的 Transformer 和经典语言模型只能获取单向信息。BERT 的主要目标是在 OpenAI GPT 的基础上对预训练任务做一些改进,以同时利用 Transformer 深度模型与双向信息的优势,所有的网络层中都受到左右文本的共同作用,BERT 在预训练期间学习 [SEP] ,[CLS] 和句子 A / B 嵌入。同时,模型输入的embedding是3类表征的求和:word representation, positional represention, segment represention ​ 对于句子级别的分类任务,只需要处理句子内部的关系 ![1547787444166](assets/1547787444166.png) 根据自身需要**自定义**新的数据读取模块 ```python class SmoothProcessor(DataProcessor): def get_train_examples(self, data_dir): return self._create_examples( self._read_tsv(os.path.join(data_dir, "train.tsv")), "train") def get_dev_examples(self, data_dir): return self._create_examples( self._read_tsv(os.path.join(data_dir, "dev.tsv")), "dev") def get_test_examples(self, data_dir): return self._create_examples( self._read_tsv(os.path.join(data_dir, "test.tsv")), "test") def get_labels(self): return ["0", "1"] def _create_examples(self, lines, set_type): """Creates examples for the training and dev sets.""" examples = [] labels = [] labels_test = [] for (i, line) in enumerate(lines): guid = "%s-%s" % (set_type, i) if set_type == "test": text_a = tokenization.convert_to_unicode(line[1]) label = "1" else: text_a = tokenization.convert_to_unicode(line[1]) label = tokenization.convert_to_unicode(line[2]) labels.append(label) examples.append( InputExample(guid=guid, text_a=text_a, text_b=None, label=label)) return examples ``` - data_dir目录下应包含名为train、val、test的三个文件,根据文件格式不同需要对读取方式进行修改 - get_labels()返回的是所有可能的类别label_list,["0", "1"] - 模块最终返回一个名为examples的列表,每个列表元素中包含序号、中文文本、类别三个元素 - 在中文BERT模型中,中文分词是基于字而非词的分词** 参数配置说明 ``` data_dir:存放数据集的文件夹 bert_config_file:bert中文模型中的bert_config.json文件 task_name:processors中添加的任务名“smooth” vocab_file:bert中文模型中的vocab.txt文件 output_dir:训练好的分类器模型的存放文件夹 init_checkpoint:bert中文模型中的bert_model.ckpt.index文件 do_train:是否训练,设置为“True” do_eval:是否验证,设置为“True” do_predict:是否测试,设置为“False” max_seq_length: 输入文本序列的最大长度,多余会去掉,不够会补齐,最大值512 train_batch_size: 训练模型求梯度时,批量处理数据集的大小 eval_batch_size: 验证时,批量处理数据集的大小 predict_batch_size: 测试时,批量处理数据集的大小 num_train_epochs: 所有样本完全训练一遍的次数 ``` ## 5. 提交结果 以下结果都是在最新的数据集 **test_v3.txt** 测试的结果,都是提交到了 **Leaderboard B** 上测评 ### 提交 1 使用 两层 LSTM进行文本分类 词向量使用搜狗新闻的词向量 sgns.sogounews.bigram-char.bz2 效果较差,F1-score结果低于随机模型 ### 提交2(全部数据train.txt 训练 1epoch) ```sh # finetune train python run_classifier.py \ --do_train=True \ --do_eval=True \ --train_batch_size=32 \ --num_train_epochs=1.0 \ --init_checkpoint=chinese_L-12_H-768_A-12/bert_model.ckpt # 总的训练轮数 global_step = 146950/32 = 4592 # predict python run_classifier.py \ --do_predict=True \ --predict_batch_size=32 \ --init_checkpoint=output/model.ckpt-4592 # threshold 0.925 0.70167 # threshold 0.980 0.794464 ``` ### 提交3 进行数据平衡性修改 对 **raw_train.txt** 中标签为0的进行过滤和随机裁剪生成标注为1的语料库 得到新的文本数据集 **new_train.txt** , 总共 146950 个文本数据 - 标签为 0:71908 / 146950(48.934%) - 标签为 1:75042 / 146950(51.066%) 将argument_data.txt和raw_train.txt合并成new_train.txt并且进行shuffle将0,1标签均匀分布 ```sh # finetune train python run_classifier.py \ --do_train=True \ --do_eval=True \ --train_batch_size=62 \ --num_train_epochs=1.0 \ --init_checkpoint=chinese_L-12_H-768_A-12/bert_model.ckpt # 总的训练轮数 global_step = 146950/32 = 4592 # predict python run_classifier.py \ --do_predict=True \ --predict_batch_size=32 \ --init_checkpoint=output/model.ckpt-4592 # threshold 0.5 0.73208 ``` Leaderboard 最终结果(2019-01-18 20:00:07截图) ![1547813047530](assets/1547813047530.png) ## 6. 未来改进 - 使用无标注的公开文本语料扩充数据集 - 需要做好数据集平衡问题 - 做好模型融合,提升效果