跳转至

🎯 计算机视觉面试题库

⚠️ 时效性说明:本章涉及前沿模型/价格/榜单等信息,可能随版本快速变化;请以论文原文、官方发布页和 API 文档为准。

覆盖CNN基础、检测/分割、Transformer、多模态、模型部署等高频面试题,每题含详细解答与代码示例。


📐 一、卷积与基础计算

Q1:卷积层输出尺寸如何计算?

标准公式:

\[ O = \left\lfloor \frac{W - K + 2P}{S} \right\rfloor + 1 \]
  • \(W\):输入尺寸,\(K\):卷积核大小,\(P\):padding,\(S\):stride

示例计算:

输入 卷积核 Padding Stride 输出
224 7 3 2 112
112 3 1 1 112
56 3 1 2 28
Python
def conv_output_size(w, k, p, s):
    """计算卷积输出尺寸"""
    return (w - k + 2 * p) // s + 1

# ResNet第一层: 224 -> 112
print(conv_output_size(224, 7, 3, 2))  # 112

面试官追问:转置卷积(反卷积)的输出尺寸公式?

\[ O = (W - 1) \times S - 2P + K + \text{output\_padding} \]

Q2:感受野(Receptive Field)如何计算?

递推公式:

\[ RF_l = RF_{l-1} + (K_l - 1) \times \prod_{i=1}^{l-1} S_i \]
Python
def compute_receptive_field(layers):
    """
    layers: list of (kernel_size, stride)
    """
    rf = 1
    stride_prod = 1
    for k, s in layers:
        rf = rf + (k - 1) * stride_prod
        stride_prod *= s
    return rf

# VGG16前3个卷积块
layers = [(3,1), (3,1), (2,2), (3,1), (3,1), (2,2), (3,1), (3,1), (3,1), (2,2)]
print(f"感受野: {compute_receptive_field(layers)}")  # 44

关键结论: - 堆叠小卷积核(3×3)的感受野等价于大卷积核,但参数更少 - 两个3×3卷积 = 一个5×5感受野,参数量 \(2 \times 3^2 = 18\) vs \(5^2 = 25\) - 空洞卷积(Dilated Conv)可以不增加参数地扩大感受野


Q3:1×1卷积的作用是什么?

三大核心作用:

  1. 通道降维/升维:调整特征通道数,减少计算量
  2. 跨通道信息交互:对同一位置不同通道做线性组合
  3. 增加非线性:配合激活函数增强表达能力
Python
import torch.nn as nn

# NiN中的1x1卷积: 256通道 -> 64通道
bottleneck = nn.Sequential(
    nn.Conv2d(256, 64, kernel_size=1),   # 参数: 256*64 = 16384
    nn.BatchNorm2d(64),
    nn.ReLU(inplace=True),
    nn.Conv2d(64, 64, kernel_size=3, padding=1),  # 参数: 64*64*9 = 36864
    nn.BatchNorm2d(64),
    nn.ReLU(inplace=True),
    nn.Conv2d(64, 256, kernel_size=1),   # 参数: 64*256 = 16384
)
# 总参数: 69632 vs 直接3x3: 256*256*9 = 589824 (节省88%)

Q4:深度可分离卷积(Depthwise Separable Conv)原理?

两步分解:

  1. Depthwise Conv:每个通道单独卷积,\(C_{in}\)\(K \times K \times 1\) 卷积核
  2. Pointwise Conv\(C_{out}\)\(1 \times 1 \times C_{in}\) 卷积核

参数量对比:

类型 参数量 以3×3, 64→128为例
标准卷积 \(K^2 \cdot C_{in} \cdot C_{out}\) 73,728
深度可分离 \(K^2 \cdot C_{in} + C_{in} \cdot C_{out}\) 8,768
压缩比 \(\approx \frac{1}{C_{out}} + \frac{1}{K^2}\) 8.4×
Python
class DepthwiseSeparableConv(nn.Module):  # 继承nn.Module定义网络层
    def __init__(self, in_ch, out_ch, kernel_size=3, stride=1, padding=1):
        super().__init__()  # super()调用父类方法
        self.depthwise = nn.Conv2d(in_ch, in_ch, kernel_size, stride, padding, groups=in_ch)
        self.pointwise = nn.Conv2d(in_ch, out_ch, 1)

    def forward(self, x):
        return self.pointwise(self.depthwise(x))

🏗️ 二、经典网络架构

Q5:ResNet为什么有效?Skip Connection的原理?

