Chinese-CLIP使用教程

目录

一:运行环境

二:代码架构 

 三:数据集准备

1. 文本数据处理

训练集文本处理

测试集文本处理

2. 图像数据处理

3. 生成LMDB数据库

四、模型微调

五:模型验证与测试 

1. 提取图文特征

2. 图文检索

3. 计算召回率

六:总结 

路径问题


 

一:运行环境

        Chinese-CLIP的代码是在Ubuntu系统上运行的,运行方式是在命令行运行 .sh 脚本。

        配置环境的时候尽量不要 pip requestment.txt  ,(好像是会自动下载最高版本的torch,导致和CUDA不匹配),按照自己的CUDA版本下载对应的torch就好了。

二:代码架构 

        参考Github:

Chinese-CLIP/
├── run_scripts/
│   ├── muge_finetune_vit-b-16_rbt-base.sh
│   ├── flickr30k_finetune_vit-b-16_rbt-base.sh
│   └── ...           # 更多finetune或评测脚本...
└── cn_clip/
    ├── clip/
    ├── eval/
    ├── preprocess/
    └── training/

${DATAPATH}
├── pretrained_weights/
├── experiments/
├── deploy/          # 用于存放ONNX & TensorRT部署模型
└── datasets/
    └── MyData/          # 自定义数据集...

自定义数据集的组织方式参考Coco,我这里是这样的,ImageData里放的是图片,word_test.csv是文本内容。

 三:数据集准备

        Cn-CLIP训练和测试时,要把数据转为LMDB数据库文件,方便运行时的随机读取。而数据保存的形式是:文本存在 json 文件,图像使用base64格式存在tsv文件。所以先把文本处理为json,图像处理为tsv,然后进行序列化,转为LMDB。

        

1. 文本数据处理

        文本数据使用的是 json 格式,如果文本是保存在excel文件的话,那么就需要做相应的转换。Github上给出的 json 格式如下:

        可以看到 json 里面包括文本的 id ,文本内容,图片 id。如果是训练集的话,知道图文对应关系,那么可以按照上述格式转换;如果是测试集,其实是不知道图文对应关系的,那么就直接把图片 id 写成空列表就行了。处理代码如下:

训练集文本处理

        假设我训练集文本xlsx格式是这样

        那么我就自己构建一个text_id,按顺序标号12345...:

import pandas as pd
import json

'''训练集文本转为json'''
df = pd.read_excel("/MyData/train_texts.xlsx")
# 构建JSON数据
with open("./train_texts.jsonl", "w", encoding='utf-8') as outfile:
    text_id = 1
    for index, row in df.iterrows():
        image_names = row[0]
        text = row[1]
        image_ids = [image_names]
        json_row = {"text_id": text_id,"text": text,"image_ids": image_ids}
        json.dump(json_row, outfile, ensure_ascii=False)  # 写入单个 JSON 对象
        outfile.write('\n')  # 写入换行符,使得每个 JSON 对象占据一行
        text_id += 1
print("JSON Lines 文件已生成:train_texts.jsonl")

测试集文本处理

假设我测试集文本xlsx文件是这样,测试集不知道文本对应的图像id,image_ids写成空列表就行。

'''测试集文本转为json'''
df = pd.read_excel("MyData/test_texts.xlsx")
# 构建JSON数据
with open("./test_texts.jsonl", "w", encoding='utf-8') as outfile:
    for index, row in df.iterrows():
        text_id = row[0]
        text = row[1]
        image_ids = []
        json_row = {"text_id": text_id,"text": text,"image_ids": image_ids}
        json.dump(json_row, outfile, ensure_ascii=False)  # 写入单个 JSON 对象
        outfile.write('\n')  # 写入换行符,使得每个 JSON 对象占据一行
print("JSON Lines 文件已生成:test_texts.jsonl")

经过上面的操作,文本数据已经处理好了。

2. 图像数据处理

        Github的原话是 ”不是将图片以大量的小文件方式存放,而是将训练/验证/测试图片以base64形式分别存放在${split}_imgs.tsv文件中。文件每行表示一张图片,包含图片id(int型)与图片base64,以tab隔开,格式如下:

        

        假设我这里原本数据集的图像是以小文件方式保存的,例如

 那就先把图片转为base64格式,保存到 tsv 文件中,代码如下:实际使用按照自己的存储路径修改路径就行了

from PIL import Image
import io
import base64
import csv
import os
import json
"""将图片转换为base64格式"""

# 定义存储图像的文件夹路径
folder_path = "MyData/ImageData"  
# 准备写入的TSV文件路径
tsv_file_path = "MyData/test_imgs.tsv"  

# 打开或创建TSV文件,并写入列名
with open(tsv_file_path, "w", newline='') as tsvfile:
    writer = csv.writer(tsvfile, delimiter='\t')

    # 遍历文件夹中的图片文件
    for filename in os.listdir(folder_path):
        if filename.endswith(".jpg") or filename.endswith(".png") or filename.endswith(".jpeg"):  # 仅处理图片文件
            # 构建图片文件的完整路径
            image_path = os.path.join(folder_path, filename)
            # 打开图片文件
            with Image.open(image_path) as img:
                # 将图片转换为Base64编码字符串
                img_buffer = io.BytesIO()
                img.save(img_buffer, format=img.format)
                byte_data = img_buffer.getvalue()
                base64_str = base64.b64encode(byte_data).decode("utf-8")
                # 写入文件名和Base64编码字符串到TSV文件中
                writer.writerow([filename, base64_str])
                # print(filename)
print("Base64编码结果已写入到TSV文件中:", tsv_file_path)

