当前位置: 首页 > news >正文

Sentence Transformers 教程!

Sentence Transformers专注于句子和文本嵌入,支持超过100种语言。利用深度学习技术,特别是Transformer架构的优势,将文本转换为高维向量空间中的点,使得相似的文本在几何意义上更接近。 

  1. 语义搜索:构建高效的语义搜索系统,找到最相关的查询结果。
  2. 信息检索与重排:在大规模文档集合中查找相关文档并重新排序。
  3. 聚类分析:将文本自动分组,发现隐藏的主题或模式。
  4. 摘要挖掘:识别和提取文本的主要观点。
  5. 平行句对挖掘:在多语言数据中找出对应的翻译句子。

💥pip安装:

pip install -U sentence-transformers

💥conda安装:

conda install -c conda-forge sentence-transformers

快速使用:

from sentence_transformers import SentenceTransformermodel = SentenceTransformer("all-MiniLM-L6-v2")
# 加载all-MiniLM-L6-v2,这是一个在超过 10 亿个训练对的大型数据集上微调的 MiniLM 模型sentences = ["The weather is lovely today.","It's so sunny outside!","He drove to the stadium.",
]embeddings = model.encode(sentences)
print(embeddings.shape)# 计算所有句子对之间的相似度
similarities = model.similarity(embeddings, embeddings)
print(similarities)

输出:

 

Cross Encoder

  • 计算给定文本对的相似度得分

  • 通常比Sentence Transformer模型慢,因为它需要对每一对而不是每个文本进行计算

  • 交叉编码器(Cross Encoder)经常被用来对Sentence Transformer模型的top-k个结果进行重新排序。

💯Cross Encoder (又名 reranker) 模型的用法与 Sentence Transformers 类似:

from sentence_transformers.cross_encoder import CrossEncoder
# 我们选择要加载的CrossEncoder模型
model = CrossEncoder("cross-encoder/stsb-distilroberta-base")# 定义查询句子和语料库
query = "A man is eating pasta."
corpus = ["A man is eating food.","A man is eating a piece of bread.","The girl is carrying a baby.","A man is riding a horse.","A woman is playing violin.","Two men pushed carts through the woods.","A man is riding a white horse on an enclosed ground.","A monkey is playing drums.","A cheetah is running behind its prey.",
]# 对句子进行排名
ranks = model.rank(query, corpus)print("Query: ", query)
for rank in ranks:print(f"{rank['score']:.2f}\t{corpus[rank['corpus_id']]}")import numpy as np
# 使用 NumPy 进行排序
sentence_combinations = [[query, sentence] for sentence in corpus]
scores = model.predict(sentence_combinations)ranked_indices = np.argsort(scores)[::-1]
print("Scores:", scores)
print("Indices:", ranked_indices)

输出:

Sentence Transformer模型用法 

  1. 计算给定文本或图像的固定大小的向量表示(嵌入)

  2. 嵌入计算往往是高效的,嵌入相似度计算非常快

  3. 适用于广泛的任务,例如语义文本相似度、语义搜索、聚类、分类、释义挖掘等。

  4. 通常用作两步检索过程的第一步,其中使用Cross-Encoder模型对双编码器的前 k 个结果进行重新排序。

语义文本相似度

💫对于语义文本相似度 (STS),我们希望为所有相关文本生成嵌入并计算它们之间的相似度。相似度得分最高的文本对在语义上最相似

from sentence_transformers import SentenceTransformermodel = SentenceTransformer("all-MiniLM-L6-v2")sentences1 = ["The new movie is awesome","The cat sits outside","A man is playing guitar",
]sentences2 = ["The dog plays in the garden","The new movie is so great","A woman watches TV",
]embeddings1 = model.encode(sentences1)
embeddings2 = model.encode(sentences2)similarities = model.similarity(embeddings1, embeddings2)for idx_i, sentence1 in enumerate(sentences1):print(sentence1)for idx_j, sentence2 in enumerate(sentences2):print(f" - {sentence2: <30}: {similarities[idx_i][idx_j]:.4f}")
  • 返回一个 3x3 矩阵,其中包含embeddings1embeddings2之间所有可能对的相应余弦相似度分数 

