关于#BERT#的问题,如何解决?

img


比如像上图这样的数据形式,我用的是K-BERT模型,这是他命名实体识别的数据形式,我想把我有关矿井提升机的数据也处理成这个样子,那么我都应该做哪些工作?我现在有数据,并且有实体标注和关系标注,但是如果一条一条像这样敲起来肯定很慢,很耗费时间,毕竟几千条上万条我一条一条敲出来耗费的时间是无法想象的。希望能给出具体的方法来让我快速的把我的数据处理成上述图片的样子
我的数据形式:比如

img


,那么箭筒是故障位置,径向开裂是故障模式。

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/726558
  • 除此之外, 这篇博客: 那些年使用BERT模型踩的坑~~中的 三、除了直接基于预训练模型的获得词向量,如何基于微调训练获得词向量? 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 1.基于预训练模型直接获得768维的词向量
    该方法简单,但是后期任务的效果很差,至少不会好!
    直接基于肖涵博士的***bert-as-service***获得词向量。
    准备工作:
    安装bert服务端:pip install bert-serving-server
    安装bert服务客户端:pip install bert-serving-client
    在命令行输入: bert-serving-start -model_dir E:/chinese_L-12_H-768_A-12
    -num_worker=2
    (训练好的中文预模型路径,num_worker的数量表示最高处理来自2个客户端的并发请求),如果成功开启则出现以下界面。
    在这里插入图片描述

    from bert_serving.client import BertClient
    bc = BertClient()
    a=bc.encode(['浙江投融界科技有限公司#服务:计算机软硬件、网络信息技术的技术开发、技术咨询、技术服务、成果转让,第二类增值电信业务中的信息服务业务(仅限互联网信息服务),计算机系统集成,实业投资、投资管理、投资咨询(以上项目除证券、期>货,未经金融等监管部门批准,不得从事向公众融资存款、融资担保、代客理财等金融服务),企业管理咨询,市场营销策划,网页>设计,承接网络工程(涉及资质证凭证经营),会展服务,经济信息咨询、商务信息咨询(除中介),设计、制作国内广告;其他无>需报经审批的一切合法项目。(依法须经批准的项目,经相关部门批准后方可开展经营活动)'])
    print(a)
    print(len(a[0]))
    

    具体可参考:肖涵博士Github
    2.基于run_classifier.py微调模型获得768维的词向量
    只需修改run_classifier.py中的fine-tuning代码,从而输出相应的经微调训练之后的词向量。
    该方法稍微有点耗时耗资源,但是后期任务的效果较好,至少不会很差!

    def create_model(bert_config, is_training, input_ids, input_mask, segment_ids,
                     labels, num_labels, use_one_hot_embeddings):
        """Creates a classification model."""
        model = modeling.BertModel(
            config=bert_config,
            is_training=is_training,
            input_ids=input_ids,
            input_mask=input_mask,
            token_type_ids=segment_ids,
            use_one_hot_embeddings=use_one_hot_embeddings)
            
        output_layer = model.get_pooled_output()     #分类任务的768维词向量
        hidden_size = output_layer.shape[-1].value # 768
        output_weights = tf.get_variable(
            "output_weights", [num_labels, hidden_size],
            initializer=tf.truncated_normal_initializer(stddev=0.02))
        output_bias = tf.get_variable(
            "output_bias", [num_labels], initializer=tf.zeros_initializer())
        with tf.variable_scope("loss"):
            if is_training:
                output_layer = tf.nn.dropout(output_layer, keep_prob=0.9)
            logits = tf.matmul(output_layer, output_weights, transpose_b=True)
            logits = tf.nn.bias_add(logits, output_bias)
            #probabilities是由输出向量经sigmoid变换得到的
            #多分类问题,但是每个样本只属于一个类别,softmax交叉熵算出来的是一个值
            #多分类问题,且一个样本可以同时拥有多个标签,一个样本会在每个类别上有一个交叉熵,使用tf.sigmoid(与tf.nn.sigmoid相同,但最好用tf.sigmoid)
            probabilities = tf.sigmoid(logits)
            label_ids = tf.cast(labels, tf.float32)
            per_example_loss = tf.reduce_sum(
                tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=label_ids), axis=-1)  #logits和labels必须有相同的类型和大小
            loss = tf.reduce_mean(per_example_loss)
            
    #         probabilities = tf.nn.softmax(logits, axis=-1)
    #         log_probs = tf.nn.log_softmax(logits, axis=-1)
    
    #         one_hot_labels = tf.one_hot(labels, depth=num_labels, dtype=tf.float32)
    
    #         per_example_loss = -tf.reduce_sum(one_hot_labels * log_probs, axis=-1)
    #         loss = tf.reduce_mean(per_example_loss)
    
            return (loss, per_example_loss, logits, probabilities, output_layer)  #只需在return中增加output_layer即可。
    
    def model_fn_builder(bert_config, num_labels, init_checkpoint, learning_rate,
                         num_train_steps, num_warmup_steps, use_tpu,
                         use_one_hot_embeddings):
        """Returns `model_fn` closure for TPUEstimator."""
    
        def model_fn(features, labels, mode, params):  # pylint: disable=unused-argument
            """The `model_fn` for TPUEstimator."""
    
            tf.logging.info("*** Features ***")
            for name in sorted(features.keys()):
                tf.logging.info("  name = %s, shape = %s" % (name, features[name].shape))
    
            input_ids = features["input_ids"]
            input_mask = features["input_mask"]
            segment_ids = features["segment_ids"]
            label_ids = features["label_ids"]
    
            is_training = (mode == tf.estimator.ModeKeys.TRAIN)
            #此处增加一个output_layer
            (total_loss, per_example_loss, logits, probabilities, ***output_layer***) = create_model(
                bert_config, is_training, input_ids, input_mask, segment_ids, label_ids,
                num_labels, use_one_hot_embeddings)
    
            tvars = tf.trainable_variables()
    
            scaffold_fn = None
            if init_checkpoint:
                (assignment_map, initialized_variable_names
                 ) = modeling.get_assignment_map_from_checkpoint(tvars, init_checkpoint)
                if use_tpu:
    
                    def tpu_scaffold():
                        tf.train.init_from_checkpoint(init_checkpoint, assignment_map)
                        return tf.train.Scaffold()
    
                    scaffold_fn = tpu_scaffold
                else:
                    tf.train.init_from_checkpoint(init_checkpoint, assignment_map)
    
            tf.logging.info("**** Trainable Variables ****")
            for var in tvars:
                init_string = ""
                if var.name in initialized_variable_names:
                    init_string = ", *INIT_FROM_CKPT*"
                tf.logging.info("  name = %s, shape = %s%s", var.name, var.shape,
                                init_string)
    
            output_spec = None
            if mode == tf.estimator.ModeKeys.TRAIN:
    
                train_op = optimization.create_optimizer(
                    total_loss, learning_rate, num_train_steps, num_warmup_steps, use_tpu)
    
                output_spec = tf.contrib.tpu.TPUEstimatorSpec(
                    mode=mode,
                    loss=total_loss,
                    train_op=train_op,
                    scaffold_fn=scaffold_fn)
            elif mode == tf.estimator.ModeKeys.EVAL:
    
                def metric_fn(per_example_loss, label_ids, probabilities):
                    predict_ids = tf.cast(probabilities > 0.5, tf.int32)
                    label_ids = tf.cast(label_ids, tf.int32)
                    elements_equal = tf.cast(tf.equal(predict_ids, label_ids), tf.int32)   #tf.equal():逐个元素判断是否相等
                    row_predict_ids = tf.reduce_sum(elements_equal, -1)
                    row_label_ids = tf.reduce_sum(tf.ones_like(label_ids), -1)
                    accuracy = tf.metrics.accuracy(
                        labels=row_label_ids, predictions=row_predict_ids)
                    loss = tf.metrics.mean(per_example_loss)
                    
                    return {
                             "eval_accuracy": accuracy,
                             "eval_loss": loss,
                             }
    
                eval_metrics = (metric_fn, [per_example_loss, label_ids, probabilities])
                output_spec = tf.contrib.tpu.TPUEstimatorSpec(
                    mode=mode,
                    loss=total_loss,
                    eval_metrics=eval_metrics,
                    scaffold_fn=scaffold_fn)
            else:
                output_spec = tf.contrib.tpu.TPUEstimatorSpec(
                    mode=mode,
                    predictions={"probabilities": probabilities, ***"output_layer":output_layer***},
                    scaffold_fn=scaffold_fn)    #predictions增加"output_layer":output_layer
            return output_spec
    
        return model_fn
    

    OK,微调后的词向量提取成功!

