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

346 天前
 OysterQAQ

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]

预览

3166 次点击
所在节点    分享创造
18 条回复
tyzandhr
345 天前
你们搞得这个呀,一颗赛艇
OysterQAQ
345 天前
没有成品应用好像大伙都不感兴趣 后面会放出以文搜图(动漫插图)的应用 api
ck65
345 天前
挽尊...还折了个置顶 😄
OysterQAQ
345 天前
@ck65 感谢挽尊🥺🥺🥺
cest
345 天前
danbooru 的已经有了
原来是 tensorflow 的
a1111 port 到 pytorch

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

或是出个 frontend 可以一次用各种 model 来 tag
再整理出最最可能的 tag
OysterQAQ
345 天前
@cest deepdanbooru 是做了多标签多分类,标签有限制数目,后续我会在千万张 pixiv 图片上提供文本到图像的检索服务,可以解决一些 pixiv 本身图片 tag 质量差的问题
oldshensheep
344 天前
搞个逆向 StableDiffusion ,输入图片生成 prompt
OysterQAQ
344 天前
@oldshensheep blip 就可以做到
chenY520
344 天前
没找到有关多模态的帖子,来这里问一下。多模态模型训练有什么最低配置嘛?
OysterQAQ
344 天前
@chenY520 moco 那种队列负样本方式的话,8 张 a100 可以跑完整的训练,微调的话,我是用一张 3090 就完成了
lopssh
344 天前
谢谢
graetdk
343 天前
太强了,大佬是研究这个领域的吗
OysterQAQ
343 天前
@graetdk 哈哈 不是大佬 我们之前还聊过呢 你应该还有我 qq 不算专业研究 cv 的 在读研 方向是深度学习的推荐系统 这些算是 side project
chenY520
343 天前
@OysterQAQ 好的谢谢
Thiece
342 天前
看见 tensorflow 就失去兴趣了
OysterQAQ
342 天前
@Thiece pytorch 和 tf 都有 里面有 tf 的代码只是我需要本地 tf-serving 部署才转换权重的 本身微调训练是 pytorch clip 本身也是 pytorch 写的
ikaros
340 天前
请问一下第一张图里 a dog 在哪里?
OysterQAQ
340 天前
@ikaros 可能是兽耳因素吧 后面是概率值 看最大的就好了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/941177

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX