Learning Transferable Visual Models From Natural Language Supervision
link
CLIP 全稱 Contrastive Language-Image Pre-training
TL;DR
一種使用圖文對做預訓練的方法,影響力:打破傳統人工標準類別Label的預訓練方式。
Method
訓練階段:將圖文樣本對分別過Encoder抽取特徵,一個大小為N的Batch內,屬於同一組圖文對為正樣本對共N組,不同圖文組成樣本對為負樣本共N^2 - N組,以此構建對比學習Loss。
推理階段:將目標測試集所有類別標籤使用Text Encoder抽取Embedding特徵,影像特徵用KNN來預測對應標籤。
Code
論文中虛擬碼看得不是很明白,直接上原始碼:open_clip
Q:為什麼需要算兩次cross_entropy_loss然後再相加?
A:為了讓每個樣本能在其它卡的Batch中獲取到更多的負樣本對。比如,Text做為query時將其它卡的影像特徵都拿到做負樣本對,Image作Query時也把其它卡上的Text特徵作為負樣本對,那麼這個兩個Loss的值自然就不一樣了。
def get_logits(self, image_features, text_features, logit_scale):
if self.world_size > 1:
all_image_features, all_text_features = gather_features(
image_features, text_features,
self.local_loss, self.gather_with_grad, self.rank, self.world_size, self.use_horovod)
if self.local_loss:
logits_per_image = logit_scale * image_features @ all_text_features.T
logits_per_text = logit_scale * text_features @ all_image_features.T
else:
logits_per_image = logit_scale * all_image_features @ all_text_features.T
logits_per_text = logits_per_image.T
else:
logits_per_image = logit_scale * image_features @ text_features.T
logits_per_text = logit_scale * text_features @ image_features.T
return logits_per_image, logits_per_text
def forward(self, image_features, text_features, logit_scale, output_dict=False):
device = image_features.device
logits_per_image, logits_per_text = self.get_logits(image_features, text_features, logit_scale)
labels = self.get_ground_truth(device, logits_per_image.shape[0])
total_loss = (
F.cross_entropy(logits_per_image, labels) +
F.cross_entropy(logits_per_text, labels)
) / 2
return {"contrastive_loss": total_loss} if output_dict else total_loss
Experiment
ZeroShot效果已經超過FewShot Of其它SSL預訓練方法了。
Conclusion
1.CLIP能充分利用大量圖文樣本作為影像與文字Encoder的預訓練資料。
2.文章實驗部分花了比較大篇幅證明了CLIP預訓練的影像Encoder有SOTA級別的表徵能力。
3.這種混合模態的預訓練方式,在後續跨模態特徵對齊過程中被廣泛使用。