由于种种原因,无法在命令行那里运行 run_classifier.py 实现文本多分类。而官方例程使用了tf-hub,由于网络限制原因这个包会报urlopen错误,所以需要本地执行模型。How?把run-classifier.py的内容拷进来,然后修改!
一、引入部分:
import pandas as pd
import tensorflow as tf
import tensorflow_hub as hub
import pickle
import bert
from bert import modeling
from bert import run_classifier
from bert import optimization
from bert import tokenization
import os
from tensorflow.python.client import device_lib
import os
optimatzation、modeling等需要 from bert一下,毕竟不是在源代码目录下执行了。
二、FLAGS的改写:
BERT_BASE_DIR = "A/chinese_L-12_H-768_A-12/"
FLAGS.task_name = "mytask"
FLAGS.do_train = True
FLAGS.do_eval = True
FLAGS.do_predict = True
FLAGS.data_dir = "A/THUC_Study/"
FLAGS.num_train_epochs = 10
FLAGS.vocab_file = BERT_BASE_DIR + "vocab.txt"
FLAGS.bert_config_file = BERT_BASE_DIR + "bert_config.json"
FLAGS.init_checkpoint = BERT_BASE_DIR + "bert_model.ckpt"
FLAGS.max_seq_length = 64
FLAGS.train_batch_size=128
FLAGS.learning_rate=5e-5
# FLAGS.num_train_epoches=10.0
FLAGS.output_dir = "./fine_tuning_out/text_classifier_64_epoch10_5e5"
由于没有命令行输入,因此需要手动定义FLAGS的值。当然,记得把原来文件里的,flags.DEFINE_string、flags.DEFINE_bool这种给删了
三、Processor的改写
参考https://blog.csdn.net/Kaiyuan_sjtu/article/details/88709580即可。
然后就可以愉快的训练了!
THUC的数据集较大,所以一开始别一股脑的全跑进去,可以先取1%的数据试验以验证流程。对此数据集我基本上没做什么处理,只进行了简单的过滤:
def remove_Punctuation(line):
line = str(line)
if line.strip()=='':
return ''
rule = re.compile(u"[^a-zA-Z\u4E00-\u9FA5]")
#baseline 中是 rule = re.compile(u"[^a-zA-Z0-9\u4E00-\u9FA5]"),这里去掉了小数
line = rule.sub('',line)
return line
处理完了是这个样子
记得完成处理后对数据集shuffle一下!!
全量数据跑了25个小时,最后结果:
准确率:
反观textCNN只有91点多的正确率,真的差了好多啊!
遗留问题:
1、虽然出了loss曲线,但感觉还是不太明白是哪里画出来的。。现在只熟悉model.fit里加tensorboard的形式。
(loss曲线是用https://www.jianshu.com/p/ba1e442fc8f6里的方法画出来的)
看起来bert是把所有的epoch都放在了一起算的step:
if FLAGS.do_train:
train_examples = processor.get_train_examples(FLAGS.data_dir)
num_train_steps = int(len(train_examples) / FLAGS.train_batch_size * FLAGS.num_train_epochs)
num_warmup_steps = int(num_train_steps * FLAGS.warmup_proportion)
tf.logging.info("***** Running training *****")
tf.logging.info(" Num examples = %d", len(train_examples))
tf.logging.info(" Batch size = %d", FLAGS.train_batch_size)
tf.logging.info(" Num steps = %d", num_train_steps)
这样就没有了像以前那种按每个epoch画train和test acc和loss的形式了