如何让机器理解人类语言?Embedding技术详解

如何让机器理解人类语言?Embedding技术详解

文章目录

  • 如何让机器理解人类语言?Embedding技术详解
    • 介绍
    • 什么是词嵌入?
    • 什么是句子嵌入?
    • 句子嵌入模型
      • 实现句子嵌入的方法
      • 值得尝试的句子嵌入模型
    • 句子嵌入库
      • 实践
        • Step 1
        • Step 2
        • Step 3
    • Doc2Vec
    • SentenceBERT(句子BERT)
    • InferSent
      • 句子编码器架构
        • GLovE (Global Vectors for Word Representation)
        • FastText
        • 示例
    • Universal Sentence Encoder
      • 语义相似
      • 文本分类
      • 示例
    • Skip-Thought Vectors
      • 示例
      • Quick-Thought Vectors
      • 示例
    • 参考资料

介绍

在语言理解方面,人类的能力是无与伦比的。因为人脑能够轻松理解语言中的各种情感信息,例如幽默、讽刺、负面情绪等,只是我们必须了解句子所用的语言。

例如,如果有人用英语评论我的文章,如果不借助翻译我可能很难理解对方想要表达的内容,所以为了有效的沟通,我们需要用对方最熟悉的语言进行交流。

同理,为了让机器能够处理并理解任何类型的文本,需要我们将文本表示为机器能够理解的“语言”。那么,机器最擅长理解哪种语言呢?没错,就是数字。无论我们提供什么样的数据给机器,例如视频、音频、图片或是文本,机器最终都只能处理数字。因此,将文本转换为数字,或者说进行文本嵌入,就是一个非常重要的手段。

在本文中,我将介绍一些主要的句子嵌入技术,并提供Python代码实现。文章将限于介绍这些技术的架构概览以及如何在Python中实现它们。我们将以查找给定句子的相似句子为例,演示如何使用这些embedding技术。

什么是词嵌入?

最初的嵌入技术只处理单词。给定一组单词,模型会为集合中的每个单词生成一个嵌入。最简单的方法是对提供的单词序列进行one-hot编码,使对应的单词用1表示,其他单词用0表示。虽然这在表示单词和其他简单的文本处理任务中比较有效,但它并不适用于更复杂的任务,例如查找相似单词。

例如,如果我们搜索查询:“广州受欢迎的景点”,我们希望获得与景点、广州的景点以及最受欢迎的一系列搜索结果。然而,如果我们得到一个搜索结果是:“广州著名旅游胜地”,我们简单的方法将无法检测到“受欢迎”与“著名”或“景点”与“旅游胜地”之间的相似性。

在这里插入图片描述

这类问题催生了词嵌入(Word embedding)技术。词嵌入不仅转换单词,还识别单词的语义和句法,构建这些信息的向量表示。一些流行的词嵌入技术包括Word2Vec、GloVe、ELMo、FastText等。

这些技术的基本概念是利用单词周围的信息来进行建模。研究人员在词嵌入技术方面取得了突破性的创新,他们找到了更好的方式来表达越来越多关于单词的信息,并且不仅仅是表示单词,而是整个句子甚至段落。

什么是句子嵌入?

在自然语言处理(NLP)中,句子嵌入指的是将句子表示为实数向量的过程,这种向量编码了句子的语义信息。这使得我们能够利用这些向量之间的距离或相似性来比较句子相似性。例如,使用深度学习模型训练的通用句子编码器(USE)生成这些嵌入,这些嵌入可用于文本分类、聚类和相似性匹配等任务。

在处理大量文本时,仅使用单词会非常繁琐,我们将受到从词嵌入中提取信息的限制,所以如果我们可以直接处理整个句子,而不仅仅是单词,那么性能将会大大提升。

例如对于这句话:“我不喜欢拥挤的地方”,然后几句话后,我们读到“然而,我喜欢世界上最繁忙的城市之一,北京”。如何使机器能够理解“拥挤的地方”和“繁忙的城市”之间的联系呢?

显然,词嵌入在这里是远远不够的,因此,我们可以使用句子嵌入来解决这一问题。句子嵌入技术表示整个句子及其语义信息为向量。这有助于机器理解文本中的上下文、意图和其他细微差别。

句子嵌入模型

