基于M3E模型的文本句嵌入与文本分类----提高语音技术的泛化能力

本文介绍了如何通过大模型如SentenceTransformer的向量嵌入技术提高文本的泛化能力,避免预设关键词的局限。文章详细描述了算法流程,包括加载基础命令、计算余弦相似度以及两种改进策略:模型微调和负语义词增设关键词。
摘要由CSDN通过智能技术生成

背景说明 

        在很多传统场景下,文本的泛化能力往往的评价一个产品是否优异的标准和软实力。例如各种产品的语音泛化能力。在传统的方案往往是采取不断添加预设关键词的方式来增加泛化能力,然鹅很明显,泛化能力存在一个上限,对于没有提前预设的命令,将不会收到任何反馈。

        近几年大模型浩浩荡荡进发,大模型对于各个行业的赋能将不可阻挡。很多嵌入式的系统虽然因为各种各样的能力(性能受限等)暂时没办法直接搭载大模型能力(步子大了容易扯着蛋),但是把大模型的一部分功能拆下来使用,便可以给产品进行极大的赋能。

        采用大模型文本嵌入的方案,将一句话映射为一个向量,通过向量之间余弦相似度比对的方案可以很好的完善泛化能力。至此,泛化是基于文本理解的泛化,而非增加预设词。

算法流程

步骤如下

  • 进入M3E官网下载基础文件和基础模型 链接:魔搭社区 (modelscope.cn) 
  • 本地新建一个DataBase.txt 的文件,用以保存基础的关键命令,格式:每一个命令一行。
  • 新建代码,代码已经附上

代码如下:

from sentence_transformers import SentenceTransformer
import numpy as np  
  
def cosine_similarity(vec1, vec2):  
    # 确保输入是numpy数组  
    vec1 = np.array(vec1)  
    vec2 = np.array(vec2)  
      
    # 计算点积  
    dot_product = np.dot(vec1, vec2)  
    # 计算范数(长度)  
    norm_a = np.linalg.norm(vec1)  
    norm_b = np.linalg.norm(vec2)  
    # 防止除以零  
    if norm_a == 0 or norm_b == 0:  
        return 0  
    # 计算余弦相似度  
    cosine_similarity = dot_product / (norm_a * norm_b)  
      
    return cosine_similarity 

#加载文件并构建embedding
def load_document_and_get_embeddings(document_path):  
    # 加载文档  
    with open(document_path, 'r', encoding='utf-8') as file:  
        lines = file.readlines()  
      
    # 初始化用于存储二元组的列表  
    embeddings_list1 = []  
    embeddings_list2 = []   
    # 对文档的每一行进行处理  
    for line in lines: 
        print("正在处理" + line)
        # 去除行尾的换行符  
        line = line.strip()  
          
        # 如果行不为空,则获取其嵌入  
        if line:  
            # 使用get_text_embeddings函数获取嵌入  
            embeddings = model.encode([line])
            # 构建二元组并添加到列表中  
            embeddings_list1.append((line, embeddings))  
            embeddings_list2.append(embeddings.tolist())
      
    return embeddings_list1, embeddings_list2
    
def PCAshow(data_transformed):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    colors = ['r', 'g', 'b', 'y']
    for i in range(len(data_transformed)):
        ax.scatter(data_transformed[i, 0], data_transformed[i, 1],
                   data_transformed[i, 2], c=colors[labels[i]])

    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    plt.show()

if __name__ == "__main__":
    print("初始化模型ing……")
    model = SentenceTransformer('m3e-base')
    print("模型加载完毕ing……")

    #本地文件加载嵌入
    embeddings_list, embeddings_list2 = load_document_and_get_embeddings("DataBase.txt")

    print("数据文本初始化完毕")

    while True:
        your_input = input("请输入:")
        yourEmbeddings = model.encode([your_input])
        similarities = []
        for idx, (sentence, embedding) in enumerate(embeddings_list): 
            similarity = cosine_similarity(embedding[0], yourEmbeddings[0])
            similarities.append([similarity, sentence])
        sorted_similarities = sorted(similarities, reverse=True) 
        print(sorted_similarities[0:3])

    t1.join()

改进策略

对于上述方案还需要对于当前场景进行微调,否则将会出现啼笑皆非的现象!

例如:新命令“开始打扫马桶” 将会被分类为 “打扫厕所”,而且相似度还很高,因为在宏观世界看来“马桶”和“厕所”的关联度很高,然鹅在扫地机器人场景来看“打扫马桶”“和打扫厕所”是完全不同的两个命令,“打扫马桶”怎么说都不能直接执行“打扫厕所”的执行命令 。

这就需要对模型本身进行微调

微调方案一:模型微调训练

采用uniem进行嵌入模型的微调

微调方式如下,说明很友好,纯新手也能很快入手。

uniem/examples/finetune.ipynb at main · wangyuxinwhy/uniem · GitHub

微调方案二:负语义词增设关键词

当然也有一个更笨的方法,把一些关联性太强的词语(但是我们不希望他们泛化到同一个命令中),都加入预设的关键词中,那么在运行过程中,把这些词统一处理即可,例如回复“暂时不支持此功能哦”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千天夜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值