V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
OysterQAQ
V2EX  ›  分享创造

ACG2vec 系列之 DanbooruCLIP——二次元数据集微调的 CLIP 模型

  •  2
     
  •   OysterQAQ ·
    OysterQAQ · 315 天前 · 3126 次点击
    这是一个创建于 315 天前的主题,其中的信息可能已经有所发展或是发生改变。

    ACG2vec 系列之 DanbooruCLIP——二次元数据集微调的 CLIP 模型

    介绍

    Huggingface 在线体验: https://huggingface.co/OysterQAQ/DanbooruCLIP

    github 主仓库地址( pt 模型文件可以在 release 下载): https://github.com/OysterQAQ/ACG2vec

    使用 danburoo2021 数据集对 clip ( ViT-L/14 )模型进行微调。

    0-3 epoch 学习率为 4e-6 ,权重衰减为 1e-3

    4-8 epoch 学习率为 1e-6 ,权重衰减为 1e-3

    标签预处理过程:

                for i in range(length):
                    # 加载并且缩放图片
                    if not is_image(data_from_db.path[i]):
                        continue
    
                    try:
                        img = self.preprocess(
                            Image.open(data_from_db.path[i].replace("./", "/mnt/lvm/danbooru2021/danbooru2021/")))
                    except Exception as e:
                        #print(e)
                        continue
                    # 处理标签
                    tags = json.loads(data_from_db.tags[i])
                    # 优先选择人物和作品标签
                    category_group = {}
                    for tag in tags:
                        category_group.setdefault(tag["category"], []).append(tag)
    
                    # category_group=groupby(tags, key=lambda x: (x["category"]))
                    character_list = category_group[4] if 4 in category_group else []
                    # 作品需要过滤以 bad 开头的
    
                    work_list = list(filter(
                        lambda e:
                                   e["name"] != "original"
                                , category_group[3])) if 3 in category_group else []
                    # work_list=  category_group[5] if 5 in category_group else []
                    general_list = category_group[0] if 0 in category_group else []
                    caption = ""
                    caption_2 = None
                    for character in character_list:
                        if len(work_list) != 0:
                            # 去除括号内作品内容
                            character["name"] = re.sub(u"\\(.*?\\)", "", character["name"])
                        caption += character["name"].replace("_", " ")
                        caption += ","
                    caption = caption[:-1]
                    caption += " "
                    if len(work_list) != 0:
                        caption += "from "
                    for work in work_list:
                        caption += work["name"].replace("_", " ")
                        caption += " "
                    # 普通标签
                    if len(general_list) != 0:
                        caption += "with "
                    if len(general_list) > 20:
                        general_list_1 = general_list[:int(len(general_list) / 2)]
                        general_list_2 = general_list[int(len(general_list) / 2):]
                        caption_2 = caption
                        for general in general_list_1:
                            if general["name"].find("girl") == -1 and general["name"].find("boy") == -1 and len(
                                    re.findall(is_contain, general["name"])) != 0:
                                caption_2 += general["name"].replace("_", " ")
                                caption_2 += ","
                        caption_2 = caption_2[:-1]
                        for general in general_list_2:
                            if general["name"].find("girl") == -1 and general["name"].find("boy") == -1 and len(
                                    re.findall(is_contain, general["name"])) != 0:
                                caption += general["name"].replace("_", " ")
                                caption += ","
                        caption = caption[:-1]
                    else:
                        for general in general_list:
                            # 如果标签数据目大于 20 则拆分成两个 caption
                            if general["name"].find("girl") == -1 and general["name"].find("boy") == -1 and len(
                                    re.findall(is_contain, general["name"])) != 0:
                                caption += general["name"].replace("_", " ")
                                caption += ","
                        caption = caption[:-1]
    
                    # 标签汇总成语句
                    # tokenize 语句
                    # 返回
                    # 过长截断 不行的话用 huggingface 的
                    text_1 = clip.tokenize(texts=caption, truncate=True)
                    text_2= None
                    if caption_2 is not None:
                        text_2 = clip.tokenize(texts=caption_2, truncate=True)
                    # 处理逻辑
    
                    # print(img)
                    yield img, text_1[0]
                    if text_2 is not None:
                        yield img, text_2[0]
    

    预览

    image-20230519093129144

    image-20230519093035218

    18 条回复    2023-05-24 14:37:20 +08:00
    tyzandhr
        1
    tyzandhr  
       314 天前 via Android
    你们搞得这个呀,一颗赛艇
    OysterQAQ
        2
    OysterQAQ  
    OP
       314 天前
    没有成品应用好像大伙都不感兴趣 后面会放出以文搜图(动漫插图)的应用 api
    ck65
        3
    ck65  
       314 天前
    挽尊...还折了个置顶 😄
    OysterQAQ
        4
    OysterQAQ  
    OP
       314 天前
    @ck65 感谢挽尊🥺🥺🥺
    cest
        5
    cest  
       314 天前
    danbooru 的已经有了
    原来是 tensorflow 的
    a1111 port 到 pytorch

    model 要能 tag 当季的才好吸睛吧

    或是出个 frontend 可以一次用各种 model 来 tag
    再整理出最最可能的 tag
    OysterQAQ
        6
    OysterQAQ  
    OP
       314 天前 via iPhone
    @cest deepdanbooru 是做了多标签多分类,标签有限制数目,后续我会在千万张 pixiv 图片上提供文本到图像的检索服务,可以解决一些 pixiv 本身图片 tag 质量差的问题
    oldshensheep
        7
    oldshensheep  
       314 天前
    搞个逆向 StableDiffusion ,输入图片生成 prompt
    OysterQAQ
        8
    OysterQAQ  
    OP
       314 天前   ❤️ 1
    @oldshensheep blip 就可以做到
    chenY520
        9
    chenY520  
       313 天前 via iPhone
    没找到有关多模态的帖子,来这里问一下。多模态模型训练有什么最低配置嘛?
    OysterQAQ
        10
    OysterQAQ  
    OP
       313 天前 via iPhone
    @chenY520 moco 那种队列负样本方式的话,8 张 a100 可以跑完整的训练,微调的话,我是用一张 3090 就完成了
    lopssh
        11
    lopssh  
       313 天前 via Android
    谢谢
    graetdk
        12
    graetdk  
       312 天前
    太强了,大佬是研究这个领域的吗
    OysterQAQ
        13
    OysterQAQ  
    OP
       312 天前
    @graetdk 哈哈 不是大佬 我们之前还聊过呢 你应该还有我 qq 不算专业研究 cv 的 在读研 方向是深度学习的推荐系统 这些算是 side project
    chenY520
        14
    chenY520  
       312 天前 via iPhone
    @OysterQAQ 好的谢谢
    Thiece
        15
    Thiece  
       312 天前
    看见 tensorflow 就失去兴趣了
    OysterQAQ
        16
    OysterQAQ  
    OP
       312 天前
    @Thiece pytorch 和 tf 都有 里面有 tf 的代码只是我需要本地 tf-serving 部署才转换权重的 本身微调训练是 pytorch clip 本身也是 pytorch 写的
    ikaros
        17
    ikaros  
       310 天前
    请问一下第一张图里 a dog 在哪里?
    OysterQAQ
        18
    OysterQAQ  
    OP
       310 天前
    @ikaros 可能是兽耳因素吧 后面是概率值 看最大的就好了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5421 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 07:37 · PVG 15:37 · LAX 00:37 · JFK 03:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.