bert模型取出的向量并不适合余弦相似度的计算方式,是因为没有训练?还是本身就不适合呢?有没有可以计算的算法呢?
不知道你这个问题是否已经解决, 如果还没有解决的话:–为什么要提出这个预训练任务呢,主要也是很多譬如问答、推理之类的任务,更多的是要学习句子之间的关系,这是语言模型无法做到的,因为语言模型根据token预测token,是在句子内部进行学习的。
bert在训练时会判断这两个输入句子是否是连续的,相关的,也就是它会做一个二分类任务,若两个句子是挨在一起的,那么预测为1,否则为0。每个句子的结尾以 [SEP] 作为分隔符。
那么句子如何选取呢??训练的时候,输入到模型的第二个句子会以50%的可能从全部文本中随机选取,剩下50%的可能从紧挨着第一个句子的文本中选取
这样看来,模型就有两个损失函数了,一个是做完形填空时产生的,一个是做二分类时产生的,两个损失函数之和就是bert总的损失函数了。源码片段:
我建议您采取以下措施来优化BERT向量的相似度计算: 1. 使用更好的相似度计算方法: 余弦相似度通常是比较常用且易于实现的算法,但它并不一定适用于所有任务。对于文本匹配问题,可以考虑使用jaccard相似度、编辑距离等其他算法。具体哪种算法最好取决于您正在处理的数据和任务。 2. Fine-tune BERT模型: Fine-tune是一种基于预训练模型的微调技术,可以用来优化BERT向量的质量。可以使用TensorFlow或PyTorch中提供的Fine-tuning代码来训练模型,然后使用transformers库中的方法来提取词向量。 3. 使用基于BERT的其他模型: BERT模型是自然语言处理领域非常流行的一种模型,具有强大的表达能力和预测能力。除了BERT模型外,还有其他基于BERT的模型,例如ALBERT、RoBERTa等。这些模型在在某些任务上可能会取得更好的效果。可以根据自己的实际情况选择适合自己的模型。 下面是采用Fine-tune BERT模型的代码示例:
import tensorflow as tf
import numpy as np
import transformers
# 加载预训练的BERT模型
tokenizer = transformers.BertTokenizer.from_pretrained("bert-base-chinese")
model = transformers.TFBertModel.from_pretrained("bert-base-chinese")
# 构造Fine-tuning模型
input_ids = tf.keras.layers.Input(shape=(max_seq_length,), dtype=tf.int32, name="input_ids")
input_mask = tf.keras.layers.Input(shape=(max_seq_length,), dtype=tf.int32, name="input_mask")
segment_ids = tf.keras.layers.Input(shape=(max_seq_length,), dtype=tf.int32, name="segment_ids")
_, sequence_output = model([input_ids, input_mask, segment_ids])
output_layer = tf.keras.layers.Lambda(lambda x: x[:, 0, :])(sequence_output)
fc_output = tf.keras.layers.Dense(768, activation="relu")(output_layer)
fc_output = tf.keras.layers.Dropout(0.1)(fc_output)
logits = tf.keras.layers.Dense(num_classes, activation="softmax")(fc_output)
fine_tune_model = tf.keras.models.Model(
inputs=[input_ids, input_mask, segment_ids], outputs=logits)
# 编译模型
optimizer = tf.keras.optimizers.Adam(learning_rate=2e-5)
fine_tune_model.compile(optimizer=optimizer, loss="categorical_crossentropy")
# Fine-tune模型
train_inputs = [train_input_ids, train_input_masks, train_segment_ids]
train_labels = np.eye(num_classes)[train_labels]
fine_tune_model.fit(train_inputs, train_labels, epochs=5, batch_size=32)
其中,train_input_ids、train_input_masks和train_segment_ids是经过处理的训练数据,train_labels是标签。Fine-tune过程将bert模型的各个参数保存下来,再用这些参数来生成向量,这样得到的向量质量会更高一些。