句子嵌入模型旨在将句子的语义封装在固定长度的向量中。与传统的词袋模型(BoW)表示或one-hot编码不同,句子嵌入能够捕捉上下文、含义和词汇间的关系。这种转换使得机器能够把握人类语言的微妙之处。

实现句子嵌入的方法

为了生成句子嵌入,采用了几种方法:

  1. 平均词嵌入法:这种方法对句子中的词嵌入取平均值。虽然简单,但可能无法捕捉复杂的上下文细节。
  2. 预训练模型如BERT:BERT(双向编码器表示从Transformer)等模型彻底改变了句子嵌入的方式。基于BERT的模型考虑句子中每个词的上下文,产生丰富且具有上下文意识的嵌入。
  3. 基于神经网络的方法:Skip-Thought向量和InferSent等神经网络基句子嵌入模型。它们通过预测周围句子来训练,从而促使它们理解句子语义。

值得尝试的句子嵌入模型

  1. BERT(双向编码器表示从Transformers):BERT设定了句子嵌入的基准,提供了针对各种NLP任务的预训练模型。其双向注意力和上下文理解使其在语义理解上尤为突出。
  2. RoBERTa:作为BERT的进化版,RoBERTa改进了其训练方法,达到了多项NLP任务的SOTA。
  3. USE(通用句子编码器):由谷歌开发的USE,可以为文本生成嵌入,这些嵌入可用于包括跨语言任务在内的多种应用。

句子嵌入库

像词嵌入一样,句子嵌入也是一个非常火的研究领域,其中包含了许多有趣的技术,这些技术突破了帮助机器理解我们语言的障碍。

我们假设您已经具有词嵌入和其他基础NLP概念的知识。在继续学习下文之前,我推荐您阅读以下文章:

  • 自然语言处理入门指南(附Python代码)
  • NLP从业者必读:预训练词嵌入指南

实践

接下来,我们将设置一些基本的库并定义我们的句子列表。以下步骤将帮助您实现这一点:

Step 1

首先,导入库并下载 punk’:

import nltk
nltk.download('punkt')
from nltk.tokenize import word_tokenize
import numpy as np
Step 2

然后,我们定义我们的句子列表。您可以使用更大的列表(最好使用句子列表以便于每个句子的处理)。

sentences = ["I ate dinner.", "We had a three-course meal.", "Brad came to dinner with us.","He loves fish tacos.","In the end, we all felt like we ate too much.","We all agreed; it was a magnificent evening."]
Step 3

然后我们对这些单词进行分词:

tokenized_sent = []
for s in sentences:tokenized_sent.append(word_tokenize(s.lower()))
print(tokenized_sent)

output:

[['i', 'ate', 'dinner', '.'], ['we', 'had', 'a', 'three-course', 'meal', '.'], ['brad', 'came', 'to', 'dinner', 'with', 'us', '.'], ['he', 'loves', 'fish', 'tacos', '.'], ['in', 'the', 'end', ',', 'we', 'all', 'felt', 'like', 'we', 'ate', 'too', 'much', '.'], ['we', 'all', 'agreed', ';', 'it', 'was', 'a', 'magnificent', 'evening', '.']]

最后,我们定义一个函数,返回两个向量之间的余弦相似性。

def cosine(u, v):return np.dot(u, v) / (np.linalg.norm(u) * np.linalg.norm(v))

Doc2Vec

Doc2Vec是Word2Vec的扩展,它是目前最流行的句子嵌入技术之一。该技术通过引入“段落向量”来扩展Word2Vec模型。有以下两种方法可以将段落向量添加到模型中:

  1. PV-DM(分布式内存的段落向量):PV-DM通过将段落(文档、句子等)表示为唯一的向量,同时将文中的单词表示为向量,来捕捉段落的语义信息。PV-DM的基本思想借鉴了Word2Vec中的连续词袋(CBOW)模型。在CBOW中,模型根据上下文单词预测当前单词,而在PV-DM中,模型使用段落向量和几个上下文单词来预测下一个单词。
  2. PV-DBOW(分布式词袋的段落向量):PV-DBOW只使用段落向量来预测句子中随机选择的单词。这种方法与Word2Vec中的Skip-gram模型相似,其中Skip-gram是通过当前单词预测上下文单词。但在PV-DBOW中,没有使用上下文单词,而是直接从段落向量预测句子中的单词。

