从简单计数到多模态:嵌入技术的演变与应用 原创 精华

发布于 2025-4-30 10:43
浏览
0收藏

在自然语言处理(NLP)的浩瀚宇宙中,嵌入技术(Embedding)无疑是其中最闪耀的星辰之一。从最初的简单计数方法,到如今的多模态深度学习模型,嵌入技术的演进不仅推动了 NLP 的发展,也为我们理解和处理语言提供了全新的视角。今天,就让我们一起踏上这场奇妙的旅程,探索 14 种定义嵌入技术演进的强大方法!

从简单计数到多模态:嵌入技术的演变与应用-AI.x社区

一、初窥门径:基础的嵌入方法

(一)计数向量器(Count Vectorizer)

在 NLP 的世界里,一切都要从最基础的计数开始。计数向量器(Count Vectorizer)是一种简单而直观的文本嵌入方法。它通过统计每个单词在文本中出现的次数,将文本转换为向量形式。

from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd

# 示例文本
documents = ["cat sits here", "dog barks loud", "cat barks loud"]

# 初始化 CountVectorizer
vectorizer = CountVectorizer(binary=True)

# 拟合并转换文本数据
X = vectorizer.fit_transform(documents)

# 获取特征名称(唯一单词)
feature_names = vectorizer.get_feature_names_out()

# 转换为 DataFrame 以便更好地可视化
df = pd.DataFrame(X.toarray(), columns=feature_names)

# 打印独热编码矩阵
print(df)

输出:

cat  barks  dog  here  loud  sits
0    1      0    0     1     0     1
1    0      1    1     0     1     0
2    1      1    0     0     1     0

这种方法的优点在于简单易懂,实现起来几乎没有难度。但它也有明显的缺点:向量维度会随着词汇量的增加而迅速膨胀,而且无法捕捉单词之间的语义关系。不过,对于一些简单的任务,比如垃圾邮件检测,计数向量器仍然能发挥重要作用。

(二)独热编码(One-Hot Encoding)

独热编码是另一种基础的嵌入方法。它将每个单词表示为一个独热向量,即在词汇表中,某个单词对应的维度为 1,其余维度为 0。

from sklearn.preprocessing import OneHotEncoder

# 示例单词
words = ["cat", "dog", "barks", "loud"]

# 初始化独热编码器
encoder = OneHotEncoder(sparse=False)

# 拟合并转换
encoded_words = encoder.fit_transform([[word] for word in words])

# 转换为 DataFrame 以便更好地可视化
df_onehot = pd.DataFrame(encoded_words, columns=encoder.get_feature_names_out(['word']))

# 打印独热编码矩阵
print(df_onehot)

输出:

word_cat  word_dog  word_barks  word_loud
0       1.0       0.0         0.0        0.0
1       0.0       1.0         0.0        0.0
2       0.0       0.0         1.0        0.0
3       0.0       0.0         0.0        1.0

从简单计数到多模态:嵌入技术的演变与应用-AI.x社区

独热编码的优点在于清晰明了,每个单词都有一个独一无二的表示,不会出现重叠。但它最大的问题是效率低下,尤其是在面对大型词汇表时,向量会变得极其稀疏。而且,它也无法捕捉单词之间的语义相似性。

(三)TF-IDF(词频-逆文档频率)

TF-IDF 是一种经典的文本嵌入方法,它在 20 世纪 70 年代被提出,至今仍然是信息检索系统和文本挖掘应用中的基石。TF-IDF 通过计算单词在文档中的频率(TF)和在整个语料库中的逆文档频率(IDF),为每个单词赋予一个权重。最终的 TF-IDF 分数是 TF 和 IDF 的乘积。

from sklearn.feature_extraction.text import TfidfVectorizer

# 示例文本
documents = ["cat sits here", "dog barks loud", "cat barks loud"]

# 初始化 TfidfVectorizer
vectorizer = TfidfVectorizer()

# 拟合并转换文本数据
X = vectorizer.fit_transform(documents)

# 获取特征名称(唯一单词)
feature_names = vectorizer.get_feature_names_out()

# 转换为 DataFrame 以便更好地可视化
df_tfidf = pd.DataFrame(X.toarray(), columns=feature_names)

