数据采样策略:四种主流方法深度解析

做PTQ校准,说白了就是给量化模型找一组“代表数据”。

数据选得好不好,直接决定量化后的精度损失。我见过太多人随便拿几百张图就跑量化,结果模型直接崩了。嗯,今天我们就聊聊四种主流的采样策略。

1. 随机采样:最朴素但最常用

随机采样,顾名思义就是从数据集中随机抽取N个样本。实现起来最简单,一行代码搞定。

import random

def random_sample(dataset, sample_size):
    return random.sample(dataset, sample_size)

但这里有个坑——随机不代表均匀。我曾经在一个分类任务里,随机采样抽到了90%都是类别A的样本,结果量化后类别B的精度掉了8个点。你想想看,校准集连类别B长什么样都没见过,模型怎么可能量化好?

⚠️ 随机采样适用于数据分布均匀的场景。如果类别不平衡,千万别直接用。

2. 分层采样:解决类别不平衡

分层采样就是按类别比例来采样。每个类别都抽一点,保证校准集和原始数据集的分布一致。

from sklearn.model_selection import StratifiedShuffleSplit

def stratified_sample(dataset, labels, sample_size):
    sss = StratifiedShuffleSplit(n_splits=1, train_size=sample_size)
    for train_idx, _ in sss.split(dataset, labels):
        return [dataset[i] for i in train_idx]

我个人习惯在分类任务中首选分层采样。它比随机采样稳定得多,尤其是当类别数量超过10个的时候。我记得有一次做自动驾驶场景的量化,有“行人”、“车辆”、“路标”等20多个类别,分层采样帮我保住了所有类别的精度。

💡 小技巧:如果某些类别样本极少(比如少于10张),可以考虑过采样或直接合并到相似类别中。

3. 基于熵的采样:关注不确定性

熵,说白了就是信息量。样本的熵越大,说明模型对它越“不确定”,这种样本对校准来说更有价值。

import numpy as np

def entropy_sample(model, dataset, sample_size):
    scores = []
    for x in dataset:
        pred = model(x)
        entropy = -np.sum(pred * np.log(pred + 1e-10))
        scores.append(entropy)
    top_indices = np.argsort(scores)[-sample_size:]
    return [dataset[i] for i in top_indices]

为什么选高熵样本?因为模型在边界附近的样本上最容易出错,量化时这些样本能帮我们更好地校准激活值的范围。我在做NLP模型量化时试过这个方法,效果比随机采样好不少。

但要注意:熵采样容易偏向噪声样本。如果数据集中有标注错误或异常值,它们的熵往往很高,选进来反而会污染校准集。

核心观点:熵采样适合模型已经比较稳定、数据质量较高的场景。

4. 基于梯度的采样:最精准但最贵

这个方法我特别喜欢,因为它直接和量化误差挂钩。原理很简单:计算每个样本对量化参数的梯度,梯度大的样本对量化影响更大。

def gradient_sample(model, dataset, sample_size):
    gradients = []
    for x in dataset:
        loss = compute_quantization_loss(model, x)
        grad = torch.autograd.grad(loss, model.parameters(), retain_graph=True)
        grad_norm = sum([g.norm().item() for g in grad])
        gradients.append(grad_norm)
    top_indices = np.argsort(gradients)[-sample_size:]
    return [dataset[i] for i in top_indices]

我曾经在一个检测模型上对比过四种方法,梯度采样的精度损失最小,但计算时间也是最长的——整整跑了3个小时。你想想看,如果数据集有10万张图,每张都要算梯度,这成本确实不低。

⚠️ 梯度采样不适合大规模数据集。建议先用随机采样缩小候选集,再在候选集上做梯度采样。

四种方法对比

方法 精度 速度 适用场景
随机采样 一般 极快 数据分布均匀
分层采样 较好 类别不平衡
熵采样 良好 中等 数据质量高
梯度采样 优秀 小数据集、高精度要求

核心逻辑图

数据采样策略 随机采样 简单快速 分布均匀时可用 分层采样 按类别比例采样 解决不平衡 熵采样 关注不确定性 适合高质量数据 梯度采样 最精准但最慢 适合小数据集

这张图把四种方法的关系理清楚了。从上到下,精度越来越高,但速度越来越慢。实际项目中怎么选?我的建议是:先看数据量,再看精度要求

💡 实战经验:我一般先用分层采样快速跑一轮,如果精度不达标,再换成熵采样或梯度采样。别一上来就上最贵的方案。

好了,四种采样策略就聊到这里。每种方法都有它的用武之地,关键是要理解它们的原理和适用场景。下次做PTQ校准的时候,记得先问问自己:我的数据长什么样?我的精度要求有多高?答案自然就有了。

蓝海数据掘金营,专注资料整理