SentenceBERT(句子BERT)

SentenceBERT 是一个修改版的 BERT 模型,能够直接为句子对生成嵌入。这是通过使用Siamese和Triplet网络结构来实现的,这意味着它能够理解和编码两个句子之间的关系。

在这里插入图片描述

假设我们有两个句子:“我爱巴黎”和“我不喜欢巴黎”。SentenceBERT 可以有效地捕捉这两个句子的语义差异,即使它们包含相似的词汇。

!pip install -q sentence-transformers
from sentence_transformers import SentenceTransformer, utilmodel = SentenceTransformer('all-MiniLM-L6-v2')
sentences = ["我爱巴黎", "我不喜欢巴黎"]# 计算嵌入
embeddings = model.encode(sentences)# 计算两个句子间的相似度
similarity = util.pytorch_cos_sim(embeddings[0], embeddings[1])

InferSent

InferSent 是由 Facebook AI Research 提出的模型,用于生成句子的通用表示。它使用监督学习方法,标签为蕴涵、矛盾或中性,训练数据为自然语言推断(NLI)任务的标签数据集。

在这里插入图片描述

句子编码器架构

总共评估了7种不同的架构,看看哪一种最能捕获句子的通用编码:

  • 长短期记忆(LSTM)标准循环编码器

  • 带门控循环单元(GRU)的标准循环编码器

  • 前向和后向GRU的最后隐藏状态的连接

  • 具有平均池化的双向lstm (BiLSTM)

  • 大池化的双向lstm (BiLSTM)

  • Self-attentive网络

  • 分层卷积网络

这七个体系结构是根据它们对广泛的NLP问题捕捉有用的信息的能力来评估的。因此,这些句子编码器体系结构生成的编码被用于以下任务:

  • 二元和多类分类:这些任务包括情感分析,主客观分类,以及寻找意见极性等任务。

  • 蕴涵和语义关联:使用的两个数据集(SICK-R和SICK-E)分别基于语义相似性和蕴涵对句子对之间的关系进行分类。

  • STS14 -语义文本相似度:该数据集包含基于相似度的人工标记的句子对。

  • 释义检测:该数据集包含根据是否捕获释义/语义等价关系而进行人工标记的句子对。

  • 标题-图像检索:图像检索的目标是根据与给定标题的相关性对图像集合进行排序。标题检索的目标是根据与给定图像的相关性对一组标题进行排序。

实证结果表明,具有max pooling的BiLSTM在这些任务上取得了最高的性能。

InferSent有两个版本。版本1使用GLovE,而版本2使用fastText向量。我们选择任意版本即可。

GLovE (Global Vectors for Word Representation)

斯坦福大学的研究人员开发了GloVe,它构建了一个大表来监控单词在文本数据集中同时出现的频率。然后,该模型使用数学方法简化该表,为单个单词生成数值向量。

这些向量封装了单词之间的含义和关系,为与语言相关的各种机器学习任务奠定了基础。

FastText

Facebook的人工智能研究实验室创建了FastText,它在Word2Vec模型的基础上进行了改进,将单词视为更小的字符串或字符n图的集合。

这种方法使模型能够更有效地捕获具有复杂单词结构的语言的复杂性,并合并原始训练数据中不存在的单词。

因此,FastText产生了一种适应性更强、更全面的语言模型,适用于各种各样的机器学习任务。

示例

给定两个句子:“天气很好。”和“今天阳光明媚。”,InferSent 能够学习到这两个句子在语义上的相似性。

from models import InferSent
import torchmodel_version = 1
MODEL_PATH = "infersent%d.pkl" % model_version
params_model = {'bsize': 64, 'word_emb_dim': 300, 'enc_lstm_dim': 2048,'pool_type': 'max', 'dpout_model': 0.0, 'version': model_version}
model = InferSent(params_model)
model.load_state_dict(torch.load(MODEL_PATH))
model.set_w2v_path(W2V_PATH)sentences = ['天气很好。', '今天阳光明媚。']
model.build_vocab(sentences, tokenize=True)
embeddings = model.encode(sentences, bsize=128, tokenize=False, verbose=True)
print(embeddings)

Universal Sentence Encoder

Universal Sentence Encoder(USE)通用句子编码器将文本编码为高维向量,可用于文本分类、语义相似、聚类和其他自然语言任务。