💫输出:

相似度计算 

可以通过多种方式改变此值:

1. 通过使用所需的相似度函数初始化 SentenceTransformer 实例:

from sentence_transformers import SentenceTransformer, SimilarityFunctionmodel = SentenceTransformer("all-MiniLM-L6-v2", similarity_fn_name=SimilarityFunction.DOT_PRODUCT)

2. 通过直接在 SentenceTransformer 实例上设置值:

from sentence_transformers import SentenceTransformer, SimilarityFunctionmodel = SentenceTransformer("all-MiniLM-L6-v2")
model.similarity_fn_name = SimilarityFunction.DOT_PRODUCT

Sentence Transformers 实现了两种方法来计算嵌入之间的相似度

from sentence_transformers import SentenceTransformer, SimilarityFunction
model = SentenceTransformer("all-MiniLM-L6-v2")sentences = ["The weather is lovely today.","It's so sunny outside!","He drove to the stadium.",
]
embeddings = model.encode(sentences)similarities = model.similarity(embeddings, embeddings)
print(similarities)model.similarity_fn_name = SimilarityFunction.MANHATTAN
print(model.similarity_fn_name)similarities = model.similarity(embeddings, embeddings)
print(similarities)

 输出:

语义搜索 

🧊语义搜索旨在通过理解搜索查询的语义含义和要搜索的语料库来提高搜索准确率。与只能根据词汇匹配查找文档的关键字搜索引擎不同,语义搜索在给定同义词、缩写和拼写错误的情况下也能表现良好。

语义搜索背后的理念是将语料库中的所有条目(无论是句子、段落还是文档)嵌入到向量空间中。在搜索时,查询被嵌入到相同的向量空间中,并从语料库中找到最接近的嵌入。这些条目应该与查询具有较高的语义相似度。

对称与非对称语义搜索

🧊我们设置的一个关键区别对称非对称语义搜索

  • 对于对称语义搜索:搜索类似问题:您的查询可能是“如何在线学习 Python?”想查找“如何在网上学习 Python?”这样的条目
  • 对于非对称语义搜索:我们通常会有一个简短的查询(例如问题或一些关键字)并且想要找到一个较长的段落来回答该查询。例如,查询“什么是 Python”,并且您想要找到段落“Python 是一种解释型、高级和通用的编程语言。Python 的设计理念……”。对于非对称任务,翻转查询和语料库中的条目通常没有意义。

对于小型语料库(最多约 100 万个条目),我们可以通过手动实现语义搜索,即计算语料库和查询的嵌入

import torchfrom sentence_transformers import SentenceTransformerembedder = SentenceTransformer("all-MiniLM-L6-v2")corpus = ["A man is eating food.","A man is eating a piece of bread.","The girl is carrying a baby.","A man is riding a horse.","A woman is playing violin.","Two men pushed carts through the woods.","A man is riding a white horse on an enclosed ground.","A monkey is playing drums.","A cheetah is running behind its prey.",
]corpus_embeddings = embedder.encode(corpus, convert_to_tensor=True)queries = ["A man is eating pasta.","Someone in a gorilla costume is playing a set of drums.","A cheetah chases prey on across a field.",
]top_k = min(5, len(corpus))
for query in queries:query_embedding = embedder.encode(query, convert_to_tensor=True)similarity_scores = embedder.similarity(query_embedding, corpus_embeddings)[0]scores, indices = torch.topk(similarity_scores, k=top_k)print("\nQuery:", query)print("Top 5 most similar sentences in corpus:")for score, idx in zip(scores, indices):print(corpus[idx], f"(Score: {score:.4f})")

输出:


🍹我们也可以不用自己实现语义搜索 ,可以使用util.semantic_search函数

