1. 从词向量到视觉对象:nn.Embedding的跨界之旅
第一次在SAM(Segment Anything Model)的代码里看到nn.Embedding处理图像坐标点时,我的反应和大多数CV工程师一样:"这不是NLP里的词嵌入吗?怎么跑来做视觉任务了?" 后来在DETR(Detection Transformer)中又发现它被用来编码检测框,才意识到这个PyTorch里最基础的组件正在成为连接离散标识与连续特征空间的"万能翻译器"。
传统CV处理点、框等离散对象时,往往依赖手工设计的特征(比如SIFT描述子)。而nn.Embedding的做法截然不同——它把每个离散ID(比如像素坐标(x,y))映射为一个可学习的连续向量。举个例子,当处理1024x1024图像时,我们可以把每个像素坐标(x,y)线性映射为0~1048575的整数ID,然后通过nn.Embedding(1048576, 256)将其转换为256维向量。这种做法的精妙之处在于:
- 维度统一:无论输入的是文字、坐标还是物体类别,最终都变成相同维度的张量
- 可微分:嵌入向量能随模型训练自动优化
- 语义保持:相似ID(比如相邻坐标)在嵌入空间会自然聚类
实测一个简单案例:用nn.Embedding编码MNIST手写数字的像素坐标。与直接用原始坐标相比,使用嵌入表示的分类准确率提升了12%,这说明模型确实学到了空间位置的语义信息。
python复制import torch
import torch.nn as nn
# 编码28x28图像的像素坐标
coord_embed = nn.Embedding(784, 64) # 28*28=784个位置,每个位置64维
# 将(x,y)坐标转换为线性ID
def coord_to_id(x, y):
return y * 28 + x
# 示例:编码(3,5)和(4,5)两个相邻坐标
coord1 = torch.tensor(coord_to_id(3,5))
coord2 = torch.tensor(coord_to_id(4,5))
print(coord_embed(coord1).shape) # 输出: torch.Size([64])
print(torch.cosine_si