该模型针对句子、短语或短段落文本进行了训练和优化。它在各种数据源和各种任务上进行训练,目的是动态适应各种自然语言理解任务。输入是可变长度的英文文本,输出是512维向量。

语义相似

简单的应用包括提高系统的覆盖范围,这些系统可以根据某些关键字、短语或话语触发行为。

在这里插入图片描述

文本分类

在这里插入图片描述

示例

embed = hub.Module("https://kaggle.com/models/google/universal-sentence-encoder/frameworks/TensorFlow1/variations/universal-sentence-encoder/versions/1")
embeddings = embed(["The quick brown fox jumps over the lazy dog.","I am a sentence for which I would like to get its embedding"])print(session.run(embeddings))# The following are example embedding output of 512 dimensions per sentence
# Embedding for: The quick brown fox jumps over the lazy dog.
# [-0.016987282782793045, -0.008949815295636654, -0.0070627182722091675, ...]
# Embedding for: I am a sentence for which I would like to get its embedding.
# [0.03531332314014435, -0.025384284555912018, -0.007880025543272495, ...]

Skip-Thought Vectors

Skip-Thought Vectors是受Word2Vec中Skip-Gram模型启发的句子级嵌入技术。与SentenceBERT和InferSent类似,Skip-Thought Vectors也使用编码器-解码器架构,但它的目标是根据前后句子来生成中间句子的表示,然后利用编码网络学习到的中心句子的表征(embedding)来重建其前一个句子和后一个句子。

在这里插入图片描述

Skip-Thoughts 模型由三部分组成:

  • 编码网络(Encoder Network):接收位于索引 i i i 的句子 x ( i ) x(i) x(i),并生成一个固定长度的表示 z ( i ) z(i) z(i)。这是一个循环网络(通常是 GRU 或 LSTM),用于依次处理句中的单词。
  • 前一个解码网络(Previous Decoder Network):取 z ( i ) z(i) z(i) 的嵌入,并尝试生成句子 x ( i − 1 ) x(i-1) x(i1)。这也是一个循环网络(通常是 GRU 或 LSTM),用于依次生成句子。
  • 下一个解码网络(Next Decoder Network):取 z ( i ) z(i) z(i) 的嵌入,并尝试生成句子 x ( i + 1 ) x(i+1) x(i+1)。同样是一个与前一个解码网络类似的循环网络。

示例

如果我们有一系列句子:“我昨天去了电影院。”,“电影很精彩。”,和“我们决定再去一次。”,Skip-Thought Vectors会试图使用第一句和第三句来预测第二句。

import skipthoughts# 载入模型
model = skipthoughts.load_model()# 编码句子
encoded_sentences = skipthoughts.encode(model, ["我昨天去了电影院。", "电影很精彩。", "我们决定再去一次。"])# 查看编码向量
print(encoded_sentences)

Quick-Thought Vectors

Quick-Thought Vectors 与 Skip-Thought Vectors 不同的是Quick-Thoughts目标是分类候选句子是否属于相邻句子。

Quick-Thought Vectors 通过选择一个句子及其上下文(前后句子),并训练模型通过分类任务来识别正确的上下文,而不是生成上下文。这使得训练过程更加高效。

在这里插入图片描述

示例

如果给定句子是:“我昨天去了电影院。”,模型将尝试识别哪些候选句子最可能是前后文。这可能包括“电影很精彩。”作为后文,而将“我喜欢在海滩上散步。”识别为不相关的句子。

# !pip install -q sentence_transformers
from sentence_transformers import SentenceTransformer, utilmodel = SentenceTransformer('all-MiniLM-L6-v2')
sentences = ["我昨天去了电影院。","电影很精彩。","我们决定再去一次。","我喜欢在海滩上散步。"
]# 计算所有句子的嵌入
embeddings = model.encode(sentences)# 假设第二个句子是中心句子,找出与其最相关的句子
query_embedding = embeddings[1]
scores = util.pytorch_cos_sim(query_embedding, embeddings).squeeze()  # 计算相似度并转换为一维数组# 排除当前句子自身
scores[1] = -1  # 将当前句子的得分设为最低# 找到最高得分的句子的索引
best_match = scores.argmax()# 打印与“电影很精彩。”最相关的句子
print("最相关的句子:", sentences[best_match])###最相关的句子: 我昨天去了电影院。

