YOLACT分割:32个原型如何生成百万Mask
2026/7/3 13:09:25 网站建设 项目流程

第一步:为什么不能直接预测 Mask?

假设:

输入图片:

640 × 640

检测出来:

猫1 猫2 狗1

如果每一个目标直接预测一个 Mask:

例如:

640 × 640

就是

409600

个像素。

假设:

100 个目标。

网络需要输出:

100 × 640 × 640 = 40960000

四千多万个数。

这是非常大的。

所以:

大家开始想:

有没有办法不要每一个目标都预测一张 Mask?

于是:

YOLACT 提出了:

Prototype。


第二步:什么叫 Prototype?

先不要想 Mask。

想画画。

假设:

我给你:

32 种颜色。

例如:

红 蓝 绿 黄 黑 白 ……

以后:

任何一幅画。

是不是都可以:

用:

不同颜色 + 不同配比

画出来?

例如:

天空:

蓝色 80% 白色 20%

树:

绿色 90% 黄色 10%

其实:

颜色没有无限多。

只需要:

几十种基础颜色。

然后:

调配。


Prototype

就是:

基础颜色。


第三步:Prototype 在 Mask 里面是什么意思?

例如:

网络先预测:

32 张:

基础Mask

例如:

(这里只是示意)

Prototype1

████ ████ .... ....

Prototype2

.... ████ ████ ....

Prototype3

██.. ██.. ██..

……

一直到:

Prototype32

注意:

这些 Prototype 并不是猫、狗、人。

而是网络自己学习出来的一组基础模板(basis)

你可以把它理解成:

32 张可以重复利用的“Mask 积木”。


第四步:那 Coefficient 是什么?

现在:

猫来了。

网络说:

这只猫:

不要重新画。

只需要:

