从文字到向量:Transformer的语言数字化之旅

简介: 向量化是将文字转化为数学向量的过程,使计算机能理解语义。通过分词、构建词汇表、词嵌入与位置编码,文本被映射到高维空间,实现语义相似度计算、搜索、分类等智能处理,是NLP的核心基础。

一、什么是向量化?

核心定义

向量化是将离散的符号(如文字)转换为连续的数值向量的过程。在深度学习中,它把人类可读的文本转换成计算机能够理解和处理的数学表示。

生动比喻:语言翻译成数学坐标

想象每个词在一个高维空间中的位置:

  • 传统词典:用文字解释文字
  • 向量空间:用数学坐标精确定位每个词的含义
"国王" → [0.8, -0.2, 0.5, 0.1, ...]
"皇后" → [0.7, -0.3, 0.6, 0.2, ...]
"男人" → [0.6, 0.1, 0.3, -0.4, ...]
"女人" → [0.5, 0.2, 0.4, -0.3, ...]

向量化的神奇特性


二、从文字到向量化的完整过程

整体流程概览

步骤1:分词 - 文本的"原子化"

基本分词方法

# 原始文本
text = "I love natural language processing!"
# 简单空格分词
tokens = text.split()
print(tokens)  # ['I', 'love', 'natural', 'language', 'processing!']
# 实际使用分词器
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
tokens = tokenizer.tokenize(text)
print(tokens)  # ['i', 'love', 'natural', 'language', 'processing', '!']

不同分词策略对比

分词方法

示例输入

输出结果

优缺点

单词级

"I'm learning NLP"

["I'm", "learning", "NLP"]

词汇表大,OOV问题

子词级

"I'm learning NLP"

["I", "'", "m", "learn", "##ing", "NL", "##P"]

平衡词汇表与OOV

字符级

"I'm learning NLP"

["I", "'", "m", " ", "l", "e", ...]

词汇表小,序列长

分词粒度比喻:乐高积木组装

  • 单词级:使用完整的大型积木块
  • 优点:表达完整,组合简单
  • 缺点:需要大量存储空间,缺少灵活性
  • 子词级:使用标准尺寸的中型积木
  • 优点:灵活组合,经济高效
  • 缺点:需要学习组合规则
  • 字符级:使用最小的基础积木单元
  • 优点:极简存储,无限组合
  • 缺点:组装复杂,效率较低

步骤2:构建词汇表 - 创建"词库字典"

词汇表构建过程

# 假设我们有训练语料
corpus = [
    "I love machine learning",
    "Deep learning is amazing", 
    "Natural language processing transforms AI"
]
# 构建词汇表
vocab = {}
for sentence in corpus:
    tokens = sentence.lower().split()
    for token in tokens:
        vocab[token] = vocab.get(token, 0) + 1
# 按频率排序并分配ID
sorted_vocab = sorted(vocab.items(), key=lambda x: x[1], reverse=True)
vocab_with_ids = {word: idx for idx, (word, _) in enumerate(sorted_vocab)}
print("词汇表:", vocab_with_ids)
# 输出: {'learning': 0, 'i': 1, 'love': 2, 'machine': 3, 
#        'deep': 4, 'is': 5, 'amazing': 6, 'natural': 7, 
#        'language': 8, 'processing': 9, 'transforms': 10, 'ai': 11}

实际Transformer词汇表示例

# BERT-base的词汇表大小
vocab_size = 30522  # 包含30522个token
# GPT-3的词汇表大小  
gpt3_vocab_size = 50257  # 包含50257个token
# 实际使用中的token到ID映射
token_ids = tokenizer.encode("Hello world!")
print("Token IDs:", token_ids)  # [101, 7592, 2088, 102]
# 反向解码
decoded_text = tokenizer.decode([101, 7592, 2088, 102])
print("Decoded:", decoded_text)  # "[CLS] hello world! [SEP]"

步骤3:词嵌入 - 从离散到连续的魔法

词嵌入的核心思想

词嵌入将离散的token ID映射到连续的向量空间:

离散ID: [101, 7592, 2088, 102] 
     ↓ 嵌入矩阵查找
连续向量: 
    [0.1, 0.4, -0.2, ..., 0.8]   # CLS token
    [0.3, -0.1, 0.5, ..., 0.2]   # "hello" 
    [-0.2, 0.6, 0.1, ..., -0.3]  # "world"
    [0.4, 0.2, -0.3, ..., 0.6]   # SEP token

代码实现词嵌入层

import torch
import torch.nn as nn
import numpy as np
class TokenEmbedding(nn.Module):
    def __init__(self, vocab_size, embedding_dim):
        super().__init__()
        self.embedding = nn.Embedding(vocab_size, embedding_dim)
        
    def forward(self, token_ids):
        # token_ids: [batch_size, seq_len]
        # 返回: [batch_size, seq_len, embedding_dim]
        return self.embedding(token_ids)