import re

def convert_data(input_file, output_file):
    with open(input_file, 'r', encoding='utf-8') as file:
        lines = file.readlines()

    converted_data = []
    for line in lines:
        line = line.strip()
        if line:
            tokens = line.split()
            converted_tokens = []
            for token in tokens:
                if '-' in token:
                    label, word = token.split('-')
                    if label.startswith('B'):
                        converted_tokens.append(f'B-{label[2:]}')
                    elif label.startswith('I'):
                        converted_tokens.append(f'I-{label[2:]}')
                    else:
                        converted_tokens.append('O')
                    converted_tokens.append(word)
                else:
                    converted_tokens.append(token)
            converted_data.append(' '.join(converted_tokens))

    with open(output_file, 'w', encoding='utf-8') as file:
        file.write('\n'.join(converted_data))

# 示例调用
input_file = 'your_input_data.txt'
output_file = 'converted_data.txt'
convert_data(input_file, output_file)

关于BERT的相关问题
可以借鉴下

你已经有了数据,并且有实体标注和关系标注,想要让自己的数据处理成像第一张图片的样子的话,直接用程序帮你实现就可以了。你写个python程序,读取自己的数据,然后在按照它那个格式,写入到数据文件中就可以了啊。python中读写文件很简单的,网上找个例子就可以了。