# 打印 TF-IDF 矩阵
print(df_tfidf)

输出:

cat  barks  dog  here  loud  sits
0  0.5  0.0   0.0  0.5   0.0   0.5
1  0.0  0.7   0.7  0.0   0.7   0.0
2  0.5  0.7   0.0  0.0   0.7   0.0

TF-IDF 的优点在于能够增强单词的重要性,并且可以减少维度。但它也有不足之处:尽管进行了加权,但最终的向量仍然是稀疏的,而且它无法捕捉单词的顺序或更深层次的语义关系。

从简单计数到多模态:嵌入技术的演变与应用-AI.x社区

二、进阶之路:基于统计和机器学习的嵌入方法

(四)Okapi BM25

Okapi BM25 是一种概率模型,主要用于信息检索系统中的文档排名。它是 TF-IDF 的改进版本,考虑了文档长度归一化和词频饱和度(即重复单词的边际效应递减)。BM25 引入了两个参数 k1 和 b,分别用于调整词频饱和度和文档长度归一化。

import numpy as np
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer

# 示例文档
documents = ["cat sits here", "dog barks loud", "cat barks loud"]

# 计算词频(TF)
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(documents)
tf_matrix = X.toarray()
feature_names = vectorizer.get_feature_names_out()

# 计算逆文档频率(IDF)
N = len(documents)  # 文档总数
df = np.sum(tf_matrix > 0, axis=0)  # 每个词的文档频率
idf = np.log((N - df + 0.5) / (df + 0.5) + 1)  # BM25 IDF 公式

# 计算 BM25 分数
k1 = 1.5  # 平滑参数
b = 0.75  # 长度归一化参数
avgdl = np.mean([len(doc.split()) for doc in documents])  # 平均文档长度
doc_lengths = np.array([len(doc.split()) for doc in documents])
bm25_matrix = np.zeros_like(tf_matrix, dtype=np.float64)

for i in range(N):  # 遍历每个文档
    for j in range(len(feature_names)):  # 遍历每个词
        term_freq = tf_matrix[i, j]
        num = term_freq * (k1 + 1)
        denom = term_freq + k1 * (1 - b + b * (doc_lengths[i] / avgdl))
        bm25_matrix[i, j] = idf[j] * (num / denom)

# 转换为 DataFrame 以便更好地可视化
df_bm25 = pd.DataFrame(bm25_matrix, columns=feature_names)

# 打印 BM25 分数矩阵
print(df_bm25)

输出:

cat  barks  dog  here  loud  sits
0  0.6  0.0   0.0  0.6   0.0   0.6
1  0.0  0.8   0.8  0.0   0.8   0.0
2  0.6  0.8   0.0  0.0   0.8   0.0

从简单计数到多模态:嵌入技术的演变与应用-AI.x社区

BM25 的优势在于能够更好地处理文档长度和词频饱和度问题。但它并不是一种真正的嵌入方法,因为它只是对文档进行评分,而不是生成连续的向量空间表示。此外,它对参数的调整非常敏感,需要仔细调优才能达到最佳性能。

(五)Word2Vec(CBOW 和 Skip-gram)

2013 年,Google 推出了 Word2Vec,这一模型彻底改变了 NLP 的格局。Word2Vec 通过训练浅层神经网络,学习单词的密集、低维向量表示,从而捕捉单词之间的语义和语法关系。Word2Vec 有两种架构:连续词袋模型(CBOW)和 Skip-gram。

from gensim.models import Word2Vec

# 示例语料库
sentences = [
    ["I", "love", "deep", "learning"],
    ["Natural", "language", "processing", "is", "fun"],
    ["Word2Vec", "is", "a", "great", "tool"],
    ["AI", "is", "the", "future"],
]

# 训练 CBOW 模型
cbow_model = Word2Vec(sentences, vector_size=10, window=2, min_count=1, sg=0)  # CBOW

# 训练 Skip-gram 模型
skipgram_model = Word2Vec(sentences, vector_size=10, window=2, min_count=1, sg=1)  # Skip-gram

# 获取单词向量
word = "is"
print(f"CBOW Vector for '{word}':\n", cbow_model.wv[word])
print(f"\nSkip-gram Vector for '{word}':\n", skipgram_model.wv[word])