# 实际使用示例
vocab_size = 50000
embedding_dim = 512  # 常见维度: 512, 768, 1024
embedding_layer = TokenEmbedding(vocab_size, embedding_dim)
# 输入: 批次大小为2, 序列长度为5
input_ids = torch.tensor([
    [101, 7592, 2088, 102, 0],   # 句子1
    [101, 4875, 2031, 102, 0]    # 句子2
])
# 获取词嵌入
word_embeddings = embedding_layer(input_ids)
print("嵌入形状:", word_embeddings.shape)  # torch.Size([2, 5, 512])

词嵌入的可视化理解

词向量的语义特性

经过训练后,词向量会捕捉丰富的语义关系:

# 语义关系的向量运算示例
def analogical_reasoning(embedding_layer, word1, word2, word3, word_to_id):
    # 获取词向量
    vec1 = embedding_layer(torch.tensor([word_to_id[word1]]))
    vec2 = embedding_layer(torch.tensor([word_to_id[word2]])) 
    vec3 = embedding_layer(torch.tensor([word_to_id[word3]]))
    
    # 类比推理: king - man + woman ≈ queen
    result_vector = vec1 - vec2 + vec3
    
    # 在实际中,我们会计算与所有词向量的相似度
    # 找到最接近的结果词
    return result_vector
# 实际中,这种语义关系是通过大规模训练自然涌现的

步骤4:位置编码 - 注入顺序信息

为什么需要位置编码?

由于Transformer的自注意力机制是置换不变的(打乱输入顺序可能得到相同输出),需要显式注入位置信息。

正弦位置编码

import math
def sinusoidal_positional_encoding(seq_len, d_model):
    """
    生成正弦位置编码
    seq_len: 序列长度
    d_model: 模型维度(嵌入维度)
    """
    position = torch.arange(seq_len).unsqueeze(1)
    div_term = torch.exp(torch.arange(0, d_model, 2) * 
                        -(math.log(10000.0) / d_model))
    
    pe = torch.zeros(seq_len, d_model)
    pe[:, 0::2] = torch.sin(position * div_term)  # 偶数维度
    pe[:, 1::2] = torch.cos(position * div_term)  # 奇数维度
    
    return pe
# 示例:生成长度为10,维度为512的位置编码
pos_encoding = sinusoidal_positional_encoding(10, 512)
print("位置编码形状:", pos_encoding.shape)  # torch.Size([10, 512])

位置编码的可视化

完整的位置感知嵌入

class TransformerInputEmbedding(nn.Module):
    def __init__(self, vocab_size, d_model, max_seq_len=512):
        super().__init__()
        self.token_embedding = nn.Embedding(vocab_size, d_model)
        self.position_embedding = nn.Parameter(
            torch.zeros(1, max_seq_len, d_model)
        )
        self.layer_norm = nn.LayerNorm(d_model)
        self.dropout = nn.Dropout(0.1)
        
    def forward(self, token_ids):
        # 词嵌入
        token_embeddings = self.token_embedding(token_ids)
        
        # 位置嵌入(截取到实际序列长度)
        seq_len = token_ids.size(1)
        position_embeddings = self.position_embedding[:, :seq_len, :]
        
        # 相加并归一化
        embeddings = token_embeddings + position_embeddings
        embeddings = self.layer_norm(embeddings)
        embeddings = self.dropout(embeddings)
        
        return embeddings

步骤5:完整流程代码示例

import torch
import torch.nn as nn
class CompleteTextToVector(nn.Module):
    def __init__(self, vocab_size, d_model=512, max_seq_len=512):
        super().__init__()
        self.d_model = d_model
        
        # 1. 词嵌入层
        self.token_embedding = nn.Embedding(vocab_size, d_model)
        
        # 2. 位置编码(可学习或正弦)
        self.position_embedding = nn.Parameter(
            torch.randn(1, max_seq_len, d_model)
        )
        
        # 3. 层归一化和dropout
        self.layer_norm = nn.LayerNorm(d_model)
        self.dropout = nn.Dropout(0.1)
    
    def forward(self, input_ids):
        batch_size, seq_len = input_ids.shape
        
        # 词嵌入查找
        token_embeds = self.token_embedding(input_ids)  # [batch, seq_len, d_model]
        
        # 添加位置信息
        position_embeds = self.position_embedding[:, :seq_len, :]
        embeddings = token_embeds + position_embeds
        
        # 归一化和正则化
        embeddings = self.layer_norm(embeddings)
        embeddings = self.dropout(embeddings)
        
        return embeddings
# 使用示例
vocab_size = 50000
model = CompleteTextToVector(vocab_size)
# 模拟输入:批次大小=2, 序列长度=8
input_ids = torch.randint(0, vocab_size, (2, 8))
# 转换为向量
output_vectors = model(input_ids)
print("输入形状:", input_ids.shape)      # torch.Size([2, 8])
print("输出形状:", output_vectors.shape) # torch.Size([2, 8, 512])

三、不同嵌入策略的对比

静态vs动态词嵌入

对比表格

特性

传统静态嵌入

Transformer动态嵌入

上下文处理

每个词固定向量

根据上下文动态调整

多义词处理

