输入相同图像时为何Google ViT的last_hidden_state与hidden_states[-1]不相等
这是Hugging Face Transformers库对ViT和BERT的架构实现差异导致的,核心原因如下:
- ViT的最终输出前存在独立的顶层LayerNorm层:ViT的计算流程为「输入嵌入 → N个Transformer Block依次计算 → 最终LayerNorm层」,其中
hidden_states列表存储的是「输入嵌入结果 + 每一个Transformer Block的输出结果」,hidden_states[-1]是最后一个Transformer Block的原始输出,还没有经过最终的顶层LayerNorm计算;而last_hidden_state是经过顶层LayerNorm之后的最终输出,二者自然数值不同。 - BERT架构无额外顶层LayerNorm:BERT的LayerNorm逻辑封装在每一个Transformer Block内部,最后一个Transformer Block的输出就是最终的隐藏状态,所以
hidden_states[-1]和last_hidden_state完全相等。
验证方法
你可以手动将hidden_states[-1]传入ViT的顶层LayerNorm计算,即可得到和last_hidden_state完全一致的结果,测试代码如下:
import torch from transformers import ViTFeatureExtractor, ViTModel feature_extractor = ViTFeatureExtractor.from_pretrained('google/vit-base-patch16-224-in21k') model = ViTModel.from_pretrained('google/vit-base-patch16-224-in21k') inputs = feature_extractor(images=[image], return_tensors="pt") outputs = model(pixel_values=inputs['pixel_values'], output_hidden_states=True) vec1 = outputs.hidden_states[-1] vec2 = outputs.last_hidden_state # 手动过顶层LayerNorm vec1_normed = model.layernorm(vec1) # 此时vec1_normed和vec2数值完全相等 print(torch.allclose(vec1_normed, vec2)) # 输出为True
内容的提问来源于stack exchange,提问作者Sheng You
相关产品推荐
相关产品推荐

