当前位置:   article > 正文

Chinese-CLIP使用教程_chineseclip

chineseclip

目录

一:运行环境

二:代码架构 

 三:数据集准备

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...:

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

测试集文本处理

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

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

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

2. 图像数据处理

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

        

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

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

  1. from PIL import Image
  2. import io
  3. import base64
  4. import csv
  5. import os
  6. import json
  7. """将图片转换为base64格式"""
  8. # 定义存储图像的文件夹路径
  9. folder_path = "MyData/ImageData"
  10. # 准备写入的TSV文件路径
  11. tsv_file_path = "MyData/test_imgs.tsv"
  12. # 打开或创建TSV文件,并写入列名
  13. with open(tsv_file_path, "w", newline='') as tsvfile:
  14. writer = csv.writer(tsvfile, delimiter='\t')
  15. # 遍历文件夹中的图片文件
  16. for filename in os.listdir(folder_path):
  17. if filename.endswith(".jpg") or filename.endswith(".png") or filename.endswith(".jpeg"): # 仅处理图片文件
  18. # 构建图片文件的完整路径
  19. image_path = os.path.join(folder_path, filename)
  20. # 打开图片文件
  21. with Image.open(image_path) as img:
  22. # 将图片转换为Base64编码字符串
  23. img_buffer = io.BytesIO()
  24. img.save(img_buffer, format=img.format)
  25. byte_data = img_buffer.getvalue()
  26. base64_str = base64.b64encode(byte_data).decode("utf-8")
  27. # 写入文件名和Base64编码字符串到TSV文件中
  28. writer.writerow([filename, base64_str])
  29. # print(filename)
  30. print("Base64编码结果已写入到TSV文件中:", tsv_file_path)

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

3. 生成LMDB数据库

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

修改一下参数如下:

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

四、模型微调

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

  1. # Number of GPUs per GPU worker
  2. GPUS_PER_NODE=1
  3. # Number of GPU workers, for single-worker training, please set to 1
  4. WORKER_CNT=1
  5. # The ip address of the rank-0 worker, for single-worker training, please set to localhost
  6. export MASTER_ADDR=localhost
  7. # The port for communication
  8. export MASTER_PORT=8514
  9. # The rank of this worker, should be in {0, ..., WORKER_CNT-1}, for single-worker training, please set to 0
  10. export RANK=0
  11. export PYTHONPATH=${PYTHONPATH}:`pwd`/cn_clip/
  12. # data options
  13. train_data=${DATAPATH}xxx/MyData/lmdb/train #这里的xxx是要改成绝对路径 下面一样
  14. val_data=${DATAPATH}xxx/MyData//lmdb/val # if val_data is not specified, the validation will be automatically disabled
  15. path to resume
  16. reset_data_offset="--reset-data-offset"
  17. reset_optimizer="--reset-optimizer"
  18. # reset_optimizer=""
  19. # output options
  20. 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,路径有问题的话,可以加上

  1. import os
  2. import sys
  3. # 获取当前脚本所在的目录路径
  4. current_directory = os.path.dirname(__file__)
  5. # 找到 cn_clip 文件夹的路径
  6. cn_clip_path = os.path.abspath(os.path.join(current_directory, '..', '..')) # 假设 cn_clip 文件夹在 eval 文件夹的上两级目录中

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/723921
推荐阅读
相关标签
  

闽ICP备14008679号