一个向量表示所有含义

不同上下文不同向量

训练方式

预训练后固定

端到端联合训练

示例

Word2Vec, GloVe

BERT, GPT, T5

向量质量

"bank"只有一个向量

"river bank"和"money bank"向量不同

四、向量化的意义与价值

1.语义空间的几何结构

经过良好训练的向量空间具有优美的数学结构:

语义相近 → 向量距离近
语义相反 → 向量方向相反
语义关系 → 向量运算可表达

2.模型能力的基石

3.实际应用价值

  • 相似度计算:通过余弦相似度比较文本相似度
  • 语义搜索:在向量空间中快速检索相关文档
  • 文本分类:基于向量表示进行情感分析、主题分类
  • 机器翻译:在不同语言的向量空间之间建立映射

总结:数字化的语言革命

文字向量化不仅是技术实现,更是思维范式的转变

从符号到向量的哲学意义

  • 传统语言学:研究符号之间的关系和规则
  • 向量语义学:在连续空间中捕捉语义的相似性和关联性

技术演进的价值

这个过程让计算机从字面理解进化到语义理解,从规则驱动进化到数据驱动,最终实现了真正意义上的语言智能。

向量化就像为人类语言和计算机思维之间搭建了一座桥梁,让两种完全不同的"思维方式"能够相互理解和沟通。这正是现代自然语言处理技术能够取得突破性进展的根本基础。

相关文章
|
20天前
|
机器学习/深度学习 人工智能 自然语言处理
GPT与BERT深度解析:Transformer的双子星架构
GPT基于Transformer解码器,擅长文本生成;BERT基于编码器,专注文本理解。二者在架构、注意力机制和训练目标上差异显著,分别适用于生成与理解任务,体现了AI智能的多元化发展。
|
20天前
|
存储 机器学习/深度学习 自然语言处理
Transformer参数规模深度解析:从模型聪明说到实际影响
Transformer参数规模显著影响模型能力,参数越多,知识容量与模式识别能力越强,但存在边际效应和过拟合风险。现代大模型通过混合专家、量化压缩等技术提升参数效率,未来趋势是优化参数使用而非盲目扩大规模,实现性能与效率的平衡。(238字)
|
19天前
|
机器学习/深度学习 人工智能 负载均衡
MoE架构:大模型的规模扩展革命
MoE(混合专家)架构通过稀疏激活多个专业化子网络,实现高效计算与大规模模型的结合,提升训练推理效率及模型可扩展性,成为大模型发展的重要范式。
|
9天前
|
弹性计算 搜索推荐 异构计算
租用阿里云服务器一年要多少钱?2025年费用价格全解析
2025年阿里云服务器优惠持续,轻量应用服务器2核2G 200M带宽38元/年起,ECS经济型e实例2核2G 3M带宽99元/年,u1实例2核4G 5M带宽199元/年,4核16G和8核32G低至89元/月起,新老用户同享,续费不涨价。
442 143
|
7天前
|
XML 机器学习/深度学习 监控
高级检索增强生成系统:LongRAG、Self-RAG 和 GraphRAG 的实现与选择
检索增强生成(RAG)已超越简单向量匹配,迈向LongRAG、Self-RAG与GraphRAG等高级形态。LongRAG通过大块重叠分片保留长上下文,提升连贯性;Self-RAG引入反思机制,动态判断检索必要性与内容相关性,增强可信度;GraphRAG构建知识图谱,支持多跳推理与复杂关系挖掘。三者分别应对上下文断裂、检索盲目性与关系表达缺失难题,代表2025年RAG工程化核心进展,可依场景组合使用以平衡准确性、成本与复杂度。
166 57
高级检索增强生成系统:LongRAG、Self-RAG 和 GraphRAG 的实现与选择
|
4天前
|
数据采集 人工智能 JavaScript
双解析引擎VS单一架构:DataEyes如何用视觉革命重塑AI数据基建
Jina与DataEyes代表AI数据工具两大技术路径。本文从架构、场景、赋能三维度对比,揭示DataEyes如何通过“视觉+代码”双模解析,提升动态数据捕获效率,实现电商、金融、农业等多行业落地,推动企业级数据获取迈向自动化与智能化。
197 154
|
23天前
|
SQL 运维 关系型数据库
云数据库 Clouder 认证:SQL 基础开发与应用题型分析
阿里云Clouder认证(数据库方向)考察SQL基础开发与应用能力,涵盖DDL/DML操作、多表查询、聚合统计、子查询等高频题型。考试以MySQL实操为主,注重语法准确性与逻辑严谨性,适合开发者、运维及数据工程师备考。
295 162
|
17天前
|
人工智能 弹性计算 安全
阿里云无影云电脑价格:企业版费用、个人版收费及免费无影云电脑申请流程
阿里云无影云电脑提供企业版与个人版,企业版4核8G低至199元/年,支持办公及GPU设计;个人版黄金款14元/月起,最高黑金款149元/月,畅享云游戏与AI开发。另有免费试用1个月可申请。
688 158
|
12天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
663 219