专栏首页钛问题如何在腾讯钛中训练基于bert预训练语言模型的文本分类模型
原创

如何在腾讯钛中训练基于bert预训练语言模型的文本分类模型

import codecs
import os

import keras
import numpy as np
import pandas as pd
from keras.callbacks import ModelCheckpoint, EarlyStopping
from keras.optimizers import Adam
from keras_bert import load_trained_model_from_checkpoint, Tokenizer
from keras_radam import RAdam
max_len = 96
config_path = 'roberta/bert_config_large.json'
checkpoint_path = 'roberta/roberta_zh_large_model.ckpt'
dict_path = 'roberta/vocab.txt'

token_dict = {}

with codecs.open(dict_path, 'r', 'utf8') as reader:
    for line in reader:
        token = line.strip()
        token_dict[token] = len(token_dict)


class OurTokenizer(Tokenizer):
    def _tokenize(self, text):
        R = []
        for c in text:
            if c in self._token_dict:
                R.append(c)
            elif self._is_space(c):
                R.append('[unused1]')  # space类用未经训练的[unused1]表示
            else:
                R.append('[UNK]')  # 剩余的字符是[UNK]
        return R


tokenizer = OurTokenizer(token_dict)

neg = pd.read_csv('data/enhance_data_result.csv', header=None)

data = []

for d, label in zip(neg[1], neg[2]):
    if label in [2, 0, 1]:
        if isinstance(d, str):
            data.append((d, label))

# 按照9:1的比例划分训练集和验证集
random_order = list(range(len(data)))
np.random.shuffle(random_order)
train_data = [data[j] for i, j in enumerate(random_order) if i % 10 != 0]
valid_data = [data[j] for i, j in enumerate(random_order) if i % 10 == 0]


def seq_padding(X, padding=0):
    L = [len(x) for x in X]
    ML = max(L)
    return np.array([
        np.concatenate([x, [padding] * (ML - len(x))]) if len(x) < ML else x for x in X
    ])


class data_generator:
    def __init__(self, data, batch_size=2):
        self.data = data
        self.batch_size = batch_size
        self.steps = len(self.data) // self.batch_size
        if len(self.data) % self.batch_size != 0:
            self.steps += 1

    def __len__(self):
        return self.steps

    def __iter__(self):
        while True:
            idxs = list(range(len(self.data)))
            np.random.shuffle(idxs)
            X1, X2, Y = [], [], []
            for i in idxs:
                d = self.data[i]
                text = d[0][:max_len]
                x1, x2 = tokenizer.encode(first=text)
                y = d[1]
                X1.append(x1)
                X2.append(x2)
                Y.append([y])
                if len(X1) == self.batch_size or i == idxs[-1]:
                    X1 = seq_padding(X1)
                    X2 = seq_padding(X2)
                    Y = seq_padding(Y)
                    yield [X1, X2], Y
                    [X1, X2, Y] = [], [], []


from keras.layers import *
from keras.models import Model

bert_model = load_trained_model_from_checkpoint(config_path, checkpoint_path, seq_len=None)

for l in bert_model.layers:
    l.trainable = True

x1_in = Input(shape=(None,))
x2_in = Input(shape=(None,))

x = bert_model([x1_in, x2_in])
x = Lambda(lambda x: x[:, 0])(x)
x = Dropout(0.8)(x)
p = Dense(3, activation='softmax')(x)

model = Model([x1_in, x2_in], p)
save = ModelCheckpoint(
    os.path.join('bert.h5'),
    monitor='val_acc',
    verbose=1,
    save_best_only=True,
    mode='auto'
)
early_stopping = EarlyStopping(
    monitor='val_acc',
    min_delta=0,
    patience=8,
    verbose=1,
    mode='auto'
)
callbacks = [save, early_stopping]
model.compile(
    loss='sparse_categorical_crossentropy',
    optimizer=Adam(1e-5),  # 用足够小的学习率
    metrics=['accuracy']
)
model.summary()

train_D = data_generator(train_data)
valid_D = data_generator(valid_data)

model.fit_generator(
    train_D.__iter__(),
    steps_per_epoch=1000,
    epochs=5000,
    validation_data=valid_D.__iter__(),
    validation_steps=1000,
    callbacks=callbacks,

)

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • keras_bert文本多分类

    用户1750490
  • 金融领域的统计学方法应用

    上升一个等级就是 第一产业 制造业 第二产业 以及第三产业服务产业的动态问题。再到中央银行对整个产业的现金流限制。

    用户1750490
  • 利用bert系列预训练模型在非结构化数据抽取数据

    https://ai.baidu.com/broad/download?dataset=sked

    用户1750490
  • CIFAR10数据集实战-ResNet网络构建(上)

    之前讲到过,ResNet包含了短接模块(short cut)。本节主要介绍如何实现这个模块。

    用户6719124
  • [pytorch] 图像识别之mixup/cutout/Margin loss....简单实现

    本人kaggle分享链接:https://www.kaggle.com/c/bengaliai-cv19/discussion/128592

    MachineLP
  • 画解算法:198. 打家劫舍

    https://leetcode-cn.com/problems/house-robber/

    灵魂画师牧码
  • 算法训练 最大的算式

    问题描述   题目很简单,给出N个数字,不改变它们的相对位置,在中间加入K个乘号和N-K-1个加号,(括号随便加)使最终结果尽量大。因为乘号和加号一共就是N...

    AI那点小事
  • java版银联8583协议解析,超简单超直观的实现及示例(全互联网最简单)

    最近有需要把8383协议的解析用到android上,但是搜遍了整个互联网,没发现有哪个简单好用点的java版8583解析库。就自己动手自己做一个吧,让其尽可能的...

    特立独行的猫a
  • 招聘信息太多,哪家职位才是适合你的?Python采集招聘信息

    在招聘信息上,会提及工作的职位,不过大多描述是笼统的,还需要我们去了解工作的具体内容和性质。要知道,在不同的公司,同样的职位做的事情也是不一样的,工作方法更是大...

    松鼠爱吃饼干
  • 三年0故障是如何做到的?

    近段时间我的团队,其他团队一直在强调代码质量,减少故障。入职快三年半了,距离我上次故障也快三年半了,所以在这方面有些感触和大家分享一下,我从 个人经历 , 代码...

    IT大咖说

扫码关注云+社区

领取腾讯云代金券