解读 create_positive_map函数, GLIP 中实现文本-视觉对齐的关键函数。
函数功能
def create_positive_map(tokenized, tokens_positive):
"""construct a map such that positive_map[i,j] = True iff box i is associated to token j"""
positive_map = torch.zeros((len(tokens_positive), 256), dtype=torch.float)
创建一个映射矩阵,其中 positive_map[i,j] = 1表示第 i 个检测框与第 j 个文本 token 相关联。
参数说明
-
tokenized: 经过 tokenizer 处理的文本,包含字符到 token 的映射信息 -
tokens_positive: 实体在原始文本中的字符位置边界列表,格式如[[[start1, end1]], [[start2, end2]], ...]
执行流程详解
1. 初始化映射矩阵
positive_map = torch.zeros((len(tokens_positive), 256), dtype=torch.float)
-
创建形状为
(实体数量, 256)的零矩阵 -
256 是预设的最大 token 数量(BERT/CLIP tokenizer 的限制)
2. 遍历每个实体
for j, tok_list in enumerate(tokens_positive):
for (beg, end) in tok_list:
-
j: 实体索引(如第0个实体是"cat",第1个是"dog") -
(beg, end): 实体在原始文本中的字符位置范围
3. 字符位置到 token 位置的转换
beg_pos = tokenized.char_to_token(beg) # 实体起始字符对应的 token 索引
end_pos = tokenized.char_to_token(end - 1) # 实体结束字符对应的 token 索引
示例分析:
假设文本是 "a black cat and a white dog",提取出的实体:
-
tokens_positive = [[[2, 10]], [[18, 26]]]# "black cat" 和 "white dog"
转换过程:
文本: a black cat and a white dog
位置: 012345678901234567890123456
"black cat": beg=2, end=10 → tokens [1,2]
"white dog": beg=18, end=26 → tokens [5,6]
4. 边界情况处理
if beg_pos is None:
beg_pos = tokenized.char_to_token(beg + 1) # 尝试下一个字符
if end_pos is None:
end_pos = tokenized.char_to_token(end - 2) # 尝试前一个字符
处理特殊字符(如空格、标点)导致的映射失败。
5. 设置正例映射
positive_map[j, beg_pos: end_pos + 1].fill_(1)
将实体对应的所有 token 位置设为 1。
6. 归一化处理
return positive_map / (positive_map.sum(-1)[:, None] + 1e-6)
对每个实体的映射进行归一化,使每个实体对应的 token 权重之和为 1。
完整示例
输入:
text = "a black cat sitting on a mat"
tokenized = tokenizer([text], return_tensors="pt")
tokens_positive = [[[2, 10]], [[11, 18]], [[24, 27]]] # "black cat", "sitting", "mat"
处理过程:
-
字符位置转换:
-
"black cat" (2-10) → tokens [1,2]
-
"sitting" (11-18) → token [3]
-
"mat" (24-27) → token [6]
-
-
创建映射矩阵:
positive_map = [
[0, 1, 1, 0, 0, 0, 0, ...], # 实体0: "black cat" → tokens 1,2
[0, 0, 0, 1, 0, 0, 0, ...], # 实体1: "sitting" → token 3
[0, 0, 0, 0, 0, 0, 1, ...] # 实体2: "mat" → token 6
]
-
归一化后:
positive_map = [
[0, 0.5, 0.5, 0, 0, 0, 0, ...], # 两个token各占0.5权重
[0, 0, 0, 1.0, 0, 0, 0, ...], # 单个token权重为1.0
[0, 0, 0, 0, 0, 0, 1.0, ...] # 单个token权重为1.0
]
在模型中的作用
这个映射矩阵告诉模型:
-
哪些文本 token 对应哪些视觉实体
-
在计算视觉-语言相似度时,如何将图像区域与文本描述对齐
-
实现开放词汇检测的关键:让模型学习将检测到的区域与自由文本描述相关联
这就是 GLIP 能够实现"用任意文本检测任意物体"的核心技术之一。
3281

被折叠的 条评论
为什么被折叠?



