Bert文本分类

Bert是一种更合理的语言模型,基于bert预训练模型fine-tune可以完成文本分类、问答匹配等任务。本文主要记录使用bert预训练语言模型做二分类文本分类的实验过程。

源码下载:https://github.com/google-research/bert
预训练模型版本:(1)chinese_L-12_H-768_A-12对应BERT-Base, Chinese: Chinese Simplified and Traditional, 12-layer, 768-hidden, 12-heads, 110M parameters;(2)chinese_wwm_ext_L-12_H-768_A-12对应BERT-Large, Cased (Whole Word Masking): 24-layer, 1024-hidden, 16-heads, 340M parameters。

源码主要代码文件:(1)tokenization.py分词器(2)optimization.py优化器(3)modeling.py 模型原理(4)run_classifier.py基于前3个文件训练文本分类任务(5)extract_features.py基于前3个文件抽取词向量编码

实验流程

实验数据放在文件test_data文件夹下,依次是train.tsv、dev.tsv、test.tsv,数据格式:

label \t 无需提前分词的文本

针对个人数据需要在run_classifier.py文件,加入数据解析类,并在main()函数处加入相应调用key-value对应:

class TestProcessor(DataProcessor):
  """Processor for the MRPC data set (GLUE version)."""

  def get_train_examples(self, data_dir):
    """See base class."""
    return self._create_examples(
        self._read_tsv(os.path.join(data_dir, "train.tsv")), "train")

  def get_dev_examples(self, data_dir):
    """See base class."""
    return self._create_examples(
        self._read_tsv(os.path.join(data_dir, "dev.tsv")), "dev")

  def get_test_examples(self, data_dir):
    """See base class."""
    return self._create_examples(
        self._read_tsv(os.path.join(data_dir, "test.tsv")), "test")

  def get_labels(self):
    """See base class."""
    return ["__label__neg", "__label__pos"]

  def _create_examples(self, lines, set_type):
    """Creates examples for the training and dev sets."""
    examples = []
    for (i, line) in enumerate(lines):
      guid = "%s-%s" % (set_type, i)
      text_a = tokenization.convert_to_unicode(line[1])
      if set_type == "test":
        label = "__label__common"
      else:
        label = tokenization.convert_to_unicode(line[0])
      examples.append(
          InputExample(guid=guid, text_a=text_a, text_b=None, label=label))
    return examples

def main(_):
  ...
  processors = {
      "cola": ColaProcessor,
      "mnli": MnliProcessor,
      "mrpc": MrpcProcessor,
      "xnli": XnliProcessor,
      "Test": TestProcessor,   #
  }

自己补入train.sh:

BERT_BASE_DIR=/home/yy/bert-master/chinese_wwm_ext_L-12_H-768_A-12
localdir=/home/yy/bert-master
inputdata=$localdir/test_data
echo $inputdata
outputmodel=$localdir/test_output
echo $outputmodel

python run_classifier.py \
  --task_name=Test \
  --do_train=true \
  --do_eval=true \
  --data_dir=$inputdata \
  --vocab_file=$BERT_BASE_DIR/vocab.txt \
  --bert_config_file=$BERT_BASE_DIR/bert_config.json \
  --init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt \
  --max_seq_length=40 \
  --train_batch_size=128 \
  --learning_rate=2e-5 \
  --num_train_epochs=3.0 \
  --output_dir=$outputmodel

自己补入test.sh:

BERT_BASE_DIR=/home/yy/bert-master/chinese_wwm_ext_L-12_H-768_A-12
localdir=/home/yy/bert-master
inputdata=$localdir/test_data
outputmodel=$localdir/test_output

python run_classifier.py \
  --task_name=Test \
  --do_predict=true \
  --data_dir=$inputdata \
  --vocab_file=$BERT_BASE_DIR/vocab.txt \
  --bert_config_file=$BERT_BASE_DIR/bert_config.json \
  --init_checkpoint=$outputmodel \
  --max_seq_length=15 \
  --predict_batch_size=256 \
  --output_dir=$outputmodel

Tesla K80的GPU卡,40W样本,训练接近6h,是真的慢啊~

1.bert的tokenization.py分词器,逻辑上是按切分的;
2.如果想替换成按词切分的,最好对应替换词表和预训练模型,不然效果不好。

nvidia-smi
# 设置选卡
if __name__ == "__main__":
    os.environ["CUDA_VISIBLE_DEVICES"]="1"
### 使用 BERT 进行文本分类的任务实现 为了利用 BERT 实现文本分类任务,需要遵循一系列标准流程来准备数据、加载预训练模型以及微调模型以适配特定任务。以下是具体方法: #### 数据预处理 对于文本分类任务,输入文本需转换成适合 BERT 的格式。这通常涉及分词操作并将特殊标记加入序列中,例如 `[CLS]` 和 `[SEP]`。这些标记分别代表分类任务的起始位置和句子之间的分割点[^1]。 ```python from transformers import BertTokenizer tokenizer = BertTokenizer.from_pretrained('bert-base-chinese') text = "这是一个测试样本" tokens = tokenizer.encode_plus( text, add_special_tokens=True, # 添加 [CLS], [SEP] max_length=128, padding='max_length', truncation=True, return_tensors="tf" ) print(tokens.input_ids) ``` 上述代码展示了如何通过 `BertTokenizer` 将原始文本转化为 token ID 序列,并填充至固定长度以便批量计算。 #### 加载预训练模型 在实际应用中,可以直接从 Hugging Face 提供的库加载已有的预训练模型及其权重文件。这里我们选用 TensorFlow 版本作为例子[^2]: ```python from transformers import TFBertForSequenceClassification model = TFBertForSequenceClassification.from_pretrained('bert-base-chinese', num_labels=2) ``` 此段脚本初始化了一个二元分类器实例 (`num_labels=2`) ,它基于 `bert-base-chinese` 预训练模型构建而成。 #### 微调过程中的超参数设置 当调整大小写敏感度时,可以通过命令行解析器传递选项给程序执行环境。下面的例子演示了如何定义一个布尔型标志变量 `--do_lower_case` 来控制是否将所有字母转为小写形式再送入模型前处理阶段[^4]: ```python import argparse parser = argparse.ArgumentParser() parser.add_argument("--do_lower_case", action='store_true') args = parser.parse_args() if args.do_lower_case: print("Lower case will be applied.") else: print("Original casing preserved.") ``` #### 训练与评估 最后一步就是编写完整的训练循环逻辑,在每轮迭代过程中更新网络参数直至收敛或者达到最大 epoch 数量为止。由于篇幅所限,此处仅提供框架示意而非详尽细节[^3]: ```python import tensorflow as tf optimizer = tf.keras.optimizers.Adam(learning_rate=5e-5) loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) def train_step(inputs, labels): with tf.GradientTape() as tape: outputs = model(inputs)[0] loss_value = loss_fn(labels, outputs) gradients = tape.gradient(loss_value, model.trainable_variables) optimizer.apply_gradients(zip(gradients, model.trainable_variables)) return loss_value for epoch in range(num_epochs): for batch_inputs, batch_labels in dataset: loss = train_step(batch_inputs, batch_labels) print(f'Loss at step {step}: {loss.numpy()}') ``` 以上即为使用 BERT 完成文本分类的整体思路概述及部分核心代码片段展示。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值