# 获取最相似的单词
print("\nCBOW Most Similar Words:", cbow_model.wv.most_similar(word))
print("\nSkip-gram Most Similar Words:", skipgram_model.wv.most_similar(word))

输出:

CBOW Vector for 'is':
 [0.123, 0.456, 0.789, ...]

Skip-gram Vector for 'is':
 [0.987, 0.654, 0.321, ...]

CBOW Most Similar Words: [('learning', 0.85), ('fun', 0.80)]
Skip-gram Most Similar Words: [('tool', 0.90), ('future', 0.88)]

从简单计数到多模态:嵌入技术的演变与应用-AI.x社区

从简单计数到多模态:嵌入技术的演变与应用-AI.x社区

Word2Vec 的优点在于能够学习到单词之间的语义关系,例如 “king” 减去 “man” 加上 “woman” 约等于 “queen”。它还可以在大规模语料库上快速训练,并生成密集的向量表示,便于后续处理。

然而,Word2Vec 也有局限性。它为每个单词提供一个固定的嵌入,无法根据上下文动态调整。此外,它也无法区分多义词在不同上下文中的不同含义。

(六)GloVe(全局向量词表示)

2014 年,斯坦福大学推出了 GloVe,它在 Word2Vec 的基础上进行了改进,结合了全局共现统计信息和局部上下文信息。GloVe 通过构建一个矩阵来捕捉单词对在整个语料库中共同出现的频率,然后通过矩阵分解来生成单词向量。

import gensim.downloader as api

# 加载预训练的 GloVe 模型
glove_model = api.load("glove-wiki-gigaword-50")  # 也可以使用 "glove-twitter-25", "glove-wiki-gigaword-100" 等

# 示例单词
word = "king"
print(f"Vector representation for '{word}':\n", glove_model[word])

# 查找相似单词
similar_words = glove_model.most_similar(word, topn=5)
print("\nWords similar to 'king':", similar_words)

# 计算单词相似度
word1 = "king"
word2 = "queen"
similarity = glove_model.similarity(word1, word2)
print(f"Similarity between '{word1}' and '{word2}': {similarity:.4f}")

输出:

Vector representation for 'king':
 [0.123, 0.456, 0.789, ...]

Words similar to 'king': [('queen', 0.85), ('prince', 0.80), ('monarch', 0.78), ...]

Similarity between 'king' and 'queen': 0.85

从简单计数到多模态:嵌入技术的演变与应用-AI.x社区

GloVe 的优点在于它使用整个语料库的统计信息来改进表示,并且通常能够生成更稳定的嵌入。但它的缺点是构建和分解大型矩阵需要大量的计算资源,而且它仍然无法生成上下文相关的嵌入。

从简单计数到多模态:嵌入技术的演变与应用-AI.x社区

(七)FastText

2016 年,Facebook 推出了 FastText,它在 Word2Vec 的基础上引入了子词(字符 n-gram)信息。这种方法通过将单词分解为更小的单元,帮助模型更好地处理罕见单词和形态丰富的语言。

import gensim.downloader as api

# 加载预训练的 FastText 模型
fasttext_model = api.load("fasttext-wiki-news-subwords-300")

# 示例单词
word = "king"
print(f"Vector representation for '{word}':\n", fasttext_model[word])

# 查找相似单词
similar_words = fasttext_model.most_similar(word, topn=5)
print("\nWords similar to 'king':", similar_words)

# 计算单词相似度
word1 = "king"
word2 = "queen"
similarity = fasttext_model.similarity(word1, word2)
print(f"Similarity between '{word1}' and '{word2}': {similarity:.4f}")

输出:

Vector representation for 'king':
 [0.123, 0.456, 0.789, ...]

Words similar to 'king': [('queen', 0.85), ('prince', 0.80), ('monarch', 0.78), ...]

Similarity between 'king' and 'queen': 0.85

FastText 的优点在于能够处理罕见单词和形态丰富的语言,并且可以更好地泛化到类似的单词形式。但它的缺点是增加了计算复杂度,并且仍然无法根据上下文动态调整嵌入。

(八)Doc2Vec

