CCF-BDCI互联网新闻情感分析(bert-base,线上0.79)

今天来讲一讲怎么用bert做文本分类,比赛是今年的CCF-BDCI
https://www.datafountain.cn/competitions/350
第一次接触bert,比较菜,线上macro_f1得分0.79:
CCF-BDCI互联网新闻情感分析(bert-base,线上0.79)_第1张图片
附上代码和数据集,数据集是tsv格式,我做了一些预处理,保存在data文件夹下面,验证集是从原训练集中按0.1的比例划分出来的。测试集test是没有标签的,想跑线下可以用train_test_split自己划分测试集:
链接:https://pan.baidu.com/s/1o44-3cAPcSXS8k4zA5A0pw
提取码:kvkl

配置要求

很多人使用bert的时候都会担心配置要求,其实正常的内存和cpu就是可以跑的,数据集精简一下也不会太慢,我8G内存I7,跑batch_size=1,max_seq_length=32的1/10数据集20分钟就跑完了。

怎么用bert

其实bert的使用非常简单,首先下载一下中文bert的模型:
https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip
如果你做的不是中文的或者想跑bert-large,这篇博文有下载地址:
https://blog.csdn.net/foxcow2012/article/details/87856557

然后去下载一下google的开源代码:
https://github.com/google-research/bert

文件结构

先来看看bert模型本身的文件结构(chinese_L-12_H-768_A-12文件夹),不妨称之为模型文件夹。CCF-BDCI互联网新闻情感分析(bert-base,线上0.79)_第2张图片
1.bert_config是bert的配置文件,这个不用改,后面运行的时候可以通过参数调整。
2.ckpt文件就是bert的模型
3.vocab.txt是bert的词汇表。打开会发现中文bert的词汇表都是单字的,这当然不如用词汇效果好。据说哈工大发布过一版词汇的,我没用过,可以去搜搜看。

把这个文件夹(chinese_L-12_H-768_A-12)放到刚刚的另一个文件夹(很多文件那个)里面,我们会通过那个文件夹的代码调用chinese_L-12_H-768_A-12里的模型和文件。不妨称之为接口文件夹。

因为我们做的是分类任务,接口文件夹里比较重要的是这个:
在这里插入图片描述
所以我们也需要修改的也只有这个文件夹。

修改代码

参考的这篇博文:
https://blog.csdn.net/clnjust/article/details/100514231
1.再run_classifier.py中添加一个类,这个类就用来执行我们自定义的分类任务:

class MyTaskProcessor(DataProcessor):
  """Processor for my task-news classification """
  def __init__(self):
    self.labels = ['0.0', '1.0', '2.0']
  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, 'val.tsv')), 'val')

  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 self.labels

  def _create_examples(self, lines, set_type):
    """create examples for the training and val sets"""
    examples = []
    for (i, line) in enumerate(lines):
      guid = '%s-%s' %(set_type, i)
      text_a = tokenization.convert_to_unicode(line[1])
      label = tokenization.convert_to_unicode(line[0])
      examples.append(InputExample(guid=guid, text_a=text_a, label=label))
    return examples

注意代码第4行是写任务的标签,是以字符串的形式读取的,我的数据文件里标签是0.0,1.0,2.0,你的是0,1,2就改成self.labels = [‘0’, ‘1’, ‘2’],因为是字符串类型读取,0.0≠0!

这个文件里会有一些配置变量,比如这段代码中的data_dir,会在运行时通过参数传入值。

2.然后在程序入口main里做一下修改,把我们的任务加进去:

def main(_):
  tf.logging.set_verbosity(tf.logging.INFO)

  processors = {
      "cola": ColaProcessor,
      "mnli": MnliProcessor,
      "mrpc": MrpcProcessor,
      "xnli": XnliProcessor,
      "mytask": MyTaskProcessor,
  }

数据集文件

我是在根目录(接口文件夹)下面新建了一个data文件夹来保存,这样待会儿写参数的时候比较好写:
CCF-BDCI互联网新闻情感分析(bert-base,线上0.79)_第3张图片

运行

直接在cmd里用命令行运行,cd进根目录,我这个就是E:\python\bert\bert-masterContent,
1.训练命令:
python run_classifier.py --task_name=mytask --do_train=true --do_eval=true --data_dir=data --vocab_file=chinese_L-12_H-768_A-12\vocab.txt --bert_config_file=chinese_L-12_H-768_A-12\bert_config.json --init_checkpoint=chinese_L-12_H-768_A-12\bert_model.ckpt --max_seq_length=128 --train_batch_size=32 --learning_rate=1e-5 --num_train_epochs=3.0 --output_dir=output

task_name是main函数里的任务名(是前面的key);do_train就是是否做训练;do_eval是是否做验证,要求有验证集,做的话训练结束之后会在output目录下生成一个预测文件(eval_results.txt),长这样:
在这里插入图片描述
data_dir就是你存放数据集文件的文件夹;vocab_file、bert_config_file、init_checkpoint就都是之前说的对bert模型的几个文件的调用路径;max_seq_length是最大句长,就是一句话最多多少个字,batch_size就是一批几条文本;learning_rate是学习率,我在上一篇博文中详细说过;num_train_epochs就是迭代次数;output_dir即输出到哪个文件夹下面,我是输出到output文件夹下面。

2.测试命令:
python run_classifier.py --task_name=mytask --do_predict=true --data_dir=data --vocab_file=chinese_L-12_H-768_A-12\vocab.txt --bert_config_file=chinese_L-12_H-768_A-12\bert_config.json --init_checkpoint=output --max_seq_length=128 --output_dir=output
参数和上面差不多,我就不详细讲解了。生成的输出文件会是m*n的浮点数组,m是测试集文本数,n是分类的类数。第i行第j列的数据表示第i条文本属于第j类的概率。
输出文件叫test_results.tsv,长这样:
CCF-BDCI互联网新闻情感分析(bert-base,线上0.79)_第4张图片

没错,其实就是带参数的运行一下run_classifier.py。这里值得注意的是linux环境目录间的分隔符是/,而windows环境是\。

训练的时候控制台是这样的:
CCF-BDCI互联网新闻情感分析(bert-base,线上0.79)_第5张图片
如果你想一次执行掉训练和预测可以写批处理文件,windows是.bat,linux是.sh。
内存不够就把max_seq_length和batch_size调小。

你可能感兴趣的:(NLP,深度学习,大数据)