回答部分参考、引用ChatGpt以便为您提供更准确的答案:

根据您的描述和提供的图片,您希望将您的数据处理成K-BERT模型所使用的命名实体识别的数据形式。以下是一些具体的方法可以帮助您快速处理您的数据:

  1. 数据标注:首先,您需要对您的数据进行标注。根据您的描述,箭筒是故障位置,径向开裂是故障模式。您可以使用一些标注工具或平台,如标注框架、Spacy或Brat等,来标注您的数据集。通过标注工具,您可以将箭筒和径向开裂等实体标记出来。
  2. 数据转换:一旦您完成了数据的标注,您可以将标注的数据转换成K-BERT模型所使用的数据格式。通常,这涉及将文本中的实体和关系转换为特定的标记格式,如BIO(Begin, Inside, Outside)或IOB(Inside, Outside, Begin)等。您可以编写脚本或使用相应的库来实现这种转换。
  3. 批处理和自动化:为了加快处理速度,您可以使用脚本或编程工具来自动化数据处理过程。通过批处理的方式,您可以一次处理多条数据,而不需要逐条手动敲入。这可以显著提高处理效率。您可以编写脚本或使用相关的数据处理工具来自动化标注和转换过程。
  4. 验证和修正:在完成数据的转换后,建议进行数据的验证和修正。您可以随机选择一部分数据进行人工检查,确保转换后的数据符合您的预期和要求。如果发现错误或不准确的标注,您可以进行修正并重新转换。

通过以上方法,您可以相对快速地将您的数据处理成K-BERT模型所使用的命名实体识别的数据形式。请注意,具体的实现方法可能因您的数据和需求而异,您可以根据实际情况进行调整和优化。

首先,你需要准备好一个定义实体和关系的字典,然后,你可以使用一些开源工具自动批量标注你的数据,标注出数据中的所有实体和关系后,你需要编写一个脚本,将结果按照你所需的格式组织,关键就是使用自动标注工具,人工主要做检查和修正

  1. flare - 专注关系抽取,和你项目需求匹配度高
  2. Stanford NER - 精度非常高,作为备选
  3. SpaCy - 可能训练成本大,作为最后选择