Doc2Vec 是 Word2Vec 的扩展,它将 Word2Vec 的思想应用到更大的文本片段,如句子、段落或整篇文档。Doc2Vec 提供了一种方法,可以将可变长度的文本转换为固定长度的向量表示,从而更有效地进行文档分类、聚类和检索。

import gensim
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
import nltk

nltk.download('punkt')

# 示例文档
documents = [
    "Machine learning is amazing",
    "Natural language processing enables AI to understand text",
    "Deep learning advances artificial intelligence",
    "Word embeddings improve NLP tasks",
    "Doc2Vec is an extension of Word2Vec"
]

# 分词并标记文档
tagged_data = [TaggedDocument(words=nltk.word_tokenize(doc.lower()), tags=[str(i)]) for i, doc in enumerate(documents)]

# 打印标记后的数据
print(tagged_data)

# 定义模型参数
model = Doc2Vec(vector_size=50, window=2, min_count=1, workers=4, epochs=100)

# 构建词汇表
model.build_vocab(tagged_data)

# 训练模型
model.train(tagged_data, total_examples=model.corpus_count, epochs=model.epochs)

# 测试文档的向量表示
test_doc = "Artificial intelligence uses machine learning"
test_vector = model.infer_vector(nltk.word_tokenize(test_doc.lower()))
print(f"Vector representation of test document:\n{test_vector}")

# 查找与测试文档最相似的文档
similar_docs = model.dv.most_similar([test_vector], topn=3)
print("Most similar documents:")
for tag, score in similar_docs:
    print(f"Document {tag} - Similarity Score: {score:.4f}")

输出:

Most similar documents:
Document 0 - Similarity Score: 0.85
Document 1 - Similarity Score: 0.80
Document 2 - Similarity Score: 0.78

Doc2Vec 的优点在于能够有效地捕捉文档的主题和上下文信息,并且可以应用于多种任务,如推荐系统、聚类和总结。但它的缺点是需要大量的数据和仔细的调整才能生成高质量的文档向量,并且每个文档的表示是固定的,无法根据内容的内部变化进行调整。

三、深度探索:基于深度学习的嵌入方法

(九)InferSent

2017 年,Facebook 推出了 InferSent,这是一种通过在自然语言推理(NLI)数据集上进行监督学习来生成高质量句子嵌入的方法。InferSent 的目标是捕捉句子级别的语义细微差别,使其在语义相似性和文本蕴含等任务中表现出色。

InferSent 使用双向 LSTM 来处理句子,从两个方向捕捉上下文信息。通过监督学习,InferSent 能够将语义相似的句子在向量空间中拉得更近,从而提高在情感分析和释义检测等任务中的性能。

# 由于 InferSent 的实现较为复杂,建议参考以下 Kaggle Notebook 进行实现:
# https://www.kaggle.com/code/jeffd23/infer-sent-implementation

InferSent 的优点在于能够提供深度、上下文丰富的句子嵌入,并且在语义推理任务中表现优异。但它的缺点是需要大量的标注数据进行训练,并且计算资源需求较高。

(十)Universal Sentence Encoder(USE)

2018 年,Google 推出了 Universal Sentence Encoder(USE),这是一种用于生成高质量、通用句子嵌入的模型。USE 的目标是在各种 NLP 任务中表现出色,而无需进行大量的微调。它可以通过 Transformer 架构或深度平均网络(DAN)来编码句子。

import tensorflow_hub as hub
import tensorflow as tf
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA

# 加载模型
embed = hub.load("https://tfhub.dev/google/universal-sentence-encoder/4")
print("USE model loaded successfully!")

# 示例句子
sentences = [
    "Machine learning is fun.",
    "Artificial intelligence and machine learning are related.",
    "I love playing football.",
    "Deep learning is a subset of machine learning."
]

# 获取句子嵌入
embeddings = embed(sentences)
embeddings_np = embeddings.numpy()

# 打印嵌入形状和第一个句子的嵌入(截断)
print(f"Embedding shape: {embeddings_np.shape}")
print(f"First sentence embedding (truncated):\n{embeddings_np[0][:10]} ...")

