CLIP模型的使用和训练-利用CLIP实现zero-shot的分类任务
CLIP模型
文章目录
- CLIP模型
- @[toc]
- 1 论文介绍
- 1.1 训练阶段
- 1.2 测试阶段
- 1.3 优缺点
- 1.4 官方给定的实验结果
- 2 利用CLIP做分类任务
- 2.1 识别杯子的二分类任务
- 2.2 人脸分类(celebface)
- 3 CLIP的再训练
1 论文介绍
官方网站
1.1 训练阶段
模型架构分为两部分,图像编码器和文本编码器,图像编码器可以是比如 resnet50,然后文本编码器可以是 transformer。
训练数据是网络社交媒体上搜集的图像文本对。在训练阶段,对于一个batch 的数据,首先通过文本编码器和图像编码器,得到文本和图像的特征,接着将所有的文本和图像特征分别计算内积,就能得到一个矩阵,然后从图像的角度看,行方向就是一个分类器,从文本角度看,列方向也是一个分类器。
而由于我们已经知道一个batch中的文本和图像的匹配关系,所以目标函数就是最大化同一对图像和文本特征的内积,也就是矩阵对角线上的元素,而最小化与不相关特征的内积。文章的作者从社交媒体上搜集了有大约4亿对的数据
1.2 测试阶段
在测试阶段,可以直接将训练好的CLIP用于其他数据集而不需要finetune。和训练阶段类似,首先将需要分类的图像经过编码器得到特征,然后对于目标任务数据集的每一个标签,或者你自己定义的标签,都构造一段对应的文本,如上图中的 dog 会改造成 “A photo of a dog”,以此类推。然后经过编码器得到文本和图像特征,接着将文本特征与图像特征做内积,内积最大对应的标签就是图像的分类结果。这就完成了目标任务上的 zero-shot 分类。
1.3 优缺点
- 千万不要被它zero-shot的能力吓到,这不是真正的zero-shot!在400M个文本图像配对的训练中,模型肯定看到了大量打着相关文本标签的图像,而且图像的应用范围比ImageNet要广得多——这也是为什么方法能够在一些高级场景(如clipart)轻松超越ImageNet预训练模型。但是要说这种方法碾压了有监督方法,就有点震惊体哗众取宠的意味了。
- 另一个耐人寻味的地方,是方法同时训练了图像和文本特征(感谢评论区 @llll 的提醒,一开始我看成只训练图像了)。我直觉地认为文本预训练特征比视觉预训练特征更可靠,但是作者却放弃了OpenAI祖传的超大的文本预训练模型,令人略感意外。尤其是,NLP的预训练模型体量远超视觉预训练模型,所以固定文本模型,也许是更实用的方法?
- 最让我感兴趣的问题,是图像和文本之间的交互方式。直接用文本的encoding结果做为图像的监督信号,显然噪声太大了;能否借鉴captioning等方向的做法,允许图像和文本在encoding过程中多次交互,从而提升效果?当然,这里还是涉及到语言模型太大,无法高效训练。不过,OpenAI也可以选择暴力出奇迹,直接从头训练大规模的跨模态预训练模型。只是这样做的话,400M的数据集可能就太小了。
- 再往深了说,NLP的预训练之所以能做得好,关键是pretext任务比较好。相比起来,CV还在苦苦寻找合适的pretext任务。当前我对跨模态的最大预期,就是能够在NLP的辅助下,定义CV的pretext任务。CLIP迈出了第一步,前面的路还长得很。
1.4 官方给定的实验结果
2 利用CLIP做分类任务
2.1 识别杯子的二分类任务
import os
import clip
import torch
from torchvision.datasets import CIFAR100
from PIL import Imageimg_pah = 'cup3.jpg'
classes = ['cup', 'not_cup']#加载模型
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load('ViT-B/32', device)#准备输入集
image = Image.open(img_pah)
image_input = preprocess(image).unsqueeze(0).to(device)
text_inputs = torch.cat([clip.tokenize(f"a photo of a {c}") for c in classes]).to(device) #生成文字描述#特征编码
with torch.no_grad():image_features = model.encode_image(image_input)text_features = model.encode_text(text_inputs)#选取参数最高的标签
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)
similarity = (100.0 * image_features @ text_features.T).softmax(dim=-1) #对图像描述和图像特征
values, indices = similarity[0].topk(1)#输出结果
print("\nTop predictions:\n")
print('classes:{} score:{:.2f}'.format(classes[indices.item()], values.item()))
针对与其他分类任务,只需要更改classes即可
2.2 人脸分类(celebface)
import os
from torch.utils.data import DataLoader
import clip
import torch
import torchvision
import timedevice = "cuda" if torch.cuda.is_available() else "cpu"def model_load(model_name):# 加载模型model, preprocess = clip.load(model_name, device) #ViT-B/32 RN50x16return model, preprocessdef data_load(data_path):#加载数据集和文字描述celeba = torchvision.datasets.CelebA(root='CELEBA', split='test', download=True)text_inputs = torch.cat([clip.tokenize(f"a photo of a {c}") for c in celeba.attr_names]).to(device)return celeba, text_inputsdef test_model(start, end, celeba, text_inputs, model, preprocess):#测试模型length = end - start + 1face_accuracy = 0face_score = 0for i, data in enumerate(celeba):face_result = 0if i < start:continueimage, target = dataimage_input = preprocess(image).unsqueeze(0).to(device)with torch.no_grad():image_features = model.encode_image(image_input)text_features = model.encode_text(text_inputs)image_features /= image_features.norm(dim=-1, keepdim=True)text_features /= text_features.norm(dim=-1, keepdim=True)text_probs = (100.0 * image_features @ text_features.T).softmax(dim=-1)top_score, top_label = text_probs.topk(6, dim=-1)for k, score in zip(top_label[0], top_score[0]):if k.item() < 40 and target[k.item()] == 1:face_result = 1face_score += score.item()print('Predict right! The predicted is {}'.format(celeba.attr_names[k.item()]))else:print('Predict flase! The predicted is {}'.format(celeba.attr_names[k.item()]))face_accuracy += face_resultif i == end:breakface_score = face_score / lengthface_accuracy = face_accuracy / lengthreturn face_score, face_accuracydef main():start = 0end = 1000model_name = 'ViT-B/32' #ViT-B/32 RN50x16data_path = 'CELEBA'time_start = time.time()model, preprocess = model_load(model_name)celeba, text_inputs = data_load(data_path)face_score, face_accuracy = test_model(start, end, celeba, text_inputs, model, preprocess)time_end = time.time()print('The prediction:')print('face_accuracy: {:.2f} face_score: {}%'.format(face_accuracy, face_score*100))print('runing time: %.4f'%(time_end - time_start))if __name__ == '__main__':main()
3 CLIP的再训练
from torch.utils.data import Dataset, DataLoader
import torch
import clip
from torch import nn, optim
import pandas as pd
from PIL import Image
import osdevice = 'cuda' if torch.cuda.is_available() else 'cpu'class image_caption_dataset(Dataset):def __init__(self, df, preprocess):self.images = df["image"]self.caption = df["caption"]self.preprocess = preprocessdef __len__(self):return len(self.caption)def __getitem__(self, idx):images = self.preprocess(Image.open(self.images[idx]))caption = self.caption[idx]return images, captiondef load_data(cup_path, cupnot_path, batch_size, preprocess):df = {'image': [], 'caption':[]}cup_list = os.listdir(cup_path)cupnot_list = os.listdir(cupnot_path)caption = cup_path.split('/')[-1]for img in cup_list:img_path = os.path.join(cup_path, img)df['image'].append(img_path)df['caption'].append(caption)caption = cupnot_path.split('/')[-1]for img in cupnot_list:img_path = os.path.join(cupnot_path, img)df['image'].append(img_path)df['caption'].append(caption)dataset = image_caption_dataset(df, preprocess)train_dataloader = DataLoader(dataset, batch_size=batch_size)return train_dataloaderdef convert_models_to_fp32(model):for p in model.parameters():p.data = p.data.float()p.grad.data = p.grad.data.float()def load_pretrian_model(model_path):model, preprocess = clip.load(model_path, device=device, jit=False) # 训练时 jit必须设置为falseif device == "cpu":model.float()else:clip.model.convert_weights(model)return model, preprocessdef train(epoch, batch_size, learning_rate, cup_path, cupnot_path):# 加载模型model, preprocess = load_pretrian_model('ViT-B/32')#加载数据集train_dataloader = load_data(cup_path, cupnot_path, batch_size, preprocess)#设置参数loss_img = nn.CrossEntropyLoss().to(device)loss_txt = nn.CrossEntropyLoss().to(device)optimizer = optim.Adam(model.parameters(), lr=learning_rate, betas=(0.9, 0.98), eps=1e-6, weight_decay=0.2)for i in range(epoch):for batch in train_dataloader:list_image, list_txt = batch # list_images is list of image in numpy array(np.uint8), or list of PIL images#list_image = list_image.to(device)texts = clip.tokenize(list_txt).to(device)images = list_image.to(device)logits_per_image, logits_per_text = model(images, texts)if device == "cpu":ground_truth = torch.arange(batch_size).long().to(device)else:#ground_truth = torch.arange(batch_size).half().to(device)ground_truth = torch.arange(batch_size, dtype=torch.long, device=device)#反向传播total_loss = (loss_img(logits_per_image, ground_truth) + loss_txt(logits_per_text, ground_truth)) / 2optimizer.zero_grad()total_loss.backward()if device == "cpu":optimizer.step()else:convert_models_to_fp32(model)optimizer.step()clip.model.convert_weights(model)print('[%d] loss: %.3f' %(i + 1, total_loss))torch.save(model, './model/model1.pkl')def main():epoch = 100batch_size = 6learning_rate = 5e-5cup_path = './data/It is photo with cup'cupnot_path = './data/It is photo without cup'train(epoch, batch_size, learning_rate, cup_path, cupnot_path)if __name__ == '__main__':main()
更新工程文件:
「CLIP」https://www.aliyundrive.com/s/mM8n836Km5M 提取码: te40
点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。
CLIP模型的使用和训练-利用CLIP实现zero-shot的分类任务相关推荐
- CVPR 2023 | 白翔团队提出:将CLIP模型用于场景文本检测
点击下方卡片,关注"CVer"公众号 AI/CV重磅干货,第一时间送达 点击进入->[计算机视觉]微信技术交流群 转载自:CSIG文档图像分析与识别专委会 本文简要介绍CV ...
- OpenAI发布CLIP模型快一年了,盘点那些CLIP相关让人印象深刻的工作
关注公众号,发现CV技术之美 ▊ 1.写在前面 2021过去了,在过去的一年了出现了许多优秀的论文.其中,令我印象最为深刻的莫过于年初OpenAI发布的CLIP模型,通过简单的对比学习预训练,就能在多 ...
- 【多模态】CLIP模型
Title: Learning transferable visual models from natural language supervision 作者:Alec Radford * 1 Jon ...
- 【VCED】Clip模型
CLIP 模型 CLIP模型将原有的图像标签替换为图像的文本描述信息,来监督视觉任务的训练,在下游任务中得到了较好的zero-shot的结果. 该模型将图像分类问题转换为图文匹配问题,在下游任务(以图 ...
- ECCV2022|港中文MM Lab证明Frozen的CLIP 模型是高效视频学习者
ECCV2022|港中文MM Lab证明Frozen的CLIP 模型是高效视频学习者 [写在前面] 视频识别一直以端到端学习范式为主--首先使用预训练图像模型的权重初始化视频识别模型,然后对视频进行端 ...
- 深度学习系列37:CLIP模型
1 模型说明 含义:CLIP(Contrastive Language-Image Pre-training) git地址:https://github.com/openai/CLIP paper:h ...
- 模型实践| CLIP 模型
实验|Aircloud 算力支持|幻方萤火二号 CLIP(Contrastive Language-Image Pre-Training,以下简称 CLIP) 模型是 OpenAI 在 2 ...
- DL之DNN:自定义2层神经网络TwoLayerNet模型(封装为层级结构)利用MNIST数据集进行训练、预测
DL之DNN:自定义2层神经网络TwoLayerNet模型(封装为层级结构)利用MNIST数据集进行训练.预测 导读 计算图在神经网络算法中的作用.计算图的节点是由局部计算构成的. ...
- DL之DNN:自定义2层神经网络TwoLayerNet模型(封装为层级结构)利用MNIST数据集进行训练、GC对比
DL之DNN:自定义2层神经网络TwoLayerNet模型(封装为层级结构)利用MNIST数据集进行训练.GC对比 导读 神经网络算法封装为层级结构的作用.在神经网络算法中,通过将 ...
最新文章
- HDU4716 A Computer Graphics Problem
- quickbuild php,QuickBooks API(php)集成
- [源码和文档分享]基于Java的带GUI界面猜数字游戏
- 数学--数论-- HDU 2601 An easy problem(约束和)
- bt云服务器地址,windows2008搭建bttracker服务器
- 重启php软重启_php-fpm 的重启方法(php7.3)
- 数据结构和算法系列13 五大查找之哈希查找
- 如何利用 Google 开源的 TFCO 构建机器学习模型?
- 一键安装thrift-0.9.0的脚本
- 佳博网口打印机驱动安装
- PMP考试今年改革吗?
- 手机变游戏机 N97/5800的GBA模拟器vBagx教程
- c51单片机矩阵键盘1602计算器_基于AT89C51单片机的十进制计算器系统设计
- oracle imp命令参数,oracle EXP/IMP 命令参数
- java动漫项目_狂拽酷炫diao炸天的开源动画项目:lottie-android,拿来就用!
- JAVA计算机毕业设计政府会议管理系统Mybatis+系统+数据库+调试部署
- Linux下让程序后台运行
- 联想数字化转型之路:从传统IT到“新IT”
- 南航计算机科学与技术学院院徽,南京航空航天大学计算机科学与技术学院简介...
- Android的涂鸦智能设备几种入网方式
热门文章
- pyton对txt文件的读取写入和加密(含代码)
- java计算机毕业设计Web企业差旅在线管理系统源码+mysql数据库+系统+lw文档+部署
- win7怎么修改系统语言
- hadoop快速自我学习--hadoop平台管理与维护
- html 调用safari,如何从托管在Web浏览器控件中的HTML中打开Safari中的链接?
- (Window环境) curl: (6) Could not resolve host: application curl: (6) Could not resolve host: ‘localhos
- B-spline Curves 学习之B样条曲线的移动控制点、修改节点分析(7)
- 谷歌手机地图中文java_谷歌地图开发(1)使用MapView显示地图
- 史上最全maven教程
- [18调剂]天津大学软件学院软件工程(专业学位)全日制及非全日制研究生接收院内校内校外调剂...