专栏首页钛问题keras_bert文本多分类
原创

keras_bert文本多分类

#! -*- coding:utf-8 -*-

import codecs
import os

import keras
import pandas as pd
from keras.callbacks import EarlyStopping
from keras.layers import *
from keras.models import Model
from keras.optimizers import Adam
from keras_bert import load_trained_model_from_checkpoint, Tokenizer
import numpy as np

max_len = 128
config_path = r'wwm/bert_config.json'
checkpoint_path = 'wwm/bert_model.ckpt'
dict_path = 'wwm/vocab.txt'
label_id = {}
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)
train_data = pd.read_csv("train_file.csv").values.tolist()
data = []
a = 0
label_id = {}
label = 0
for data_message in train_data:
    if data_message[1] not in label_id.keys():
        label_id[data_message[1]] = label
        one_label = label
        label = label + 1
    else:
        one_label = label_id[data_message[1]]
    if isinstance(data_message[0], str):
        data.append([data_message[0], one_label])
print("label", 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 and i % 10 != 1]
valid_data = [data[j] for i, j in enumerate(random_order) if i % 10 == 0]
test_data = [data[j] for i, j in enumerate(random_order) if i % 10 == 1]


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=64):
        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] = [], [], []


bert_model = load_trained_model_from_checkpoint(config_path,
                                                checkpoint_path,
#                                                 training=True,
                                                seq_len=64)
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)
p = Dense(label+1, activation='softmax')(x)

model = Model([x1_in, x2_in], p)

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)
early_stopping = EarlyStopping(
    monitor='val_loss',
    min_delta=0,
    patience=8,
    verbose=1,
    mode='auto'
)
tb_cb = keras.callbacks.TensorBoard(log_dir="log_dir", write_images=1, histogram_freq=1)
model.fit_generator(
    train_D.__iter__(),
    steps_per_epoch=len(train_D),
    epochs=5000,
    validation_data=valid_D.__iter__(),
    validation_steps=1000,
    callbacks=[early_stopping, tb_cb]
)

model.save("bert_base_model")


def predict(model, test_data):
    """
    预测
    :param test_data:
    :return:
    """
    X1, X2, Y = [], [], []
    for s in test_data:
        x1, x2 = tokenizer.encode(first=s[0][:max_len])
        X1.append(x1)
        X2.append(x2)
        Y.append(s[1])
    X1 = seq_padding(X1)
    X2 = seq_padding(X2)
    Y = seq_padding(Y)
    model.evaluate([X1, X2], Y)


test_data = pd.read_csv(os.path.join('data/valid.data.v3'), sep='\t', encoding='utf-8')
predict_test = []
for i, j in zip(test_data['question1'], test_data['question2']):
    if i is not None and j is not None:
        predict_test.append([str(i), str(j)])
evaluate(model, predict_test)

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

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

我来说两句

0 条评论
登录 后参与评论

相关文章

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

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

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

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

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

    用户1750490
  • python人工智能:完整的图片识别(非图片验证码),以及模型的使用

    这个可以说是一个绝对的福利中的福利。一整套的AI图片识别以及模型的使用。 一直都在说人工智能,图像识别,又有几个人会呢,网上文章成山,前一段时间因工作需要,我...

    Python疯子
  • python人工智能:完整的图片识别(非图片验证码),以及模型的使用

    这个可以说是一个绝对的福利中的福利。一整套的AI图片识别以及模型的使用。 一直都在说人工智能,图像识别,又有几个人会呢,网上文章成山,前一段时间因工作需要,我一...

    Python疯子
  • Python:Python 本地模拟HTTP,post,get

    1.Python CGI响应HTTPget/post请求,test.py(Python CGI 配置请查看上篇文章)

    菜菜不吃蔡
  • UNIX网络编程卷1(第三版)套接字编程简介

      通常也被成为“网际套接字地址结构”,以sockaddr_in命名,定义在<netinet/in.h>头文件中。 

    心跳包
  • Python实现数据写入 Excel 的三种模块!

    本文说明如何使用 xlsxwriter、pandas、openpyxl 三个库来实现数据写入 Excel,写入后的格式如下图所示:

    朱小五
  • python3 tornado开发TCP服务程序,也是666

    上一次利用tornado开发了一个http API服务程序,在centos7.4 64位 2C/4G的服务器上进行了一次,很轻松的rps就到10000每秒,利用...

    企鹅号小编
  • shellcheck 帮助你写出更好的脚本

    首先,可以帮助你提前发现并修复简单的语法错误,节约时间。每次都需要运行才发现写错了一个小地方,确实非常浪费时间。 其次,可以针对你当前不够完善不够健壮的写法,...

    zqb_all

扫码关注云+社区

领取腾讯云代金券