到这里已经把数据集格式处理完了:文本是json文件,图像是tsv文件。接下来进行序列化,转为LMDB数据库文件。

3. 生成LMDB数据库

        这个代码GitHub有给,代码是在cn-clip/preprocess文件夹下的build_lmdb_dataset.py,

修改一下参数如下:


def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--data_dir", type=str, default='/MyData/', help="the directory which stores the image tsvfiles and the text jsonl annotations"
    ) #路径
    parser.add_argument(
        "--splits", type=str, default="test", help="specify the dataset splits which this script processes, concatenated by comma \
            (e.g. train,valid,test)"
    )# 选择是训练集还是验证集还是测试集
    parser.add_argument(
        "--lmdb_dir", type=str, default=None, help="specify the directory which stores the output lmdb files. \
            If set to None, the lmdb_dir will be set to {args.data_dir}/lmdb"
    )#不用写 默认生成在MyData文件夹下
    return parser.parse_args()

四、模型微调

        如果是本地单卡训练,修改shell脚本部分参数如下:


# Number of GPUs per GPU worker
GPUS_PER_NODE=1
# Number of GPU workers, for single-worker training, please set to 1
WORKER_CNT=1
# The ip address of the rank-0 worker, for single-worker training, please set to localhost
export MASTER_ADDR=localhost
# The port for communication
export MASTER_PORT=8514
# The rank of this worker, should be in {0, ..., WORKER_CNT-1}, for single-worker training, please set to 0
export RANK=0 

export PYTHONPATH=${PYTHONPATH}:`pwd`/cn_clip/

# data options
train_data=${DATAPATH}xxx/MyData/lmdb/train   #这里的xxx是要改成绝对路径 下面一样
val_data=${DATAPATH}xxx/MyData//lmdb/val # if val_data is not specified, the validation will be automatically disabled
path to resume
reset_data_offset="--reset-data-offset"
reset_optimizer="--reset-optimizer"
# reset_optimizer=""

# output options
output_base_dir=${DATAPATH}xxx/MyData/experiments/ #xxx是绝对路径

        然后在命令行cd到Chinese-CLIP文件夹,运行下面这行代码

bash run_scripts/muge_finetune_vit-b-16_rbt-base.sh ${DataPath}

        关于训练过程中如果出现其它的bug,需要自己慢慢调试了,基本上都是对training文件夹下的py文件做一些小修改。

五:模型验证与测试 

        训练完后权重会保存到 MyData/experiments/里面的checkpoints文件夹下。

1. 提取图文特征

        这一步图搜文和文搜图,用的是一样的代码,都是要先对图片和文本提取特征,然后后面再进行相似度计算。代码是cn_clip/eval/文件夹下的extract_features.py ,根据注释直接在py文件里修改好参数。注意要将extract-image-feats和extract-text-feats参数设为True,才能开始提取特征。提取完后是保存在两个jsonl文件里的,这两个jsonl文件应该是默认保存在MyData文件夹下。

2. 图文检索

        检索部分的代码是分开的,都在cn_clip/eval/文件夹下。文搜图是make_topk_predictions.py文件,图搜文是make_topk_predictions_tr.py文件。这里也是把提取的特征的两个jsonl文件填到路径里,然后设置一下输出的结果的路径。

        检索完成后的结果保存在设置的输出路径中,是 jsonl 文件格式。 

3. 计算召回率

        代码都在cn_clip/eval/文件夹下,用evaluation.py计算文搜图的recall,evaluation_tr.py计算图搜文的recall。

        standard_path = sys.argv[1]可以把sys.argv[1]改成本地的文件地址sys.argv[2]和[3]同理。

        使用evaluation_tr.py前需要先通过 transform_ir_annotation_to_tr.py 把 train_texts.jsonl(就是图文对应的那个json文件)由文到图的格式转为图到文。

六:总结 

1.用Make_json.py将xlsx里的文本转换成json格式(对于测试集只有文本,不知道图文对匹配关系的情况,每行的image_ids字段处理为空列表即可,即"image_ids": []);
用Img2base64将图片编码成base64格式(.tsv文件)

2.用build_Imdb_dataset.py把.tsv和.json文件转换为内存索引的LMDB数据库文件

2.5.对模型进行finetune(微调)。(可以不进行,直接用预训练模型)

3.用extrac_features.py提取图文特征得到train_texts.txt_feat.jsonl和train_imgs.img_feat.jsonl
注意文本最大字长设置为finetune时的一样,不然会影响准确率

4.用make_topk_predictions.py进行文到图检索(文本召回相关图片)通过3得到的两个jsonl文件得到train_predictions.jsonl;
用make_topk_predictions_tr.py进行图到文检索(图片召回相关文本)通过3得到的两个jsonl文件得到train_predictions_tr.jsonl
检索是利用提取出的图像特征和文本特征计算相似度,然后对相似度进行排序。

5.用evaluation.py计算文搜图的recall,evaluation_tr.py计算图搜文的recall。(transform_ir_annotation_to_tr.py用来把
train_texts.jsonl由文到图的格式转为图到文)
standard_path = sys.argv[1]可以把sys.argv[1]改成本地的文件地址sys.argv[2]和[3]同理r

路径问题

如果运行eval文件夹里的文件,找不到cn_clip,路径有问题的话,可以加上

import os
import sys

# 获取当前脚本所在的目录路径
current_directory = os.path.dirname(__file__)

# 找到 cn_clip 文件夹的路径
cn_clip_path = os.path.abspath(os.path.join(current_directory, '..', '..'))  # 假设 cn_clip 文件夹在 eval 文件夹的上两级目录中

 

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值