CLIP图生文

发布于:2024-04-26 ⋅ 阅读:(28) ⋅ 点赞:(0)

CLIP模型本身并不是图生文的,CLIP模型用来做图片和文本描述的匹配。
但它可以与其他技术结合使用来实现这一点,以下是两种常见的方法:

  1. CLIP作为文本灵感检索系统:

这种方法利用了 CLIP 在寻找图像和文本之间相似表示方面的优势。

步骤:
1.准备图像: 准备好要为其生成文本的图像。
2.使用 CLIP 对图像进行编码:使用 CLIP 的图像编码器部分生成图像的矢量表示。
3.搜索相似的文本嵌入: 搜索文本嵌入数据库(预先训练的文本编码)以查找最接近图像编码的文本嵌入。
4.使用检索到的文本获取灵感: 具有最接近嵌入的检索到的文本可以用作您自己的创意文本生成的起点,您可以使用此文本作为故事、诗歌或任何其他创意写作任务的灵感。

  1. CLIP 引导文本生成与附加模型:

这种方法将 CLIP 与单独的文本生成模型相结合,以实现更多控制:

需要:
CLIP模型:对图像进行编码并理解其内容。
文本生成模型:这可以是像 GPT-3 这样的预训练模型,也可以是您根据自己的文本数据训练的模型。
步骤:
1.使用 CLIP 对图像进行编码:与之前的方法类似,使用 CLIP 的图像编码器生成图像的矢量表示。
2.使用图像编码作为提示: 将图像编码与文本提示(可选)一起提供给文本生成模型。
3.生成文本:文本生成模型将使用提示和图像编码来创建与图像相关并遵循提示指导(如果提供)的新文本输出。

open_clip的generate函数已经实现了这一功能。
这里用COCO图片测试。

首先安装open_clip.

pip install open_clip_torch
import open_clip
import torch
from PIL import Image

model, _, transform = open_clip.create_model_and_transforms(
  model_name="coca_ViT-L-14",
  pretrained="mscoco_finetuned_laion2B-s13B-b90k"
)

im = Image.open("cat.jpg").convert("RGB")
im = transform(im).unsqueeze(0)

with torch.no_grad(), torch.cuda.amp.autocast():
  generated = model.generate(im)

print(open_clip.decode(generated[0]).split("<end_of_text>")[0].replace("<start_of_text>", ""))

这时候大概率会碰到如下error:

RuntimeError: Boolean value of Tensor with more than one value is ambiguous

这是transformer的问题,参见#860
一般会显示出现在coca_model.py, 点进去,这样修改即可。
在这里插入图片描述
看下测试结果:

在这里插入图片描述

coca_ViT-L-14的输出:

a white and brown dog with its tongue hanging out and a bowl of food in front of a person .

coca_ViT-B-32的输出:

a brown and white dog sitting on top of a bathroom floor .

如果你想finetune, 那么数据量一定要大。
准备一个csv文件,两列,一列是filepath, 一列是文本描述。
用COCO数据集的话csv可以自动生成。

当然首先要pip install clip_benchmark.

from clip_benchmark.datasets.builder import build_dataset
import pandas as pd
import os

root_path = "path/to/data/dir" # set this to smth meaningful
ds = build_dataset("mscoco_captions", root=root_path, split="train") # this downloads the dataset if it is not there already
coco = ds.coco
imgs = coco.loadImgs(coco.getImgIds())
future_df = {"filepath":[], "title":[]}
for img in imgs:
    caps = coco.imgToAnns[img["id"]]
    for cap in caps:
        future_df["filepath"].append(img["file_name"])
        future_df["title"].append(cap["caption"])
pd.DataFrame.from_dict(future_df).to_csv(
  os.path.join(root_path, "train2014.csv"), index=False, sep="\t"
)

用csv文件finetune, 数据集没有那么大的话可换成小一点的coca_ViT-B-32.

python -m training.main \
    --dataset-type "csv" \
    --train-data "path/to/data/dir/train2014.csv" \
    --warmup 1000 \
    --batch-size 128 \
    --lr 1e-5 \
    --wd 0.1 \
    --epochs 1 \
    --workers 3 \
    --model "coca_ViT-L-14" \
    --report-to "wandb" \
    --coca-contrastive-loss-weight 0 \
    --coca-caption-loss-weight 1 \
    --log-every-n-steps 100

还有其他方法也可由图生文,比如clip_interrogator。有web UI界面。

和上面同样的图片,生成结果如下:

there is a dog that is standing next to a person, unsplash photography, bowl filled with food, movie still of a snarling, as an offering to zeus, template layout, someone in home sits in bed, bite, stainless steel, short spout, chloe price

还可以参考CapDec,实现不同风格的text.
CLIP-Caption-Reward,用不同的reward训练生成Text.

想用中文版的CLIP看这里

一些好的CLIP应用可以参考Awesome-CLIP