# 计算两两余弦相似度
similarity_matrix = cosine_similarity(embeddings_np)
similarity_df = pd.DataFrame(similarity_matrix, index=sentences, columns=sentences)
print("\nSentence Similarity Matrix:\n")
print(similarity_df.round(2))

# 可视化句子嵌入(PCA 降维)
pca = PCA(n_compnotallow=2)
reduced = pca.fit_transform(embeddings_np)

plt.figure(figsize=(8, 6))
plt.scatter(reduced[:, 0], reduced[:, 1], color='blue')
for i, sentence in enumerate(sentences):
    plt.annotate(f"Sentence {i+1}", (reduced[i, 0]+0.01, reduced[i, 1]+0.01))
plt.title("Sentence Embeddings (PCA projection)")
plt.xlabel("PCA 1")
plt.ylabel("PCA 2")
plt.grid(True)
plt.show()

输出:

Embedding shape: (4, 512)
First sentence embedding (truncated):
[0.123, 0.456, 0.789, ...] ...

Sentence Similarity Matrix:
Machine learning is fun.                     1.00  0.85  0.20  0.30
Artificial intelligence and machine learning are related.  0.85  1.00  0.25  0.35
I love playing football.                     0.20  0.25  1.00  0.15
Deep learning is a subset of machine learning.  0.30  0.35  0.15  1.00

USE 的优点在于它的通用性和易用性,无需进行大量的任务特定调整即可在多种应用中发挥作用。但它的缺点是生成的句子嵌入是固定的,无法根据不同的上下文动态调整,并且某些变体的模型较大,可能会影响在资源受限环境中的部署。

(十一)Node2Vec

Node2Vec 是一种用于学习图结构中节点嵌入的方法,虽然它本身并不是一种文本表示方法,但在涉及网络或图数据的 NLP 任务中,如社交网络或知识图谱,它得到了越来越多的应用。

Node2Vec 通过在图上执行有偏随机游走来生成节点序列,然后使用类似 Word2Vec 的策略来学习低维节点嵌入。这种方法能够有效地捕捉图的局部和全局结构。

import networkx as nx
import numpy as np
from node2vec import Node2Vec
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA

# 创建一个简单的图
G = nx.karate_club_graph()  # 一个著名的测试图,包含 34 个节点

# 可视化原始图
plt.figure(figsize=(6, 6))
nx.draw(G, with_labels=True, node_color='skyblue', edge_color='gray', node_size=500)
plt.title("Original Karate Club Graph")
plt.show()

# 初始化 Node2Vec 模型
node2vec = Node2Vec(G, dimensinotallow=64, walk_length=30, num_walks=200, workers=2)

# 训练模型(底层使用 Word2Vec)
model = node2vec.fit(window=10, min_count=1, batch_words=4)

# 获取某个节点的嵌入
node_id = 0
vector = model.wv[str(node_id)]  # 注意:节点 ID 以字符串形式存储
print(f"Embedding for node {node_id}:\n{vector[:10]}...")  # 截断显示

# 获取所有嵌入
node_ids = model.wv.index_to_key
embeddings = np.array([model.wv[node] for node in node_ids])

# 降维到 2D
pca = PCA(n_compnotallow=2)
reduced = pca.fit_transform(embeddings)

# 可视化嵌入
plt.figure(figsize=(8, 6))
plt.scatter(reduced[:, 0], reduced[:, 1], color='orange')
for i, node in enumerate(node_ids):
    plt.annotate(node, (reduced[i, 0] + 0.05, reduced[i, 1] + 0.05))
plt.title("Node2Vec Embeddings (PCA Projection)")
plt.xlabel("PCA 1")
plt.ylabel("PCA 2")
plt.grid(True)
plt.show()

# 查找与节点 0 最相似的节点
similar_nodes = model.wv.most_similar(str(0), topn=5)
print("Nodes most similar to node 0:")
for node, score in similar_nodes:
    print(f"Node {node} → Similarity Score: {score:.4f}")

输出:

Embedding for node 0:
[0.123, 0.456, 0.789, ...]

Nodes most similar to node 0:
Node 1 → Similarity Score: 0.85
Node 2 → Similarity Score: 0.80
Node 3 → Similarity Score: 0.78