sentence_transformers.util.semantic_search(query_embeddings: Tensor, corpus_embeddings: Tensor, query_chunk_size: int = 100, corpus_chunk_size: int = 500000, top_k: int = 10, score_function: Callable[[Tensor, Tensor], Tensor] = <function cos_sim>) →列表[列表[字典[ str , int | float ] ] ]
  • query_embeddingsTensor)– 具有查询嵌入的二维张量。

  • corpus_embeddings张量)– 具有语料库嵌入的二维张量。

  • query_chunk_sizeint 可选)– 同时处理 100 个查询。增加该值可以提高速度,但需要更多内存。默认为 100。

  • corpus_chunk_sizeint 可选) – 一次扫描语料库中的 100k 个条目。增加该值可以提高速度,但需要更多内存。默认为 500000。

  • top_k ( int 可选) – 检索前 k 个匹配条目。默认为 10。

  • score_functionCallable Tensor Tensor Tensor 可选)– 用于计算分数的函数。默认情况下,余弦相似度。

  • 返回:每个查询对应一个条目的列表。每个条目都是一个字典列表,其中包含键“corpus_id”和“score”,按余弦相似度得分降序排序。

速度优化

corpus_embeddings = corpus_embeddings.to("cuda")
corpus_embeddings = util.normalize_embeddings(corpus_embeddings)query_embeddings = query_embeddings.to("cuda")
query_embeddings = util.normalize_embeddings(query_embeddings)
hits = util.semantic_search(query_embeddings, corpus_embeddings, score_function=util.dot_score)

检索和重新排序 

对于复杂的搜索任务,例如问答检索,使用检索和重新排名可以显著提高搜索质量。

 

给定一个搜索查询,我们首先使用一个检索系统来检索一个大列表,例如 100 个可能与该查询相关的结果。对于检索,我们可以使用词汇搜索,例如使用 Elasticsearch 之类的矢量引擎,或者我们可以使用双编码器进行密集检索。但是,检索系统可能会检索与搜索查询不太相关的文档。 

🌤️双编码器会为段落和搜索查询独立生成嵌入 

from sentence_transformers import SentenceTransformermodel = SentenceTransformer("multi-qa-mpnet-base-dot-v1")docs = ["My first paragraph. That contains information","Python is a programming language.",
]
document_embeddings = model.encode(docs)
print('document_embeddings:',document_embeddings)
query = "What is Python?"
query_embedding = model.encode(query)
print('query_embedding:',query_embedding)

 输出:


http://www.mrgr.cn/news/34348.html

相关文章:

  • 【解密 Kotlin 扩展函数】扩展函数的底层原理(十八)
  • 云原生周刊:Artifact Hub 成为 CNCF 孵化项目|2024.9.23
  • 项目实现:云备份服务端③(热点模块、服务端业务处理模块实现)
  • 三线城市的女玩家们不想“谈恋爱”,小游戏掘金新蓝海
  • 【Transformers基础入门篇4】基础组件之Model
  • 干货:企业微信批量删除客户指南!
  • 13.第二阶段x86游戏实战2-动态模块地址
  • 【Go】Go语言中深拷贝和浅拷贝
  • Java详细学习路线:从入门到精通的全方位指南
  • 数字人起飞!字节Loopy对口型功能上线 可根据语境匹配表情和情绪
  • 一个可以在线制作样本册,拥有海量样本图册模板可以套用的网站
  • Vert.x,Core - Future
  • 视频无损压缩工具+预览视频生成工具
  • Java 中使用 Gson 实现深度克隆 #什么是深克隆与浅克隆?#clone方法为什么不能直接通过某个对象实例在外部类调用?
  • 我设置了路由器自动切换ip,这会让我的账号登录地址经常改变吗
  • 奔驰「进退」两难
  • Webpack 常见配置项
  • apply、call和bind的作用和区别
  • 装饰器模式
  • Vue使用Vue Router路由:开发单页应用