核心答案:

  1. 缓解梯度消失:梯度可以通过shortcut直接回传,保证深层网络可训练
  2. 恒等映射学习:网络只需学残差 \(F(x) = H(x) - x\),趋近于0比学恒等映射更容易
  3. 集成学习效应:ResNet可视为多条不同深度路径的隐式集成

数学推导:

\[ \frac{\partial \mathcal{L}}{\partial x_l} = \frac{\partial \mathcal{L}}{\partial x_L} \cdot \prod_{i=l}^{L-1}(1 + \frac{\partial F_i}{\partial x_i}) \]

因为包含 \(1\),梯度不会消失为 \(0\)

Python
class BasicBlock(nn.Module):
    def __init__(self, in_planes, planes, stride=1):
        super().__init__()
        self.conv1 = nn.Conv2d(in_planes, planes, 3, stride, 1, bias=False)
        self.bn1 = nn.BatchNorm2d(planes)
        self.conv2 = nn.Conv2d(planes, planes, 3, 1, 1, bias=False)
        self.bn2 = nn.BatchNorm2d(planes)

        self.shortcut = nn.Sequential()
        if stride != 1 or in_planes != planes:
            self.shortcut = nn.Sequential(
                nn.Conv2d(in_planes, planes, 1, stride, bias=False),
                nn.BatchNorm2d(planes)
            )

    def forward(self, x):
        out = F.relu(self.bn1(self.conv1(x)))  # F.xxx PyTorch函数式API
        out = self.bn2(self.conv2(out))
        out += self.shortcut(x)  # Skip Connection
        return F.relu(out)

面试官追问:Pre-Activation ResNet vs 标准ResNet的区别? - Pre-Act: BN→ReLU→Conv,最后一层输出不经过ReLU,信息更通畅


Q6:BatchNorm在训练和推理时有什么区别?

训练时: - 使用当前mini-batch的均值 \(\mu_B\) 和方差 \(\sigma_B^2\) - 维护全局running mean和running var(指数移动平均)

推理时: - 使用训练积累的running mean和running var - BN层可融入卷积层,零额外开销

Python
class BatchNorm2d(nn.Module):
    def __init__(self, num_features, eps=1e-5, momentum=0.1):
        super().__init__()
        self.gamma = nn.Parameter(torch.ones(num_features))
        self.beta = nn.Parameter(torch.zeros(num_features))
        self.register_buffer('running_mean', torch.zeros(num_features))
        self.register_buffer('running_var', torch.ones(num_features))
        self.eps = eps
        self.momentum = momentum

    def forward(self, x):
        if self.training:
            mean = x.mean(dim=(0, 2, 3))  # 对N,H,W维度求均值
            var = x.var(dim=(0, 2, 3), unbiased=False)
            # 更新running统计量
            self.running_mean = (1 - self.momentum) * self.running_mean + self.momentum * mean
            self.running_var = (1 - self.momentum) * self.running_var + self.momentum * var
        else:
            mean = self.running_mean
            var = self.running_var

        x_norm = (x - mean[None,:,None,None]) / torch.sqrt(var[None,:,None,None] + self.eps)
        return self.gamma[None,:,None,None] * x_norm + self.beta[None,:,None,None]

BN融合到卷积(推理加速):

\[ W_{fused} = \frac{\gamma}{\sqrt{\sigma^2 + \epsilon}} W, \quad b_{fused} = \frac{\gamma}{\sqrt{\sigma^2 + \epsilon}}(b - \mu) + \beta \]

面试官追问:BN在batch_size=1时失效怎么办? - 使用 GroupNorm / LayerNorm / InstanceNorm 替代


Q7:各种Normalization方法对比?