Prototype1 × 0.8
    Prototype7 × 0.2
      Prototype18 × 0.5

        ……

        最后:

        组合。

        就得到:

        猫Mask

        所以:

        Coefficient:

        其实就是:

        32 个权重

        例如:

        [0.8,0.1,0.0,...0.4]

        长度:

        就是:

        32。


        第五步:为什么一定是32?

        这里就是你的问题。

        答案其实是:

        没有任何理论规定必须是32。

        完全是:

        超参数(Hyperparameter)。

        论文作者:

        实验发现:

        例如:

        Prototype数量效果
        8太少
        16一般
        32很好
        64提升很小
        128几乎没提升

        所以:

        选择:

        32

        这是:

        经验值。

        不是数学公式。


        实际上:

        如果你打开 YOLACT 源码。

        你会看到:

        mask_dim=32

        完全可以:

        改:

        mask_dim=64

        网络:

        一样可以训练。

        YOLO Seg:

        也是一样。


        第六步:为什么32就够了?

        这是很多人第二个疑问。

        例如:

        猫有:

        胖猫 瘦猫 黑猫 白猫 ……

        为什么:

        32 张 Prototype

        能够表示:

        所有 Mask?

        答案:

        因为:

        Prototype

        不是:

        猫模板

        而是:

        边缘 圆形 竖条 横条 局部纹理 ……

        这些:

        基础形状。

        类似:

        数学里面:

        向量空间。

        例如:

        二维空间:

        任何向量:

        (x,y)

        其实:

        都可以:

        表示成:

        (1,0) + (0,1)

        两个基底。

        Prototype:

        其实:

        就是:

        Mask Space

        里面的:

        Basis(基)。

        所以:

        论文里面:

        很多地方:

        直接叫:

        Prototype Basis Dictionary

        意思:

        一样。


        第七步:真正的公式是什么?

        假设:

        Prototype:

        Proto.shape=(32,160,160)

        表示:

        32 张:

        160×160

        Mask。

        例如:

        第一张:

        160×160

        第二张:

        160×160

        ……

        第32张:

        160×160

        现在:

        第一只猫:

        预测:

        Coeff=(32,)

        例如:

        [0.2,0.7,...0.5]

        真正计算:

        就是:

        Mask=Σ Coeff[i]× Proto[i]

        也就是:

        Mask=0.2×Proto1+0.7×Proto2+……+0.5×Proto32

        最后:

        得到:

        160×160

        Mask。

        然后:

        Upsample:

        640×640

        结束。


        第八步:为什么这种方法这么快?

        假设:

        有:

        100 个目标。

        如果:

        每一个:

        预测:

        640×640

        Mask。

        需要:

        100 × 640 × 640

        如果:

        用 Prototype。

        整个图片:

        只预测:

        32 × 160 × 160

        一次。

        然后:

        每个目标:

        只预测:

        32

        个数。

        例如:

        100 个目标:

        只需要:

        100 × 32

        这点计算量几乎可以忽略。

        所以:

        速度:

        非常快。

        这也是YOLACT 和 YOLO11-Seg 能做到实时实例分割的关键原因


        最后,我想纠正一个很多人都会产生的误解

        Prototype 不是 32 个类别。

        也不是:

        • 第一张 Proto = 猫
        • 第二张 Proto = 狗
        • 第三张 Proto = 人

        完全不是。

        它更像是神经网络自己学习出来的32 个“基础形状基底(basis masks)”

        和线性代数非常像:

        二维空间 e1 e2 ↓ 任何向量

        YOLO 分割里面:

        32 个 Prototype ↓ 任何实例 Mask

        所以,32 只是“基底数量”,而不是类别数、目标数或者 Mask 数。



        我们就拿一个真实例子来算,你立刻就能理解为什么要用Prototype + Coefficient


        假设有这样一张图片

        输入:

        640 × 640

        里面有:

        猫 × 50 狗 × 50 共100个目标

        我们来比较两种方案。


        第一种:每个目标直接预测一张 Mask(最笨的方法)

        假设:

        每个目标输出:

        640 × 640

        Mask。

        那么:

        一个目标:

        需要预测:

        640 × 640 = 409600

        个数。

        100个目标:

        需要:

        409600 × 100 = 40960000

        也就是:

        4096 万个输出值。

        注意:

        这里只是输出。

        还没开始:

        • Sigmoid
        • NMS
        • Crop
        • Loss

        所以:

        输出层已经爆炸了。


        再算一下内存

        假设:

        float32

        一个数:

        4 Byte

        那么:

        40960000

        需要:

        40960000 × 4 = 163840000 Byte

        约:

        156 MB

        仅仅:

        Mask。

        还没算:

        Feature。

        还没算:

        梯度。

        所以:

        基本不可接受。


        第二种:YOLO Seg(Prototype)

        YOLO:

        先预测:

        Proto=(32,160,160)

        总共有:

        32 × 160 × 160 = 819200

        个数。

        然后:

        100个目标。

        每一个:

        预测:

        32

        Coefficient。

        所以:

        100个目标:

        100 × 32 = 3200

        最后:

        总输出:

        819200 + 3200 = 822400

        约:

        82 万个数。


        对比一下

        方法输出数量
        每目标预测640×640 Mask40,960,000
        YOLO Prototype822,400

        比值:

        40960000 / 822400 ≈ 49.8

        也就是说:

        减少约 50 倍。

        注意:

        这里只是假设:

        100个目标。

        目标越多:

        优势越明显。


        为什么还要用160×160?

        继续算。

        如果:

        Prototype:

        也是:

        640×640

        那么:

        Proto:

        32 × 640 × 640 = 13107200

        1310万个数。

        反而:

        又变大了。

        所以:

        作者:

        继续:

        降低:

        分辨率。

        变成:

        160×160

        于是:

        只有:

        819200

        个数。

        这就是:

        为什么:

        Prototype:

        不是:

        640。

        而是:

        160。


        那会不会精度下降?

        这是大家都会想到的问题。

        答案:

        会。

        所以:

        YOLO最后:

        还要:

        Upsample

        恢复:

        640。

        同时:

        利用:

        Box:

        进行:

        Crop。

        例如:

        猫:

        实际上:

        Box:

        100×120

        那么:

        Mask:

        最终:

        只保留:

        这个区域。

        所以:

        即使:

        Prototype:

        比较粗。

        最后:

        Mask:

        还是:

        比较准确。


        那 Prototype × Coefficient 的计算量大吗?

        再算。

        Proto:

        32 × 160 × 160

        每一个Pixel:

        都有:

        32个值。

        例如:

        某一个Pixel:

        [ 0.1, 0.3, 0.8, ... ]

        第一只猫:

        Coeff:

        [ 0.2, 0.4, 0.1, ... ]

        计算:

        其实就是:

        一个长度为32的点积(Dot Product):

        32 次乘法 + 31 次加法

        得到:

        Mask(100,200)

        整个:

        160×160:

        共有:

        160 × 160 = 25600

        Pixel。

        所以:

        总计算:

        25600 × 32 = 819200

        次乘法。

        对于GPU来说:

        这几乎:

        可以忽略。


        如果不用 Prototype 呢?

        假设:

        直接:

        预测:

        100个:

        640×640

        Mask。

        实际上:

        最后一层卷积:

        需要:

        100 × 640 × 640

        输出。

        GPU:

        压力:

        巨大。

        所以:

        Prototype:

        真正解决的是:

        “每个目标都画一张完整 Mask”的问题。

        它改成了:

        “整张图只画一次基础模板(Prototype),每个目标只告诉我怎么组合(Coefficient)”。


        既然只有 32 张 Prototype,100 只猫是不是都在共用同样的 32 张?它们怎么可能长得不一样?

        这个问题实际上是Prototype 最核心、也是最容易误解的地方

        答案是:

        是的,它们共用同一组 Prototype,但每个目标使用的是不同的 Coefficient,而且后面还会根据自己的检测框进行裁剪(Crop)。

        需要专业的网站建设服务?

        联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

        立即咨询