如何使用预训练的BERT模型进行下一句标注?

我对AI和NLP是新手。我想了解BERT是如何工作的。我使用了BERT预训练模型:https://github.com/google-research/bert

我运行了extract_features.py示例,如readme.md中提到的提取特征段落所述。我得到了向量作为输出。

大家,如何将我在extract_features.py中得到的结果转换为下一句/非下一句标签呢?

我想运行BERT来检查两个句子是否相关,并查看结果。

谢谢!


回答:

答案是使用用于下一句训练的权重,以及从中得到的logits。因此,要使用BERT进行下一句预测,请以训练时使用的格式输入两个句子:

def convert_single_example(ex_index, example, label_list, max_seq_length,                           tokenizer):    """将单个`InputExample`转换为单个`InputFeatures`。"""    label_map = {}    for (i, label) in enumerate(label_list):        label_map[label] = i    tokens_a = tokenizer.tokenize(example.text_a)    tokens_b = None    if example.text_b:        tokens_b = tokenizer.tokenize(example.text_b)    if tokens_b:        # 修改`tokens_a`和`tokens_b`,使总长度小于指定长度。        # 考虑到[CLS], [SEP], [SEP],使用"- 3"        _truncate_seq_pair(tokens_a, tokens_b, max_seq_length - 3)    else:        # 考虑到[CLS]和[SEP],使用"- 2"        if len(tokens_a) > max_seq_length - 2:            tokens_a = tokens_a[0:(max_seq_length - 2)]    # BERT的惯例是:    # (a) 对于序列对:    #  tokens:   [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP]    #  type_ids: 0     0  0    0    0     0       0 0     1  1  1  1   1 1    # (b) 对于单个序列:    #  tokens:   [CLS] the dog is hairy . [SEP]    #  type_ids: 0     0   0   0  0     0 0    #    # 其中"type_ids"用于指示这是第一个序列还是第二个序列。`type=0`和`type=1`的嵌入向量在预训练期间学习,并添加到词片嵌入向量(和位置向量)中。这不是*严格*必要的,因为[SEP]标记明确分隔序列,但它使模型更容易学习序列的概念。    #    # 对于分类任务,第一个向量(对应于[CLS])被用作“句子向量”。请注意,这只有在整个模型进行微调时才有意义。    tokens = []    segment_ids = []    tokens.append("[CLS]")    segment_ids.append(0)    for token in tokens_a:        tokens.append(token)        segment_ids.append(0)    tokens.append("[SEP]")    segment_ids.append(0)    if tokens_b:        for token in tokens_b:            tokens.append(token)            segment_ids.append(1)        tokens.append("[SEP]")        segment_ids.append(1)    input_ids = tokenizer.convert_tokens_to_ids(tokens)    # 掩码对于真实标记为1,对于填充标记为0。只有真实标记会被关注。    input_mask = [1] * len(input_ids)    # 零填充至序列长度。    while len(input_ids) < max_seq_length:        input_ids.append(0)        input_mask.append(0)        segment_ids.append(0)    assert len(input_ids) == max_seq_length    assert len(input_mask) == max_seq_length    assert len(segment_ids) == max_seq_length    label_id = label_map[example.label]    if ex_index < 5:        tf.logging.info("*** Example ***")        tf.logging.info("guid: %s" % (example.guid))        tf.logging.info("tokens: %s" % " ".join(            [tokenization.printable_text(x) for x in tokens]))        tf.logging.info("input_ids: %s" % " ".join([str(x) for x in input_ids]))        tf.logging.info("input_mask: %s" % " ".join([str(x) for x in input_mask]))        tf.logging.info("segment_ids: %s" % " ".join([str(x) for x in segment_ids]))        tf.logging.info("label: %s (id = %d)" % (example.label, label_id))    feature = InputFeatures(        input_ids=input_ids,        input_mask=input_mask,        segment_ids=segment_ids,        label_id=label_id)    return feature

然后使用以下代码扩展BERT模型

def create_model(bert_config, is_training, input_ids, input_mask, segment_ids,                 labels, num_labels, use_one_hot_embeddings):    """创建一个分类模型。"""    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)    # 在演示中,我们在整个段落上进行简单的分类任务。    #    # 如果你想使用标记级别的输出,请使用model.get_sequence_output()    # 代替。    output_layer = model.get_pooled_output()    hidden_size = output_layer.shape[-1].value    with tf.variable_scope("cls/seq_relationship"):        output_weights = tf.get_variable(            "output_weights", [num_labels, hidden_size])        output_bias = tf.get_variable(            "output_bias", [num_labels])    with tf.variable_scope("loss"):        if is_training:            # 即,0.1的dropout            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 = 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)

probabilities – 这就是你需要的,它是下一句的预测结果

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注