如何让机器理解人类语言?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, util

model = 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 torch

model_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, util

model = 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SwiftUI中三大渐变色的介绍

在SwiftUI中,渐变色是一种常用的视觉效果,用于创建平滑过渡的颜色变化。通过使用渐变色,我们可以实现丰富多彩的界面设计,增强用户体验。 1. 渐变色的种类和用途 种类: 线性渐变(Linear Gradient&#x…

oracle多条重复数据,取最新的

1、原理讲解-可直接看2 筛选出最新的 SELECT * FROM ( SELECT t.*, ROW_NUMBER() OVER (PARTITION BY LOCALAUTHID ORDER BY LASTUPDATETIME DESC) AS rn FROM USER_LOCALAUTH_STATE t ) t WHERE t.rn 1; 解释: 这个序号是基于[LOCALAUTHID]字段进行分…

计算机vcruntime140.dll找不到如何修复,分享5种靠谱的修复教程

当您在运行某个应用程序或游戏时遇到提示“找不到vcruntime140.dll”,这通常意味着系统中缺少了Visual C Redistributable for Visual Studio 2015或更高版本的一个重要组件。这个错误通常发生在运行某些程序时,系统无法找到所需的动态链接库文件。小编将…

ASP.NET医药进销存系统

摘 要 目前,大中型城市的多数药品店已经实现了商品管理、客户管理、销售管理及销售管理等的信息化和网络化,提高了管理效率。但是,在大多数小药品店,药品店管理仍然以传统人工管理为主,特别是在药品的采购、销售、库…

电商核心技术揭秘56:客户关系管理与忠诚度提升

相关系列文章 电商技术揭秘相关系列文章合集(1) 电商技术揭秘相关系列文章合集(2) 电商技术揭秘相关系列文章合集(3) 文章目录 引言客户关系管理(CRM)的重要性提升顾客体验数据驱…

Springboot打包jar如何后台启动和查看日志?

如何后台启动Spring Boot的fat jar 使用nohup命令启动: 在Linux或Unix系统中,你可以使用nohup命令来启动jar包,以确保即使你关闭了终端或断开了SSH连接,程序仍然可以在后台运行。命令格式如下:nohup java -jar yourapp…

PCie协议之-TLP Header详解(一)

✨前言: 在PCIe通信过程中,事务层数据包(Transaction Layer Packets,简称TLP)扮演着非常重要的角色。TLP用于在设备之间传递数据和控制信息,它们是PCIe的基本信息传输单元。 TLP可分为几个部分&#xff0c…

硬盘格式化后能恢复数据吗?这个恢复方法电脑小白也能用!

硬盘格式化后能恢复数据吗?对于这个问题需要先了解清楚硬盘格式化和数据恢复的原理了。 目前我们所说的硬盘格式化通常都是指“快速格式化”,一般来说当我们在清理磁盘空间或者新建磁盘分区时会使用到这个功能,最终的结果就是清除掉磁盘上的…

“打工搬砖记”中吃什么的轮盘功能实现(二)

文章目录 打工搬砖记转盘主要的逻辑实现转盘的素材小结 打工搬砖记 先来一个吃什么轮盘的预览图,这轮盘文案加字呈圆形铺出来,开始后旋转到指定的选项处停下来。 已上线小程序“打工人搬砖记”,可以扫码进行预览观看。 转盘主要的逻辑实现…

【Unity Shader入门精要 第7章】基础纹理补充内容:MipMap原理

1.纹理采样 我们对纹理采样进行显示的过程,可以理解为将屏幕上的一个像素(下文用像素表示)映射到纹理上的一个像素(下文用纹素表示),然后用纹理上的这个像素的颜色进行显示。 理想情况下,屏幕…

AcqKnowledge 5.0使用方法

Biopac 数据导入 matlab 处理方法 第一步:在 AcqKnowledge 软件中,将数据通道的 mark 信息导入到 Graph,并将数据存储为 acq3 的格式 第二步:MATLAB中读取acq3文件脚本 clc clear %%%所有被试这一层路径 pathsub fullfile(file…

【JavaEE】HTTP 协议

文章目录 一、HTTP 协议1、HTTP 是什么2、理解 "应用层协议"3、理解 HTTP 协议的工作过程4、HTTP 协议格式5、HTTP 请求 (Request)5.1 认识 URL 6、 二、HTTPS1、HTTPS是什么2、"加密" 是什么3、HTTPS 的工作过程3.1 对称加密3.2 非对称加密3.3 证书3.4 完…

iOS——消息传递和消息转发

消息传递(Message Passing): 在 iOS 中,消息传递机制是基于 Objective-C 语言的动态性质的一种编程方式。这种机制主要涉及到两个概念:发送者(即消息的发送对象)和接收者(即消息的接…

RS422一主多从MAX3490

RS422一主多从MAX3490 最近项目用到了RS422一主多从,一个主机4个从机。芯片用的MAX3490,几经折腾,最终只能从一拖4改为一拖2。 主机发送端,从机4个接收端都是正常的,没有问题。波形非常完美,没有太大变形 …

matlab使用2-基础绘图

matlab使用2-基础绘图 文章目录 matlab使用2-基础绘图1. 二维平面绘图2. 三维立体绘图3. 图形窗口的分割 1. 二维平面绘图 % 创建一些二维数据 x 0:0.01:10; % x轴的数据点,从0到10,间隔为0.01 y sin(x); % y轴的数据点,是x的正弦…

版本控制:软件开发的基石(一文读懂版本控制)

未经允许,禁止转载! 在现代软件开发中,版本控制是不可或缺的工具。它帮助开发者跟踪和管理代码的变化,协作完成项目,并确保代码的完整性和安全性。本文将基于Git官网的视频“什么是版本控制”来深入探讨版本控制的基本…

pyqt QComboBox下拉列表框控件

pyqt QComboBox下拉列表框控件 QComboBox效果代码 QComboBox QComboBox 是 PyQt(中的一个控件,它允许用户从下拉列表中选择一个选项。这个控件在需要用户从预定义选项中进行选择时非常有用。 效果 代码 import sys from PyQt5.QtWidgets import QAppl…

转发_重定向

1.Servlet/JSP单独使用的弊端 当我们用Servlet或者JSP单独处理请求的时候 Servlet:拼接大量的html字符串 造成可读性差、难以维护JSP:使得html和Java代码互相交织 也造成了可读性差、难以维护的后果 最合适的做法就是两者结合使用 2.ServletJSP处理请…

宿舍管理系统代码详解(主页面)

本篇将对管理系统的主页面的代码进行详细的介绍。 目录 一、主页面前端代码 1.样式展示 2.代码详解 (1)template部分 (2)script部分 (3)路由导航守卫 (4)在vue中引用vue 一、主页…

数据库的三大范式!!!初学者必看

数据库的三大范式!!!初学者必看 三大范式是 Mysql数据库设计表结构所遵循的规范和指导方法目的是为了减少冗余,建立结构合理的数据库,从而提高数据存储和使用的性能。 三大范式之间是具有依赖关系的,比如第…