Node2Vec 的优点在于能够捕捉图结构中的丰富关系信息,并且可以应用于任何图结构数据。但它的缺点是对于非图结构的文本数据不太适用,并且嵌入的质量对随机游走的参数非常敏感。

(十二)ELMo(语言模型嵌入)

2018 年,艾伦人工智能研究所推出了 ELMo,这是一种突破性的方法,能够提供深度上下文化的单词表示。与早期的模型不同,ELMo 为每个单词生成动态嵌入,这些嵌入会根据句子的上下文发生变化,从而捕捉语法和语义的细微差别。

ELMo 使用双向 LSTM 来处理文本,从两个方向捕捉完整的上下文信息。它通过结合神经网络的多层表示,每层捕捉语言的不同方面,从而实现这一目标。

# ELMo 的实现较为复杂,建议参考以下文章进行实现:
# https://www.geeksforgeeks.org/elmo-embeddings-in-python/

ELMo 的优点在于它能够根据上下文动态调整单词嵌入,并且在情感分析、问答和机器翻译等多种任务中提高了性能。但它的缺点是计算资源需求较高,并且实现和调整相对复杂。

(十三)BERT 及其变体

BERT(双向编码器表示)是 Google 在 2018 年推出的一种基于 Transformer 的架构,它通过捕捉双向上下文彻底改变了 NLP 的格局。BERT 的出现使得模型能够同时考虑每个单词的左侧和右侧上下文,从而在问答、情感分析和命名实体识别等任务中表现出色。

BERT 的工作机制基于 Transformer 架构,它使用自注意力机制同时捕捉句子中所有单词之间的依赖关系。BERT 在预训练过程中随机掩盖某些单词,然后根据上下文预测这些单词,从而学习双向上下文。此外,BERT 还通过训练句子对来预测一个句子是否逻辑上跟随另一个句子,从而捕捉句子之间的关系。

from transformers import AutoTokenizer, AutoModel
import torch

# 输入句子
sentence = "Natural Language Processing is transforming how machines understand humans."

# 选择设备(如果有 GPU 则使用 GPU)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 加载 BERT 模型
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name).to(device)
model.eval()

# 分词
inputs = tokenizer(sentence, return_tensors='pt', truncatinotallow=True, padding=True).to(device)

# 前向传播获取嵌入
with torch.no_grad():
    outputs = model(**inputs)

# 获取单词嵌入
token_embeddings = outputs.last_hidden_state  # (batch_size, seq_len, hidden_size)

# 通过平均池化获取句子嵌入
sentence_embedding = torch.mean(token_embeddings, dim=1)
print(f"Sentence embedding from {model_name}:")
print(sentence_embedding)

输出:

Sentence embedding from bert-base-uncased:
tensor([[ 0.1234,  0.5678, -0.9012,  ...,  0.3456, -0.7890,  0.1111]])

BERT 的优点在于它能够生成更丰富、更细致的单词表示,并且可以通过少量的微调应用于各种下游任务。但它的缺点是计算资源需求高,模型参数多,部署在资源受限的环境中可能会有困难。

(十四)CLIP 和 BLIP

CLIP 和 BLIP 是现代多模态模型的代表,它们将文本和视觉数据结合起来,为涉及语言和图像的任务提供了强大的支持。这些模型在图像搜索、图像描述和视觉问答等应用中发挥着重要作用。

CLIP 通过在大规模图像-文本对数据集上进行对比学习,将图像嵌入和对应的文本嵌入对齐到一个共享的向量空间中。而 BLIP 则通过引导式训练方法进一步优化语言和视觉之间的对齐。

from transformers import CLIPProcessor, CLIPModel
from PIL import Image
import torch
import requests

# 加载模型和处理器
clip_model_name = "openai/clip-vit-base-patch32"
clip_model = CLIPModel.from_pretrained(clip_model_name).to(device)
clip_processor = CLIPProcessor.from_pretrained(clip_model_name)

# 加载示例图像和文本
image_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/datasets/cat_style_layout.png"
image = Image.open(requests.get(image_url, stream=True).raw).convert("RGB")
text = "a cute puppy"

# 预处理输入
inputs = clip_processor(text=[text], images=image, return_tensors="pt", padding=True).to(device)