参考资料

  1. InferSent Explained

  2. My thoughts on Skip-Thoughts

  3. Building sentence embeddings via quick thoughts

  4. Top 4 Sentence Embedding Techniques using Python

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/698602.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【其他学习参考文档记录】

交叉编译学习参考 nodejs 交叉编译-cliff工作室

ComfyUI相见恨晚的提示词插件,简直堪称神器!

之前我曾介绍过一款专为SD设计的中文提示词插件——prompt-all-in-one,想必使用过的小伙伴们都已经感受到了它的便捷与实用吧。 不过,那款插件是基于webUI版本的,而现在,越来越多的朋友开始探索ComfyUI这一新选择。 假如在Comfy…

【源码+文档+调试讲解】微信小程序家政项目小程序

摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了微信小程序家政项目小程序的开发全过程。通过分析微信小程序家政项目小程序管理的不足,创建了一个计算机管理微信小程序家政项目小程序的方案。文章介…

OpenAI GPT-4o - 介绍

本文翻译整理自: Hello GPT-4o https://openai.com/index/hello-gpt-4o/ 文章目录 一、关于 GPT-4o二、模型能力三、能力探索四、模型评估1、文本评价2、音频 ASR 性能3、音频翻译性能4、M3Exam 零样本结果5、视觉理解评估6、语言 tokenization 六、模型安全性和局限…

Vitis HLS 学习笔记--理解串流Stream(1)

目录 1. 介绍 2. 示例 2.1 代码解析 2.2 串流数据类型 2.3 综合报告 3. 总结 1. 介绍 在Vitis HLS中,hls::stream是一个用于在C/C中进行高级合成的关键数据结构。它类似于C标准库中的std::stream,但是专门设计用于硬件描述语言(如Veri…

答辩PPT设计太耗时?aippt工具,AI一站式服务

这些网站我愿称之为制作答辩PPT的神! 很多快要毕业的同学在做答辩PPT的时候总是感觉毫无思路,一窍不通。但这并不是你们的错,对于平时没接触过相关方面,第一次搞答辩PPT的人来说,这是很正常的一件事。一个好的答辩PPT…

用vue实现json模版编辑器

用vue实现json模版编辑器 控件区表单区配置项区 (还没写)业务逻辑 设想业务逻辑是拖拽控件生成表单 动手做了一个简单的demo 业务的原型图设想如下所示 其中使用的技术主要是vuedragger 控件区 做控件区的时候首先我们要有确定的配置项 其实也很简单 …

yarn 安装以及报错处理

前一种报错是由于没有安装yarn导致的,使用以下命令即可安装: npm install -g yarn 如果成功安装,将显示Yarn的版本号。 yarn --version 第二种报错是因为系统上的执行策略限制导致的。执行策略是一种安全功能,用于控制在计算机…

问题—前端调用接口url多加一个/,本地可以调通,测试环境报错302,分开调两个接口

问题背景 接口url前面多加一个/ ,npm run serve 起项目,本地调用正常 npm run build 打包到测试环境,接口出现问题,分开调用接口,且报302错误 问题原因: 本地开发环境和测试环境的URL处理方式不同 本地使…

putty如何让正在执行的命令后台运行,而后可退出putty

putty如何让正在执行的命令后台运行后可退出putty Putty常用于远程登录Linux服务器,其相比于远程可视化桌面控制VNC具有一些特定的优点,比如更快的传输文件和更便捷的登录操作方式。但是有些时候我们可能需要用到Linux集群去计算一些大型的结构文件&…

vue2 报错,警告 解决方法 component name“Index“should always be multi-word

报错原因: 组件名称应该为俩个或俩个以上单词组成的,并且还要是大驼峰命名,例如:MyIndex,MyLogin等 解决方法一: 将组件名称改为俩个或俩个以上单词组成的名称,且为大驼峰命名,例如…

Linux安装MySQL(CentOS 7)

安装步骤 下载的MySQL版本为mysql-8.0.26 进入网站MySQL,点击下载 找到mysql社区版 点击Archive,查看所有相关不同版本 点击MySQL Community Server 注意下载MySQL对应的Linux版本,CentOS7 对应 Linux7,如果下成Linux 8 则后面…