方法 归一化维度 适用场景 batch依赖
BatchNorm (N, H, W) CNN主流
LayerNorm (C, H, W) Transformer/RNN
InstanceNorm (H, W) 风格迁移
GroupNorm (C//G, H, W) 小batch CNN

🔍 三、目标检测

Q8:Anchor-based vs Anchor-free检测器的区别?

特性 Anchor-based Anchor-free
代表模型 Faster R-CNN, YOLOv3-v5 FCOS, CenterNet, YOLOv8
先验框 需预定义anchor尺寸/比例 不需要
正负样本 IoU阈值分配 几何关系分配
超参数 多(anchor尺寸/比例/数量)
回归目标 相对anchor的偏移 点到边界的距离
泛化性 受anchor设计影响 通常更好

FCOS的核心思想:

Python
# Anchor-free: 直接回归每个点到4个边界的距离
# 对于特征图上每个位置(x, y), 回归 (l, t, r, b)
def fcos_target(gt_boxes, feature_points):
    """
    gt_boxes: (N, 4) -> (x1, y1, x2, y2)
    feature_points: (H*W, 2) -> (cx, cy)
    """
    l = feature_points[:, 0:1] - gt_boxes[:, 0:1]  # 到左边界
    t = feature_points[:, 1:2] - gt_boxes[:, 1:2]  # 到上边界
    r = gt_boxes[:, 2:3] - feature_points[:, 0:1]  # 到右边界
    b = gt_boxes[:, 3:4] - feature_points[:, 1:2]  # 到下边界
    return torch.stack([l, t, r, b], dim=-1)  # torch.stack沿新维度拼接张量

Q9:NMS及其变体(Soft-NMS, DIoU-NMS)原理?

标准NMS流程:

Python
def nms(boxes, scores, iou_threshold=0.5):
    """标准NMS"""
    order = scores.argsort(descending=True)
    keep = []
    while order.numel() > 0:
        i = order[0].item()  # 将单元素张量转为Python数值
        keep.append(i)
        if order.numel() == 1:
            break
        ious = compute_iou(boxes[i].unsqueeze(0), boxes[order[1:]])  # unsqueeze增加一个维度
        mask = ious.squeeze() <= iou_threshold  # squeeze压缩维度
        order = order[1:][mask]
    return keep

Soft-NMS:不直接删除,而是衰减分数:

\[ s_i = \begin{cases} s_i \cdot e^{-\frac{IoU^2}{\sigma}} & \text{(Gaussian)} \\ s_i \cdot (1 - IoU) & \text{(Linear, if IoU} \geq N_t\text{)} \end{cases} \]
Python
def soft_nms(boxes, scores, sigma=0.5, score_threshold=0.001):
    """Soft-NMS Gaussian"""
    keep = []
    while scores.max() > score_threshold:
        i = scores.argmax().item()
        keep.append(i)
        ious = compute_iou(boxes[i].unsqueeze(0), boxes)
        decay = torch.exp(-(ious ** 2) / sigma)
        scores = scores * decay.squeeze()
        scores[i] = 0
    return keep

DIoU-NMS:用DIoU替代IoU,考虑中心距离:

\[ DIoU = IoU - \frac{d^2(b, b^{gt})}{c^2} \]

优点:密集遮挡场景下保留效果更好。

面试官追问:NMS的时间复杂度?如何加速? - 标准NMS: \(O(N^2)\),可用CUDA并行加速或按类别并行处理


Q10:IoU及其变体(GIoU, DIoU, CIoU)的区别?

指标 公式核心 解决的问题
IoU \(\frac{\lvert A \cap B\rvert}{\lvert A \cup B\rvert}\) 基础重叠度
GIoU \(IoU - \frac{\lvert C \setminus (A \cup B)\rvert}{\lvert C\rvert}\) 无重叠时梯度为0
DIoU \(IoU - \frac{d^2}{c^2}\) 中心距离
CIoU \(DIoU - \alpha v\) 长宽比一致性

其中 \(v = \frac{4}{\pi^2}(\arctan\frac{w^{gt}}{h^{gt}} - \arctan\frac{w}{h})^2\)


Q11:FPN(特征金字塔网络)的设计思想?

核心思想:自顶向下路径 + 横向连接,融合多尺度特征

Text Only
C5 (1/32) → P5 ←→ 检测大目标
  ↓ 上采样+横向连接
C4 (1/16) → P4 ←→ 检测中目标
C3 (1/8)  → P3 ←→ 检测小目标
C2 (1/4)  → P2 ←→ 检测更小目标
Python
class FPN(nn.Module):
    def __init__(self, in_channels_list, out_channels=256):
        super().__init__()
        self.lateral_convs = nn.ModuleList([
            nn.Conv2d(c, out_channels, 1) for c in in_channels_list
        ])
        self.output_convs = nn.ModuleList([
            nn.Conv2d(out_channels, out_channels, 3, padding=1)
            for _ in in_channels_list
        ])

    def forward(self, features):  # [C2, C3, C4, C5]
        laterals = [conv(f) for conv, f in zip(self.lateral_convs, features)]  # zip按位置配对
        # 自顶向下融合
        for i in range(len(laterals) - 2, -1, -1):
            laterals[i] += F.interpolate(laterals[i + 1], scale_factor=2, mode='nearest')
        return [conv(lat) for conv, lat in zip(self.output_convs, laterals)]

🤖 四、Transformer在CV中的应用

Q12:ViT(Vision Transformer)的核心设计?

关键步骤:

  1. 图像分patch:\(224 \times 224\) 切成 \(16 \times 16\) 的patch → \(14 \times 14 = 196\) 个token
  2. Patch Embedding:线性投影到D维
  3. 加CLS token + 位置编码
  4. 标准Transformer Encoder
Python
class ViT(nn.Module):
    def __init__(self, img_size=224, patch_size=16, dim=768, depth=12, heads=12, num_classes=1000):
        super().__init__()
        num_patches = (img_size // patch_size) ** 2  # 196
        patch_dim = 3 * patch_size ** 2              # 768

        self.patch_embed = nn.Sequential(
            nn.Conv2d(3, dim, kernel_size=patch_size, stride=patch_size),  # 等价于线性投影
        )
        self.cls_token = nn.Parameter(torch.randn(1, 1, dim))
        self.pos_embed = nn.Parameter(torch.randn(1, num_patches + 1, dim))
        self.transformer = nn.TransformerEncoder(
            nn.TransformerEncoderLayer(d_model=dim, nhead=heads, dim_feedforward=dim*4, batch_first=True),
            num_layers=depth
        )
        self.head = nn.Linear(dim, num_classes)

    def forward(self, x):
        B = x.shape[0]
        x = self.patch_embed(x).flatten(2).transpose(1, 2)  # (B, 196, 768)
        cls = self.cls_token.expand(B, -1, -1)
        x = torch.cat([cls, x], dim=1)                       # (B, 197, 768)  # torch.cat沿已有维度拼接张量
        x = x + self.pos_embed
        x = self.transformer(x)
        return self.head(x[:, 0])  # CLS token分类

面试官追问:ViT的计算复杂度?

\[ \text{Self-Attention}: O(N^2 \cdot D), \quad N = \frac{H \times W}{P^2} \]

对于224图像+16patch: \(N = 196\),可接受。对于高分辨率需要Swin Transformer的窗口注意力。


Q13:DETR的核心创新是什么?

核心创新: 1. 端到端检测:无需NMS、无需Anchor、无需手工后处理 2. 集合预测:用二分图匹配(Hungarian算法)做标签分配 3. Object Queries:可学习的检测query替代anchor

匈牙利匹配损失:

\[ \mathcal{L}_{match} = \lambda_{cls} \mathcal{L}_{cls} + \lambda_{L1} \|b_i - \hat{b}_{\sigma(i)}\|_1 + \lambda_{giou} \mathcal{L}_{GIoU} \]

面试官追问:DETR的缺点? - 训练收敛慢(500 epochs vs FRCNN 12 epochs) - 小目标检测效果差 → 后续 Deformable DETR 改进


Q14:SAM(Segment Anything)的架构设计?

三大组件:

组件 功能 技术
Image Encoder 图像特征提取 MAE预训练的ViT-H
Prompt Encoder 编码prompt 点/框/文本/掩码
Mask Decoder 生成分割掩码 双向Cross-Attention

关键设计: - Promptable分割:支持点、框、文本等多种prompt - 一次提取图像特征,多次解码不同prompt → 实时交互 - 训练数据:SA-1B数据集,11M图像+1B掩码


🌐 五、多模态模型

Q15:CLIP的训练方式和原理?

对比学习框架:

Text Only
Image Encoder (ViT/ResNet)  →  图像特征 [B, D]
                                    ↕ 对比损失
Text Encoder (Transformer)  →  文本特征 [B, D]

InfoNCE损失(对称):

\[ \mathcal{L} = -\frac{1}{2N}\sum_{i=1}^{N}\left[\log\frac{e^{sim(I_i, T_i)/\tau}}{\sum_j e^{sim(I_i, T_j)/\tau}} + \log\frac{e^{sim(T_i, I_i)/\tau}}{\sum_j e^{sim(T_i, I_j)/\tau}}\right] \]
Python
def clip_loss(image_features, text_features, temperature=0.07):
    """CLIP对比学习损失"""
    # 归一化
    image_features = F.normalize(image_features, dim=-1)
    text_features = F.normalize(text_features, dim=-1)

    # 计算相似度矩阵 (B, B)
    logits = image_features @ text_features.T / temperature

    # 对称交叉熵
    labels = torch.arange(len(logits), device=logits.device)
    loss_i2t = F.cross_entropy(logits, labels)  # F.cross_entropy PyTorch函数式交叉熵损失
    loss_t2i = F.cross_entropy(logits.T, labels)
    return (loss_i2t + loss_t2i) / 2

面试官追问:CLIP的zero-shot分类怎么做? - 构造文本 "a photo of a {class}" → 计算图文相似度 → 选最大值


Q16:GPT-4V等多模态大模型的架构思路?

主流架构模式:

  1. 视觉编码器 + 投影层 + LLM(LLaVA风格)
  2. ViT提取视觉token → MLP投影 → 拼接到文本token

  3. 交叉注意力融合(Flamingo风格)

  4. 在LLM层间插入Cross-Attention层

  5. 统一tokenizer(将图像离散化为token)

关键面试题:视觉token如何与文本token对齐?

Python
class VisionLanguageModel(nn.Module):
    def __init__(self, vision_encoder, llm, projection_dim):
        super().__init__()
        self.vision_encoder = vision_encoder  # CLIP ViT
        self.projector = nn.Linear(vision_encoder.hidden_dim, llm.hidden_dim)
        self.llm = llm

    def forward(self, images, text_tokens):
        # 视觉特征 → 投影到LLM空间
        vis_features = self.vision_encoder(images)  # (B, N_vis, D_vis)
        vis_tokens = self.projector(vis_features)    # (B, N_vis, D_llm)

        # 拼接视觉token和文本token
        text_embeds = self.llm.embed_tokens(text_tokens)
        inputs = torch.cat([vis_tokens, text_embeds], dim=1)
        return self.llm(inputs_embeds=inputs)

⚡ 六、模型部署与优化

Q17:模型量化(Quantization)的原理和方法?

量化类型:

类型 时机 精度 适用场景
PTQ(训练后量化) 训练后 略有损失 快速部署
QAT(量化感知训练) 训练时模拟 几乎无损 精度敏感
动态量化 推理时 中等 权重量化为主

INT8量化公式:

\[ x_{int8} = \text{round}\left(\frac{x_{float}}{scale}\right) + \text{zero\_point} \]
\[ scale = \frac{x_{max} - x_{min}}{2^8 - 1} \]
Python
import torch.quantization as quant

# 训练后静态量化 (PTQ)
model.eval()  # eval()评估模式
model.qconfig = quant.get_default_qconfig('x86')
model_prepared = quant.prepare(model)

# 用校准数据集收集统计量
with torch.no_grad():  # 禁用梯度计算,节省内存
    for data in calibration_loader:
        model_prepared(data)

model_quantized = quant.convert(model_prepared)
# 模型大小减少约4倍,推理速度提升2-4倍

面试官追问:量化对不同层的影响? - 第一层和最后一层对量化最敏感,通常保持FP16 - 深层特征量化鲁棒性更好


Q18:ONNX导出和TensorRT部署流程?

Python
import torch
import onnxruntime as ort

# 1. PyTorch → ONNX
dummy_input = torch.randn(1, 3, 224, 224)
torch.onnx.export(
    model, dummy_input, "model.onnx",
    input_names=["input"],
    output_names=["output"],
    dynamic_axes={"input": {0: "batch"}, "output": {0: "batch"}},
    opset_version=17
)

# 2. ONNX Runtime 推理
session = ort.InferenceSession("model.onnx", providers=['CUDAExecutionProvider'])
result = session.run(None, {"input": input_numpy})

# 3. TensorRT 优化(命令行)
# trtexec --onnx=model.onnx --saveEngine=model.trt --fp16 --workspace=4096

部署性能对比(ResNet50, batch=1, V100):

框架 延迟 吞吐量
PyTorch FP32 8.2ms 122 fps
ONNX Runtime 4.1ms 243 fps
TensorRT FP16 1.5ms 667 fps
TensorRT INT8 0.9ms 1111 fps

Q19:知识蒸馏(Knowledge Distillation)原理?

核心思想: 用大模型(Teacher)的soft label指导小模型(Student)训练。

\[ \mathcal{L} = \alpha \cdot \mathcal{L}_{CE}(y, p_s) + (1 - \alpha) \cdot T^2 \cdot KL(p_t^T \| p_s^T) \]

其中 \(p^T = \text{softmax}(z / T)\)\(T\) 为温度系数。

Python
def distillation_loss(student_logits, teacher_logits, labels, T=4.0, alpha=0.5):
    """知识蒸馏损失"""
    # Hard label loss
    hard_loss = F.cross_entropy(student_logits, labels)

    # Soft label loss (KL散度)
    soft_student = F.log_softmax(student_logits / T, dim=-1)
    soft_teacher = F.softmax(teacher_logits / T, dim=-1)
    soft_loss = F.kl_div(soft_student, soft_teacher, reduction='batchmean') * (T ** 2)

    return alpha * hard_loss + (1 - alpha) * soft_loss

🧩 七、数据增强与训练技巧

Q20:常用数据增强方法及其原理?

几何变换类: - 随机翻转、旋转、裁剪、缩放 - 仿射变换、透视变换

像素变换类: - 颜色抖动(Color Jitter) - 随机擦除(Random Erasing) - Cutout、CutMix、MixUp

高级增强:

Python
import torchvision.transforms as T

# MixUp
def mixup(x, y, alpha=0.2):
    lam = np.random.beta(alpha, alpha)
    idx = torch.randperm(x.size(0))
    mixed_x = lam * x + (1 - lam) * x[idx]
    y_a, y_b = y, y[idx]
    return mixed_x, y_a, y_b, lam

# CutMix
def cutmix(x, y, alpha=1.0):
    lam = np.random.beta(alpha, alpha)
    B, _, H, W = x.shape
    cut_h = int(H * np.sqrt(1 - lam))
    cut_w = int(W * np.sqrt(1 - lam))
    cx, cy = np.random.randint(W), np.random.randint(H)
    x1 = np.clip(cx - cut_w // 2, 0, W)
    y1 = np.clip(cy - cut_h // 2, 0, H)
    x2 = np.clip(cx + cut_w // 2, 0, W)
    y2 = np.clip(cy + cut_h // 2, 0, H)

    idx = torch.randperm(B)
    x[:, :, y1:y2, x1:x2] = x[idx, :, y1:y2, x1:x2]
    lam = 1 - (y2-y1)*(x2-x1) / (H*W)
    return x, y, y[idx], lam

面试官追问:MixUp和CutMix哪个效果好? - CutMix通常更好,因为保留了局部空间信息,且对遮挡有鲁棒性


Q21:混合精度训练(AMP)原理?

Python
from torch.amp import autocast, GradScaler

scaler = GradScaler()

for data, target in dataloader:
    optimizer.zero_grad()  # 清零梯度

    with autocast('cuda'):  # FP16前向传播
        output = model(data)
        loss = criterion(output, target)

    scaler.scale(loss).backward()   # 缩放梯度防止下溢
    scaler.step(optimizer)
    scaler.update()

关键点: - 前向用FP16(减少显存+加速计算),反向梯度FP32(保持精度) - Loss Scaling防止FP16梯度下溢 - 显存节省约50%,速度提升约2倍


🔬 八、经典问题速答

Q22:为什么CNN鲁棒性不如Transformer?

  • CNN归纳偏置(局部性+平移不变性)在小数据上有利,但限制了全局建模
  • Transformer通过全局注意力学习更robust的特征
  • 但需要更多数据/预训练

Q23:过拟合和欠拟合的判别与解决?

问题 表现 解决方案
过拟合 训练acc高,验证acc低 正则化/Dropout/数据增强/Early Stop
欠拟合 训练acc低 增加模型容量/减少正则化/更多训练

Q24:目标检测中正负样本不平衡怎么办?

  • Focal Loss\(FL = -\alpha_t (1-p_t)^\gamma \log(p_t)\),抑制易分类样本
  • OHEM:在线困难样本挖掘
  • 正负样本比例控制:如1:3

Q25:mAP(mean Average Precision)如何计算?

  1. 每类按置信度排序 → 计算 Precision-Recall 曲线
  2. AP = PR曲线下面积(11点插值或所有点插值)
  3. mAP = 所有类别AP的平均

📝 面试备考清单

  • 卷积输出尺寸 / 感受野计算(手写)
  • ResNet / BatchNorm 原理(深度理解)
  • Anchor-based vs Anchor-free(对比分析)
  • NMS及变体(代码实现)
  • IoU / GIoU / DIoU / CIoU(公式推导)
  • ViT / DETR / SAM(架构和创新点)
  • CLIP / 多模态模型(对比学习+融合)
  • 量化 / 蒸馏 / 部署(工程实践)
  • 数据增强 / 混合精度(训练技巧)
  • mAP / FPS / FLOPs(评估指标)

💡 高频出题公司参考:字节跳动(视觉大模型/多模态)、商汤/旷视(检测分割)、大疆(部署优化)、腾讯(视频理解)