# 获取文本和图像嵌入
with torch.no_grad():
    text_embeddings = clip_model.get_text_features(input_ids=inputs["input_ids"])
    image_embeddings = clip_model.get_image_features(pixel_values=inputs["pixel_values"])

# 归一化嵌入(可选)
text_embeddings = text_embeddings / text_embeddings.norm(dim=-1, keepdim=True)
image_embeddings = image_embeddings / image_embeddings.norm(dim=-1, keepdim=True)

print("Text Embedding Shape (CLIP):", text_embeddings.shape)
print("Image Embedding Shape (CLIP):", image_embeddings.shape)

输出:

Text Embedding Shape (CLIP): torch.Size([1, 512])
Image Embedding Shape (CLIP): torch.Size([1, 512])

CLIP 和 BLIP 的优点在于它们能够提供跨模态的强大表示,并且在多模态任务中表现出色。但它们的缺点是训练需要大量的配对数据,并且计算资源需求极高。

四、综合对比

序号

嵌入方法

类型

模型架构/方法

常见用途

1

Count Vectorizer

无上下文依赖,无机器学习

基于计数(词袋模型)

搜索、聊天机器人、语义相似性中的句子嵌入

2

One-Hot Encoding

无上下文依赖,无机器学习

手动编码

基线模型、基于规则的系统

3

TF-IDF

无上下文依赖,无机器学习

计数 + 逆文档频率

文档排名、文本相似性、关键词提取

4

Okapi BM25

无上下文依赖,统计排名

概率信息检索模型

搜索引擎、信息检索

5

Word2Vec(CBOW、SG)

无上下文依赖,基于机器学习

浅层神经网络

情感分析、单词相似性、NLP 流水线

6

GloVe

无上下文依赖,基于机器学习

全局共现矩阵 + 机器学习

单词相似性、嵌入初始化

7

FastText

无上下文依赖,基于机器学习

Word2Vec + 子词嵌入

丰富的形态语言、处理未登录词

8

Doc2Vec

无上下文依赖,基于机器学习

Word2Vec 的文档扩展

文档分类、聚类

9

InferSent

有上下文依赖,基于 RNN

带监督学习的双向 LSTM

语义相似性、自然语言推理任务

10

Universal Sentence Encoder

有上下文依赖,基于 Transformer

Transformer / 深度平均网络(DAN)

搜索、聊天机器人、语义相似性中的句子嵌入

11

Node2Vec

基于图的嵌入

随机游走 + Skipgram

图表示、推荐系统、链接预测

12

ELMo

有上下文依赖,基于 RNN

双向 LSTM

命名实体识别、问答、共指消解

13

BERT 及其变体

有上下文依赖,基于 Transformer

问答、情感分析、总结、语义搜索

问答、情感分析、总结、语义搜索

14

CLIP

多模态,基于 Transformer

视觉 + 文本编码器(对比学习)

图像描述、跨模态搜索、文本到图像检索

15

BLIP

多模态,基于 Transformer

视觉 - 语言预训练(VLP)

图像描述、视觉问答(VQA)

五、总结与展望

从基础的计数方法到如今的多模态深度学习模型,嵌入技术的演进历程充满了创新和突破。每一种方法都有其独特的优势和局限性,它们在不同的任务和场景中发挥着重要作用。

在实际应用中,选择合适的嵌入技术至关重要。如果你正在构建一个简单的聊天机器人,计数向量器或 TF-IDF 可能就足够了;如果你需要处理复杂的语义任务,BERT 或其变体可能是更好的选择;而如果你需要处理多模态数据,CLIP 和 BLIP 则是不可或缺的工具。

随着技术的不断发展,嵌入技术也在不断进化。未来,我们可以期待更高效、更智能的嵌入模型出现,它们将能够更好地理解和处理人类语言,为自然语言处理领域带来更多的可能性。

在这个充满挑战和机遇的时代,让我们一起探索嵌入技术的无限可能,用向量的力量点亮语言智能的未来!


本文转载自公众号Halo咯咯    作者:基咯咯

原文链接:​​https://mp.weixin.qq.com/s/3PQcxLgkri4zYqDtA8YxIg​


©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报
回复
相关推荐