Download README_zh.md from Redstonexs/kagami-24k: direct link, hf CLI and curl.
- Browser
- Download file 8.74 kB
-
https://huggingface.co/Redstonexs/kagami-24k/resolve/main/README_zh.md
- Command line
-
hf download hf://Redstonexs/kagami-24k/README_zh.md
-
curl -L -o README_zh.md https://huggingface.co/Redstonexs/kagami-24k/resolve/main/README_zh.md
Kagami-24k(中文说明)
English · 中文
一个基于 EVA02-L 的 Danbooru 标注模型,通用标签词表 24,000 条。在两项排序
指标上都超过 wd-eva02-large-tagger-v3,且是单模型——在 11,639 张所有对比
模型训练截止之后的图片上测得,并给出配对自助法(paired bootstrap)置信区间。
鏡——镜子只如实映出眼前之物。
结果
测试集为 11,639 篇 id > 8,600,750 的投稿,晚于所有参与对比模型的训练截止时间
(WD 7.22M、Camie 约 8.36M、PixAI 8.60M)。评分基于七个词表的交集(7,779 条
标签,其中 3,101 条正样本数 ≥10)。之所以用交集而非各自词表:在自己的词表上算
宏平均 F1,等于奖励"词表更大"而不是"预测更准"。
| 模型 | micro-F1 | macro-F1 | 宏平均 AP | 细粒度 AP | 词表 | 覆盖率 |
|---|---|---|---|---|---|---|
| Kagami-24k | 0.6710 | 0.5138 | 0.5086 | 0.6170 | 24,000 | 0.914 |
| danbooru-tagger-v1(我们的上一版) | 0.6569 | 0.4889 | 0.4672 | 0.5643 | 24,000 | 0.914 |
| wd-eva02-large-tagger-v3 | 0.6369 | 0.4728 | 0.4668 | 0.5979 | 8,106 | 0.506 |
| wd-vit-large-tagger-v3 | 0.6366 | 0.4574 | 0.4576 | 0.5960 | 8,106 | 0.506 |
| wd-swinv2-tagger-v3 | 0.6380 | 0.4522 | 0.4549 | 0.5821 | 8,106 | 0.506 |
| pixai-tagger-v0.9 | 0.6060 | 0.4481 | 0.4482 | 0.5696 | 9,740 | 0.588 |
| cl_tagger-1.02 | 0.5744 | 0.3973 | 0.3960 | 0.5329 | 25,098 | 0.869 |
| camie-tagger-v2 | 0.5848 | 0.3592 | 0.3509 | 0.4609 | 30,841 | 0.858 |
这个提升是真的吗?配对自助法,200 次重采样
只看点估计不够,所以发布标准是事先定好的:两项排序指标的差值都要 > 0, 且 95% 置信区间下界都要 > 0。
| 对比基线 | Δ 宏平均 AP | 95% CI | Δ 细粒度 AP | 95% CI | |
|---|---|---|---|---|---|
| wd-eva02-large-v3 | +0.0418 | [+0.0393, +0.0448] | +0.0190 | [+0.0060, +0.0288] | 通过 |
| danbooru-tagger-v1 | +0.0414 | [+0.0392, +0.0437] | +0.0527 | [+0.0321, +0.0652] | 通过 |
| wd-swinv2-v3 | +0.0537 | [+0.0507, +0.0568] | +0.0348 | [+0.0125, +0.0510] | 通过 |
| wd-vit-large-v3 | +0.0510 | [+0.0477, +0.0541] | +0.0209 | [−0.0001, +0.0349] | 见下 |
重采样是按图片配对的:每一次重采样两个系统看到完全相同的图片,因此占方差 主要部分的"图片本身难易度"被抵消掉了。
一个必须如实说明的例外:与 wd-vit-large-v3 相比,细粒度 AP 的置信区间下界
擦到了零,因此这一项优势在统计上并未成立——尽管对同一模型的宏平均 AP 优势
非常明确。细粒度 AP 只由三个标签组(共 38 条标签)平均而来,区间自然偏宽。其余
所有对比都干净通过。
表中的 F1 列对所有模型都偏乐观。 评分脚本在这个测试集上扫阈值。这对所有候选 模型一视同仁,所以比较是公平的,但 F1 的绝对值不是干净的数字。AP 与阈值无关 ——这正是发布标准建立在 AP 上的原因。
分组 AP——上一版输掉的那几类
| 模型 | flowers | hands | worn_small | scene | miko | framing |
|---|---|---|---|---|---|---|
| Kagami-24k | 0.6796 | 0.5369 | 0.6344 | 0.5505 | 0.6670 | 0.4645 |
| wd-eva02-large-v3 | 0.6750 | 0.5131 | 0.6057 | 0.5546 | 0.6162 | 0.4301 |
| danbooru-tagger-v1 | 0.6229 | 0.4785 | 0.5915 | 0.5207 | 0.6616 | 0.4298 |
对 wd-eva02 六组赢五组,只在 scene 上落后 0.0041。上一版是六组输四组,其中包括
flowers 和 worn_small 这两个小物体组。
训练方法
上一版只用真实标签微调 WD 的编码器。它赢下了 F1 系列指标,却在细粒度 AP 上输了 0.0336——编码器发生漂移,恰好损害了它本该保住的小细节标签。
我们做了一个 2×2 消融实验,把两个编码器和两个分类头交叉组合。结果表明这次漂移 无法归因于其中任何单一部件:交叉组合的两格直接崩塌(宏平均 AP 0.1743 和 0.0613,而两个原配组合是 0.4230 和 0.4080)。用其中三格拟合一个可加模型去预测 第四格,得到 −0.1873——对一个取值在 [0,1] 的量而言这是不可能的数值。编码器和 分类头已经共同适应成了一种 WD 的任何部件都读不懂的表示。因此"冻结浅层"这个方案 从来就没有证据支持,被放弃了。
取而代之的思路是锚定而不是固定。先构造一个冻结的教师模型:
teacher = 0.35 · 上一版 + 0.65 · mean(wd_eva02, wd_vit_large, wd_swinv2)
在与 WD 词表共享的 7,800 条通用标签上,对全部 677,355 张语料图片预先算好。0.35 这个权重是在留出的 dev 集上用折外交叉拟合(out-of-fold cross-fitting)选出来的, 从未使用测试集。逐标签加权和按词频分组加权两种更复杂的方案都试过并被否决—— 单一全局权重与最优逐标签方案只差 0.0009 宏平均 AP,低于我们为"采纳额外复杂度" 设定的门槛。
训练时所有层都可训练,采用逐层学习率衰减 0.92(编码器顶层 2.5e-6,向下衰减 到底层 3.4e-7,分类头 7e-5)。损失是真实标签上的 ASL 加上教师项,教师项权重在 整个训练过程中从 1.0 衰减到 0.3——漂移发生在早期,所以锚定在最需要的时候最强; 后期由真实标签主导,而 8.6M 之后的新知识正来自那里。共 196,000 步,batch 12, EMA 0.9998。
教师模型在 dev 上是 0.4691 宏平均 AP / 0.6250 细粒度 AP。Kagami 达到 0.4612 / 0.6211——追回了上一版与教师之间 87% 的宏平均 AP 差距和 94% 的细粒度 AP 差距, 明显高于集成蒸馏通常能回收的 50–80%。
发布的权重是原始参数,不是 EMA。两者都在 dev 上评过分,差异是 +0.0001 宏平均 AP / −0.0002 细粒度 AP——属于噪声,所以选择更简单的那个。
用法
import numpy as np, onnxruntime as ort
from PIL import Image
import csv
sess = ort.InferenceSession("model_prob.onnx", providers=["CPUExecutionProvider"])
tags = [r["name"] for r in csv.DictReader(open("selected_tags.csv"))]
def prep(path, side=448):
im = Image.open(path).convert("RGB")
w, h = im.size
s = side / max(w, h)
im = im.resize((max(1, round(w*s)), max(1, round(h*s))), Image.BICUBIC)
sq = Image.new("RGB", (side, side), (255, 255, 255))
sq.paste(im, ((side-im.size[0])//2, (side-im.size[1])//2))
x = np.asarray(sq, dtype=np.float32) / 255.
x = (x - 0.5) / 0.5
return x.transpose(2, 0, 1)[::-1][None].copy() # NCHW, BGR
p = sess.run(None, {"input": prep("image.jpg")})[0][0]
for i in np.argsort(-p)[:30]:
print(f"{tags[i]:30s} {p[i]:.3f}")
输入是 NCHW BGR,归一化 mean=std=0.5,白色方形填充——与 WD 自己的预处理一致, 不是 NHWC。SmilingWolf 发布的 ONNX 是 NHWC 格式;如果你在改造现有的 WD 流水线, 请相应地转置。
推荐阈值:宏平均 F1 用 0.37,micro-F1 用 0.54。这两个值是在测试集上扫出来 的,属于参考建议,不是严格标定。
局限
词表的大部分并未得到验证。 24,000 条标签中,14,626 条(61%)的训练样本少于 1,000 条,而 11,639 张图的评测集根本查不动它们:
| 训练样本数 | 标签数 | 可测(评测集正样本 ≥5) | 平均 AP |
|---|---|---|---|
| 100–1,000 | 13,970 | 67 | 0.4095 |
| 1,000–10,000 | 6,507 | 2,278 | 0.3826 |
| 10,000+ | 2,867 | 2,828 | 0.4714 |
100–1,000 这一档的 13,970 条标签里只有 67 条在这里是可测的。长尾部分既没有被证明 好,也没有被证明差——它是未经检验的。"24,000 条标签"描述的是输出层的宽度, 不是 24,000 条已验证的标签。
训练分辨率 448,而语料按长边 640 存储,所以模型只见过二次重采样的图像。喂原始 分辨率会比它训练时见过的任何图像都更锐利。我们做过对照实验,这个存储环节的代价在 测量精度内为零(宏平均 AP +0.0001,细粒度 AP +0.0010,CI [−0.0021, +0.0045])。
不包含角色标签和版权标签——仅通用标签。
许可与来源
Apache-2.0,衍生自 wd-eva02-large-tagger-v3(Apache-2.0)。用作蒸馏教师的三个 WD
模型均为 Apache-2.0。Camie 和 cl_tagger 仅作为基准对比出现,本模型未使用二者的任何
权重。
训练产物、日志与验证关卡:
Redstonexs/danbooru-tagger-round3-artifacts。