[
  {
    "path": ".gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\npip-wheel-metadata/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pyenv\n.python-version\n\n# pipenv\n#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.\n#   However, in case of collaboration, if having platform-specific dependencies or dependencies\n#   having no cross-platform support, pipenv may install dependencies that don't work, or not\n#   install all needed dependencies.\n#Pipfile.lock\n\n# PEP 582; used by e.g. github.com/David-OConnor/pyflow\n__pypackages__/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 Weifeng Chen\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<h2 align=\"center\">\nSome Scripts For DEEP LEARNING\n\n# 1. detection \n## yolo2coco.py\n将yolo格式数据集修改成coco格式。`$ROOT_PATH`是根目录，需要按下面的形式组织数据：\n\n```bash\n└── $ROOT_PATH\n\n  ├── classes.txt\n\n  ├── images\n\n  └──labels\n```\n\n- `classes.txt` 是类的声明，一行一类。\n\n- `images` 目录包含所有图片 (目前支持`png`和`jpg`格式数据)\n\n- `labels` 目录包含所有标签(与图片**同名**的`txt`格式数据)\n\n配置好文件夹后，执行：`python yolo2coco.py --root_dir $ROOT_PATH ` ，然后就能看见生成的 `annotations` 文件夹。\n\n**参数说明**\n- `--root_path` 输入根目录`$ROOT_PATH`的位置。\n- `--save_path` 如果不进行数据集划分，可利用此参数指定输出文件的名字，默认保存为`train.json`\n- `--random_split`  随机划分参数，若指定`--random_split`参数，则输出在`annotations`文件夹下包含 `train.json` `val.json` `test.json` （默认随机划分成8:1:1）\n- `--split_by_file` 自定义数据集划分，若指定`--split_by_file`参数，则输出在`annotations`文件夹 `train.json` `val.json` `test.json`。需要在`$ROOT_PATH`文件下有 `./train.txt ./val.txt ./test.txt` ，可以这3个文件来定义训练集、验证集、测试集。**注意**， 这里里面填写的应是图片文件名字，而不是图片的绝对地址。（在line 43也自行可以修改一下读取方式，为了方便起见，不推荐把图片放在不同位置） \n\n\n## coco2yolo.py\n\n读入coco数据集json格式的标注，输出可供yolo训练的标签。\n\n**需要注意的是，COCO2017官方的数据集中categories id 是不连续的**，这在yolo读取的时候会出问题，所以需要重新映射一下，这个代码会按id从小到大映射到0~79之间。（如果是自己的数据集，也会重新映射）\n\n执行：`python coco2yolo.py --json_path $JSON_FILE_PATH --save_path $LABEL_SAVE_PATH`\n\n- `$JSON_FILE_PATH`是json文件的地址。\n- `$JSON_FILE_PATH`是输出目录（默认为工作目录下的`./labels`目录。\n\n\n## zeroshot_retrieval_evaluation.ipynb\n- 检索topN的计算，支持一对多检索。（一张图对应有多个captions）\n\n## vis_yolo_gt_dt.py\n同时把GT和预测结果可视化在同一张图中。`$DT_DIR`是预测结果标签地址，必须是和GT同名的标签。`$ROOT_PATH`文件目录：\n\n```bash\n└── $ROOT_PATH\n\n  ├── classes.txt\n\n  ├── images\n\n  └── labels\n```\n\n执行：`python vis_yolo_gt_dt.py --root $ROOT_PATH --dt $DT_DIR`后生成在`outputs`文件夹中。\n\n- `classes.txt`和`images`必须有。\n- `labels`可以没有，那样就只展示`$DT_DIR`预测结果。\n- `$DT_DIR` 若没有输入，则只展示标签结果。\n\n## coco_eval.py\n\n评估生成的结果，针对**yolov5**生成的检测结果（test中的`--save-json`参数，会生成`best_predictions.json`)，但是这个不适应cocoapi，需要用脚本来修改适应。执行：\n\n`python coco_eval.py --gt $GT_PATH --dt $DT_PATH --yolov5`\n\n- `--gt` json格式，用于指定测试集的结果，如果没有，可以利用前面的`yolo2coco.py`进行转换。\n- `--dt` 同样检测网络生成的预测，使用cocoapi中`loadRes`来加载，所以需要有相应格式的检测结果。\n- `--yolov5` 将官方代码中生成的结果转换成适配cocoapi的结果。\n\n# 2. text-image\n## zeroshot_retrieval_evalution.ipynb\n检索模型的评估指标。（topK召回率），支持多对多的情况。（比如一个文本匹配多张图片）\n## fid_clip_score\n用于画text2image的 FID-CLIP Score曲线图。"
  },
  {
    "path": "detection/coco2yolo.py",
    "content": "\"\"\"\n2021/1/24\nCOCO 格式的数据集转化为 YOLO 格式的数据集，源代码采取遍历方式，太慢，\n这里改进了一下时间复杂度，从O(nm)改为O(n+m)，但是牺牲了一些内存占用\n--json_path 输入的json文件路径\n--save_path 保存的文件夹名字，默认为当前目录下的labels。\n\"\"\"\n\nimport os \nimport json\nfrom tqdm import tqdm\nimport argparse\n\nparser = argparse.ArgumentParser()\nparser.add_argument('--json_path', default='./instances_val2017.json',type=str, help=\"input: coco format(json)\")\nparser.add_argument('--save_path', default='./labels', type=str, help=\"specify where to save the output dir of labels\")\narg = parser.parse_args()\n\ndef convert(size, box):\n    dw = 1. / (size[0])\n    dh = 1. / (size[1])\n    x = box[0] + box[2] / 2.0\n    y = box[1] + box[3] / 2.0\n    w = box[2]\n    h = box[3]\n\n    x = x * dw\n    w = w * dw\n    y = y * dh\n    h = h * dh\n    return (x, y, w, h)\n\nif __name__ == '__main__':\n    json_file =   arg.json_path # COCO Object Instance 类型的标注\n    ana_txt_save_path = arg.save_path  # 保存的路径\n\n    data = json.load(open(json_file, 'r'))\n    if not os.path.exists(ana_txt_save_path):\n        os.makedirs(ana_txt_save_path)\n    \n    id_map = {} # coco数据集的id不连续！重新映射一下再输出！\n    for i, category in enumerate(data['categories']): \n        id_map[category['id']] = i\n\n    # 通过事先建表来降低时间复杂度\n    max_id = 0\n    for img in data['images']:\n        max_id = max(max_id, img['id'])\n    # 注意这里不能写作 [[]]*(max_id+1)，否则列表内的空列表共享地址\n    img_ann_dict = [[] for i in range(max_id+1)] \n    for i, ann in enumerate(data['annotations']):\n        img_ann_dict[ann['image_id']].append(i)\n\n    for img in tqdm(data['images']):\n        filename = img[\"file_name\"]\n        img_width = img[\"width\"]\n        img_height = img[\"height\"]\n        img_id = img[\"id\"]\n        head, tail = os.path.splitext(filename)\n        ana_txt_name = head + \".txt\"  # 对应的txt名字，与jpg一致\n        f_txt = open(os.path.join(ana_txt_save_path, ana_txt_name), 'w')\n        '''for ann in data['annotations']:\n            if ann['image_id'] == img_id:\n                box = convert((img_width, img_height), ann[\"bbox\"])\n                f_txt.write(\"%s %s %s %s %s\\n\" % (id_map[ann[\"category_id\"]], box[0], box[1], box[2], box[3]))'''\n        # 这里可以直接查表而无需重复遍历\n        for ann_id in img_ann_dict[img_id]:\n            ann = data['annotations'][ann_id]\n            box = convert((img_width, img_height), ann[\"bbox\"])\n            f_txt.write(\"%s %s %s %s %s\\n\" % (id_map[ann[\"category_id\"]], box[0], box[1], box[2], box[3]))\n        f_txt.close()\n        \n# 旧版，很慢hhh\n# \"\"\"\n# COCO 格式的数据集转化为 YOLO 格式的数据集\n# --json_path 输入的json文件路径\n# --save_path 保存的文件夹名字，默认为当前目录下的labels。\n# \"\"\"\n\n# import os \n# import json\n# from tqdm import tqdm\n# import argparse\n\n# parser = argparse.ArgumentParser()\n# parser.add_argument('--json_path', default='./instances_val2017.json',type=str, help=\"input: coco format(json)\")\n# parser.add_argument('--save_path', default='./labels', type=str, help=\"specify where to save the output dir of labels\")\n# arg = parser.parse_args()\n\n# def convert(size, box):\n#     dw = 1. / (size[0])\n#     dh = 1. / (size[1])\n#     x = box[0] + box[2] / 2.0\n#     y = box[1] + box[3] / 2.0\n#     w = box[2]\n#     h = box[3]\n\n#     x = x * dw\n#     w = w * dw\n#     y = y * dh\n#     h = h * dh\n#     return (x, y, w, h)\n\n# if __name__ == '__main__':\n#     json_file =   arg.json_path # COCO Object Instance 类型的标注\n#     ana_txt_save_path = arg.save_path  # 保存的路径\n\n#     data = json.load(open(json_file, 'r'))\n#     if not os.path.exists(ana_txt_save_path):\n#         os.makedirs(ana_txt_save_path)\n    \n#     id_map = {} # coco数据集的id不连续！重新映射一下再输出！\n#     with open(os.path.join(ana_txt_save_path, 'classes.txt'), 'w') as f:\n#         # 写入classes.txt\n#         for i, category in enumerate(data['categories']): \n#             f.write(f\"{category['name']}\\n\") \n#             id_map[category['id']] = i\n#     # print(id_map)\n\n#     for img in tqdm(data['images']):\n#         filename = img[\"file_name\"]\n#         img_width = img[\"width\"]\n#         img_height = img[\"height\"]\n#         img_id = img[\"id\"]\n#         head, tail = os.path.splitext(filename)\n#         ana_txt_name = head + \".txt\"  # 对应的txt名字，与jpg一致\n#         f_txt = open(os.path.join(ana_txt_save_path, ana_txt_name), 'w')\n#         for ann in data['annotations']:\n#             if ann['image_id'] == img_id:\n#                 box = convert((img_width, img_height), ann[\"bbox\"])\n#                 f_txt.write(\"%s %s %s %s %s\\n\" % (id_map[ann[\"category_id\"]], box[0], box[1], box[2], box[3]))\n#         f_txt.close()\n"
  },
  {
    "path": "detection/coco_eval.py",
    "content": "import json\nimport argparse\nfrom pycocotools.coco import COCO \nfrom pycocotools.cocoeval import COCOeval \nimport os\nimport time\n\ndef transform_yolov5_result(result, filename2id):\n    f = open(result ,'r',encoding='utf-8')\n    dts = json.load(f)\n    output_dts = []\n    for dt in dts:\n        dt['image_id'] = filename2id[dt['image_id']+'.jpg']\n        dt['category_id'] # id对应好，coco格式和yolo格式的category_id可能不同。\n        output_dts.append(dt)\n    with open('temp.json', 'w') as f:\n        json.dump(output_dts, f)\n\ndef coco_evaluate(gt_path, dt_path, yolov5_flag):\n    cocoGt = COCO(gt_path)\n    imgIds = cocoGt.getImgIds()\n    gts = cocoGt.loadImgs(imgIds)\n    filename2id = {}\n\n    for gt in gts:\n        filename2id[gt['file_name']] = gt['id']\n    print(\"NUM OF TEST IMAGES: \",len(filename2id))\n\n    if yolov5_flag:\n        transform_yolov5_result(dt_path, filename2id)\n        cocoDt = cocoGt.loadRes('temp.json')\n    else:\n        cocoDt = cocoGt.loadRes(dt_path)\n    cocoEval = COCOeval(cocoGt, cocoDt, \"bbox\")\n    cocoEval.evaluate()\n    cocoEval.accumulate()\n    cocoEval.summarize()\n    if yolov5_flag:\n        os.remove('temp.json')\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--gt\", type=str, help=\"Assign the groud true path.\", default=None)\n    parser.add_argument(\"--dt\", type=str, help=\"Assign the detection result path.\", default=None)\n    parser.add_argument(\"--yolov5\",action='store_true',help=\"fix yolov5 output bug\", default=None)\n\n    args = parser.parse_args()\n    gt_path = args.gt\n    dt_path = args.dt\n    if args.yolov5:\n        coco_evaluate(gt_path, dt_path, True)\n    else:\n        coco_evaluate(gt_path, dt_path, False)\n    "
  },
  {
    "path": "detection/vis_yolo_gt_dt.py",
    "content": "import cv2\nimport os\nfrom glob import glob\nimport random\nimport matplotlib.pyplot as plt \nimport argparse\nfrom tqdm import tqdm\nimport numpy as np\n\nparser = argparse.ArgumentParser()\nparser.add_argument('--root',type=str ,default='', help=\"which should include ./images and ./labels and classes.txt\")\nparser.add_argument('--dt',type=str ,default='' , help=\"yolo format results of detection, include ./labels\")\nparser.add_argument('--conf' , type=float ,default=0.5, help=\"visulization conf thres\")\narg = parser.parse_args()\n\ncolorlist = []\n# 5^3种颜色。\nfor i in range(25,256,50):\n    for j in range(25,256,50):\n        for k in range(25,256,50):\n            colorlist.append((i,j,k))\nrandom.shuffle(colorlist)\n\ndef plot_bbox(img_path, img_dir, out_dir, gt=None ,dt=None, cls2label=None, line_thickness=None):\n    img = cv2.imread(os.path.join(img_dir, img_path))\n    height, width,_ = img.shape\n    tl = line_thickness or round(0.002 * (width + height) / 2) + 1  # line/font thickness\n    font = cv2.FONT_HERSHEY_SIMPLEX\n    if gt:\n        tf = max(tl - 1, 1)  # font thickness\n        with open(gt,'r') as f:\n            annotations = f.readlines()\n            # print(annotations)    \n            for ann in annotations:\n                ann = list(map(float,ann.split()))\n                ann[0] = int(ann[0])\n                # print(ann)\n                cls,x,y,w,h = ann\n                color = colorlist[cls]\n                c1, c2 = (int((x-w/2)*width),int((y-h/2)*height)), (int((x+w/2)*width), int((y+h/2)*height))\n                cv2.rectangle(img, c1, c2, color, thickness=tl*2, lineType=cv2.LINE_AA)\n                # 类别名称显示\n                cv2.putText(img, str(cls2label[cls]), (c1[0], c1[1] - 2), 0, tl / 4, color, thickness=tf, lineType=cv2.LINE_AA)\n    if dt:\n        with open(dt,'r') as f:\n            annotations = f.readlines()\n            # print(annotations)    \n            for ann in annotations:\n                ann = list(map(float,ann.split()))\n                ann[0] = int(ann[0])\n                # print(ann)\n                if len(ann) == 6:\n                    cls,x,y,w,h,conf = ann\n                    if conf < arg.conf:\n                        # thres = 0.5\n                        continue\n                elif len(ann) == 5:\n                    cls,x,y,w,h = ann\n                color = colorlist[len(colorlist) - cls - 1]\n\n                c1, c2 = (int((x-w/2)*width), int((y-h/2)*height)), (int((x+w/2)*width), int((y+h/2)*height))\n                cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)\n\n                # # cls label\n                tf = max(tl - 1, 1)  # font thickness\n                t_size = cv2.getTextSize(cls2label[cls], 0, fontScale=tl / 3, thickness=tf)[0]\n                c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3\n                # cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)  # filled\n                if len(ann) == 6:\n                    cv2.putText(img, str(round(conf,2)), (c1[0], c1[1] - 2), 0, tl / 4, color, thickness=tf, lineType=cv2.LINE_AA)\n    cv2.imwrite(os.path.join(out_dir,img_path),img)\n    \nif __name__ == \"__main__\":\n    root_path = arg.root\n    pred_path = arg.dt\n    img_dir = os.path.join(root_path,'images')\n    GT_dir = os.path.join(root_path,'labels')\n    DT_dir = os.path.join(pred_path)\n    out_dir = os.path.join(root_path,'outputs')\n    cls_dir = os.path.join(root_path,'classes.txt')\n    cls_dict = {}\n\n    if not os.path.exists(img_dir):\n        raise Exception(\"image dir {} do not exist!\".format(img_dir))\n    if not os.path.exists(cls_dir):\n        raise Exception(\"class dir {} do not exist!\".format(cls_dir))\n    else:\n        with open(cls_dir,'r') as f:\n            classes = f.readlines()\n            for i in range(len(classes)):\n                cls_dict[i] = classes[i].strip()\n            print(\"class map:\", cls_dict)\n    if not os.path.exists(out_dir):\n        os.mkdir(out_dir)\n    if not os.path.exists(GT_dir):\n        print(f\"WARNNING: {GT_dir} ,GT NOT Available!\")\n    if not os.path.exists(DT_dir):\n        print(f\"WARNNING: {DT_dir} ,DT NOT Available!\")\n    for each_img in tqdm(os.listdir(img_dir)):\n        gt = None\n        dt = None\n        if os.path.exists(os.path.join(GT_dir,each_img.replace('jpg','txt'))):\n            gt = os.path.join(GT_dir,each_img.replace('jpg','txt'))\n        if os.path.exists(os.path.join(DT_dir,each_img.replace('jpg','txt'))):\n            dt = os.path.join(DT_dir,each_img.replace('jpg','txt'))\n        \n        plot_bbox(each_img, img_dir, out_dir, gt, dt, cls2label=cls_dict)\n        "
  },
  {
    "path": "detection/yolo2coco.py",
    "content": "\"\"\"\nYOLO 格式的数据集转化为 COCO 格式的数据集\n--root_dir 输入根路径\n--save_path 保存文件的名字(没有random_split时使用)\n--random_split 有则会随机划分数据集，然后再分别保存为3个文件。\n--split_by_file 按照 ./train.txt ./val.txt ./test.txt 来对数据集进行划分。\n\"\"\"\n\nimport os\nimport cv2\nimport json\nfrom tqdm import tqdm\nfrom sklearn.model_selection import train_test_split\nimport argparse\n\nparser = argparse.ArgumentParser()\nparser.add_argument('--root_dir', default='./data',type=str, help=\"root path of images and labels, include ./images and ./labels and classes.txt\")\nparser.add_argument('--save_path', type=str,default='./train.json', help=\"if not split the dataset, give a path to a json file\")\nparser.add_argument('--random_split', action='store_true', help=\"random split the dataset, default ratio is 8:1:1\")\nparser.add_argument('--split_by_file', action='store_true', help=\"define how to split the dataset, include ./train.txt ./val.txt ./test.txt \")\n\narg = parser.parse_args()\n\ndef train_test_val_split_random(img_paths,ratio_train=0.8,ratio_test=0.1,ratio_val=0.1):\n    # 这里可以修改数据集划分的比例。\n    assert int(ratio_train+ratio_test+ratio_val) == 1\n    train_img, middle_img = train_test_split(img_paths,test_size=1-ratio_train, random_state=233)\n    ratio=ratio_val/(1-ratio_train)\n    val_img, test_img  =train_test_split(middle_img,test_size=ratio, random_state=233)\n    print(\"NUMS of train:val:test = {}:{}:{}\".format(len(train_img), len(val_img), len(test_img)))\n    return train_img, val_img, test_img\n\ndef train_test_val_split_by_files(img_paths, root_dir):\n    # 根据文件 train.txt, val.txt, test.txt（里面写的都是对应集合的图片名字） 来定义训练集、验证集和测试集\n    phases = ['train', 'val', 'test']\n    img_split = []\n    for p in phases:\n        define_path = os.path.join(root_dir, f'{p}.txt')\n        print(f'Read {p} dataset definition from {define_path}')\n        assert os.path.exists(define_path)\n        with open(define_path, 'r') as f:\n            img_paths = f.readlines()\n            # img_paths = [os.path.split(img_path.strip())[1] for img_path in img_paths]  # NOTE 取消这句备注可以读取绝对地址。\n            img_split.append(img_paths)\n    return img_split[0], img_split[1], img_split[2]\n\n\ndef yolo2coco(arg):\n    root_path = arg.root_dir\n    print(\"Loading data from \",root_path)\n\n    assert os.path.exists(root_path)\n    originLabelsDir = os.path.join(root_path, 'labels')                                        \n    originImagesDir = os.path.join(root_path, 'images')\n    with open(os.path.join(root_path, 'classes.txt')) as f:\n        classes = f.read().strip().split()\n    # images dir name\n    indexes = os.listdir(originImagesDir)\n\n    if arg.random_split or arg.split_by_file:\n        # 用于保存所有数据的图片信息和标注信息\n        train_dataset = {'categories': [], 'annotations': [], 'images': []}\n        val_dataset = {'categories': [], 'annotations': [], 'images': []}\n        test_dataset = {'categories': [], 'annotations': [], 'images': []}\n\n        # 建立类别标签和数字id的对应关系, 类别id从0开始。\n        for i, cls in enumerate(classes, 0):\n            train_dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})\n            val_dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})\n            test_dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})\n            \n        if arg.random_split:\n            print(\"spliting mode: random split\")\n            train_img, val_img, test_img = train_test_val_split_random(indexes,0.8,0.1,0.1)\n        elif arg.split_by_file:\n            print(\"spliting mode: split by files\")\n            train_img, val_img, test_img = train_test_val_split_by_files(indexes, root_path)\n    else:\n        dataset = {'categories': [], 'annotations': [], 'images': []}\n        for i, cls in enumerate(classes, 0):\n            dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})\n    \n    # 标注的id\n    ann_id_cnt = 0\n    for k, index in enumerate(tqdm(indexes)):\n        # 支持 png jpg 格式的图片。\n        txtFile = index.replace('images','txt').replace('.jpg','.txt').replace('.png','.txt')\n        # 读取图像的宽和高\n        im = cv2.imread(os.path.join(root_path, 'images/') + index)\n        height, width, _ = im.shape\n        if arg.random_split or arg.split_by_file:\n            # 切换dataset的引用对象，从而划分数据集\n                if index in train_img:\n                    dataset = train_dataset\n                elif index in val_img:\n                    dataset = val_dataset\n                elif index in test_img:\n                    dataset = test_dataset\n        # 添加图像的信息\n        dataset['images'].append({'file_name': index,\n                                    'id': k,\n                                    'width': width,\n                                    'height': height})\n        if not os.path.exists(os.path.join(originLabelsDir, txtFile)):\n            # 如没标签，跳过，只保留图片信息。\n            continue\n        with open(os.path.join(originLabelsDir, txtFile), 'r') as fr:\n            labelList = fr.readlines()\n            for label in labelList:\n                label = label.strip().split()\n                x = float(label[1])\n                y = float(label[2])\n                w = float(label[3])\n                h = float(label[4])\n\n                # convert x,y,w,h to x1,y1,x2,y2\n                H, W, _ = im.shape\n                x1 = (x - w / 2) * W\n                y1 = (y - h / 2) * H\n                x2 = (x + w / 2) * W\n                y2 = (y + h / 2) * H\n                # 标签序号从0开始计算, coco2017数据集标号混乱，不管它了。\n                cls_id = int(label[0])   \n                width = max(0, x2 - x1)\n                height = max(0, y2 - y1)\n                dataset['annotations'].append({\n                    'area': width * height,\n                    'bbox': [x1, y1, width, height],\n                    'category_id': cls_id,\n                    'id': ann_id_cnt,\n                    'image_id': k,\n                    'iscrowd': 0,\n                    # mask, 矩形是从左上角点按顺时针的四个顶点\n                    'segmentation': [[x1, y1, x2, y1, x2, y2, x1, y2]]\n                })\n                ann_id_cnt += 1\n\n    # 保存结果\n    folder = os.path.join(root_path, 'annotations')\n    if not os.path.exists(folder):\n        os.makedirs(folder)\n    if arg.random_split or arg.split_by_file:\n        for phase in ['train','val','test']:\n            json_name = os.path.join(root_path, 'annotations/{}.json'.format(phase))\n            with open(json_name, 'w') as f:\n                if phase == 'train':\n                    json.dump(train_dataset, f)\n                elif phase == 'val':\n                    json.dump(val_dataset, f)\n                elif phase == 'test':\n                    json.dump(test_dataset, f)\n            print('Save annotation to {}'.format(json_name))\n    else:\n        json_name = os.path.join(root_path, 'annotations/{}'.format(arg.save_path))\n        with open(json_name, 'w') as f:\n            json.dump(dataset, f)\n            print('Save annotation to {}'.format(json_name))\n\nif __name__ == \"__main__\":\n\n    yolo2coco(arg)"
  },
  {
    "path": "text-image/convert_diffusers_to_original_stable_diffusion.py",
    "content": "# Script for converting a HF Diffusers saved pipeline to a Stable Diffusion checkpoint.\n# *Only* converts the UNet, VAE, and Text Encoder.\n# Does not convert optimizer state or any other thing.\n\nimport argparse\nimport os.path as osp\n\nimport torch\n\n\n# =================#\n# UNet Conversion #\n# =================#\n\nunet_conversion_map = [\n    # (stable-diffusion, HF Diffusers)\n    (\"time_embed.0.weight\", \"time_embedding.linear_1.weight\"),\n    (\"time_embed.0.bias\", \"time_embedding.linear_1.bias\"),\n    (\"time_embed.2.weight\", \"time_embedding.linear_2.weight\"),\n    (\"time_embed.2.bias\", \"time_embedding.linear_2.bias\"),\n    (\"input_blocks.0.0.weight\", \"conv_in.weight\"),\n    (\"input_blocks.0.0.bias\", \"conv_in.bias\"),\n    (\"out.0.weight\", \"conv_norm_out.weight\"),\n    (\"out.0.bias\", \"conv_norm_out.bias\"),\n    (\"out.2.weight\", \"conv_out.weight\"),\n    (\"out.2.bias\", \"conv_out.bias\"),\n]\n\nunet_conversion_map_resnet = [\n    # (stable-diffusion, HF Diffusers)\n    (\"in_layers.0\", \"norm1\"),\n    (\"in_layers.2\", \"conv1\"),\n    (\"out_layers.0\", \"norm2\"),\n    (\"out_layers.3\", \"conv2\"),\n    (\"emb_layers.1\", \"time_emb_proj\"),\n    (\"skip_connection\", \"conv_shortcut\"),\n]\n\nunet_conversion_map_layer = []\n# hardcoded number of downblocks and resnets/attentions...\n# would need smarter logic for other networks.\nfor i in range(4):\n    # loop over downblocks/upblocks\n\n    for j in range(2):\n        # loop over resnets/attentions for downblocks\n        hf_down_res_prefix = f\"down_blocks.{i}.resnets.{j}.\"\n        sd_down_res_prefix = f\"input_blocks.{3*i + j + 1}.0.\"\n        unet_conversion_map_layer.append((sd_down_res_prefix, hf_down_res_prefix))\n\n        if i < 3:\n            # no attention layers in down_blocks.3\n            hf_down_atn_prefix = f\"down_blocks.{i}.attentions.{j}.\"\n            sd_down_atn_prefix = f\"input_blocks.{3*i + j + 1}.1.\"\n            unet_conversion_map_layer.append((sd_down_atn_prefix, hf_down_atn_prefix))\n\n    for j in range(3):\n        # loop over resnets/attentions for upblocks\n        hf_up_res_prefix = f\"up_blocks.{i}.resnets.{j}.\"\n        sd_up_res_prefix = f\"output_blocks.{3*i + j}.0.\"\n        unet_conversion_map_layer.append((sd_up_res_prefix, hf_up_res_prefix))\n\n        if i > 0:\n            # no attention layers in up_blocks.0\n            hf_up_atn_prefix = f\"up_blocks.{i}.attentions.{j}.\"\n            sd_up_atn_prefix = f\"output_blocks.{3*i + j}.1.\"\n            unet_conversion_map_layer.append((sd_up_atn_prefix, hf_up_atn_prefix))\n\n    if i < 3:\n        # no downsample in down_blocks.3\n        hf_downsample_prefix = f\"down_blocks.{i}.downsamplers.0.conv.\"\n        sd_downsample_prefix = f\"input_blocks.{3*(i+1)}.0.op.\"\n        unet_conversion_map_layer.append((sd_downsample_prefix, hf_downsample_prefix))\n\n        # no upsample in up_blocks.3\n        hf_upsample_prefix = f\"up_blocks.{i}.upsamplers.0.\"\n        sd_upsample_prefix = f\"output_blocks.{3*i + 2}.{1 if i == 0 else 2}.\"\n        unet_conversion_map_layer.append((sd_upsample_prefix, hf_upsample_prefix))\n\nhf_mid_atn_prefix = \"mid_block.attentions.0.\"\nsd_mid_atn_prefix = \"middle_block.1.\"\nunet_conversion_map_layer.append((sd_mid_atn_prefix, hf_mid_atn_prefix))\n\nfor j in range(2):\n    hf_mid_res_prefix = f\"mid_block.resnets.{j}.\"\n    sd_mid_res_prefix = f\"middle_block.{2*j}.\"\n    unet_conversion_map_layer.append((sd_mid_res_prefix, hf_mid_res_prefix))\n\n\ndef convert_unet_state_dict(unet_state_dict):\n    # buyer beware: this is a *brittle* function,\n    # and correct output requires that all of these pieces interact in\n    # the exact order in which I have arranged them.\n    mapping = {k: k for k in unet_state_dict.keys()}\n    for sd_name, hf_name in unet_conversion_map:\n        mapping[hf_name] = sd_name\n    for k, v in mapping.items():\n        if \"resnets\" in k:\n            for sd_part, hf_part in unet_conversion_map_resnet:\n                v = v.replace(hf_part, sd_part)\n            mapping[k] = v\n    for k, v in mapping.items():\n        for sd_part, hf_part in unet_conversion_map_layer:\n            v = v.replace(hf_part, sd_part)\n        mapping[k] = v\n    new_state_dict = {v: unet_state_dict[k] for k, v in mapping.items()}\n    return new_state_dict\n\n\n# ================#\n# VAE Conversion #\n# ================#\n\nvae_conversion_map = [\n    # (stable-diffusion, HF Diffusers)\n    (\"nin_shortcut\", \"conv_shortcut\"),\n    (\"norm_out\", \"conv_norm_out\"),\n    (\"mid.attn_1.\", \"mid_block.attentions.0.\"),\n]\n\nfor i in range(4):\n    # down_blocks have two resnets\n    for j in range(2):\n        hf_down_prefix = f\"encoder.down_blocks.{i}.resnets.{j}.\"\n        sd_down_prefix = f\"encoder.down.{i}.block.{j}.\"\n        vae_conversion_map.append((sd_down_prefix, hf_down_prefix))\n\n    if i < 3:\n        hf_downsample_prefix = f\"down_blocks.{i}.downsamplers.0.\"\n        sd_downsample_prefix = f\"down.{i}.downsample.\"\n        vae_conversion_map.append((sd_downsample_prefix, hf_downsample_prefix))\n\n        hf_upsample_prefix = f\"up_blocks.{i}.upsamplers.0.\"\n        sd_upsample_prefix = f\"up.{3-i}.upsample.\"\n        vae_conversion_map.append((sd_upsample_prefix, hf_upsample_prefix))\n\n    # up_blocks have three resnets\n    # also, up blocks in hf are numbered in reverse from sd\n    for j in range(3):\n        hf_up_prefix = f\"decoder.up_blocks.{i}.resnets.{j}.\"\n        sd_up_prefix = f\"decoder.up.{3-i}.block.{j}.\"\n        vae_conversion_map.append((sd_up_prefix, hf_up_prefix))\n\n# this part accounts for mid blocks in both the encoder and the decoder\nfor i in range(2):\n    hf_mid_res_prefix = f\"mid_block.resnets.{i}.\"\n    sd_mid_res_prefix = f\"mid.block_{i+1}.\"\n    vae_conversion_map.append((sd_mid_res_prefix, hf_mid_res_prefix))\n\n\nvae_conversion_map_attn = [\n    # (stable-diffusion, HF Diffusers)\n    (\"norm.\", \"group_norm.\"),\n    (\"q.\", \"query.\"),\n    (\"k.\", \"key.\"),\n    (\"v.\", \"value.\"),\n    (\"proj_out.\", \"proj_attn.\"),\n]\n\n\ndef reshape_weight_for_sd(w):\n    # convert HF linear weights to SD conv2d weights\n    return w.reshape(*w.shape, 1, 1)\n\n\ndef convert_vae_state_dict(vae_state_dict):\n    mapping = {k: k for k in vae_state_dict.keys()}\n    for k, v in mapping.items():\n        for sd_part, hf_part in vae_conversion_map:\n            v = v.replace(hf_part, sd_part)\n        mapping[k] = v\n    for k, v in mapping.items():\n        if \"attentions\" in k:\n            for sd_part, hf_part in vae_conversion_map_attn:\n                v = v.replace(hf_part, sd_part)\n            mapping[k] = v\n    new_state_dict = {v: vae_state_dict[k] for k, v in mapping.items()}\n    weights_to_convert = [\"q\", \"k\", \"v\", \"proj_out\"]\n    for k, v in new_state_dict.items():\n        for weight_name in weights_to_convert:\n            if f\"mid.attn_1.{weight_name}.weight\" in k:\n                print(f\"Reshaping {k} for SD format\")\n                new_state_dict[k] = reshape_weight_for_sd(v)\n    return new_state_dict\n\n\n# =========================#\n# Text Encoder Conversion #\n# =========================#\n# pretty much a no-op\n\n\ndef convert_text_enc_state_dict(text_enc_dict):\n    return text_enc_dict\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser()\n\n    parser.add_argument(\"--model_path\", default=None, type=str, required=True, help=\"Path to the model to convert.\")\n    parser.add_argument(\"--checkpoint_path\", default=None, type=str, required=True, help=\"Path to the output model.\")\n    parser.add_argument(\"--half\", action=\"store_true\", help=\"Save weights in half precision.\")\n\n    args = parser.parse_args()\n\n    assert args.model_path is not None, \"Must provide a model path!\"\n\n    assert args.checkpoint_path is not None, \"Must provide a checkpoint path!\"\n\n    unet_path = osp.join(args.model_path, \"unet\", \"diffusion_pytorch_model.bin\")\n    vae_path = osp.join(args.model_path, \"vae\", \"diffusion_pytorch_model.bin\")\n    text_enc_path = osp.join(args.model_path, \"text_encoder\", \"pytorch_model.bin\")\n\n    # Convert the UNet model\n    unet_state_dict = torch.load(unet_path, map_location=\"cpu\")\n    unet_state_dict = convert_unet_state_dict(unet_state_dict)\n    unet_state_dict = {\"model.diffusion_model.\" + k: v for k, v in unet_state_dict.items()}\n\n    # Convert the VAE model\n    vae_state_dict = torch.load(vae_path, map_location=\"cpu\")\n    vae_state_dict = convert_vae_state_dict(vae_state_dict)\n    vae_state_dict = {\"first_stage_model.\" + k: v for k, v in vae_state_dict.items()}\n\n    # Convert the text encoder model\n    text_enc_dict = torch.load(text_enc_path, map_location=\"cpu\")\n    text_enc_dict = convert_text_enc_state_dict(text_enc_dict)\n    text_enc_dict = {\"cond_stage_model.transformer.\" + k: v for k, v in text_enc_dict.items()}\n\n    # Put together new checkpoint\n    state_dict = {**unet_state_dict, **vae_state_dict, **text_enc_dict}\n    if args.half:\n        state_dict = {k: v.half() for k, v in state_dict.items()}\n    state_dict = {\"state_dict\": state_dict}\n    torch.save(state_dict, args.checkpoint_path)"
  },
  {
    "path": "text-image/data_filter/data_filter_demo.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# 集成了水印、美学、CLIP模型，用于给图文质量打分\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import pytorch_lightning as pl\\n\",\n    \"import torch.nn as nn\\n\",\n    \"import torch.nn.functional as F\\n\",\n    \"import torch\\n\",\n    \"import timm\\n\",\n    \"from torchvision import transforms as T\\n\",\n    \"import open_clip\\n\",\n    \"import torch\\n\",\n    \"from transformers import BertModel, BertTokenizer\\n\",\n    \"from PIL import Image\\n\",\n    \"\\n\",\n    \"class AestheticsMLP(pl.LightningModule):\\n\",\n    \"    # 美学判别器是基于CLIP的基础上接了一个MLP\\n\",\n    \"    def __init__(self, input_size, xcol='emb', ycol='avg_rating'):\\n\",\n    \"        super().__init__()\\n\",\n    \"        self.input_size = input_size\\n\",\n    \"        self.xcol = xcol\\n\",\n    \"        self.ycol = ycol\\n\",\n    \"        self.layers = nn.Sequential(\\n\",\n    \"            nn.Linear(self.input_size, 1024),\\n\",\n    \"            #nn.ReLU(),\\n\",\n    \"            nn.Dropout(0.2),\\n\",\n    \"            nn.Linear(1024, 128),\\n\",\n    \"            #nn.ReLU(),\\n\",\n    \"            nn.Dropout(0.2),\\n\",\n    \"            nn.Linear(128, 64),\\n\",\n    \"            #nn.ReLU(),\\n\",\n    \"            nn.Dropout(0.1),\\n\",\n    \"\\n\",\n    \"            nn.Linear(64, 16),\\n\",\n    \"            #nn.ReLU(),\\n\",\n    \"\\n\",\n    \"            nn.Linear(16, 1)\\n\",\n    \"        )\\n\",\n    \"\\n\",\n    \"    def forward(self, x):\\n\",\n    \"        return self.layers(x)\\n\",\n    \"\\n\",\n    \"    def training_step(self, batch, batch_idx):\\n\",\n    \"            x = batch[self.xcol]\\n\",\n    \"            y = batch[self.ycol].reshape(-1, 1)\\n\",\n    \"            x_hat = self.layers(x)\\n\",\n    \"            loss = F.mse_loss(x_hat, y)\\n\",\n    \"            return loss\\n\",\n    \"    \\n\",\n    \"    def validation_step(self, batch, batch_idx):\\n\",\n    \"        x = batch[self.xcol]\\n\",\n    \"        y = batch[self.ycol].reshape(-1, 1)\\n\",\n    \"        x_hat = self.layers(x)\\n\",\n    \"        loss = F.mse_loss(x_hat, y)\\n\",\n    \"        return loss\\n\",\n    \"\\n\",\n    \"    def configure_optimizers(self):\\n\",\n    \"        optimizer = torch.optim.Adam(self.parameters(), lr=1e-3)\\n\",\n    \"        return optimizer\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class WaterMarkModel(nn.Module):\\n\",\n    \"    def __init__(self, model_path='./watermark_model_v1.pt'):\\n\",\n    \"        super(WaterMarkModel, self).__init__()\\n\",\n    \"        # model definition\\n\",\n    \"        self.model = timm.create_model(\\n\",\n    \"                'efficientnet_b3a', pretrained=True, num_classes=2)\\n\",\n    \"\\n\",\n    \"        self.model.classifier = nn.Sequential(\\n\",\n    \"            # 1536 is the orginal in_features\\n\",\n    \"            nn.Linear(in_features=1536, out_features=625),\\n\",\n    \"            nn.ReLU(),  # ReLu to be the activation function\\n\",\n    \"            nn.Dropout(p=0.3),\\n\",\n    \"            nn.Linear(in_features=625, out_features=256),\\n\",\n    \"            nn.ReLU(),\\n\",\n    \"            nn.Linear(in_features=256, out_features=2),\\n\",\n    \"        )\\n\",\n    \"        self.model.load_state_dict(torch.load(model_path))\\n\",\n    \"    def forward(self, x):\\n\",\n    \"        return self.model(x)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class FilterSystem:\\n\",\n    \"    def __init__(\\n\",\n    \"                    self, \\n\",\n    \"                    clip_model_path=\\\"IDEA-CCNL/Taiyi-CLIP-RoBERTa-102M-ViT-L-Chinese\\\",\\n\",\n    \"                    aesthetics_model_path=\\\"./ava+logos-l14-linearMSE.pth\\\",\\n\",\n    \"                    watermark_model_path=\\\"./watermark_model_v1.pt\\\"\\n\",\n    \"                ):\\n\",\n    \"        self.clip_model_path = clip_model_path\\n\",\n    \"        self.aesthetics_model_path = aesthetics_model_path\\n\",\n    \"        self.watermark_model_path = watermark_model_path\\n\",\n    \"\\n\",\n    \"    def init_clip_model(self, ):\\n\",\n    \"        # 此处初始化clip模型，返回模型、tokenizer、processor\\n\",\n    \"        text_encoder = BertModel.from_pretrained(self.clip_model_path).eval().cuda()\\n\",\n    \"        text_tokenizer = BertTokenizer.from_pretrained(self.clip_model_path)\\n\",\n    \"        clip_model, _, processor = open_clip.create_model_and_transforms('ViT-L-14', pretrained='openai')\\n\",\n    \"        clip_model = clip_model.eval().cuda()\\n\",\n    \"        self.text_encoder, self.text_tokenizer, self.clip_model, self.processor = text_encoder, text_tokenizer, clip_model, processor\\n\",\n    \"        print(\\\"clip model loaded\\\")\\n\",\n    \"        return None\\n\",\n    \"\\n\",\n    \"    def init_aesthetics_model(self, ):\\n\",\n    \"        # 此处初始化美学模型\\n\",\n    \"        self.aesthetics_model = AestheticsMLP(768)\\n\",\n    \"        self.aesthetics_model.load_state_dict(torch.load(self.aesthetics_model_path))\\n\",\n    \"        self.aesthetics_model.eval().cuda()\\n\",\n    \"        print(\\\"aesthetics model loaded\\\")\\n\",\n    \"        return None\\n\",\n    \"\\n\",\n    \"    def init_watermark_model(self, ):\\n\",\n    \"        self.watermark_model = WaterMarkModel(self.watermark_model_path)\\n\",\n    \"        self.watermark_model.eval().cuda()\\n\",\n    \"        self.watermark_processor =  T.Compose([\\n\",\n    \"                                                T.Resize((256, 256)),\\n\",\n    \"                                                T.ToTensor(),\\n\",\n    \"                                                T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\\n\",\n    \"                                            ])\\n\",\n    \"        print(\\\"watermark model loaded\\\")\\n\",\n    \"        return None\\n\",\n    \"\\n\",\n    \"    def get_image_feature(self, images):\\n\",\n    \"        # 此处返回图像的特征向量\\n\",\n    \"        if isinstance(images, list):\\n\",\n    \"            images = torch.stack([self.processor(image) for image in images]).cuda()\\n\",\n    \"        elif isinstance(images, torch.Tensor):\\n\",\n    \"            images = images.cuda()\\n\",\n    \"\\n\",\n    \"        with torch.no_grad():\\n\",\n    \"            image_features = self.clip_model.encode_image(images)\\n\",\n    \"            image_features /= image_features.norm(dim=1, keepdim=True)\\n\",\n    \"        return image_features\\n\",\n    \"    \\n\",\n    \"    def get_text_feature(self, text):\\n\",\n    \"        # 此处返回文本的特征向量\\n\",\n    \"        if isinstance(text, list) or isinstance(text, str):\\n\",\n    \"            text = self.text_tokenizer(text, return_tensors='pt', padding=True)['input_ids'].cuda()\\n\",\n    \"        elif isinstance(text, torch.Tensor):\\n\",\n    \"            text = text.cuda()\\n\",\n    \"\\n\",\n    \"        with torch.no_grad():\\n\",\n    \"            text_features = self.text_encoder(text)[1]\\n\",\n    \"            text_features /= text_features.norm(dim=1, keepdim=True)\\n\",\n    \"        return text_features\\n\",\n    \"\\n\",\n    \"    def calculate_clip_score(self, features1, features2):\\n\",\n    \"        # 此处2个特征向量的相似度，输入可以是 图片+文本、文本+文本、图片+图片。\\n\",\n    \"        # 返回的是相似度矩阵，维度为 f1.shape[0] * f2.shape[0]\\n\",\n    \"        score_matrix =  features1 @ features2.t()\\n\",\n    \"        return score_matrix\\n\",\n    \"\\n\",\n    \"    def get_aesthetics_score(self, features):\\n\",\n    \"        # 此处返回美学分数，传入的是CLIP的feature, 先计算get_image_feature在传入此函数~(模型是ViT-L-14)\\n\",\n    \"        with torch.no_grad():\\n\",\n    \"            scores = self.aesthetics_model(features)\\n\",\n    \"            scores = scores[:, 0].detach().cpu().numpy()\\n\",\n    \"        return scores\\n\",\n    \"    \\n\",\n    \"    def get_watermark_score(self, images):\\n\",\n    \"        if isinstance(images, list):\\n\",\n    \"            images = torch.stack([self.watermark_processor(image) for image in images]).cuda()\\n\",\n    \"        elif isinstance(images, torch.Tensor):\\n\",\n    \"            images = images.cuda()\\n\",\n    \"        with torch.no_grad():\\n\",\n    \"            pred = self.watermark_model(images)\\n\",\n    \"            watermark_scores = F.softmax(pred, dim=1)[:,0].detach().cpu().numpy()\\n\",\n    \"\\n\",\n    \"        return watermark_scores\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## 小规模数据测试\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"demo = FilterSystem()\\n\",\n    \"demo.init_clip_model()\\n\",\n    \"demo.init_aesthetics_model()\\n\",\n    \"demo.init_watermark_model()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"image_path = './demo_images/watermark_example.png'\\n\",\n    \"image_path2 = './demo_images/mengna.jpg'\\n\",\n    \"image_path3 = './demo_images/shuiyin.jpg'\\n\",\n    \"image_path4 = './demo_images/1.jpg'\\n\",\n    \"image_demo =  [Image.open(image_path).convert('RGB'), Image.open(image_path2).convert('RGB'), Image.open(image_path3).convert('RGB'), Image.open(image_path4).convert('RGB')]\\n\",\n    \"image_feature = demo.get_image_feature(image_demo,)  # 计算图片特征，传入图片列表，一般而言，可以在数据库保存这个东西，用于响应文本query\\n\",\n    \"aes_score = demo.get_aesthetics_score(image_feature)  # 计算美学分数，传入图片特征，一般而言，可以在数据库保存这个东西，用于响应文本query\\n\",\n    \"print(aes_score)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"text_demo = ['一副很美的画','港口小船', '蒙娜丽莎'] # 这里也可以只有一个文本，也就是query\\n\",\n    \"text_feature = demo.get_text_feature(text_demo) # 计算文本特征，传入文本列表\\n\",\n    \"similarity = demo.calculate_clip_score(image_feature, text_feature)  # 计算相似度\\n\",\n    \"print(similarity)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"watermark_score = demo.get_watermark_score(image_demo)\\n\",\n    \"print(watermark_score)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## 读取处理保存（单个进程）\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# data setting\\n\",\n    \"root_path = \\\"./project/dataset/laion_chinese_cwf/image_part00\\\"\\n\",\n    \"all_folders = sorted(os.listdir(root_path))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# model setting\\n\",\n    \"filter_model = FilterSystem()\\n\",\n    \"filter_model.init_clip_model()\\n\",\n    \"filter_model.init_aesthetics_model()\\n\",\n    \"filter_model.init_watermark_model()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from model import FilterSystem\\n\",\n    \"from dataset import TxtDataset\\n\",\n    \"import os\\n\",\n    \"from torch.utils.data import DataLoader\\n\",\n    \"from tqdm import tqdm\\n\",\n    \"from PIL import Image\\n\",\n    \"import numpy as np\\n\",\n    \"import pandas as pd\\n\",\n    \"\\n\",\n    \"def sub_process(filter_model, each_folder_path):\\n\",\n    \"    each_dataset = TxtDataset(each_folder_path)\\n\",\n    \"    each_dataloader = DataLoader(each_dataset, batch_size=8, shuffle=False, num_workers=8)\\n\",\n    \"\\n\",\n    \"    image_paths = []\\n\",\n    \"    aes_scores = []\\n\",\n    \"    clip_scores = []\\n\",\n    \"    watermark_scores = []\\n\",\n    \"    for iii, (batch_image_paths, texts,) in enumerate(tqdm(each_dataloader)):\\n\",\n    \"        images =  [Image.open(each_image_path).convert(\\\"RGB\\\") for each_image_path in batch_image_paths]\\n\",\n    \"        image_paths.extend(batch_image_paths)\\n\",\n    \"\\n\",\n    \"        image_features = filter_model.get_image_feature(images,)  # 计算图片特征，传入图片列表，一般而言，可以在数据库保存这个东西，用于响应文本query\\n\",\n    \"        aes_score = filter_model.get_aesthetics_score(image_features)  # 计算美学分数，传入图片特征，一般而言，可以在数据库保存这个东西，用于响应文本query\\n\",\n    \"        aes_scores.extend(aes_score)\\n\",\n    \"\\n\",\n    \"        text_features = filter_model.get_text_feature(list(texts)) # 计算文本特征，传入文本列表\\n\",\n    \"        clip_score = filter_model.calculate_clip_score(image_features, text_features)  # 计算相似度\\n\",\n    \"        clip_scores.extend(torch.diagonal(clip_score).detach().cpu().numpy())  # 需要取对角线，只需要自己和对应文本的相似度\\n\",\n    \"\\n\",\n    \"        watermark_score = filter_model.get_watermark_score(images)  # 计算水印分数，传入图片路径列表\\n\",\n    \"        watermark_scores.extend(watermark_score)\\n\",\n    \"        \\n\",\n    \"        # print('aes_score:', aes_score, '\\\\n',\\n\",\n    \"        #     'clip_score:', clip_score, '\\\\n',\\n\",\n    \"        #     'watermark_score:', watermark_score, '\\\\n',\\n\",\n    \"        #     'image_paths:', image_paths, '\\\\n',\\n\",\n    \"        #     'texts:', texts)\\n\",\n    \"        \\n\",\n    \"    score_pd = pd.DataFrame({'image_path': image_paths, 'aes_score': aes_scores, 'clip_score': clip_scores, 'watermark_score': watermark_scores})\\n\",\n    \"    score_pd.to_csv(os.path.join(each_folder_path, 'score.csv'), index=False)\\n\",\n    \"    print('save score.csv in {}'.format(each_folder_path), '\\\\n', '-'*20)\\n\",\n    \"\\n\",\n    \"for each_folder in all_folders[:10]:\\n\",\n    \"    each_folder_path = os.path.join(root_path, each_folder)\\n\",\n    \"    sub_process(filter_model, each_folder_path)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from model import FilterSystem\\n\",\n    \"from dataset import TxtDataset\\n\",\n    \"import os\\n\",\n    \"from torch.utils.data import DataLoader\\n\",\n    \"from tqdm import tqdm\\n\",\n    \"from PIL import Image\\n\",\n    \"import numpy as np\\n\",\n    \"import pandas as pd\\n\",\n    \"from concurrent.futures import ProcessPoolExecutor, wait, ALL_COMPLETED\\n\",\n    \"\\n\",\n    \"p = ProcessPoolExecutor(max_workers=4)\\n\",\n    \"\\n\",\n    \"def sub_process(filter_model, each_folder_path):\\n\",\n    \"    each_dataset = TxtDataset(each_folder_path)\\n\",\n    \"    each_dataloader = DataLoader(each_dataset, batch_size=8, shuffle=False, num_workers=8)\\n\",\n    \"\\n\",\n    \"    image_paths = []\\n\",\n    \"    aes_scores = []\\n\",\n    \"    clip_scores = []\\n\",\n    \"    watermark_scores = []\\n\",\n    \"    for iii, (batch_image_paths, texts,) in enumerate(each_dataloader):\\n\",\n    \"        images =  [Image.open(each_image_path) for each_image_path in batch_image_paths]\\n\",\n    \"        image_paths.extend(batch_image_paths)\\n\",\n    \"\\n\",\n    \"        image_features = filter_model.get_image_feature(images,)  # 计算图片特征，传入图片列表，一般而言，可以在数据库保存这个东西，用于响应文本query\\n\",\n    \"        aes_score = filter_model.get_aesthetics_score(image_features)  # 计算美学分数，传入图片特征，一般而言，可以在数据库保存这个东西，用于响应文本query\\n\",\n    \"        aes_scores.extend(aes_score)\\n\",\n    \"\\n\",\n    \"        text_features = filter_model.get_text_feature(list(texts)) # 计算文本特征，传入文本列表\\n\",\n    \"        clip_score = filter_model.calculate_clip_score(image_features, text_features)  # 计算相似度\\n\",\n    \"        clip_scores.extend(torch.diagonal(clip_score).detach().cpu().numpy())  # 需要取对角线，只需要自己和对应文本的相似度\\n\",\n    \"\\n\",\n    \"        watermark_score = filter_model.get_watermark_score(images)  # 计算水印分数，传入图片路径列表\\n\",\n    \"        watermark_scores.extend(watermark_score)\\n\",\n    \"        \\n\",\n    \"        # print('aes_score:', aes_score, '\\\\n',\\n\",\n    \"        #     'clip_score:', clip_score, '\\\\n',\\n\",\n    \"        #     'watermark_score:', watermark_score, '\\\\n',\\n\",\n    \"        #     'image_paths:', image_paths, '\\\\n',\\n\",\n    \"        #     'texts:', texts)\\n\",\n    \"        \\n\",\n    \"    score_pd = pd.DataFrame({'image_path': image_paths, 'aes_score': aes_scores, 'clip_score': clip_scores, 'watermark_score': watermark_scores})\\n\",\n    \"    score_pd.to_csv(os.path.join(each_folder_path, 'score.csv'), index=False)\\n\",\n    \"    print('save score.csv in {}'.format(each_folder_path), '\\\\n', '-'*20)\\n\",\n    \"\\n\",\n    \"for each_folder in all_folders[:10]:\\n\",\n    \"    each_folder_path = os.path.join(root_path, each_folder)\\n\",\n    \"    f1 = p.submit(sub_process, model_pool[0], each_folder_path)\\n\",\n    \"    f2 = p.submit(sub_process, model_pool[1], each_folder_path)\\n\",\n    \"    f3 = p.submit(sub_process, model_pool[2], each_folder_path)\\n\",\n    \"    f4 = p.submit(sub_process, model_pool[3], each_folder_path)\\n\",\n    \"    res = wait([f1, f2, f3, f4], return_when=ALL_COMPLETED)\\n\",\n    \"p.shutdown()\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# 用model pool来开启4进程跑\\n\",\n    \"model_pool = [FilterSystem() for i in range(4)]\\n\",\n    \"for model in model_pool:\\n\",\n    \"    model.init_clip_model()\\n\",\n    \"    model.init_aesthetics_model()\\n\",\n    \"    model.init_watermark_model()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"print(aes_scores, clip_scores, watermark_scores)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"print('image_paths:', image_paths, '\\\\n',  'texts:', texts)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# pytorch lightning + multi process.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import pytorch_lightning as pl\\n\",\n    \"\\n\",\n    \"class ScoreSystem(pl.LightningModule):\\n\",\n    \"    def __init__(Self):\\n\",\n    \"        super().__init__()\\n\",\n    \"        self.text_encoder, self.text_tokenizer, self.clip_model, self.processor = self.init_clip_model()\\n\",\n    \"        self.aesthetics_model = self.init_aesthetics_model()\\n\",\n    \"        self.watermark_model, self.watermark_processor = self.init_watermark_model()\\n\",\n    \"\\n\",\n    \"    def init_clip_model(self):\\n\",\n    \"        text_encoder = BertModel.from_pretrained(self.clip_model_path).eval().cuda()\\n\",\n    \"        text_tokenizer = BertTokenizer.from_pretrained(self.clip_model_path)\\n\",\n    \"        clip_model, _, processor = open_clip.create_model_and_transforms('ViT-L-14', pretrained='openai')\\n\",\n    \"        clip_model = clip_model.eval().cuda()\\n\",\n    \"        print(\\\"clip model loaded\\\")\\n\",\n    \"        return text_encoder, text_tokenizer, clip_model, processor\\n\",\n    \"\\n\",\n    \"    def init_aesthetics_model(self, ):\\n\",\n    \"        # 此处初始化美学模型\\n\",\n    \"        aesthetics_model = AestheticsMLP(768)\\n\",\n    \"        aesthetics_model.load_state_dict(torch.load(self.aesthetics_model_path)).eval().cuda()\\n\",\n    \"        print(\\\"aesthetics model loaded\\\")\\n\",\n    \"        return aesthetics_model\\n\",\n    \"\\n\",\n    \"    def init_watermark_model(self, ):\\n\",\n    \"        watermark_model = WaterMarkModel(self.watermark_model_path)\\n\",\n    \"        watermark_model.eval().cuda()\\n\",\n    \"        watermark_processor =  T.Compose([\\n\",\n    \"                                                T.Resize((256, 256)),\\n\",\n    \"                                                T.ToTensor(),\\n\",\n    \"                                                T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\\n\",\n    \"                                            ])\\n\",\n    \"        print(\\\"watermark model loaded\\\")\\n\",\n    \"        return watermark_model, watermark_processor\\n\",\n    \"\\n\",\n    \"    def get_image_feature(self, images):\\n\",\n    \"        # 此处返回图像的特征向量\\n\",\n    \"        if isinstance(images, list):\\n\",\n    \"            images = torch.stack([self.processor(image) for image in images]).cuda()\\n\",\n    \"        elif isinstance(images, torch.Tensor):\\n\",\n    \"            images = images.cuda()\\n\",\n    \"\\n\",\n    \"        with torch.no_grad():\\n\",\n    \"            image_features = self.clip_model.encode_image(images)\\n\",\n    \"            image_features /= image_features.norm(dim=1, keepdim=True)\\n\",\n    \"        return image_features\\n\",\n    \"    \\n\",\n    \"    def get_text_feature(self, text):\\n\",\n    \"        # 此处返回文本的特征向量\\n\",\n    \"        if isinstance(text, list) or isinstance(text, str):\\n\",\n    \"            text = self.text_tokenizer(text, return_tensors='pt', padding=True)['input_ids'].cuda()\\n\",\n    \"        elif isinstance(text, torch.Tensor):\\n\",\n    \"            text = text.cuda()\\n\",\n    \"\\n\",\n    \"        with torch.no_grad():\\n\",\n    \"            text_features = self.text_encoder(text)[1]\\n\",\n    \"            text_features /= text_features.norm(dim=1, keepdim=True)\\n\",\n    \"        return text_features\\n\",\n    \"\\n\",\n    \"    def calculate_clip_score(self, features1, features2):\\n\",\n    \"        # 此处2个特征向量的相似度，输入可以是 图片+文本、文本+文本、图片+图片。\\n\",\n    \"        # 返回的是相似度矩阵，维度为 f1.shape[0] * f2.shape[0]\\n\",\n    \"        score_matrix =  features1 @ features2.t()\\n\",\n    \"        return score_matrix\\n\",\n    \"\\n\",\n    \"    def get_aesthetics_score(self, features):\\n\",\n    \"        # 此处返回美学分数，传入的是CLIP的feature, 先计算get_image_feature在传入此函数~(模型是ViT-L-14)\\n\",\n    \"        with torch.no_grad():\\n\",\n    \"            scores = self.aesthetics_model(features)\\n\",\n    \"            scores = scores[:, 0].detach().cpu().numpy()\\n\",\n    \"        return scores\\n\",\n    \"    \\n\",\n    \"    def get_watermark_score(self, images):\\n\",\n    \"        if isinstance(images, list):\\n\",\n    \"            images = torch.stack([self.watermark_processor(image) for image in images]).cuda()\\n\",\n    \"        elif isinstance(images, torch.Tensor):\\n\",\n    \"            images = images.cuda()\\n\",\n    \"        with torch.no_grad():\\n\",\n    \"            pred = self.watermark_model(images)\\n\",\n    \"            watermark_scores = F.softmax(pred, dim=1)[:,0].detach().cpu().numpy()\\n\",\n    \"\\n\",\n    \"        return watermark_scores\\n\",\n    \"\\n\",\n    \"    def predict_step(self, batch, batch_idx):\\n\",\n    \"        images, texts = batch   \\n\",\n    \"        # TODO 这里要么传入处理后的2种图片，要么传入纯图片，然后在下面的函数处理。（目前是传入纯图片）\\n\",\n    \"        image_features = self.get_image_feature(images)\\n\",\n    \"        text_features = self.get_text_feature(texts)\\n\",\n    \"        clip_scores = self.calculate_clip_score(image_features, text_features)\\n\",\n    \"        aes_scores = self.get_aesthetics_score(image_features)\\n\",\n    \"        watermark_scores = self.get_watermark_score(images)\\n\",\n    \"        return clip_scores, aes_scores, watermark_scores\\n\",\n    \"\\n\",\n    \"    def on_predict_epoch_end(self, outputs):\\n\",\n    \"        # 此处返回所有预测结果\\n\",\n    \"        clip_scores = torch.cat([output[0] for output in outputs], dim=0)\\n\",\n    \"        aes_scores = torch.cat([output[1] for output in outputs], dim=0)\\n\",\n    \"        watermark_scores = torch.cat([output[2] for output in outputs], dim=0)\\n\",\n    \"        return clip_scores, aes_scores, watermark_scores\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3.9.13 ('base')\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.9.13\"\n  },\n  \"orig_nbformat\": 4,\n  \"vscode\": {\n   \"interpreter\": {\n    \"hash\": \"4cc247672a8bfe61dc951074f9ca89ab002dc0f7e14586a8bb0828228bebeefa\"\n   }\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"
  },
  {
    "path": "text-image/data_filter/wukong_filter.py",
    "content": "# %%\nfrom torch.utils.data import Dataset, ConcatDataset\nfrom torchvision import transforms\nimport os\nfrom PIL import Image\nfrom concurrent.futures import ProcessPoolExecutor\nimport json\nimport torch\nfrom transformers import BertModel\nimport open_clip\nimport numpy as np\nfrom transformers import BertTokenizer\nimport pandas as pd\nfrom tqdm import tqdm\nimport argparse\n\n\nparser = argparse.ArgumentParser(description=\"Simple example of a training script.\")\nparser.add_argument(\n    \"--part\",\n    type=int,\n    default=0,\n    required=True,\n)\nargs = parser.parse_args()\n\n\nclass CsvDataset(Dataset):\n    def __init__(self, input_filename, transforms, input_root, tokenizer, img_key, caption_key, sep=\"\\t\"):\n        # logging.debug(f'Loading csv data from {input_filename}.')\n        print(f'Loading csv data from {input_filename}.')\n        self.images = []\n        self.captions = []\n        if input_filename.endswith('.csv'):\n            df = pd.read_csv(input_filename, index_col=0)\n            df = df[df['used'] == 1]\n            self.images.extend(df[img_key].tolist())\n            self.captions.extend(df[caption_key].tolist())\n        # NOTE 中文的tokenizer\n        self.tokenizer = tokenizer\n        self.context_length = 77\n        self.root = input_root\n        self.transforms = transforms\n\n    def __len__(self):\n        return len(self.images)\n\n    def __getitem__(self, idx):\n        img_path = str(self.images[idx])\n        image = self.transforms(Image.open( os.path.join(self.root, img_path ))) \n        text = self.tokenizer(str(self.captions[idx]), max_length=self.context_length, padding='max_length', truncation=True, return_tensors='pt')['input_ids'][0]\n        return image, text, img_path\n\n\ntext_encoder = BertModel.from_pretrained(\"IDEA-CCNL/Taiyi-CLIP-RoBERTa-102M-ViT-L-Chinese\").eval().cuda()\nclip_model, _, processor = open_clip.create_model_and_transforms('ViT-L-14', pretrained='openai')\nclip_model = clip_model.eval().cuda()\ntext_tokenizer = BertTokenizer.from_pretrained(\"IDEA-CCNL/Taiyi-CLIP-RoBERTa-102M-ViT-L-Chinese\")\n\n\ninput_filename = './project/dataset/wukong/release'\npreprocess_fn = processor\ninput_root = './project/dataset/wukong/images'\ntokenizer = text_tokenizer\nall_csvs = sorted(os.listdir(input_filename))\n\nfor i in range(len(all_csvs)*args.part//5, len(all_csvs)*(args.part+1)//5):\n    # 分成5part\n    each_csv_path = os.path.join(input_filename, all_csvs[i])\n    dataset = CsvDataset(each_csv_path, preprocess_fn, input_root, tokenizer, img_key=\"name\", caption_key=\"caption\")\n    dataloader = torch.utils.data.DataLoader(dataset, batch_size=64, shuffle=False, num_workers=8, pin_memory=True)\n    \n    df = pd.read_csv(each_csv_path, index_col=0)\n    df = df[df['used'] == 1]\n    scores = []\n    for iii, (image, text, image_path) in enumerate(tqdm(dataloader)):\n        # print(image.shape, text.shape)\n        with torch.no_grad():\n            image = image.cuda()\n            text = text.cuda()\n            # print(image.shape, text.shape)\n            image_features = clip_model.encode_image(image)\n            text_features = text_encoder(text)[1]\n\n            # print(image_features.shape, text_features.shape)\n            # 归一化\n            image_features = image_features / image_features.norm(dim=1, keepdim=True)\n            text_features = text_features / text_features.norm(dim=1, keepdim=True)\n            score_each_pair =  image_features @ text_features.t()\n\n            scores.extend(torch.diagonal(score_each_pair).detach().cpu().numpy())\n            # break\n    df['score'] = scores\n    df.to_csv( each_csv_path.replace(all_csvs[i], 'score'+all_csvs[i]) , index=False)\n    print('saving score to', each_csv_path.replace(all_csvs[i], 'score'+all_csvs[i]) )\n   "
  },
  {
    "path": "text-image/data_filter/wukong_reader.py",
    "content": "from torch.utils.data import Dataset, ConcatDataset\nfrom torchvision import transforms\nimport os\nfrom PIL import Image\nfrom concurrent.futures import ProcessPoolExecutor\nimport json\nimport torch\nfrom transformers import BertModel\nimport open_clip\nimport numpy as np\nfrom transformers import BertTokenizer\nimport pandas as pd\nfrom tqdm import tqdm\nimport argparse\nimport torch\n# NOTE 加速读取数据，直接用原版的，在外部使用并行读取策略。30min->3min\nclass CsvDataset(Dataset):\n    def __init__(self, input_filename, input_root, img_key, caption_key, transforms=None, thres=0.2, sep=\"\\t\"):\n        # logging.debug(f'Loading csv data from {input_filename}.')\n        print(f'Loading csv data from {input_filename}.')\n        self.images = []\n        self.captions = []\n\n        if input_filename.endswith('.csv'):\n            # print(f\"Load Data from{input_filename}\")\n            df = pd.read_csv(input_filename, index_col=0)\n            df = df[df['used'] == 1]\n            df = df[df['score']>thres]\n            self.images.extend(df[img_key].tolist())\n            self.captions.extend(df[caption_key].tolist())\n        \n        # NOTE 中文的tokenizer\n        self.tokenizer = BertTokenizer.from_pretrained(\"hfl/chinese-roberta-wwm-ext\")\n\n        self.context_length = 77\n        self.root = input_root\n        self.transforms = transforms\n\n    def __len__(self):\n        return len(self.images)\n\n    def __getitem__(self, idx):\n        img_path = str(self.images[idx])\n        image = self.transforms(Image.open( os.path.join(self.root, img_path ))) \n        text = self.tokenizer(str(self.captions[idx]), max_length=self.context_length, padding='max_length', truncation=True, return_tensors='pt')['input_ids'][0]\n        return image, text\n\n\ndef process_pool_read_csv_dataset(input_root, input_filename, thres=0.20):\n    # here input_filename is a directory containing a CSV file\n    all_csvs = os.listdir(input_filename)\n\n    csv_with_score = [each for each in all_csvs if 'score' in each ]\n    all_datasets = []\n    res = []        \n    p = ProcessPoolExecutor(max_workers=24)\n    for i in range(len(csv_with_score)):\n        each_csv_path = os.path.join(input_filename, csv_with_score[i])\n        print(i, each_csv_path)\n        res.append(p.submit(CsvDataset, each_csv_path, input_root, img_key=\"name\", caption_key=\"caption\", thres=thres))\n    p.shutdown()\n    for future in res:\n        all_datasets.append(future.result())\n    dataset = ConcatDataset(all_datasets)\n    return dataset\n\n\ntokenizer = BertTokenizer.from_pretrained(\"IDEA-CCNL/Taiyi-CLIP-RoBERTa-102M-ViT-L-Chinese\", model_max_length=512)\ninput_filename = './project/dataset/wukong/release'   # 这里存的是csv标注地址\ninput_root = './project/dataset/wukong/images'\ndataset = process_pool_read_csv_dataset(input_root, input_filename, thres=0.22)\n\nprint(len(dataset))"
  },
  {
    "path": "text-image/fid_clip_score/.gitignore",
    "content": "/output*\n"
  },
  {
    "path": "text-image/fid_clip_score/coco_sample_generator.py",
    "content": "from torch.utils.data import Dataset, DataLoader\nimport pandas as pd \nimport os\nfrom diffusers import StableDiffusionPipeline\nfrom argparse import ArgumentParser\nfrom tqdm import tqdm\nfrom multiprocessing import Process\n\nparser = ArgumentParser()\nparser.add_argument('--coco_path', type=str, default='../dataset/coco')\nparser.add_argument('--coco_cache_file', type=str, default='../dataset/coco/subset.parquet')\nparser.add_argument('--output_path', type=str, default='./output')\nparser.add_argument('--model_path', type=str, default='../pretrained_models/stable-diffusion-v1-4')\nparser.add_argument('--sample_step', type=int, default=20)\nparser.add_argument('--guidance_scale', type=float, default=1.5)\nparser.add_argument('--batch_size', type=int, default=2)\nargs = parser.parse_args()\n\n\nclass COCOCaptionSubset(Dataset):\n    def __init__(self, path, transform=None):\n        self.df = pd.read_parquet(path)\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n        return row['file_name'], row['caption']\n\ndef save_images(images, image_paths, output_path):\n    for i, image_path in enumerate(image_paths):\n        image_path = image_path.replace('/', '_')\n        image_path = os.path.join(output_path, image_path)\n        images[i].save(image_path)\n\nif __name__ == '__main__':\n    # testing \n    coco_path = args.coco_path\n    # coco_cache_file = f'{coco_path}/subset.parquet'     # sampled subsets\n    cocosubset = COCOCaptionSubset(args.coco_cache_file)\n    cocosubsetloader = DataLoader(cocosubset, batch_size=args.batch_size, shuffle=False, num_workers=8)\n\n    # load the t2i model\n    stable_diffusion = StableDiffusionPipeline.from_pretrained(args.model_path, requires_safety_checker=False).to('cuda')   \n\n    sample_step = args.sample_step\n    guidance_scale = args.guidance_scale\n\n\n    output_path = os.path.join(\n        args.output_path,\n        f'./gs{guidance_scale}_ss{sample_step}'\n    ) \n    os.makedirs(output_path, exist_ok=True)\n\n    for i, (image_paths, captions) in enumerate(tqdm(cocosubsetloader)):\n        outputs = stable_diffusion(list(captions), num_inference_steps=sample_step, guidance_scale=guidance_scale).images\n        p = Process(target=save_images, args=(outputs, image_paths, output_path))\n        p.start()"
  },
  {
    "path": "text-image/fid_clip_score/compute_fid.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# FID指标计算\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"FID (same): -0.001\\n\",\n      \"FID (different): 486.117\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"import numpy as np\\n\",\n    \"from scipy.linalg import sqrtm\\n\",\n    \"def calculate_fid(act1, act2):\\n\",\n    \"    # calculate mean and covariance statistics\\n\",\n    \"    mu1, sigma1 = act1.mean(axis=0), np.cov(act1, rowvar=False)\\n\",\n    \"    mu2, sigma2 = act2.mean(axis=0), np.cov(act2, rowvar=False)\\n\",\n    \"    # print(mu1.shape, mu2.shape, sigma1.shape, sigma2.shape)\\n\",\n    \"    # calculate sum squared difference between means\\n\",\n    \"    ssdiff = np.sum((mu1 - mu2)**2.0)\\n\",\n    \"    # print(ssdiff)\\n\",\n    \"    # calculate sqrt of product between cov\\n\",\n    \"    covmean = sqrtm(sigma1.dot(sigma2)) # 负数平方根也能算\\n\",\n    \"    # print(covmean)\\n\",\n    \"    # check and correct imaginary numbers from sqrt\\n\",\n    \"    if np.iscomplexobj(covmean):\\n\",\n    \"        covmean = covmean.real\\n\",\n    \"    # calculate score\\n\",\n    \"    fid = ssdiff + np.trace(sigma1 + sigma2 - 2.0 * covmean)\\n\",\n    \"    return fid\\n\",\n    \"\\n\",\n    \"# define two collections of activations\\n\",\n    \"act1 = np.random.rand(2, 2048)\\n\",\n    \"act2 = np.random.rand(3, 2048)\\n\",\n    \"# fid between act1 and act1\\n\",\n    \"fid = calculate_fid(act1, act1)\\n\",\n    \"print('FID (same): %.3f' % fid) # should be 0.0\\n\",\n    \"# fid between act1 and act2\\n\",\n    \"fid = calculate_fid(act1, act2)\\n\",\n    \"print('FID (different): %.3f' % fid)    # should be > 0.0\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3.9.13 ('base')\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.9.13\"\n  },\n  \"orig_nbformat\": 4,\n  \"vscode\": {\n   \"interpreter\": {\n    \"hash\": \"4cc247672a8bfe61dc951074f9ca89ab002dc0f7e14586a8bb0828228bebeefa\"\n   }\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"
  },
  {
    "path": "text-image/fid_clip_score/fid_clip_coco.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"reference: https://wandb.ai/dalle-mini/dalle-mini/reports/CLIP-score-vs-FID-pareto-curves--VmlldzoyMDYyNTAy\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Sampling data\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# load data\\n\",\n    \"import json\\n\",\n    \"coco_path = '/home/tiger/project/dataset/coco'\\n\",\n    \"data_file = f'{coco_path}/annotations/captions_val2014.json'\\n\",\n    \"data = json.load(open(data_file))\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"# merge images and annotations\\n\",\n    \"import pandas as pd\\n\",\n    \"images = data['images']\\n\",\n    \"annotations = data['annotations']\\n\",\n    \"df = pd.DataFrame(images)\\n\",\n    \"df_annotations = pd.DataFrame(annotations)\\n\",\n    \"df = df.merge(pd.DataFrame(annotations), how='left', left_on='id', right_on='image_id')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"# keep only the relevant columns\\n\",\n    \"df = df[['file_name', 'caption']]\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"# shuffle the dataset\\n\",\n    \"df = df.sample(frac=1)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"# remove duplicate images\\n\",\n    \"df = df.drop_duplicates(subset='file_name')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"# create a random subset\\n\",\n    \"n_samples = 10000\\n\",\n    \"df_sample = df.sample(n_samples)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"# save the sample to a parquet file\\n\",\n    \"df_sample.to_parquet(f'{coco_path}/subset.parquet')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"# copy the images to reference folder\\n\",\n    \"from pathlib import Path\\n\",\n    \"import shutil\\n\",\n    \"subset_path = Path(f'{coco_path}/subset')\\n\",\n    \"subset_path.mkdir(exist_ok=True)\\n\",\n    \"for i, row in df_sample.iterrows():\\n\",\n    \"    path = f'{coco_path}/val2014/' + row['file_name']\\n\",\n    \"    shutil.copy(path, f'{coco_path}/subset/')\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# center crop the images\\n\",\n    \"def center_crop_images(folder, output_folder, size):\\n\",\n    \"    # coco images are not square, so we need to center crop them\\n\",\n    \"    from PIL import Image\\n\",\n    \"    import os\\n\",\n    \"    os.makedirs(output_folder, exist_ok=True)\\n\",\n    \"    for file in os.listdir(folder):\\n\",\n    \"        image_path = os.path.join(folder, file)\\n\",\n    \"        image = Image.open(image_path)\\n\",\n    \"        width, height = image.size\\n\",\n    \"        left = (width - size) / 2 if width > size else 0\\n\",\n    \"        top = (height - size) / 2 if height > size else 0\\n\",\n    \"        right = (width + size) / 2 if width > size else width\\n\",\n    \"        bottom = (height + size) / 2 if height > size else height\\n\",\n    \"        image = image.crop((left, top, right, bottom))\\n\",\n    \"        image = image.resize((size, size))  # resize non-square images\\n\",\n    \"        image.save(os.path.join(output_folder, file))\\n\",\n    \"\\n\",\n    \"folder_name = '/home/tiger/project/dataset/coco/subset'\\n\",\n    \"output_folder = '/home/tiger/project/dataset/coco/subset_cropped'\\n\",\n    \"center_crop_images(folder_name, output_folder, 320)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Load subset as dataloader\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# load the subset\\n\",\n    \"from torch.utils.data import Dataset, DataLoader\\n\",\n    \"import pandas as pd \\n\",\n    \"\\n\",\n    \"class COCOCaptionSubset(Dataset):\\n\",\n    \"    def __init__(self, path, transform=None):\\n\",\n    \"        self.df = pd.read_parquet(path)\\n\",\n    \"\\n\",\n    \"    def __len__(self):\\n\",\n    \"        return len(self.df)\\n\",\n    \"\\n\",\n    \"    def __getitem__(self, idx):\\n\",\n    \"        row = self.df.iloc[idx]\\n\",\n    \"        return row['file_name'], row['caption']\\n\",\n    \"\\n\",\n    \"# testing \\n\",\n    \"coco_path = '/home/tiger/project/dataset/coco'\\n\",\n    \"coco_cache_file = f'{coco_path}/subset.parquet'     # sampled subsets\\n\",\n    \"cocosubset = COCOCaptionSubset(coco_cache_file)\\n\",\n    \"cocosubsetloader = DataLoader(cocosubset, batch_size=64, shuffle=False, num_workers=8)\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": []\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Generating Images Via T2I Model\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# demo inference, use coco_sample_generator.py to generate more\\n\",\n    \"# load the t2i model\\n\",\n    \"# from diffusers import StableDiffusionPipeline\\n\",\n    \"# stable_diffusion = StableDiffusionPipeline.from_pretrained(\\\"/home/tiger/project/pretrained_models/stable-diffusion-v1-4\\\").to('cuda')   \\n\",\n    \"\\n\",\n    \"# sample_step = 20\\n\",\n    \"# guidance_scale = 1.5\\n\",\n    \"\\n\",\n    \"# import os\\n\",\n    \"\\n\",\n    \"# output_path = f'./output_gs{guidance_scale}_ss{sample_step}'\\n\",\n    \"# os.makedirs(output_path, exist_ok=True)\\n\",\n    \"\\n\",\n    \"# for i, (image_paths, captions) in enumerate(cocosubsetloader):\\n\",\n    \"#     outputs = stable_diffusion(list(captions), num_inference_steps=sample_step, guidance_scale=guidance_scale).images\\n\",\n    \"#     for j, image_path in enumerate(image_paths):\\n\",\n    \"#         image_path = image_path.replace('/', '_')\\n\",\n    \"#         image_path = os.path.join(output_path, image_path)\\n\",\n    \"#         outputs[j].save(image_path)\\n\",\n    \"#     break\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": []\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import torch\\n\",\n    \"device = torch.device('cuda')\\n\",\n    \"\\n\",\n    \"coco_subset_crop_path = '/home/tiger/project/dataset/coco/subset_cropped'\\n\",\n    \"output_root = '/home/tiger/project/position-guided-t2i/output'\\n\",\n    \"output_paths = [os.path.join(output_root, out) for out in sorted(os.listdir(output_root))]\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/anaconda3/lib/python3.9/site-packages/torchvision/models/_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated since 0.13 and will be removed in 0.15, please use 'weights' instead.\\n\",\n      \"  warnings.warn(\\n\",\n      \"/home/tiger/anaconda3/lib/python3.9/site-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and will be removed in 0.15. The current behavior is equivalent to passing `weights=None`.\\n\",\n      \"  warnings.warn(msg)\\n\",\n      \"100%|██████████| 50/50 [00:13<00:00,  3.58it/s]\\n\",\n      \"100%|██████████| 50/50 [00:16<00:00,  3.06it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs1.5_ss20 22.765903388613765\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 50/50 [00:09<00:00,  5.50it/s]\\n\",\n      \"100%|██████████| 50/50 [00:16<00:00,  3.03it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs2.0_ss20 18.159921113816665\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 50/50 [00:10<00:00,  4.95it/s]\\n\",\n      \"100%|██████████| 50/50 [00:15<00:00,  3.14it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs3.0_ss20 15.94397287378655\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 50/50 [00:09<00:00,  5.18it/s]\\n\",\n      \"100%|██████████| 50/50 [00:15<00:00,  3.14it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs4.0_ss20 16.315106185605657\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 50/50 [00:09<00:00,  5.17it/s]\\n\",\n      \"100%|██████████| 50/50 [00:16<00:00,  3.00it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs5.0_ss20 17.35088805364785\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 50/50 [00:09<00:00,  5.15it/s]\\n\",\n      \"100%|██████████| 50/50 [00:16<00:00,  3.01it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs6.0_ss20 17.933771904354728\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 50/50 [00:09<00:00,  5.21it/s]\\n\",\n      \"100%|██████████| 50/50 [00:16<00:00,  3.06it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs7.0_ss20 19.059673548019532\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 50/50 [00:09<00:00,  5.18it/s]\\n\",\n      \"100%|██████████| 50/50 [00:17<00:00,  2.90it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs8.0_ss20 20.12984543749127\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# fid score\\n\",\n    \"\\n\",\n    \"# !pip install pytorch_fid\\n\",\n    \"# !python -m pytorch_fid /home/tiger/project/dataset/coco/subset_cropped /home/tiger/project/position-guided-t2i/output/gs2.0_ss20\\n\",\n    \"\\n\",\n    \"from pytorch_fid.fid_score import calculate_fid_given_paths\\n\",\n    \"\\n\",\n    \"fids = []\\n\",\n    \"for output_path in output_paths:\\n\",\n    \"    fid_value = calculate_fid_given_paths([coco_subset_crop_path, output_path], batch_size=200, device=device, dims=2048, num_workers=8)\\n\",\n    \"    fids.append(fid_value)\\n\",\n    \"    print(output_path, fid_value)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from transformers import CLIPProcessor, CLIPModel, CLIPTokenizer\\n\",\n    \"from PIL import Image\\n\",\n    \"import numpy as np\\n\",\n    \"from tqdm import tqdm\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def load_clip_model(model_path='openai/clip-vit-large-patch14'):\\n\",\n    \"    # text_encoder = BertModel.from_pretrained(model_path).eval().cuda()\\n\",\n    \"    # text_tokenizer = BertTokenizer.from_pretrained(model_path)\\n\",\n    \"    clip_model = CLIPModel.from_pretrained(model_path)\\n\",\n    \"    processor = CLIPProcessor.from_pretrained(model_path)\\n\",\n    \"    tokenizer = CLIPTokenizer.from_pretrained(model_path)\\n\",\n    \"\\n\",\n    \"    clip_model = clip_model.eval().cuda()\\n\",\n    \"    return clip_model, processor, tokenizer\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def clip_score(clip_model, processor, tokenizer, dataloader, output_image_path):\\n\",\n    \"    all_image_features = []\\n\",\n    \"    all_text_features = []\\n\",\n    \"    for (i, (image_paths, captions)) in enumerate(tqdm(dataloader)):\\n\",\n    \"        # print(image_paths, captions)\\n\",\n    \"        text_inputs = tokenizer(list(captions), padding=True, return_tensors=\\\"pt\\\").to('cuda')\\n\",\n    \"        text_features = clip_model.get_text_features(**text_inputs)\\n\",\n    \"        text_features = text_features / text_features.norm(dim=-1, keepdim=True)\\n\",\n    \"        text_features = text_features.detach().cpu().numpy()\\n\",\n    \"        all_text_features.append(text_features)\\n\",\n    \"\\n\",\n    \"        # vit 速度比较龟\\n\",\n    \"        images = [Image.open(os.path.join( output_image_path , image_path)) for image_path in image_paths]\\n\",\n    \"        image_inputs = processor(images = images, return_tensors=\\\"pt\\\").to('cuda')\\n\",\n    \"        image_features = clip_model.get_image_features(**image_inputs)\\n\",\n    \"        image_features = image_features / image_features.norm(dim=-1, keepdim=True)\\n\",\n    \"        image_features = image_features.detach().cpu().numpy()\\n\",\n    \"        all_image_features.append(image_features)\\n\",\n    \"\\n\",\n    \"        # NOTE testing 等太久了，抽样吧... 需要全部的话，把这个 if 去掉\\n\",\n    \"        if i == 10:\\n\",\n    \"            break\\n\",\n    \"\\n\",\n    \"    all_text_features = np.concatenate(all_text_features, axis=0)\\n\",\n    \"    all_image_features = np.concatenate(all_image_features, axis=0)\\n\",\n    \"    mean_similarity = (all_image_features @ all_text_features.T).diagonal().mean()\\n\",\n    \"    return mean_similarity\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 6,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"  6%|▋         | 10/157 [00:15<03:45,  1.54s/it]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs1.5_ss20 0.23490335\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"  6%|▋         | 10/157 [00:14<03:39,  1.50s/it]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs2.0_ss20 0.24406949\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"  6%|▋         | 10/157 [00:15<03:41,  1.51s/it]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs3.0_ss20 0.25112092\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"  6%|▋         | 10/157 [00:14<03:39,  1.49s/it]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs4.0_ss20 0.25709876\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"  6%|▋         | 10/157 [00:14<03:37,  1.48s/it]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs5.0_ss20 0.25781947\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"  6%|▋         | 10/157 [00:14<03:40,  1.50s/it]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs6.0_ss20 0.2593051\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"  6%|▋         | 10/157 [00:14<03:37,  1.48s/it]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs7.0_ss20 0.26007786\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"  6%|▋         | 10/157 [00:14<03:37,  1.48s/it]\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/project/position-guided-t2i/output/gs8.0_ss20 0.2596085\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"clip_model_path=\\\"/home/tiger/project/pretrained_models/clip-vit-large-patch14\\\"\\n\",\n    \"clip_model, processor, tokenizer = load_clip_model(clip_model_path)\\n\",\n    \"clip_scores = []\\n\",\n    \"for output_path in output_paths:\\n\",\n    \"    clip_score_each = clip_score(clip_model, processor, tokenizer, cocosubsetloader, output_path)   # 3min ....\\n\",\n    \"    print(output_path, clip_score_each)\\n\",\n    \"    clip_scores.append(clip_score_each)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 7,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"image/png\": \"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\",\n      \"text/plain\": [\n       \"<Figure size 640x480 with 1 Axes>\"\n      ]\n     },\n     \"metadata\": {},\n     \"output_type\": \"display_data\"\n    }\n   ],\n   \"source\": [\n    \"# plot clip score as x-axis, fid score as y-axis, line chart\\n\",\n    \"import matplotlib.pyplot as plt\\n\",\n    \"plt.plot(clip_scores, fids, 'o-')\\n\",\n    \"plt.xlabel('clip score')\\n\",\n    \"plt.ylabel('fid score')\\n\",\n    \"plt.show()\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3.9.13 ('base')\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.9.13\"\n  },\n  \"orig_nbformat\": 4,\n  \"vscode\": {\n   \"interpreter\": {\n    \"hash\": \"4cc247672a8bfe61dc951074f9ca89ab002dc0f7e14586a8bb0828228bebeefa\"\n   }\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"
  },
  {
    "path": "text-image/fid_clip_score/fid_clip_coco_cn.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# load data\\n\",\n    \"import json\\n\",\n    \"import pandas as pd\\n\",\n    \"import os\\n\",\n    \"\\n\",\n    \"coco_path = '../dataset/coco'\\n\",\n    \"data_file = f'../dataset/coco/coco-cn-version1805v1.1/imageid.human-written-caption.txt'\\n\",\n    \"\\n\",\n    \"df = pd.read_table(data_file, sep='\\\\t', header=None, names = ['file_name', 'caption'])\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"df['file_name'] = df['file_name'].apply(lambda x: os.path.join(x.split('_')[1], x.split('#')[0]+'.jpg'))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# shuffle the dataset\\n\",\n    \"df = df.sample(frac=1)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"# remove duplicate images\\n\",\n    \"df = df.drop_duplicates(subset='file_name')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"# create a random subset\\n\",\n    \"n_samples = 1000\\n\",\n    \"df_sample = df.sample(n_samples)\\n\",\n    \"# save the sample to a parquet file\\n\",\n    \"df_sample.to_parquet(f'{coco_path}/subset_cn.parquet')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"# copy the images to reference folder\\n\",\n    \"from pathlib import Path\\n\",\n    \"import shutil\\n\",\n    \"subset_path = Path(f'{coco_path}/subset_cn')\\n\",\n    \"subset_path.mkdir(exist_ok=True)\\n\",\n    \"for i, row in df_sample.iterrows():\\n\",\n    \"    path = f'{coco_path}/' + row['file_name']\\n\",\n    \"    shutil.copy(path, f'{coco_path}/subset_cn/')\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# center crop the images\\n\",\n    \"def center_crop_images(folder, output_folder, size):\\n\",\n    \"    # coco images are not square, so we need to center crop them\\n\",\n    \"    from PIL import Image\\n\",\n    \"    import os\\n\",\n    \"    os.makedirs(output_folder, exist_ok=True)\\n\",\n    \"    for file in os.listdir(folder):\\n\",\n    \"        image_path = os.path.join(folder, file)\\n\",\n    \"        image = Image.open(image_path)\\n\",\n    \"        width, height = image.size\\n\",\n    \"        left = (width - size) / 2 if width > size else 0\\n\",\n    \"        top = (height - size) / 2 if height > size else 0\\n\",\n    \"        right = (width + size) / 2 if width > size else width\\n\",\n    \"        bottom = (height + size) / 2 if height > size else height\\n\",\n    \"        image = image.crop((left, top, right, bottom))\\n\",\n    \"        image = image.resize((size, size))  # resize non-square images\\n\",\n    \"        image.save(os.path.join(output_folder, file))\\n\",\n    \"\\n\",\n    \"folder_name = '../dataset/coco/subset_cn'\\n\",\n    \"output_folder = '../dataset/coco/subset_cn_cropped'\\n\",\n    \"center_crop_images(folder_name, output_folder, 320)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# ⬆️ preprocess data ⬇️ load data\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# load the subset\\n\",\n    \"from torch.utils.data import Dataset, DataLoader\\n\",\n    \"import pandas as pd \\n\",\n    \"\\n\",\n    \"class COCOCaptionSubset(Dataset):\\n\",\n    \"    def __init__(self, path, transform=None):\\n\",\n    \"        self.df = pd.read_parquet(path)\\n\",\n    \"        self.df['file_name'] = self.df['file_name'].apply(lambda x: x.replace('/', '_'))\\n\",\n    \"\\n\",\n    \"    def __len__(self):\\n\",\n    \"        return len(self.df)\\n\",\n    \"\\n\",\n    \"    def __getitem__(self, idx):\\n\",\n    \"        row = self.df.iloc[idx]\\n\",\n    \"        \\n\",\n    \"        return row['file_name'], row['caption']\\n\",\n    \"\\n\",\n    \"# testing \\n\",\n    \"coco_path = '../dataset/coco'\\n\",\n    \"coco_cache_file = f'{coco_path}/subset_cn.parquet'     # sampled subsets\\n\",\n    \"cocosubset = COCOCaptionSubset(coco_cache_file)\\n\",\n    \"cocosubsetloader = DataLoader(cocosubset, batch_size=16, shuffle=False, num_workers=8)\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"cocosubset[0]\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from diffusers import StableDiffusionPipeline, DDIMScheduler\\n\",\n    \"stable_diffusion = StableDiffusionPipeline.from_pretrained(\\\"../pretrained_models/stable_cn\\\").to('cuda')   \\n\",\n    \"out = stable_diffusion('古道西风瘦马，中国画')\\n\",\n    \"out[0][0]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# After generation by `run_generator_cn.sh`\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"/home/tiger/anaconda3/lib/python3.9/site-packages/torchvision/models/_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated since 0.13 and will be removed in 0.15, please use 'weights' instead.\\n\",\n      \"  warnings.warn(\\n\",\n      \"/home/tiger/anaconda3/lib/python3.9/site-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and will be removed in 0.15. The current behavior is equivalent to passing `weights=None`.\\n\",\n      \"  warnings.warn(msg)\\n\",\n      \"100%|██████████| 5/5 [00:10<00:00,  2.07s/it]\\n\",\n      \"100%|██████████| 5/5 [00:04<00:00,  1.08it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"[0.37982094 0.32691598 0.32423221 ... 0.46967193 0.41200255 0.40518777] (2048,)\\n\",\n      \"./output_cn/gs1.5_ss20 82.83122165497986\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 5/5 [00:02<00:00,  1.67it/s]\\n\",\n      \"  0%|          | 0/5 [00:01<?, ?it/s]\\n\"\n     ]\n    },\n    {\n     \"ename\": \"KeyboardInterrupt\",\n     \"evalue\": \"\",\n     \"output_type\": \"error\",\n     \"traceback\": [\n      \"\\u001b[0;31m---------------------------------------------------------------------------\\u001b[0m\",\n      \"\\u001b[0;31mKeyboardInterrupt\\u001b[0m                         Traceback (most recent call last)\",\n      \"\\u001b[0;32m/tmp/ipykernel_253571/2121088339.py\\u001b[0m in \\u001b[0;36m<module>\\u001b[0;34m\\u001b[0m\\n\\u001b[1;32m     12\\u001b[0m \\u001b[0mfids\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0;34m[\\u001b[0m\\u001b[0;34m]\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m     13\\u001b[0m \\u001b[0;32mfor\\u001b[0m \\u001b[0moutput_path\\u001b[0m \\u001b[0;32min\\u001b[0m \\u001b[0moutput_paths\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m---> 14\\u001b[0;31m     \\u001b[0mfid_value\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0mcalculate_fid_given_paths\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0;34m[\\u001b[0m\\u001b[0mcoco_subset_crop_path\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0moutput_path\\u001b[0m\\u001b[0;34m]\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mbatch_size\\u001b[0m\\u001b[0;34m=\\u001b[0m\\u001b[0;36m200\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mdevice\\u001b[0m\\u001b[0;34m=\\u001b[0m\\u001b[0mdevice\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mdims\\u001b[0m\\u001b[0;34m=\\u001b[0m\\u001b[0;36m2048\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mnum_workers\\u001b[0m\\u001b[0;34m=\\u001b[0m\\u001b[0;36m8\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[1;32m     15\\u001b[0m     \\u001b[0mfids\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0mappend\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mfid_value\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m     16\\u001b[0m     \\u001b[0mprint\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0moutput_path\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mfid_value\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/site-packages/pytorch_fid/fid_score.py\\u001b[0m in \\u001b[0;36mcalculate_fid_given_paths\\u001b[0;34m(paths, batch_size, device, dims, num_workers)\\u001b[0m\\n\\u001b[1;32m    257\\u001b[0m     m1, s1 = compute_statistics_of_path(paths[0], model, batch_size,\\n\\u001b[1;32m    258\\u001b[0m                                         dims, device, num_workers)\\n\\u001b[0;32m--> 259\\u001b[0;31m     m2, s2 = compute_statistics_of_path(paths[1], model, batch_size,\\n\\u001b[0m\\u001b[1;32m    260\\u001b[0m                                         dims, device, num_workers)\\n\\u001b[1;32m    261\\u001b[0m     \\u001b[0mprint\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mm1\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mm1\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0mshape\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/site-packages/pytorch_fid/fid_score.py\\u001b[0m in \\u001b[0;36mcompute_statistics_of_path\\u001b[0;34m(path, model, batch_size, dims, device, num_workers)\\u001b[0m\\n\\u001b[1;32m    239\\u001b[0m         files = sorted([file for ext in IMAGE_EXTENSIONS\\n\\u001b[1;32m    240\\u001b[0m                        for file in path.glob('*.{}'.format(ext))])\\n\\u001b[0;32m--> 241\\u001b[0;31m         m, s = calculate_activation_statistics(files, model, batch_size,\\n\\u001b[0m\\u001b[1;32m    242\\u001b[0m                                                dims, device, num_workers)\\n\\u001b[1;32m    243\\u001b[0m \\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/site-packages/pytorch_fid/fid_score.py\\u001b[0m in \\u001b[0;36mcalculate_activation_statistics\\u001b[0;34m(files, model, batch_size, dims, device, num_workers)\\u001b[0m\\n\\u001b[1;32m    224\\u001b[0m                \\u001b[0mthe\\u001b[0m \\u001b[0minception\\u001b[0m \\u001b[0mmodel\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    225\\u001b[0m     \\\"\\\"\\\"\\n\\u001b[0;32m--> 226\\u001b[0;31m     \\u001b[0mact\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0mget_activations\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mfiles\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mmodel\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mbatch_size\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mdims\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mdevice\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mnum_workers\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[1;32m    227\\u001b[0m     \\u001b[0mmu\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0mnp\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0mmean\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mact\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0maxis\\u001b[0m\\u001b[0;34m=\\u001b[0m\\u001b[0;36m0\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    228\\u001b[0m     \\u001b[0msigma\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0mnp\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0mcov\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mact\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mrowvar\\u001b[0m\\u001b[0;34m=\\u001b[0m\\u001b[0;32mFalse\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/site-packages/pytorch_fid/fid_score.py\\u001b[0m in \\u001b[0;36mget_activations\\u001b[0;34m(files, model, batch_size, dims, device, num_workers)\\u001b[0m\\n\\u001b[1;32m    128\\u001b[0m     \\u001b[0mstart_idx\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0;36m0\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    129\\u001b[0m \\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m--> 130\\u001b[0;31m     \\u001b[0;32mfor\\u001b[0m \\u001b[0mbatch\\u001b[0m \\u001b[0;32min\\u001b[0m \\u001b[0mtqdm\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mdataloader\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[1;32m    131\\u001b[0m         \\u001b[0mbatch\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0mbatch\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0mto\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mdevice\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    132\\u001b[0m \\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/site-packages/tqdm/std.py\\u001b[0m in \\u001b[0;36m__iter__\\u001b[0;34m(self)\\u001b[0m\\n\\u001b[1;32m   1193\\u001b[0m \\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m   1194\\u001b[0m         \\u001b[0;32mtry\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m-> 1195\\u001b[0;31m             \\u001b[0;32mfor\\u001b[0m \\u001b[0mobj\\u001b[0m \\u001b[0;32min\\u001b[0m \\u001b[0miterable\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[1;32m   1196\\u001b[0m                 \\u001b[0;32myield\\u001b[0m \\u001b[0mobj\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m   1197\\u001b[0m                 \\u001b[0;31m# Update and possibly print the progressbar.\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/site-packages/torch/utils/data/dataloader.py\\u001b[0m in \\u001b[0;36m__next__\\u001b[0;34m(self)\\u001b[0m\\n\\u001b[1;32m    679\\u001b[0m                 \\u001b[0;31m# TODO(https://github.com/pytorch/pytorch/issues/76750)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    680\\u001b[0m                 \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_reset\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0;34m)\\u001b[0m  \\u001b[0;31m# type: ignore[call-arg]\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m--> 681\\u001b[0;31m             \\u001b[0mdata\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_next_data\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[1;32m    682\\u001b[0m             \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_num_yielded\\u001b[0m \\u001b[0;34m+=\\u001b[0m \\u001b[0;36m1\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    683\\u001b[0m             \\u001b[0;32mif\\u001b[0m \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_dataset_kind\\u001b[0m \\u001b[0;34m==\\u001b[0m \\u001b[0m_DatasetKind\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0mIterable\\u001b[0m \\u001b[0;32mand\\u001b[0m\\u001b[0;31m \\u001b[0m\\u001b[0;31m\\\\\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/site-packages/torch/utils/data/dataloader.py\\u001b[0m in \\u001b[0;36m_next_data\\u001b[0;34m(self)\\u001b[0m\\n\\u001b[1;32m   1357\\u001b[0m \\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m   1358\\u001b[0m             \\u001b[0;32massert\\u001b[0m \\u001b[0;32mnot\\u001b[0m \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_shutdown\\u001b[0m \\u001b[0;32mand\\u001b[0m \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_tasks_outstanding\\u001b[0m \\u001b[0;34m>\\u001b[0m \\u001b[0;36m0\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m-> 1359\\u001b[0;31m             \\u001b[0midx\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mdata\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_get_data\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[1;32m   1360\\u001b[0m             \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_tasks_outstanding\\u001b[0m \\u001b[0;34m-=\\u001b[0m \\u001b[0;36m1\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m   1361\\u001b[0m             \\u001b[0;32mif\\u001b[0m \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_dataset_kind\\u001b[0m \\u001b[0;34m==\\u001b[0m \\u001b[0m_DatasetKind\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0mIterable\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/site-packages/torch/utils/data/dataloader.py\\u001b[0m in \\u001b[0;36m_get_data\\u001b[0;34m(self)\\u001b[0m\\n\\u001b[1;32m   1323\\u001b[0m         \\u001b[0;32melse\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m   1324\\u001b[0m             \\u001b[0;32mwhile\\u001b[0m \\u001b[0;32mTrue\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m-> 1325\\u001b[0;31m                 \\u001b[0msuccess\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mdata\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_try_get_data\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[1;32m   1326\\u001b[0m                 \\u001b[0;32mif\\u001b[0m \\u001b[0msuccess\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m   1327\\u001b[0m                     \\u001b[0;32mreturn\\u001b[0m \\u001b[0mdata\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/site-packages/torch/utils/data/dataloader.py\\u001b[0m in \\u001b[0;36m_try_get_data\\u001b[0;34m(self, timeout)\\u001b[0m\\n\\u001b[1;32m   1161\\u001b[0m         \\u001b[0;31m#   (bool: whether successfully get data, any: data if successful else None)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m   1162\\u001b[0m         \\u001b[0;32mtry\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m-> 1163\\u001b[0;31m             \\u001b[0mdata\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_data_queue\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0mget\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mtimeout\\u001b[0m\\u001b[0;34m=\\u001b[0m\\u001b[0mtimeout\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[1;32m   1164\\u001b[0m             \\u001b[0;32mreturn\\u001b[0m \\u001b[0;34m(\\u001b[0m\\u001b[0;32mTrue\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mdata\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m   1165\\u001b[0m         \\u001b[0;32mexcept\\u001b[0m \\u001b[0mException\\u001b[0m \\u001b[0;32mas\\u001b[0m \\u001b[0me\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/multiprocessing/queues.py\\u001b[0m in \\u001b[0;36mget\\u001b[0;34m(self, block, timeout)\\u001b[0m\\n\\u001b[1;32m    111\\u001b[0m                 \\u001b[0;32mif\\u001b[0m \\u001b[0mblock\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    112\\u001b[0m                     \\u001b[0mtimeout\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0mdeadline\\u001b[0m \\u001b[0;34m-\\u001b[0m \\u001b[0mtime\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0mmonotonic\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m--> 113\\u001b[0;31m                     \\u001b[0;32mif\\u001b[0m \\u001b[0;32mnot\\u001b[0m \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_poll\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mtimeout\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[1;32m    114\\u001b[0m                         \\u001b[0;32mraise\\u001b[0m \\u001b[0mEmpty\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    115\\u001b[0m                 \\u001b[0;32melif\\u001b[0m \\u001b[0;32mnot\\u001b[0m \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_poll\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/multiprocessing/connection.py\\u001b[0m in \\u001b[0;36mpoll\\u001b[0;34m(self, timeout)\\u001b[0m\\n\\u001b[1;32m    260\\u001b[0m         \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_check_closed\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    261\\u001b[0m         \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_check_readable\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m--> 262\\u001b[0;31m         \\u001b[0;32mreturn\\u001b[0m \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_poll\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mtimeout\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[1;32m    263\\u001b[0m \\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    264\\u001b[0m     \\u001b[0;32mdef\\u001b[0m \\u001b[0m__enter__\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mself\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/multiprocessing/connection.py\\u001b[0m in \\u001b[0;36m_poll\\u001b[0;34m(self, timeout)\\u001b[0m\\n\\u001b[1;32m    427\\u001b[0m \\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    428\\u001b[0m     \\u001b[0;32mdef\\u001b[0m \\u001b[0m_poll\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mself\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mtimeout\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m--> 429\\u001b[0;31m         \\u001b[0mr\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0mwait\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0;34m[\\u001b[0m\\u001b[0mself\\u001b[0m\\u001b[0;34m]\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mtimeout\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[1;32m    430\\u001b[0m         \\u001b[0;32mreturn\\u001b[0m \\u001b[0mbool\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mr\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    431\\u001b[0m \\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/multiprocessing/connection.py\\u001b[0m in \\u001b[0;36mwait\\u001b[0;34m(object_list, timeout)\\u001b[0m\\n\\u001b[1;32m    934\\u001b[0m \\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    935\\u001b[0m             \\u001b[0;32mwhile\\u001b[0m \\u001b[0;32mTrue\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m--> 936\\u001b[0;31m                 \\u001b[0mready\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0mselector\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0mselect\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mtimeout\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[1;32m    937\\u001b[0m                 \\u001b[0;32mif\\u001b[0m \\u001b[0mready\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    938\\u001b[0m                     \\u001b[0;32mreturn\\u001b[0m \\u001b[0;34m[\\u001b[0m\\u001b[0mkey\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0mfileobj\\u001b[0m \\u001b[0;32mfor\\u001b[0m \\u001b[0;34m(\\u001b[0m\\u001b[0mkey\\u001b[0m\\u001b[0;34m,\\u001b[0m \\u001b[0mevents\\u001b[0m\\u001b[0;34m)\\u001b[0m \\u001b[0;32min\\u001b[0m \\u001b[0mready\\u001b[0m\\u001b[0;34m]\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;32m~/anaconda3/lib/python3.9/selectors.py\\u001b[0m in \\u001b[0;36mselect\\u001b[0;34m(self, timeout)\\u001b[0m\\n\\u001b[1;32m    414\\u001b[0m         \\u001b[0mready\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0;34m[\\u001b[0m\\u001b[0;34m]\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    415\\u001b[0m         \\u001b[0;32mtry\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m--> 416\\u001b[0;31m             \\u001b[0mfd_event_list\\u001b[0m \\u001b[0;34m=\\u001b[0m \\u001b[0mself\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0m_selector\\u001b[0m\\u001b[0;34m.\\u001b[0m\\u001b[0mpoll\\u001b[0m\\u001b[0;34m(\\u001b[0m\\u001b[0mtimeout\\u001b[0m\\u001b[0;34m)\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[1;32m    417\\u001b[0m         \\u001b[0;32mexcept\\u001b[0m \\u001b[0mInterruptedError\\u001b[0m\\u001b[0;34m:\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m    418\\u001b[0m             \\u001b[0;32mreturn\\u001b[0m \\u001b[0mready\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0;34m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[0;31mKeyboardInterrupt\\u001b[0m: \"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# fid\\n\",\n    \"import torch\\n\",\n    \"device = torch.device('cuda')\\n\",\n    \"\\n\",\n    \"coco_subset_crop_path = '../dataset/coco/subset_cn_cropped'\\n\",\n    \"output_root = './output_cn'\\n\",\n    \"output_paths = [os.path.join(output_root, out) for out in sorted(os.listdir(output_root))]\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"from pytorch_fid.fid_score import calculate_fid_given_paths\\n\",\n    \"\\n\",\n    \"fids = []\\n\",\n    \"for output_path in output_paths:\\n\",\n    \"    fid_value = calculate_fid_given_paths([coco_subset_crop_path, output_path], batch_size=200, device=device, dims=2048, num_workers=8)\\n\",\n    \"    fids.append(fid_value)\\n\",\n    \"    print(output_path, fid_value)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 63/63 [00:31<00:00,  1.98it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"./output_cn/gs1.5_ss20 0.10783037\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 63/63 [00:31<00:00,  2.00it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"./output_cn/gs2.0_ss20 0.12101555\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 63/63 [00:31<00:00,  2.00it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"./output_cn/gs3.0_ss20 0.13520376\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 63/63 [00:31<00:00,  2.01it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"./output_cn/gs4.0_ss20 0.14092724\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 63/63 [00:31<00:00,  1.99it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"./output_cn/gs5.0_ss20 0.14418064\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 63/63 [00:31<00:00,  1.99it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"./output_cn/gs6.0_ss20 0.1452085\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 63/63 [00:31<00:00,  2.00it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"./output_cn/gs7.0_ss20 0.1480369\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"100%|██████████| 63/63 [00:31<00:00,  2.00it/s]\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"./output_cn/gs8.0_ss20 0.14733191\\n\"\n     ]\n    },\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# clip score\\n\",\n    \"from transformers import CLIPProcessor, CLIPModel, CLIPTokenizer, BertTokenizer, BertModel\\n\",\n    \"from PIL import Image\\n\",\n    \"import numpy as np\\n\",\n    \"from tqdm import tqdm\\n\",\n    \"\\n\",\n    \"def load_clip_model(model_path='openai/clip-vit-large-patch14'):\\n\",\n    \"    text_encoder = BertModel.from_pretrained('../pretrained_models/Taiyi-CLIP-RoBERTa-102M-ViT-L-Chinese').eval().cuda()\\n\",\n    \"    text_tokenizer = BertTokenizer.from_pretrained('../pretrained_models/Taiyi-CLIP-RoBERTa-102M-ViT-L-Chinese')\\n\",\n    \"    clip_model = CLIPModel.from_pretrained(model_path)\\n\",\n    \"    processor = CLIPProcessor.from_pretrained(model_path)\\n\",\n    \"    # tokenizer = CLIPTokenizer.from_pretrained(model_path)\\n\",\n    \"\\n\",\n    \"    clip_model = clip_model.eval().cuda()\\n\",\n    \"    return clip_model, processor, text_tokenizer, text_encoder\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def clip_score(clip_model, processor, tokenizer, text_encoder, dataloader, output_image_path):\\n\",\n    \"    all_image_features = []\\n\",\n    \"    all_text_features = []\\n\",\n    \"    for (i, (image_paths, captions)) in enumerate(tqdm(dataloader)):\\n\",\n    \"        # print(image_paths, captions)\\n\",\n    \"        text_inputs = tokenizer(list(captions), padding=True, return_tensors=\\\"pt\\\").to('cuda')\\n\",\n    \"        # print(text_inputs)\\n\",\n    \"        text_features = text_encoder(text_inputs.input_ids)[1]\\n\",\n    \"        text_features = text_features / text_features.norm(dim=-1, keepdim=True)\\n\",\n    \"        text_features = text_features.detach().cpu().numpy()\\n\",\n    \"        all_text_features.append(text_features)\\n\",\n    \"\\n\",\n    \"        images = [Image.open(os.path.join( output_image_path , image_path)) for image_path in image_paths]\\n\",\n    \"        image_inputs = processor(images = images, return_tensors=\\\"pt\\\").to('cuda')\\n\",\n    \"        image_features = clip_model.get_image_features(**image_inputs)\\n\",\n    \"        # image_inputs = [processor(image) for image in images]\\n\",\n    \"        # image_inputs = torch.stack(image_inputs).to('cuda')\\n\",\n    \"        image_features = clip_model.get_image_features(**image_inputs)\\n\",\n    \"        image_features = image_features / image_features.norm(dim=-1, keepdim=True)\\n\",\n    \"        image_features = image_features.detach().cpu().numpy()\\n\",\n    \"        all_image_features.append(image_features)\\n\",\n    \"\\n\",\n    \"    all_text_features = np.concatenate(all_text_features, axis=0)\\n\",\n    \"    all_image_features = np.concatenate(all_image_features, axis=0)\\n\",\n    \"    mean_similarity = (all_image_features @ all_text_features.T).diagonal().mean()\\n\",\n    \"    return mean_similarity\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"clip_model_path=\\\"../pretrained_models/clip-vit-large-patch14\\\"\\n\",\n    \"clip_model, processor, tokenizer, text_encoder = load_clip_model(clip_model_path)\\n\",\n    \"clip_scores = []\\n\",\n    \"for output_path in output_paths:\\n\",\n    \"    clip_score_each = clip_score(clip_model, processor, tokenizer, text_encoder, cocosubsetloader, output_path)   \\n\",\n    \"    print(output_path, clip_score_each)\\n\",\n    \"    clip_scores.append(clip_score_each)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"image/png\": \"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\",\n      \"text/plain\": [\n       \"<Figure size 640x480 with 1 Axes>\"\n      ]\n     },\n     \"metadata\": {},\n     \"output_type\": \"display_data\"\n    }\n   ],\n   \"source\": [\n    \"# plot clip score as x-axis, fid score as y-axis, line chart\\n\",\n    \"import matplotlib.pyplot as plt\\n\",\n    \"plt.plot(clip_scores, fids, 'o-')\\n\",\n    \"plt.xlabel('clip score')\\n\",\n    \"plt.ylabel('fid score')\\n\",\n    \"plt.show()\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3.9.13 ('base')\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.9.13\"\n  },\n  \"orig_nbformat\": 4,\n  \"vscode\": {\n   \"interpreter\": {\n    \"hash\": \"4cc247672a8bfe61dc951074f9ca89ab002dc0f7e14586a8bb0828228bebeefa\"\n   }\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"
  },
  {
    "path": "text-image/fid_clip_score/run_generator.sh",
    "content": "#!/bin/bash\nps aux | grep -E 'run_watch.sh|watch.py' |awk '{print $2}' | xargs kill -9 # kill previous watchdog\nguidance_scales=(1.5 2.0 3.0 4.0 5.0 6.0 7.0 8.0)\nfor i in {0..7}\ndo\n    echo ${i}\n    CUDA_VISIBLE_DEVICES=${i} nohup python coco_sample_generator.py --guidance_scale ${guidance_scales[${i}]} --batch_size 16 --sample_step 20 > stable_generator.log 2>&1 &\ndone\nwait\nbash ~/release_watchdog.sh # start watchdog"
  },
  {
    "path": "text-image/fid_clip_score/run_generator_cn.sh",
    "content": "#!/bin/bash\nps aux | grep -E 'run_watch.sh|watch.py' |awk '{print $2}' | xargs kill -9 # kill previous watchdog\nguidance_scales=(1.5 2.0 3.0 4.0 5.0 6.0 7.0 8.0)\nfor i in {0..7}\ndo\n    echo ${i}\n    CUDA_VISIBLE_DEVICES=${i} nohup python coco_sample_generator.py --model_path ../pretrained_models/stable_cn --coco_cache_file ../dataset/coco/subset_cn.parquet --output_path ./output_cn --guidance_scale ${guidance_scales[${i}]} --batch_size 16 --sample_step 20 > stable_generator.log 2>&1 &\ndone\nwait\nbash ~/release_watchdog.sh # start watchdog"
  },
  {
    "path": "text-image/imagenet_CN_zeroshot_data.py",
    "content": "\n\nimagenet_classnames = [\n                        \"丁鲷\",\n                        \"金鱼\",\n                        \"大白鲨\",\n                        \"虎鲨\",\n                        \"锤头鲨\",\n                        \"电鳐\",\n                        \"黄貂鱼\",\n                        \"公鸡\",\n                        \"母鸡\",\n                        \"鸵鸟\",\n                        \"燕雀\",\n                        \"金翅雀\",\n                        \"家朱雀\",\n                        \"灯芯草雀\",\n                        \"靛蓝雀\",\n                        \"蓝鹀\",\n                        \"夜莺\",\n                        \"松鸦\",\n                        \"喜鹊\",\n                        \"山雀\",\n                        \"河鸟\",\n                        \"鸢（猛禽）\",\n                        \"秃头鹰\",\n                        \"秃鹫\",\n                        \"大灰猫头鹰\",\n                        \"欧洲火蝾螈\",\n                        \"普通蝾螈\",\n                        \"水蜥\",\n                        \"斑点蝾螈\",\n                        \"蝾螈\",\n                        \"牛蛙\",\n                        \"树蛙\",\n                        \"尾蛙\",\n                        \"红海龟\",\n                        \"皮革龟\",\n                        \"泥龟\",\n                        \"淡水龟\",\n                        \"箱龟\",\n                        \"带状壁虎\",\n                        \"普通鬣蜥\",\n                        \"美国变色龙\",\n                        \"鞭尾蜥蜴\",\n                        \"飞龙科蜥蜴\",\n                        \"褶边蜥蜴\",\n                        \"鳄鱼蜥蜴\",\n                        \"毒蜥\",\n                        \"绿蜥蜴\",\n                        \"非洲变色龙\",\n                        \"科莫多蜥蜴\",\n                        \"非洲鳄\",\n                        \"美国鳄鱼\",\n                        \"三角龙\",\n                        \"雷蛇\",\n                        \"环蛇\",\n                        \"希腊蛇\",\n                        \"绿蛇\",\n                        \"国王蛇\",\n                        \"袜带蛇\",\n                        \"水蛇\",\n                        \"藤蛇\",\n                        \"夜蛇\",\n                        \"大蟒蛇\",\n                        \"岩石蟒蛇\",\n                        \"印度眼镜蛇\",\n                        \"绿曼巴\",\n                        \"海蛇\",\n                        \"角腹蛇\",\n                        \"菱纹响尾蛇\",\n                        \"角响尾蛇\",\n                        \"三叶虫\",\n                        \"盲蜘蛛\",\n                        \"蝎子\",\n                        \"黑金花园蜘蛛\",\n                        \"谷仓蜘蛛\",\n                        \"花园蜘蛛\",\n                        \"黑寡妇蜘蛛\",\n                        \"狼蛛\",\n                        \"狼蜘蛛\",\n                        \"壁虱\",\n                        \"蜈蚣\",\n                        \"黑松鸡\",\n                        \"松鸡\",\n                        \"披肩鸡\",\n                        \"草原鸡\",\n                        \"孔雀\",\n                        \"鹌鹑\",\n                        \"鹧鸪\",\n                        \"非洲灰鹦鹉\",\n                        \"金刚鹦鹉\",\n                        \"硫冠鹦鹉\",\n                        \"短尾鹦鹉\",\n                        \"褐翅鸦鹃\",\n                        \"食蜂鸟；蜂虎\",\n                        \"犀鸟\",\n                        \"蜂鸟\",\n                        \"鹟䴕\",\n                        \"巨嘴鸟；大嘴鸟\",\n                        \"野鸭\",\n                        \"红胸秋沙鸭\",\n                        \"鹅\",\n                        \"黑天鹅\",\n                        \"大象\",\n                        \"针鼹鼠\",\n                        \"鸭嘴兽\",\n                        \"沙袋鼠\",\n                        \"考拉\",\n                        \"袋熊\",\n                        \"水母\",\n                        \"海葵\",\n                        \"脑珊瑚\",\n                        \"扁形虫扁虫\",\n                        \"线虫\",\n                        \"海螺\",\n                        \"蜗牛\",\n                        \"鼻涕虫\",\n                        \"海蛞蝓；海参\",\n                        \"石鳖\",\n                        \"鹦鹉螺\",\n                        \"珍宝蟹\",\n                        \"石蟹\",\n                        \"招潮蟹\",\n                        \"帝王蟹\",\n                        \"美国龙虾\",\n                        \"大螯虾\",\n                        \"小龙虾\",\n                        \"寄居蟹\",\n                        \"等足目动物（明虾和螃蟹近亲）\",\n                        \"白鹳\",\n                        \"黑鹳\",\n                        \"鹭\",\n                        \"火烈鸟\",\n                        \"小蓝鹭\",\n                        \"美国鹭\",\n                        \"麻鸦\",\n                        \"鹤\",\n                        \"秧鹤\",\n                        \"欧洲水鸡\",\n                        \"沼泽泥母鸡\",\n                        \"鸨\",\n                        \"红翻石鹬\",\n                        \"红背鹬\",\n                        \"红脚鹬\",\n                        \"半蹼鹬\",\n                        \"蛎鹬\",\n                        \"鹈鹕\",\n                        \"国王企鹅\",\n                        \"信天翁\",\n                        \"灰鲸\",\n                        \"杀人鲸\",\n                        \"海牛\",\n                        \"海狮\",\n                        \"吉娃娃\",\n                        \"日本狆犬\",\n                        \"马尔济斯犬\",\n                        \"狮子狗\",\n                        \"西施犬\",\n                        \"布莱尼姆猎犬\",\n                        \"巴比狗\",\n                        \"玩具犬\",\n                        \"罗得西亚长背猎狗\",\n                        \"阿富汗猎犬\",\n                        \"巴吉度猎犬\",\n                        \"比格犬\",\n                        \"侦探犬\",\n                        \"蓝色快狗\",\n                        \"黑褐猎浣熊犬\",\n                        \"沃克猎犬\",\n                        \"英国猎狐犬\",\n                        \"美洲赤狗\",\n                        \"俄罗斯猎狼犬\",\n                        \"爱尔兰猎狼犬\",\n                        \"意大利灰狗\",\n                        \"惠比特犬\",\n                        \"依比沙猎犬\",\n                        \"挪威猎犬\",\n                        \"奥达猎犬\",\n                        \"沙克犬\",\n                        \"苏格兰猎鹿犬\",\n                        \"威玛猎犬\",\n                        \"斯塔福德郡斗牛犬\",\n                        \"美国斯塔福德郡梗\",\n                        \"贝德灵顿梗\",\n                        \"边境梗\",\n                        \"凯丽蓝梗\",\n                        \"爱尔兰梗\",\n                        \"诺福克梗\",\n                        \"诺维奇梗\",\n                        \"约克犬；约克夏梗犬\",\n                        \"刚毛猎狐梗\",\n                        \"莱克兰梗\",\n                        \"锡利哈姆梗\",\n                        \"艾尔谷犬\",\n                        \"凯恩梗\",\n                        \"澳大利亚梗\",\n                        \"丹迪丁蒙梗\",\n                        \"波士顿梗\",\n                        \"迷你雪纳瑞犬\",\n                        \"巨型雪纳瑞犬\",\n                        \"标准雪纳瑞犬\",\n                        \"苏格兰梗犬\",\n                        \"西藏梗\",\n                        \"丝毛梗\",\n                        \"爱尔兰软毛梗犬\",\n                        \"西高地白梗\",\n                        \"拉萨阿普索犬\",\n                        \"平毛寻回犬\",\n                        \"卷毛寻回犬\",\n                        \"金毛猎犬\",\n                        \"拉布拉多猎犬\",\n                        \"乞沙比克猎犬\",\n                        \"德国短毛指示犬\",\n                        \"维兹拉犬\",\n                        \"英国塞特犬\",\n                        \"爱尔兰雪达犬\",\n                        \"戈登雪达犬\",\n                        \"布列塔尼犬猎犬\",\n                        \"黄毛\",\n                        \"英国史宾格犬\",\n                        \"威尔士史宾格犬\",\n                        \"可卡犬\",\n                        \"萨塞克斯猎犬\",\n                        \"爱尔兰水猎犬\",\n                        \"哥威斯犬\",\n                        \"舒柏奇犬\",\n                        \"比利时牧羊犬\",\n                        \"马里努阿犬\",\n                        \"伯瑞犬\",\n                        \"凯尔皮犬\",\n                        \"匈牙利牧羊犬\",\n                        \"老英国牧羊犬\",\n                        \"喜乐蒂牧羊犬\",\n                        \"牧羊犬\",\n                        \"边境牧羊犬\",\n                        \"法兰德斯牧牛狗\",\n                        \"罗特韦尔犬\",\n                        \"德国牧羊犬\",\n                        \"多伯曼犬\",\n                        \"鹿犬；迷你杜宾犬\",\n                        \"大瑞士山地犬\",\n                        \"伯恩山犬\",\n                        \"阿策尔山犬\",\n                        \"恩特尔布赫山犬\",\n                        \"拳师狗\",\n                        \"斗牛獒\",\n                        \"藏獒\",\n                        \"法国斗牛犬\",\n                        \"大丹犬\",\n                        \"圣伯纳德狗\",\n                        \"爱斯基摩犬\",\n                        \"阿拉斯加雪橇犬\",\n                        \"哈士奇\",\n                        \"达尔马提亚\",\n                        \"狮毛狗\",\n                        \"巴辛吉狗\",\n                        \"八哥犬\",\n                        \"莱昂贝格狗\",\n                        \"纽芬兰犬\",\n                        \"大白熊犬\",\n                        \"萨摩耶犬\",\n                        \"博美犬\",\n                        \"松狮\",\n                        \"凯斯犬\",\n                        \"布鲁塞尔格林芬犬\",\n                        \"彭布洛克威尔士科基犬\",\n                        \"威尔士柯基犬\",\n                        \"玩具贵宾犬\",\n                        \"迷你贵宾犬\",\n                        \"标准贵宾犬\",\n                        \"墨西哥无毛犬\",\n                        \"灰狼\",\n                        \"白狼\",\n                        \"红太狼\",\n                        \"狼\",\n                        \"澳洲野狗\",\n                        \"豺\",\n                        \"非洲猎犬\",\n                        \"鬣狗\",\n                        \"红狐狸\",\n                        \"沙狐\",\n                        \"北极狐狸\",\n                        \"灰狐狸\",\n                        \"虎斑猫\",\n                        \"山猫\",\n                        \"波斯猫\",\n                        \"暹罗猫\",\n                        \"埃及猫\",\n                        \"美洲狮\",\n                        \"猞猁\",\n                        \"豹子\",\n                        \"雪豹\",\n                        \"美洲虎\",\n                        \"狮子\",\n                        \"老虎\",\n                        \"猎豹\",\n                        \"棕熊\",\n                        \"美洲黑熊\",\n                        \"冰熊\",\n                        \"懒熊\",\n                        \"獴\",\n                        \"猫鼬\",\n                        \"虎甲虫\",\n                        \"瓢虫\",\n                        \"土鳖虫\",\n                        \"天牛\",\n                        \"龟甲虫\",\n                        \"粪甲虫\",\n                        \"犀牛甲虫\",\n                        \"象甲\",\n                        \"苍蝇\",\n                        \"蜜蜂\",\n                        \"蚂蚁\",\n                        \"蚱蜢\",\n                        \"蟋蟀\",\n                        \"竹节虫\",\n                        \"蟑螂\",\n                        \"螳螂\",\n                        \"蝉\",\n                        \"叶蝉\",\n                        \"草蜻蛉\",\n                        \"蜻蜓\",\n                        \"豆娘\",\n                        \"优红蛱蝶\",\n                        \"小环蝴蝶\",\n                        \"君主蝴蝶\",\n                        \"菜粉蝶\",\n                        \"白蝴蝶\",\n                        \"灰蝶\",\n                        \"海星\",\n                        \"海胆\",\n                        \"海黄瓜；海参\",\n                        \"野兔\",\n                        \"兔\",\n                        \"安哥拉兔\",\n                        \"仓鼠\",\n                        \"刺猬\",\n                        \"黑松鼠\",\n                        \"土拨鼠\",\n                        \"海狸\",\n                        \"豚鼠\",\n                        \"栗色马\",\n                        \"斑马\",\n                        \"猪\",\n                        \"野猪\",\n                        \"疣猪\",\n                        \"河马\",\n                        \"牛\",\n                        \"水牛\",\n                        \"野牛\",\n                        \"公羊\",\n                        \"大角羊\",\n                        \"山羊\",\n                        \"狷羚\",\n                        \"黑斑羚\",\n                        \"瞪羚\",\n                        \"阿拉伯单峰骆驼\",\n                        \"骆驼\",\n                        \"黄鼠狼\",\n                        \"水貂\",\n                        \"臭猫\",\n                        \"黑足鼬\",\n                        \"水獭\",\n                        \"臭鼬\",\n                        \"獾\",\n                        \"犰狳\",\n                        \"树懒\",\n                        \"猩猩\",\n                        \"大猩猩\",\n                        \"黑猩猩\",\n                        \"长臂猿\",\n                        \"合趾猿长臂猿\",\n                        \"长尾猴\",\n                        \"赤猴\",\n                        \"狒狒\",\n                        \"恒河猴\",\n                        \"白头叶猴\",\n                        \"疣猴\",\n                        \"长鼻猴\",\n                        \"狨（美洲产小型长尾猴）\",\n                        \"卷尾猴\",\n                        \"吼猴\",\n                        \"伶猴\",\n                        \"蜘蛛猴\",\n                        \"松鼠猴\",\n                        \"马达加斯加环尾狐猴\",\n                        \"大狐猴\",\n                        \"印度大象\",\n                        \"非洲象\",\n                        \"小熊猫\",\n                        \"大熊猫\",\n                        \"杖鱼\",\n                        \"鳗鱼\",\n                        \"银鲑\",\n                        \"三色刺蝶鱼\",\n                        \"海葵鱼\",\n                        \"鲟鱼\",\n                        \"雀鳝\",\n                        \"狮子鱼\",\n                        \"河豚\",\n                        \"算盘\",\n                        \"长袍\",\n                        \"学位袍\",\n                        \"手风琴\",\n                        \"原声吉他\",\n                        \"航空母舰\",\n                        \"客机\",\n                        \"飞艇\",\n                        \"祭坛\",\n                        \"救护车\",\n                        \"水陆两用车\",\n                        \"模拟时钟\",\n                        \"蜂房\",\n                        \"围裙\",\n                        \"垃圾桶\",\n                        \"攻击步枪\",\n                        \"背包\",\n                        \"面包店\",\n                        \"平衡木\",\n                        \"热气球\",\n                        \"圆珠笔\",\n                        \"创可贴\",\n                        \"班卓琴\",\n                        \"栏杆\",\n                        \"杠铃\",\n                        \"理发师的椅子\",\n                        \"理发店\",\n                        \"牲口棚\",\n                        \"晴雨表\",\n                        \"圆筒\",\n                        \"园地小车\",\n                        \"棒球\",\n                        \"篮球\",\n                        \"婴儿床\",\n                        \"巴松管\",\n                        \"游泳帽\",\n                        \"沐浴毛巾\",\n                        \"浴缸\",\n                        \"沙滩车\",\n                        \"灯塔\",\n                        \"烧杯\",\n                        \"熊皮高帽\",\n                        \"啤酒瓶\",\n                        \"啤酒杯\",\n                        \"钟塔\",\n                        \"（小儿用的）围嘴\",\n                        \"串联自行车\",\n                        \"比基尼\",\n                        \"装订册\",\n                        \"双筒望远镜\",\n                        \"鸟舍\",\n                        \"船库\",\n                        \"双人雪橇\",\n                        \"饰扣式领带\",\n                        \"阔边女帽\",\n                        \"书橱\",\n                        \"书店\",\n                        \"瓶盖\",\n                        \"弓箭\",\n                        \"蝴蝶结领结\",\n                        \"铜制牌位\",\n                        \"奶罩\",\n                        \"防波堤\",\n                        \"铠甲\",\n                        \"扫帚\",\n                        \"桶\",\n                        \"扣环\",\n                        \"防弹背心\",\n                        \"动车\",\n                        \"肉铺\",\n                        \"出租车\",\n                        \"大锅\",\n                        \"蜡烛\",\n                        \"大炮\",\n                        \"独木舟\",\n                        \"开瓶器\",\n                        \"开衫\",\n                        \"车镜\",\n                        \"旋转木马\",\n                        \"木匠的工具包\",\n                        \"纸箱\",\n                        \"车轮\",\n                        \"取款机\",\n                        \"盒式录音带\",\n                        \"卡带播放器\",\n                        \"城堡\",\n                        \"双体船\",\n                        \"CD播放器\",\n                        \"大提琴\",\n                        \"移动电话\",\n                        \"铁链\",\n                        \"围栏\",\n                        \"链甲\",\n                        \"电锯\",\n                        \"箱子\",\n                        \"梳妆台\",\n                        \"编钟\",\n                        \"中国橱柜\",\n                        \"圣诞袜\",\n                        \"教堂\",\n                        \"电影院\",\n                        \"切肉刀\",\n                        \"悬崖屋\",\n                        \"斗篷\",\n                        \"木屐\",\n                        \"鸡尾酒调酒器\",\n                        \"咖啡杯\",\n                        \"咖啡壶\",\n                        \"螺旋结构（楼梯）\",\n                        \"组合锁\",\n                        \"电脑键盘\",\n                        \"糖果\",\n                        \"集装箱船\",\n                        \"敞篷车\",\n                        \"瓶塞钻\",\n                        \"短号\",\n                        \"牛仔靴\",\n                        \"牛仔帽\",\n                        \"摇篮\",\n                        \"起重机\",\n                        \"头盔\",\n                        \"板条箱\",\n                        \"小儿床\",\n                        \"砂锅\",\n                        \"槌球\",\n                        \"拐杖\",\n                        \"胸甲\",\n                        \"大坝\",\n                        \"书桌\",\n                        \"台式电脑\",\n                        \"有线电话\",\n                        \"尿布湿\",\n                        \"数字时钟\",\n                        \"数字手表\",\n                        \"餐桌板\",\n                        \"抹布\",\n                        \"洗碗机\",\n                        \"盘式制动器\",\n                        \"码头\",\n                        \"狗拉雪橇\",\n                        \"圆顶\",\n                        \"门垫\",\n                        \"钻井平台\",\n                        \"鼓\",\n                        \"鼓槌\",\n                        \"哑铃\",\n                        \"荷兰烤箱\",\n                        \"电风扇\",\n                        \"电吉他\",\n                        \"电力机车\",\n                        \"组合电视柜\",\n                        \"信封\",\n                        \"浓缩咖啡机\",\n                        \"扑面粉\",\n                        \"女用长围巾\",\n                        \"文件\",\n                        \"消防船\",\n                        \"消防车\",\n                        \"火炉栏\",\n                        \"旗杆\",\n                        \"长笛\",\n                        \"折叠椅\",\n                        \"橄榄球头盔\",\n                        \"叉车\",\n                        \"喷泉\",\n                        \"钢笔\",\n                        \"有四根帷柱的床\",\n                        \"运货车厢\",\n                        \"圆号\",\n                        \"煎锅\",\n                        \"裘皮大衣\",\n                        \"垃圾车\",\n                        \"防毒面具\",\n                        \"汽油泵\",\n                        \"高脚杯\",\n                        \"卡丁车\",\n                        \"高尔夫球\",\n                        \"高尔夫球车\",\n                        \"狭长小船\",\n                        \"锣\",\n                        \"礼服\",\n                        \"钢琴\",\n                        \"温室\",\n                        \"散热器格栅\",\n                        \"杂货店\",\n                        \"断头台\",\n                        \"小发夹\",\n                        \"头发喷雾\",\n                        \"半履带装甲车\",\n                        \"锤子\",\n                        \"大篮子\",\n                        \"手摇鼓风机\",\n                        \"手提电脑\",\n                        \"手帕\",\n                        \"硬盘\",\n                        \"口琴\",\n                        \"竖琴\",\n                        \"收割机\",\n                        \"斧头\",\n                        \"手枪皮套\",\n                        \"家庭影院\",\n                        \"蜂窝\",\n                        \"钩爪\",\n                        \"衬裙\",\n                        \"单杠\",\n                        \"马车\",\n                        \"沙漏\",\n                        \"iPod\",\n                        \"熨斗\",\n                        \"南瓜灯笼\",\n                        \"牛仔裤\",\n                        \"吉普车\",\n                        \"T恤衫\",\n                        \"拼图\",\n                        \"人力车\",\n                        \"操纵杆\",\n                        \"和服\",\n                        \"护膝\",\n                        \"蝴蝶结\",\n                        \"大褂\",\n                        \"长柄勺\",\n                        \"灯罩\",\n                        \"笔记本电脑\",\n                        \"割草机\",\n                        \"镜头盖\",\n                        \"开信刀\",\n                        \"图书馆\",\n                        \"救生艇\",\n                        \"点火器\",\n                        \"豪华轿车\",\n                        \"远洋班轮\",\n                        \"唇膏\",\n                        \"平底便鞋\",\n                        \"洗剂\",\n                        \"扬声器\",\n                        \"放大镜\",\n                        \"锯木厂\",\n                        \"磁罗盘\",\n                        \"邮袋\",\n                        \"信箱\",\n                        \"女游泳衣\",\n                        \"有肩带浴衣\",\n                        \"窨井盖\",\n                        \"沙球（一种打击乐器）\",\n                        \"马林巴木琴\",\n                        \"面膜\",\n                        \"火柴\",\n                        \"花柱\",\n                        \"迷宫\",\n                        \"量杯\",\n                        \"药箱\",\n                        \"巨石\",\n                        \"麦克风\",\n                        \"微波炉\",\n                        \"军装\",\n                        \"奶桶\",\n                        \"迷你巴士\",\n                        \"迷你裙\",\n                        \"面包车\",\n                        \"导弹\",\n                        \"连指手套\",\n                        \"搅拌钵\",\n                        \"活动房屋（由汽车拖拉的）\",\n                        \"T型发动机小汽车\",\n                        \"调制解调器\",\n                        \"修道院\",\n                        \"显示器\",\n                        \"电瓶车\",\n                        \"砂浆\",\n                        \"学士\",\n                        \"清真寺\",\n                        \"蚊帐\",\n                        \"摩托车\",\n                        \"山地自行车\",\n                        \"登山帐\",\n                        \"鼠标\",\n                        \"捕鼠器\",\n                        \"搬家货车\",\n                        \"动物的口套\",\n                        \"金属钉子\",\n                        \"颈托\",\n                        \"项链\",\n                        \"乳头（瓶）\",\n                        \"笔记本\",\n                        \"方尖碑\",\n                        \"双簧管\",\n                        \"陶笛\",\n                        \"里程表\",\n                        \"滤油器\",\n                        \"风琴\",\n                        \"示波器\",\n                        \"罩裙\",\n                        \"牛车\",\n                        \"氧气面罩\",\n                        \"包装\",\n                        \"船桨\",\n                        \"明轮\",\n                        \"挂锁\",\n                        \"画笔\",\n                        \"睡衣\",\n                        \"宫殿\",\n                        \"排箫\",\n                        \"纸巾\",\n                        \"降落伞\",\n                        \"双杠\",\n                        \"公园长椅\",\n                        \"停车收费表\",\n                        \"客车\",\n                        \"露台\",\n                        \"付费电话\",\n                        \"基座\",\n                        \"铅笔盒\",\n                        \"卷笔刀\",\n                        \"香水（瓶）\",\n                        \"培养皿\",\n                        \"复印机\",\n                        \"拨弦片\",\n                        \"尖顶头盔\",\n                        \"用尖板条连成的尖桩篱栅\",\n                        \"皮卡\",\n                        \"桥墩\",\n                        \"存钱罐\",\n                        \"药瓶\",\n                        \"枕头\",\n                        \"乒乓球\",\n                        \"风车\",\n                        \"海盗船\",\n                        \"水罐\",\n                        \"木工刨\",\n                        \"天文馆\",\n                        \"塑料袋\",\n                        \"板架\",\n                        \"犁型铲雪机\",\n                        \"手压皮碗泵\",\n                        \"宝丽来相机\",\n                        \"电线杆\",\n                        \"警车\",\n                        \"雨披\",\n                        \"台球桌\",\n                        \"充气饮料瓶\",\n                        \"花盆\",\n                        \"陶工旋盘\",\n                        \"电钻\",\n                        \"祈祷垫\",\n                        \"打印机\",\n                        \"监狱\",\n                        \"炮弹\",\n                        \"投影仪\",\n                        \"冰球\",\n                        \"沙包\",\n                        \"小钱袋；手袋\",\n                        \"羽管笔\",\n                        \"被子\",\n                        \"赛车\",\n                        \"球拍\",\n                        \"散热器\",\n                        \"收音机\",\n                        \"射电望远镜\",\n                        \"雨桶\",\n                        \"休闲车\",\n                        \"卷轴\",\n                        \"反射式照相机\",\n                        \"冰箱\",\n                        \"遥控器\",\n                        \"餐厅\",\n                        \"左轮手枪\",\n                        \"步枪\",\n                        \"摇椅\",\n                        \"电转烤肉架\",\n                        \"橡皮\",\n                        \"橄榄球\",\n                        \"直尺\",\n                        \"跑步鞋\",\n                        \"保险柜\",\n                        \"安全别针\",\n                        \"盐瓶（调味用）\",\n                        \"凉鞋\",\n                        \"纱笼\",\n                        \"萨克斯管\",\n                        \"剑鞘\",\n                        \"秤\",\n                        \"校车\",\n                        \"帆船\",\n                        \"记分牌\",\n                        \"屏幕\",\n                        \"螺丝\",\n                        \"螺丝刀\",\n                        \"安全带\",\n                        \"缝纫机\",\n                        \"盾牌\",\n                        \"皮鞋店\",\n                        \"障子\",\n                        \"购物篮\",\n                        \"购物车\",\n                        \"铁锹\",\n                        \"浴帽\",\n                        \"浴帘\",\n                        \"滑雪板\",\n                        \"滑雪面罩\",\n                        \"睡袋\",\n                        \"滑尺\",\n                        \"滑动门\",\n                        \"角子老虎机\",\n                        \"潜水通气管\",\n                        \"摩托雪橇；雪地机动车\",\n                        \"扫雪机\",\n                        \"皂液器\",\n                        \"足球\",\n                        \"袜子\",\n                        \"碟式太阳能\",\n                        \"宽边帽\",\n                        \"汤碗\",\n                        \"空格键\",\n                        \"空间加热器\",\n                        \"航天飞机\",\n                        \"锅铲；做饭的铲子\",\n                        \"快艇\",\n                        \"蜘蛛网\",\n                        \"纺锤；手纺用的绕线杆\",\n                        \"跑车\",\n                        \"聚光灯\",\n                        \"舞台\",\n                        \"蒸汽机车\",\n                        \"钢拱桥\",\n                        \"钢滚筒\",\n                        \"听诊器\",\n                        \"女用披肩\",\n                        \"石头墙\",\n                        \"秒表\",\n                        \"火炉\",\n                        \"过滤器\",\n                        \"有轨电车\",\n                        \"担架\",\n                        \"沙发床\",\n                        \"佛塔\",\n                        \"潜艇\",\n                        \"套装\",\n                        \"日晷\",\n                        \"太阳镜\",\n                        \"太阳镜\",\n                        \"防晒霜\",\n                        \"悬索桥\",\n                        \"拖把\",\n                        \"运动衫\",\n                        \"游泳裤\",\n                        \"秋千\",\n                        \"开关\",\n                        \"注射器；吸管\",\n                        \"台灯\",\n                        \"坦克\",\n                        \"录音机\",\n                        \"茶壶\",\n                        \"泰迪\",\n                        \"电视\",\n                        \"网球；打网球的球\",\n                        \"茅草\",\n                        \"幕布\",\n                        \"顶针\",\n                        \"打谷机；脱粒机\",\n                        \"宝座\",\n                        \"瓦屋顶\",\n                        \"烤面包机\",\n                        \"烟草店\",\n                        \"马桶\",\n                        \"火炬\",\n                        \"图腾柱\",\n                        \"拖车；牵引车\",\n                        \"玩具店\",\n                        \"拖拉机\",\n                        \"半挂汽车\",\n                        \"托盘\",\n                        \"风衣\",\n                        \"三轮车\",\n                        \"三体船\",\n                        \"三脚架\",\n                        \"凯旋门\",\n                        \"无轨电车\",\n                        \"长号\",\n                        \"浴盆\",\n                        \"旋转式栅门\",\n                        \"打字机键盘\",\n                        \"伞\",\n                        \"独轮车\",\n                        \"直立式钢琴\",\n                        \"吸尘器\",\n                        \"花瓶；装饰瓶\",\n                        \"拱顶\",\n                        \"天鹅绒\",\n                        \"自动售货机\",\n                        \"法衣；祭衣；祭服\",\n                        \"高架桥\",\n                        \"小提琴\",\n                        \"排球\",\n                        \"松饼机\",\n                        \"挂钟\",\n                        \"钱包；钱夹\",\n                        \"衣柜衣橱\",\n                        \"军用飞机\",\n                        \"洗脸盆\",\n                        \"洗衣机\",\n                        \"水瓶\",\n                        \"水壶\",\n                        \"水塔\",\n                        \"威士忌壶\",\n                        \"哨子\",\n                        \"假发\",\n                        \"纱窗\",\n                        \"百叶窗\",\n                        \"温莎领带\",\n                        \"葡萄酒瓶\",\n                        \"飞机翅膀\",\n                        \"炒菜锅\",\n                        \"木勺子；木头勺子\",\n                        \"毛织品\",\n                        \"原木栅栏\",\n                        \"沉船\",\n                        \"双桅船\",\n                        \"蒙古包\",\n                        \"网站；网页\",\n                        \"漫画\",\n                        \"纵横字谜\",\n                        \"路标\",\n                        \"交通信号灯\",\n                        \"防尘罩\",\n                        \"菜单\",\n                        \"盘子\",\n                        \"墨西哥鳄梨酱；墨西哥牛油果酱\",\n                        \"清炖肉汤\",\n                        \"火锅\",\n                        \"乳脂蛋糕；英国甜点\",\n                        \"冰淇淋\",\n                        \"冰棍；雪糕\",\n                        \"法式面包\",\n                        \"百吉饼\",\n                        \"椒盐脆饼\",\n                        \"芝士汉堡\",\n                        \"热狗\",\n                        \"土豆泥\",\n                        \"结球甘蓝\",\n                        \"西兰花；绿菜花\",\n                        \"菜花；花椰菜\",\n                        \"西葫芦\",\n                        \"金丝瓜；意面南瓜；面条瓜\",\n                        \"绿色小南瓜；青南瓜\",\n                        \"南瓜\",\n                        \"黄瓜\",\n                        \"洋蓟；球蓟\",\n                        \"甜椒\",\n                        \"刺棘蓟\",\n                        \"蘑菇\",\n                        \"绿苹果\",\n                        \"草莓\",\n                        \"橘子\",\n                        \"柠檬\",\n                        \"无花果\",\n                        \"菠萝\",\n                        \"香蕉\",\n                        \"菠萝蜜\",\n                        \"番荔枝\",\n                        \"石榴\",\n                        \"干草\",\n                        \"培根蛋酱意大利面\",\n                        \"巧克力酱\",\n                        \"生面；面团\",\n                        \"瑞士肉包\",\n                        \"披萨\",\n                        \"馅饼\",\n                        \"卷饼\",\n                        \"红葡萄酒\",\n                        \"意式浓缩咖啡\",\n                        \"杯子\",\n                        \"蛋酒\",\n                        \"高山\",\n                        \"泡泡\",\n                        \"悬崖\",\n                        \"珊瑚礁\",\n                        \"间歇泉；间断喷发的温泉\",\n                        \"湖边\",\n                        \"岬角；深入海中的狭长高地\",\n                        \"沙洲\",\n                        \"沙滩\",\n                        \"峡谷\",\n                        \"火山\",\n                        \"棒球运动员\",\n                        \"新郎\",\n                        \"潜水员\",\n                        \"油菜\",\n                        \"雏菊\",\n                        \"杓兰\",\n                        \"玉米\",\n                        \"橡子\",\n                        \"玫瑰果\",\n                        \"七叶树果实\",\n                        \"珊瑚菌\",\n                        \"木耳\",\n                        \"鹿花菌\",\n                        \"臭角菇\",\n                        \"地星\",\n                        \"多叶奇果菌\",\n                        \"牛肝菌\",\n                        \"玉米棒子\",\n                        \"卫生纸\"\n                        ]\n\n\n\n\nopenai_imagenet_template = [\n    lambda c: f'质量差的{c}的照片。',\n    lambda c: f'许多{c}的照片。',\n    lambda c: f'{c}的雕塑。',\n    lambda c: f'难以看到{c}的照片。',\n    lambda c: f'{c}的低分辨率照片。',\n    lambda c: f'{c}的渲染。',\n    lambda c: f'涂鸦{c}。',\n    lambda c: f'{c}的糟糕照片。',\n    lambda c: f'{c}的裁剪照片。',\n    lambda c: f'{c}的纹身。',\n    lambda c: f'{c}的刺绣照片。',\n    lambda c: f'很难看到{c}的照片。',\n    lambda c: f'{c}的明亮照片。',\n    lambda c: f'一张干净的{c}的照片。',\n    lambda c: f'一张包含{c}的照片。',\n    lambda c: f'{c}的深色照片。',\n    lambda c: f'{c}的手绘画。',\n    lambda c: f'我的{c}的照片。',\n    lambda c: f'不自然的{c}的照片。',\n    lambda c: f'一张酷的{c}的照片。',\n    lambda c: f'{c}的特写照片。',\n    lambda c: f'{c}的黑白照片。',\n    lambda c: f'一幅{c}的画。',\n    lambda c: f'一幅{c}的绘画。',\n    lambda c: f'一张{c}的像素照片。',\n    lambda c: f'{c}的雕像。',\n    lambda c: f'一张{c}的明亮照片。',\n    lambda c: f'{c}的裁剪照片。',\n    lambda c: f'人造的{c}的照片。',\n    lambda c: f'一张关于{c}的照片。',\n    lambda c: f'损坏的{c}的jpeg照片。',\n    lambda c: f'{c}的模糊照片。',\n    lambda c: f'{c}的相片。',\n    lambda c: f'一张{c}的好照片。',\n    lambda c: f'{c}的渲染照。',\n    lambda c: f'视频游戏中的{c}。',\n    lambda c: f'一张{c}的照片。',\n    lambda c: f'{c}的涂鸦。',\n    lambda c: f'{c}的近距离照片。',\n    lambda c: f'{c}的折纸。',\n    lambda c: f'{c}在视频游戏中。',\n    lambda c: f'{c}的草图。',\n    lambda c: f'{c}的涂鸦照。',\n    lambda c: f'{c}的折纸形状。',\n    lambda c: f'低分辨率的{c}的照片。',\n    lambda c: f'玩具{c}。',\n    lambda c: f'{c}的副本。',\n    lambda c: f'{c}的干净的照片。',\n    lambda c: f'一张大{c}的照片。',\n    lambda c: f'{c}的重现。',\n    lambda c: f'一张漂亮的{c}的照片。',\n    lambda c: f'一张奇怪的{c}的照片。',\n    lambda c: f'模糊的{c}的照片。',\n    lambda c: f'卡通{c}。',\n    lambda c: f'{c}的艺术作品。',\n    lambda c: f'{c}的素描。',\n    lambda c: f'刺绣{c}。',\n    lambda c: f'{c}的像素照。',\n    lambda c: f'{c}的拍照。',\n    lambda c: f'{c}的损坏的照片。',\n    lambda c: f'高质量的{c}的照片。',\n    lambda c: f'毛绒玩具{c}。',\n    lambda c: f'漂亮的{c}的照片。',\n    lambda c: f'小{c}的照片。',\n    lambda c: f'照片是奇怪的{c}。',\n    lambda c: f'漫画{c}。',\n    lambda c: f'{c}的艺术照。',\n    lambda c: f'{c}的图形。',\n    lambda c: f'大{c}的照片。',\n    lambda c: f'黑白的{c}的照片。',\n    lambda c: f'{c}毛绒玩具。',\n    lambda c: f'一张{c}的深色照片。',\n    lambda c: f'{c}的摄影图。',\n    lambda c: f'{c}的涂鸦照。',\n    lambda c: f'玩具形状的{c}。',\n    lambda c: f'拍了{c}的照片。',\n    lambda c: f'酷酷的{c}的照片。',\n    lambda c: f'照片里的小{c}。',\n    lambda c: f'{c}的刺青。',\n]\n"
  },
  {
    "path": "text-image/iterable_tar_unzip.sh",
    "content": "# for name in `ls -d */`;\n# do;\nname=\"image_part12/\"\nfor i in `ls $name*.tar`;\ndo \nmkdir ./project/dataset/laion_chinese_cwf/${i%.tar} \ntar xvf $i -C ./project/dataset/laion_chinese_cwf/${i%.tar};\ndone;\n# done\n\n\n"
  },
  {
    "path": "text-image/save_hg_ckpt.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Roberta-base 转换为hugging face版\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import torch\\n\",\n    \"from transformers import BertForSequenceClassification, BertConfig, BertTokenizer\\n\",\n    \"\\n\",\n    \"# NOTE 使用open_clip 中文pretrain model训练的结果\\n\",\n    \"taiyi_path = './project/open_clip_new/src/logs/2022_11_18-21_15_16-model_ViT-L-14-lr_0.0001-b_640-j_16-p_amp/checkpoints/epoch_4.pt'\\n\",\n    \"bertconfig = BertConfig.from_pretrained(\\\"hfl/chinese-roberta-wwm-ext\\\", num_labels=512)\\n\",\n    \"my_transformer = BertForSequenceClassification.from_pretrained(\\\"hfl/chinese-roberta-wwm-ext\\\", config=bertconfig)\\n\",\n    \"mytokenizer = BertTokenizer.from_pretrained(\\\"hfl/chinese-roberta-wwm-ext\\\")\\n\",\n    \"\\n\",\n    \"# NOTE 需要改名加载\\n\",\n    \"state_dict_of_bert = torch.load(taiyi_path)['state_dict']\\n\",\n    \"bert_weights = {k.replace('module.transformer.',''):v for k,v in state_dict_of_bert.items() if 'module.transformer' in k}\\n\",\n    \"my_transformer.load_state_dict(bert_weights)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# 同时保存模型和词表格。然后把这个上传到huggingface上面去\\n\",\n    \"my_transformer.save_pretrained('./CLIP-roberta')\\n\",\n    \"mytokenizer.save_pretrained('./CLIP-roberta')\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"total = sum([param.nelement() for param in my_transformer.parameters()])\\n\",\n    \"print(\\\"Number of parameter: %.2fM\\\" % (total/1e6))\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Roberta-large 版\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import torch\\n\",\n    \"from transformers import BertForSequenceClassification, BertConfig, BertTokenizer\\n\",\n    \"\\n\",\n    \"# NOTE 使用中文pretrain model训练的结果\\n\",\n    \"taiyi_path = './open_clip/src/logs/2022_07_18-18_39_51-model_ViT-L-14-lr_1e-05-b_224-j_8-p_amp/checkpoints/epoch_7.pt'\\n\",\n    \"bertconfig = BertConfig.from_pretrained(\\\"hfl/chinese-roberta-wwm-ext-large\\\", num_labels=768)\\n\",\n    \"my_transformer = BertForSequenceClassification.from_pretrained(\\\"hfl/chinese-roberta-wwm-ext-large\\\", config=bertconfig)\\n\",\n    \"mytokenizer = BertTokenizer.from_pretrained(\\\"hfl/chinese-roberta-wwm-ext-large\\\")\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"state_dict_of_bert = torch.load(taiyi_path)['state_dict']\\n\",\n    \"bert_weights = {k.replace('module.transformer.',''):v for k,v in state_dict_of_bert.items() if 'module.transformer' in k}\\n\",\n    \"my_transformer.load_state_dict(bert_weights)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# 同时保存模型和词表格。然后把这个上传到huggingface上面去\\n\",\n    \"my_transformer.save_pretrained('./Taiyi-CLIP-Roberta-large-326M-Chinese')\\n\",\n    \"mytokenizer.save_pretrained('./Taiyi-CLIP-Roberta-large-326M-Chinese')\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"total = sum([param.nelement() for param in my_transformer.parameters()])\\n\",\n    \"print(\\\"Number of parameter: %.2fM\\\" % (total/1e6))\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from PIL import Image\\n\",\n    \"import requests\\n\",\n    \"import clip\\n\",\n    \"import torch\\n\",\n    \"from transformers import BertForSequenceClassification, BertConfig, BertTokenizer\\n\",\n    \"from transformers import CLIPProcessor, CLIPModel\\n\",\n    \"import numpy as np\\n\",\n    \"\\n\",\n    \"query_texts = [\\\"一只猫\\\", \\\"一只狗\\\",'两只猫', '两只老虎','一只老虎']  # 这里是输入文本的，可以随意替换。\\n\",\n    \"# 加载Taiyi 中文 text encoder\\n\",\n    \"text_tokenizer = BertTokenizer.from_pretrained(\\\"IDEA-CCNL/Taiyi-CLIP-Roberta-large-326M-Chinese\\\")\\n\",\n    \"text_encoder = BertForSequenceClassification.from_pretrained(\\\"IDEA-CCNL/Taiyi-CLIP-Roberta-large-326M-Chinese\\\").eval()\\n\",\n    \"text = text_tokenizer(query_texts, return_tensors='pt', padding=True)['input_ids']\\n\",\n    \"\\n\",\n    \"url = \\\"http://images.cocodataset.org/val2017/000000039769.jpg\\\"  # 这里可以换成任意图片的url\\n\",\n    \"# 加载CLIP的image encoder\\n\",\n    \"clip_model = CLIPModel.from_pretrained(\\\"openai/clip-vit-large-patch14\\\")  \\n\",\n    \"processor = CLIPProcessor.from_pretrained(\\\"openai/clip-vit-large-patch14\\\")\\n\",\n    \"image = processor(images=Image.open(requests.get(url, stream=True).raw), return_tensors=\\\"pt\\\")\\n\",\n    \"\\n\",\n    \"with torch.no_grad():\\n\",\n    \"    image_features = clip_model.get_image_features(**image)\\n\",\n    \"    text_features = text_encoder(text).logits\\n\",\n    \"    # 归一化\\n\",\n    \"    image_features = image_features / image_features.norm(dim=1, keepdim=True)\\n\",\n    \"    text_features = text_features / text_features.norm(dim=1, keepdim=True)\\n\",\n    \"    # 计算余弦相似度 logit_scale是尺度系数\\n\",\n    \"    logit_scale = clip_model.logit_scale.exp()\\n\",\n    \"    logits_per_image = logit_scale * image_features @ text_features.t()\\n\",\n    \"    logits_per_text = logits_per_image.t()\\n\",\n    \"    probs = logits_per_image.softmax(dim=-1).cpu().numpy()\\n\",\n    \"    print(np.around(probs, 3))\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# ViT-H， 维度对应的Roberta-Large\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import torch\\n\",\n    \"from transformers import BertModel, BertTokenizer\\n\",\n    \"\\n\",\n    \"# NOTE load from local path\\n\",\n    \"local_path = './scripts_t2i/open_clip_new/src/logs/2022_09_16-23_03_14-model_ViT-H-14-lr_5e-05-b_256-j_32-p_amp/checkpoints/epoch_21.pt'\\n\",\n    \"text_encoder = BertModel.from_pretrained(\\\"hfl/chinese-roberta-wwm-ext-large\\\").cuda().eval()\\n\",\n    \"state_dict_of_bert = torch.load(local_path)['state_dict']\\n\",\n    \"bert_weights = {k.replace('module.transformer.',''):v for k,v in state_dict_of_bert.items() if 'module.transformer' in k}\\n\",\n    \"text_encoder.load_state_dict(bert_weights)\\n\",\n    \"tokenizer = BertTokenizer.from_pretrained(\\\"hfl/chinese-roberta-wwm-ext\\\")\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# 同时保存模型和词表格。然后把这个上传到huggingface上面去\\n\",\n    \"text_encoder.save_pretrained('./fengshen/Taiyi-CLIP-Roberta-326M-ViT-H-Chinese')\\n\",\n    \"tokenizer.save_pretrained('./fengshen/Taiyi-CLIP-Roberta-326M-ViT-H-Chinese')\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# ViT-L --- Roberta-base\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import torch\\n\",\n    \"from transformers import BertModel, BertTokenizer\\n\",\n    \"\\n\",\n    \"# NOTE load from local path\\n\",\n    \"local_path = './project/open_clip_new/src/logs/2022_11_18-21_15_16-model_ViT-L-14-lr_0.0001-b_640-j_16-p_amp/checkpoints/epoch_4.pt'\\n\",\n    \"text_encoder = BertModel.from_pretrained(\\\"hfl/chinese-roberta-wwm-ext\\\").cuda().eval()\\n\",\n    \"state_dict_of_bert = torch.load(local_path)['state_dict']\\n\",\n    \"bert_weights = {k.replace('module.transformer.',''):v for k,v in state_dict_of_bert.items() if 'module.transformer' in k}\\n\",\n    \"text_encoder.load_state_dict(bert_weights)\\n\",\n    \"tokenizer = BertTokenizer.from_pretrained(\\\"hfl/chinese-roberta-wwm-ext\\\")\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# 同时保存模型和词表格。然后把这个上传到huggingface上面去\\n\",\n    \"text_encoder.save_pretrained('./project/temp_weights/vit-l-roberta-base')\\n\",\n    \"tokenizer.save_pretrained('./project/temp_weights/vit-l-roberta-base')\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"total = sum([param.nelement() for param in text_encoder.parameters()])\\n\",\n    \"print(\\\"Number of parameter: %.2fM\\\" % (total/1e6))\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3.9.13 ('base')\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.9.13\"\n  },\n  \"orig_nbformat\": 4,\n  \"vscode\": {\n   \"interpreter\": {\n    \"hash\": \"4cc247672a8bfe61dc951074f9ca89ab002dc0f7e14586a8bb0828228bebeefa\"\n   }\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"
  },
  {
    "path": "text-image/zeroshot_retrieval_evaluation.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def get_metrics(image_features, text_features, labels, logit_scale):\\n\",\n    \"    # 计算相似度，支持多个样本的情况（比如一个图片有多个caption）\\n\",\n    \"    # img2txt计算的时候要用到，因为一张图片可能对应多个文本。\\n\",\n    \"    # txt2img计算的时候不需要（一般一个text只有一个对应图片）\\n\",\n    \"    metrics = {}\\n\",\n    \"    logits_per_image = (logit_scale * image_features @ text_features.t()).detach().cpu()\\n\",\n    \"    logits_per_text = logits_per_image.t().detach().cpu()\\n\",\n    \"\\n\",\n    \"    logits = {\\\"image_to_text\\\": logits_per_image, \\\"text_to_image\\\": logits_per_text}\\n\",\n    \"\\n\",\n    \"    label2idx = {}  # 计算label到idx的映射。\\n\",\n    \"    repeat_id = []\\n\",\n    \"    for i, label in enumerate(labels):\\n\",\n    \"        if label not in label2idx:\\n\",\n    \"            label2idx[label] = [i]\\n\",\n    \"        else:\\n\",\n    \"            # 表示该index的标签出现过，记录这个index，后续算txt2img分数的时候，这些index的权值要降低。\\n\",\n    \"            label2idx[label].append(i)\\n\",\n    \"            repeat_id.append(i)\\n\",\n    \"    # print(label2idx)    # 标注了每个label的idx\\n\",\n    \"\\n\",\n    \"    # print('repeat_id:', repeat_id)\\n\",\n    \"    ground_truth = [label2idx[label] for label in labels]\\n\",\n    \"    # print(ground_truth)\\n\",\n    \"\\n\",\n    \"    for name, logit in logits.items():\\n\",\n    \"        # print(name, logit.shape)\\n\",\n    \"        if name == 'text_to_image':\\n\",\n    \"            logit[:, repeat_id] -= 1e8   # 这部分的分数要降低。（重复出现的图片，直接忽略）\\n\",\n    \"        r1_stat, r5_stat, r10_stat = [], [], []\\n\",\n    \"        ranking = torch.argsort(logit, descending=True) # index of the largest element to the smallest\\n\",\n    \"        # print(name, ranking[:, :10])\\n\",\n    \"        for i, each_query in enumerate(ranking[:, :10]):\\n\",\n    \"            for j, q in enumerate(each_query):\\n\",\n    \"                if q in ground_truth[i]:\\n\",\n    \"                    if j == 0:\\n\",\n    \"                        r1_stat.append(1)\\n\",\n    \"                        r5_stat.append(1)\\n\",\n    \"                        r10_stat.append(1)\\n\",\n    \"                        break\\n\",\n    \"                    if j < 5:\\n\",\n    \"                        r5_stat.append(1)\\n\",\n    \"                        r10_stat.append(1)\\n\",\n    \"                        break\\n\",\n    \"                    if j < 10:\\n\",\n    \"                        r10_stat.append(1)\\n\",\n    \"                        break\\n\",\n    \"        print(f'{name} r1:{sum(r1_stat)/len(logit)}, r5:{sum(r5_stat)/len(logit)}, r10:{sum(r10_stat)/len(logit)}')\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# COCO-CN\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from transformers import BertTokenizer\\n\",\n    \"from torch.utils.data import Dataset\\n\",\n    \"from torch.utils.data import DataLoader\\n\",\n    \"from PIL import Image\\n\",\n    \"class COCO_CN(Dataset):\\n\",\n    \"    def __init__(self, img_root_path='./dataset/coco', \\\\\\n\",\n    \"                test_img_path='./dataset/coco/coco-cn-version1805v1.1/coco-cn_test.txt', \\\\\\n\",\n    \"                annot_path = './dataset/coco/coco-cn-version1805v1.1/imageid.human-written-caption.txt', \\\\\\n\",\n    \"                transform=None):\\n\",\n    \"        self.images = []\\n\",\n    \"        self.captions = []\\n\",\n    \"        self.labels = []\\n\",\n    \"        self.root = img_root_path\\n\",\n    \"        \\n\",\n    \"        test_path = dict()\\n\",\n    \"        with open(test_img_path, 'r') as f:\\n\",\n    \"            for line in f:\\n\",\n    \"                line = line.strip()\\n\",\n    \"                if line not in test_path:\\n\",\n    \"                    test_path[line] = 1\\n\",\n    \"        # print(test_path)\\n\",\n    \"\\n\",\n    \"        with open(annot_path, 'r') as f:\\n\",\n    \"            for line in f:\\n\",\n    \"                line = line.strip().split('\\\\t')\\n\",\n    \"                key, caption = line[0].split('#')[0], line[1]\\n\",\n    \"                # NOTE 只保留test set的\\n\",\n    \"                if key not in test_path:\\n\",\n    \"                    continue\\n\",\n    \"                # if line[0].split('#')[-1] != '0':\\n\",\n    \"                #     # print(key, line[0].split('#')[-1])\\n\",\n    \"                #     continue # 只保留一句\\n\",\n    \"                img_path = key + '.jpg'\\n\",\n    \"\\n\",\n    \"                if 'train' in img_path:\\n\",\n    \"                    self.images.append(os.path.join('train2014' ,img_path) )\\n\",\n    \"                else:\\n\",\n    \"                    self.images.append(os.path.join('val2014' ,img_path) )\\n\",\n    \"                self.captions.append(caption)\\n\",\n    \"                self.labels.append(key)\\n\",\n    \"        self.transforms = transform\\n\",\n    \"        self.tokenizer = BertTokenizer.from_pretrained(\\\"hfl/chinese-roberta-wwm-ext\\\")\\n\",\n    \"\\n\",\n    \"        # NOTE large 模型\\n\",\n    \"        self.context_length = 77\\n\",\n    \"\\n\",\n    \"    def __len__(self):\\n\",\n    \"        return len(self.images)\\n\",\n    \"\\n\",\n    \"    def __getitem__(self, idx):\\n\",\n    \"        img_path = str(self.images[idx])\\n\",\n    \"        image = self.transforms(Image.open( os.path.join(self.root, img_path ))) \\n\",\n    \"        text = self.tokenizer(str(self.captions[idx]), max_length=self.context_length, padding='max_length', truncation=True, return_tensors='pt')['input_ids'][0]\\n\",\n    \"        label = self.labels[idx]\\n\",\n    \"        return image, text, label\\n\",\n    \"\\n\",\n    \"from torchvision.transforms import Normalize, Compose, RandomResizedCrop, InterpolationMode, ToTensor, Resize, \\\\\\n\",\n    \"    CenterCrop\\n\",\n    \"def _convert_to_rgb(image):\\n\",\n    \"    return image.convert('RGB')\\n\",\n    \"\\n\",\n    \"def image_transform(\\n\",\n    \"        image_size: int,\\n\",\n    \"        is_train: bool,\\n\",\n    \"        mean=(0.48145466, 0.4578275, 0.40821073),\\n\",\n    \"        std=(0.26862954, 0.26130258, 0.27577711)\\n\",\n    \"):\\n\",\n    \"    normalize = Normalize(mean=mean, std=std)\\n\",\n    \"    if is_train:\\n\",\n    \"        return Compose([\\n\",\n    \"            RandomResizedCrop(image_size, scale=(0.9, 1.0), interpolation=InterpolationMode.BICUBIC),\\n\",\n    \"            _convert_to_rgb,\\n\",\n    \"            ToTensor(),\\n\",\n    \"            normalize,\\n\",\n    \"        ])\\n\",\n    \"    else:\\n\",\n    \"        return Compose([\\n\",\n    \"            Resize(image_size, interpolation=InterpolationMode.BICUBIC),\\n\",\n    \"            CenterCrop(image_size),\\n\",\n    \"            _convert_to_rgb,\\n\",\n    \"            ToTensor(),\\n\",\n    \"            normalize,\\n\",\n    \"        ])\\n\",\n    \"\\n\",\n    \"val_transform = image_transform(224, False)\\n\",\n    \"dataset = COCO_CN(transform = val_transform)\\n\",\n    \"dataloader = DataLoader(dataset, batch_size=128, shuffle=False, num_workers=4)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"len(dataset)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from transformers import BertTokenizer\\n\",\n    \"from transformers import BertForSequenceClassification\\n\",\n    \"from transformers import CLIPModel\\n\",\n    \"import torch\\n\",\n    \"# NOTE load model\\n\",\n    \"\\n\",\n    \"text_encoder = BertForSequenceClassification.from_pretrained(\\\"IDEA-CCNL/Taiyi-CLIP-Roberta-102M-Chinese\\\").cuda().eval()\\n\",\n    \"clip_model = CLIPModel.from_pretrained(\\\"openai/clip-vit-base-patch32\\\").cuda().eval() \\n\",\n    \"\\n\",\n    \"# text_encoder = BertForSequenceClassification.from_pretrained(\\\"IDEA-CCNL/Taiyi-CLIP-Roberta-large-326M-Chinese\\\").cuda().eval()\\n\",\n    \"# clip_model = CLIPModel.from_pretrained(\\\"openai/clip-vit-large-patch14\\\").cuda().eval() \\n\",\n    \"\\n\",\n    \"\\n\",\n    \"all_img_features, all_text_features, all_labels = [], [], []\\n\",\n    \"with torch.no_grad():\\n\",\n    \"    for i, data in enumerate(dataloader):\\n\",\n    \"        images, captions, labels = data\\n\",\n    \"        images = images.cuda()\\n\",\n    \"        captions = captions.cuda()\\n\",\n    \"        all_labels.extend(labels)\\n\",\n    \"        # print(images.shape, captions.shape, labels)\\n\",\n    \"\\n\",\n    \"        image_features = clip_model.get_image_features(images)\\n\",\n    \"        text_features = text_encoder(captions).logits\\n\",\n    \"        # 归一化\\n\",\n    \"        image_features = image_features / image_features.norm(dim=1, keepdim=True)\\n\",\n    \"        text_features = text_features / text_features.norm(dim=1, keepdim=True)\\n\",\n    \"        all_img_features.append(image_features)\\n\",\n    \"        all_text_features.append(text_features)\\n\",\n    \"        # if i == 10:\\n\",\n    \"        #     break\\n\",\n    \"    img_features = torch.cat(all_img_features)\\n\",\n    \"    text_features = torch.cat(all_text_features)\\n\",\n    \"    print(img_features.shape, text_features.shape, len(all_labels))\\n\",\n    \"get_metrics(img_features, text_features, all_labels, 100)  \"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# flickr30k-CNA\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from transformers import BertTokenizer\\n\",\n    \"from torch.utils.data import Dataset\\n\",\n    \"from torch.utils.data import DataLoader\\n\",\n    \"from PIL import Image\\n\",\n    \"class flickr30k_CNA(Dataset):\\n\",\n    \"    def __init__(self, img_root_path='./dataset/mm_data/Flickr30k-CNA/flickr30k/images', \\\\\\n\",\n    \"                text_annot_path='./dataset/mm_data/Flickr30k-CNA/test/flickr30k_cn_test.txt', \\\\\\n\",\n    \"                transform=None):\\n\",\n    \"        self.images = []\\n\",\n    \"        self.captions = []\\n\",\n    \"        self.labels = []\\n\",\n    \"        self.root = img_root_path\\n\",\n    \"        with open(text_annot_path, 'r') as f:\\n\",\n    \"            for line in f:\\n\",\n    \"                line = line.strip().split('\\\\t')\\n\",\n    \"                key, caption = line[0].split('#')[0], line[1]\\n\",\n    \"                img_path = key + '.jpg'\\n\",\n    \"                self.images.append(img_path)\\n\",\n    \"                self.captions.append(caption)\\n\",\n    \"                self.labels.append(key)\\n\",\n    \"        self.transforms = transform\\n\",\n    \"        self.tokenizer = BertTokenizer.from_pretrained(\\\"hfl/chinese-roberta-wwm-ext\\\")\\n\",\n    \"\\n\",\n    \"        # NOTE large 模型\\n\",\n    \"        self.context_length = 77\\n\",\n    \"\\n\",\n    \"    def __len__(self):\\n\",\n    \"        return len(self.images)\\n\",\n    \"\\n\",\n    \"    def __getitem__(self, idx):\\n\",\n    \"        img_path = str(self.images[idx])\\n\",\n    \"        image = self.transforms(Image.open( os.path.join(self.root, img_path ))) \\n\",\n    \"        text = self.tokenizer(str(self.captions[idx]), max_length=self.context_length, padding='max_length', truncation=True, return_tensors='pt')['input_ids'][0]\\n\",\n    \"        label = self.labels[idx]\\n\",\n    \"        return image, text, label\\n\",\n    \"\\n\",\n    \"from torchvision.transforms import Normalize, Compose, RandomResizedCrop, InterpolationMode, ToTensor, Resize, \\\\\\n\",\n    \"    CenterCrop\\n\",\n    \"def _convert_to_rgb(image):\\n\",\n    \"    return image.convert('RGB')\\n\",\n    \"\\n\",\n    \"def image_transform(\\n\",\n    \"        image_size: int,\\n\",\n    \"        is_train: bool,\\n\",\n    \"        mean=(0.48145466, 0.4578275, 0.40821073),\\n\",\n    \"        std=(0.26862954, 0.26130258, 0.27577711)\\n\",\n    \"):\\n\",\n    \"    normalize = Normalize(mean=mean, std=std)\\n\",\n    \"    if is_train:\\n\",\n    \"        return Compose([\\n\",\n    \"            RandomResizedCrop(image_size, scale=(0.9, 1.0), interpolation=InterpolationMode.BICUBIC),\\n\",\n    \"            _convert_to_rgb,\\n\",\n    \"            ToTensor(),\\n\",\n    \"            normalize,\\n\",\n    \"        ])\\n\",\n    \"    else:\\n\",\n    \"        return Compose([\\n\",\n    \"            Resize(image_size, interpolation=InterpolationMode.BICUBIC),\\n\",\n    \"            CenterCrop(image_size),\\n\",\n    \"            _convert_to_rgb,\\n\",\n    \"            ToTensor(),\\n\",\n    \"            normalize,\\n\",\n    \"        ])\\n\",\n    \"\\n\",\n    \"val_transform = image_transform(224, False)\\n\",\n    \"img_root = '/dataset/mm_data/Flickr30k-CNA/flickr30k/images'\\n\",\n    \"text_annot_path = './dataset/mm_data/Flickr30k-CNA/test/flickr30k_cn_test.txt'\\n\",\n    \"dataset = flickr30k_CNA(img_root, text_annot_path, val_transform)\\n\",\n    \"dataloader = DataLoader(dataset, batch_size=128, shuffle=False, num_workers=4)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from transformers import BertTokenizer\\n\",\n    \"from transformers import BertForSequenceClassification\\n\",\n    \"from transformers import CLIPModel\\n\",\n    \"import torch\\n\",\n    \"# text_encoder = BertForSequenceClassification.from_pretrained(\\\"IDEA-CCNL/Taiyi-CLIP-Roberta-102M-Chinese\\\").cuda().eval()\\n\",\n    \"# clip_model = CLIPModel.from_pretrained(\\\"openai/clip-vit-base-patch32\\\").cuda().eval() \\n\",\n    \"\\n\",\n    \"# NOTE large\\n\",\n    \"text_encoder = BertForSequenceClassification.from_pretrained(\\\"IDEA-CCNL/Taiyi-CLIP-Roberta-large-326M-Chinese\\\").cuda().eval()\\n\",\n    \"clip_model = CLIPModel.from_pretrained(\\\"openai/clip-vit-large-patch14\\\").cuda().eval() \"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"all_img_features, all_text_features, all_labels = [], [], []\\n\",\n    \"with torch.no_grad():\\n\",\n    \"    for i, data in enumerate(dataloader):\\n\",\n    \"        images, captions, labels = data\\n\",\n    \"        images = images.cuda()\\n\",\n    \"        captions = captions.cuda()\\n\",\n    \"        all_labels.extend(labels)\\n\",\n    \"        # print(images.shape, captions.shape, labels)\\n\",\n    \"\\n\",\n    \"        image_features = clip_model.get_image_features(images)\\n\",\n    \"        text_features = text_encoder(captions).logits\\n\",\n    \"        # 归一化\\n\",\n    \"        image_features = image_features / image_features.norm(dim=1, keepdim=True)\\n\",\n    \"        text_features = text_features / text_features.norm(dim=1, keepdim=True)\\n\",\n    \"        all_img_features.append(image_features)\\n\",\n    \"        all_text_features.append(text_features)\\n\",\n    \"        # if i == 10:\\n\",\n    \"        #     break\\n\",\n    \"    img_features = torch.cat(all_img_features)\\n\",\n    \"    text_features = torch.cat(all_text_features)\\n\",\n    \"    print(img_features.shape, text_features.shape, len(all_labels))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"get_metrics(img_features, text_features, all_labels, 100)  # 图片取前1000张，因为后面的是重复的（每张图片对应5个caption）Flickr\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# non-classification\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# NOTE load from local path\\n\",\n    \"from transformers import BertModel\\n\",\n    \"local_path = './project/open_clip_new/src/logs/2022_11_18-21_15_16-model_ViT-L-14-lr_0.0001-b_640-j_16-p_amp/checkpoints/epoch_5.pt'\\n\",\n    \"text_encoder = BertModel.from_pretrained(\\\"hfl/chinese-roberta-wwm-ext\\\").cuda().eval()\\n\",\n    \"state_dict_of_bert = torch.load(local_path)['state_dict']\\n\",\n    \"bert_weights = {k.replace('module.transformer.',''):v for k,v in state_dict_of_bert.items() if 'module.transformer' in k}\\n\",\n    \"text_encoder.load_state_dict(bert_weights)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"all_img_features, all_text_features, all_labels = [], [], []\\n\",\n    \"with torch.no_grad():\\n\",\n    \"    for i, data in enumerate(dataloader):\\n\",\n    \"        images, captions, labels = data\\n\",\n    \"        images = images.cuda()\\n\",\n    \"        captions = captions.cuda()\\n\",\n    \"        all_labels.extend(labels)\\n\",\n    \"        # print(images.shape, captions.shape, labels)\\n\",\n    \"\\n\",\n    \"        image_features = clip_model.get_image_features(images)\\n\",\n    \"        text_features = text_encoder(captions)[1]\\n\",\n    \"        # 归一化\\n\",\n    \"        image_features = image_features / image_features.norm(dim=1, keepdim=True)\\n\",\n    \"        text_features = text_features / text_features.norm(dim=1, keepdim=True)\\n\",\n    \"        all_img_features.append(image_features)\\n\",\n    \"        all_text_features.append(text_features)\\n\",\n    \"        # if i == 10:\\n\",\n    \"        #     break\\n\",\n    \"    img_features = torch.cat(all_img_features)\\n\",\n    \"    text_features = torch.cat(all_text_features)\\n\",\n    \"    print(img_features.shape, text_features.shape, len(all_labels))\\n\",\n    \"get_metrics(img_features, text_features, all_labels, 100)  # 图片取前1000张，因为后面的是重复的（每张图片对应5个caption）Flickr\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3.9.13 ('base')\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.9.13\"\n  },\n  \"orig_nbformat\": 4,\n  \"vscode\": {\n   \"interpreter\": {\n    \"hash\": \"4cc247672a8bfe61dc951074f9ca89ab002dc0f7e14586a8bb0828228bebeefa\"\n   }\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"
  }
]