恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

知识蒸馏实战:本科毕设人脸关键点小模型CPU实时方案

  • 首页
  • 资讯中心
  • /
  • 知识蒸馏实战:本科毕设人脸关键点小模型CPU实时方案

相关资讯

Python数据分析实战:300行代码分析数据分析师岗位要求与薪资 2026/10/1 3:17:32
企业AI转型四步法:从场景选择到规模化落地的避坑指南 2026/10/1 3:17:32
深度可分离UNet:轻量级医学图像分割实战与优化 2026/10/1 3:17:32

最新资讯

Docker Swarm负载均衡与自动扩缩容实战:原理、实践与踩坑
从零手搓AI工程化流程:模型部署、性能优化与监控实战
从零搭建AI工程能力:避开“会调包”陷阱的实战指南
AI Engineering from Scratch:从零构建高可靠AI系统
小绿叶蝉目标检测数据集:从数据体检到YOLOv8训练与切片推理
Docker Compose V2企业级部署优化:微服务编排与生产实践

今日推荐

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

本周热门

从像素到笔画:srt-whiteboard-animation骨架笔迹追踪实现(Zhang-Suen细化+8邻接追踪)
网站建设的英语怎么说?别只背单词,看完这套安全完整流程才敢上线
新手入门看这篇:建设网站加盟避坑指南与SEO实操

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

知识蒸馏实战:本科毕设人脸关键点小模型CPU实时方案

发布时间:2026/10/1 3:22:33
知识蒸馏实战:本科毕设人脸关键点小模型CPU实时方案 简介本资源为本科毕业设计项目源码主题是结合知识蒸馏训练人脸关键点检测的极小模型面向计算机、人工智能、通信工程、自动化等专业的在校学生与教师也适合作为课程设计、作业或项目立项演示的参考。项目代码经过完整测试运行成功后才上传答辩评审平均分达到96分适合希望学习模型压缩与轻量化部署的读者进阶使用。压缩包共约2000个文件包含997个png图像、987个pts关键点标注、11个py源码脚本以及csv、json配置与md说明文档整体约408.9MB覆盖数据集、标注、训练与配置等环节。目前已有76人学习下载。读者可从中获取知识蒸馏训练极小模型的完整实现思路、人脸关键点检测的数据组织方式与代码结构并在此基础上修改扩展用于毕设、课设或功能演示。1. 本科毕设选知识蒸馏做人脸关键点为什么小模型也能跑出可用的点人脸关键点检测这个方向本科毕设最容易翻车的地方不是算法本身而是模型大小和部署环境对不上。你在服务器上拿 ResNet 训一个 68 点检测器精度确实好看但毕设答辩现场老师让你在笔记本上跑个 demo风扇狂转、帧率掉到个位数场面就很尴尬。知识蒸馏恰好是解决这个矛盾的成熟路径用一个大的教师模型Teacher在训练阶段提供软标签让一个极小的学生模型Student在推理阶段独立完成检测参数量可以压到几十 KB 级别CPU 上也能跑到实时。这篇笔记面向的是正在做本科毕设、需要一套能跑通、能写进论文、能在答辩现场演示的人脸关键点检测方案的同学。核心思路是教师模型用现成的预训练网络学生模型自己搭一个轻量结构通过蒸馏损失把教师的输出分布迁移过来。整套流程用 Python 实现依赖 PyTorch 和 OpenCV不需要 GPU 也能完成训练和推理。下面从原理、数据、模型、训练、避坑到进阶一步步拆开讲。2. 知识蒸馏做人脸关键点的原理与选型教师怎么选、学生怎么搭2.1 知识蒸馏在人脸关键点任务上的适配逻辑知识蒸馏最早用在分类任务上教师输出的是类别概率分布学生去拟合这个分布。人脸关键点检测是回归任务输出的是坐标值直接套分类蒸馏的 KL 散度会出问题。常见做法有两种一种是把坐标回归转成热力图Heatmap预测每个关键点生成一张高斯热力图教师和学生的热力图逐像素做蒸馏另一种是直接对坐标做 L2 蒸馏但教师和学生输出维度一致时效果有限。我一般推荐热力图方案原因是热力图保留了空间不确定性信息。教师模型对某个关键点的预测如果不太确定热力图上的高斯分布会偏平这个“软信息”比单纯的坐标值更有迁移价值。学生模型学到的不只是“点在哪”还有“教师有多确信”。这对极小模型尤其重要因为小模型容量有限硬标签容易过拟合软标签相当于一种正则化。具体到损失函数总损失由三部分组成学生热力图和真实标签的 MSE 损失、学生热力图和教师热力图的蒸馏损失通常用 KL 散度或 MSE、以及可选的坐标回归损失。蒸馏温度 T 控制软标签的平滑程度T 越大分布越平滑一般取 2 到 4 之间。温度太高会让所有关键点的热力图趋于均匀学生学不到区分性温度太低则退化成硬标签蒸馏失去意义。2.2 教师模型和学生模型的选型参数教师模型不需要自己从头训直接用现成的预训练人脸关键点网络即可。常见选择是 HRNet-W18 或者 ResNet-50 加反卷积头输入 256x256输出 68 通道热力图。这两个在公开数据集上都有不错的预训练权重拿来当教师省时省力。如果你手头没有预训练权重也可以用自己训的一个稍大的模型当教师精度不用追求 SOTA比学生高就行。学生模型是毕设的核心产出需要自己设计。目标是参数量控制在 50KB 到 200KB 之间CPU 单帧推理时间在 20ms 以内。我一般用深度可分离卷积堆叠结构参考 MobileNetV2 的倒残差块但通道数砍到 1/4。输入分辨率可以降到 128x128热力图输出 32x32这样计算量大幅下降。下面是一个学生模型的 PyTorch 定义import torch import torch.nn as nn class DepthwiseSeparableConv(nn.Module): def __init__(self, in_ch, out_ch, stride1): super().__init__() # 深度卷积每个通道独立卷积参数量极小 self.dw nn.Conv2d(in_ch, in_ch, 3, stride, 1, groupsin_ch, biasFalse) self.bn1 nn.BatchNorm2d(in_ch) # 逐点卷积1x1 卷积做通道融合 self.pw nn.Conv2d(in_ch, out_ch, 1, 1, 0, biasFalse) self.bn2 nn.BatchNorm2d(out_ch) self.relu nn.ReLU6(inplaceTrue) def forward(self, x): x self.relu(self.bn1(self.dw(x))) x self.relu(self.bn2(self.pw(x))) return x class TinyLandmarkNet(nn.Module): def __init__(self, num_points68): super().__init__() # 输入 128x128x3逐步下采样到 32x32 self.stem nn.Sequential( nn.Conv2d(3, 16, 3, 2, 1, biasFalse), nn.BatchNorm2d(16), nn.ReLU6(inplaceTrue) ) # 64x64 self.block1 DepthwiseSeparableConv(16, 32, stride2) # 32x32 self.block2 DepthwiseSeparableConv(32, 32, stride1) self.block3 DepthwiseSeparableConv(32, 64, stride2) # 16x16 self.block4 DepthwiseSeparableConv(64, 64, stride1) # 上采样回 32x32 输出热力图 self.up nn.Upsample(scale_factor2, modebilinear, align_cornersFalse) self.head nn.Conv2d(64, num_points, 1, 1, 0) def forward(self, x): x self.stem(x) x self.block1(x) x self.block2(x) x self.block3(x) x self.block4(x) x self.up(x) # 32x32 heatmap self.head(x) # [B, 68, 32, 32] return heatmap这个学生模型参数量大约 80KB输入 128x128 时 CPU 单帧推理在 15ms 左右i5 八代实测。关键参数说明num_points根据你的数据集定68 点是 300W-LP 和 AFLW 的常见配置98 点是 WFLW 的配置stride2的块负责下采样stride1的块保持分辨率做特征提取最后用双线性上采样回 32x32 是为了和教师热力图尺寸对齐方便计算蒸馏损失。教师模型这边如果你用 HRNet-W18输入 256x256输出 64x64 热力图需要先下采样到 32x32 再和学生做蒸馏或者把学生上采样到 64x64。我一般统一到 32x32因为学生输出小上采样教师比下采样学生更省计算。教师模型在训练时冻结参数只做前向传播不参与梯度更新。2.3 数据准备和热力图生成的具体步骤人脸关键点数据集常用 300W、AFLW、WFLW。300W 有 68 点标注覆盖姿态和表情变化适合毕设。数据准备分三步人脸检测裁剪、关键点归一化、热力图生成。第一步用 OpenCV 的 Haar 级联或 DNN 人脸检测器把每张图的人脸框出来裁剪并缩放到 128x128。注意留 20% 的边距避免关键点被裁掉。第二步把关键点坐标归一化到 [0,1]再映射到 32x32 热力图坐标系。第三步对每个关键点生成高斯热力图高斯核大小一般取 3 到 5sigma 取 1.5 到 2.0。下面是生成热力图的代码import numpy as np import cv2 def generate_heatmap(keypoints, heatmap_size32, sigma2.0): keypoints: [68, 2] 归一化坐标 (x, y) 范围 [0, 1] heatmap_size: 输出热力图边长 返回: [68, heatmap_size, heatmap_size] num_points keypoints.shape[0] heatmaps np.zeros((num_points, heatmap_size, heatmap_size), dtypenp.float32) # 生成高斯核的坐标网格 ax np.arange(heatmap_size, dtypenp.float32) xx, yy np.meshgrid(ax, ax) for i in range(num_points): # 把归一化坐标映射到热力图网格 cx keypoints[i, 0] * (heatmap_size - 1) cy keypoints[i, 1] * (heatmap_size - 1) # 高斯函数距离中心越近值越接近 1 gauss np.exp(-((xx - cx) ** 2 (yy - cy) ** 2) / (2 * sigma ** 2)) heatmaps[i] gauss return heatmaps参数说明sigma控制高斯分布的宽度值越大热力图越平滑教师软标签的信息越丰富但定位精度会下降。我一般训练时用 sigma2.0评估时用 sigma1.0 做峰值提取。heatmap_size要和模型输出一致学生是 32教师如果是 64 就先生成 64 再下采样。注意关键点坐标归一化时要按人脸框的宽高分别归一化不要用整张图的尺寸否则不同尺度的人脸热力图分布会不一致。数据增强方面随机旋转 ±30 度、随机缩放 0.8 到 1.2、随机水平翻转。水平翻转时关键点索引要对应交换68 点的左右对称索引是固定的比如 0-16 是下巴轮廓17-21 是右眉22-26 是左眉翻转时 17-21 和 22-26 互换以此类推。这个索引映射表建议提前写好避免训练时现算。3. 蒸馏训练全流程从教师前向到学生反向的代码实现3.1 训练循环的损失函数和温度参数设置训练循环的核心是同时计算学生损失和蒸馏损失。学生损失用 MSE 衡量学生热力图和真实热力图的差异蒸馏损失用 KL 散度衡量学生热力图和教师热力图的分布差异。KL 散度计算前要对热力图做 softmax 归一化温度 T 作用在 softmax 里。总损失公式是L alpha * MSE(student, gt) (1 - alpha) * T^2 * KL(softmax(student/T), softmax(teacher/T))alpha 一般取 0.3 到 0.5表示学生损失占主导蒸馏损失做辅助。T 取 3 左右。T^2 是为了补偿温度对梯度尺度的缩放。下面是训练循环的关键代码import torch import torch.nn as nn import torch.nn.functional as F def train_one_epoch(student, teacher, dataloader, optimizer, device, T3.0, alpha0.4): student.train() teacher.eval() # 教师冻结只做前向 total_loss 0.0 for imgs, gt_heatmaps in dataloader: imgs imgs.to(device) gt_heatmaps gt_heatmaps.to(device) # 教师前向不计算梯度 with torch.no_grad(): teacher_heatmaps teacher(imgs) # 如果教师输出尺寸和学生不一致下采样对齐 if teacher_heatmaps.shape[-1] ! gt_heatmaps.shape[-1]: teacher_heatmaps F.interpolate( teacher_heatmaps, sizegt_heatmaps.shape[-2:], modebilinear, align_cornersFalse ) # 学生前向 student_heatmaps student(imgs) # 学生硬损失和真实热力图做 MSE loss_mse F.mse_loss(student_heatmaps, gt_heatmaps) # 蒸馏损失KL 散度温度缩放 # 对空间维度做 softmax把热力图转成概率分布 student_log_softmax F.log_softmax(student_heatmaps.view(student_heatmaps.size(0), 68, -1) / T, dim-1) teacher_softmax F.softmax(teacher_heatmaps.view(teacher_heatmaps.size(0), 68, -1) / T, dim-1) loss_kd F.kl_div(student_log_softmax, teacher_softmax, reductionbatchmean) * (T * T) # 总损失 loss alpha * loss_mse (1 - alpha) * loss_kd optimizer.zero_grad() loss.backward() optimizer.step() total_loss loss.item() return total_loss / len(dataloader)逻辑说明教师前向放在torch.no_grad()里避免计算图和显存占用。热力图 softmax 是在空间维度32x321024上做的不是通道维度这样每个关键点的热力图被归一化成概率分布KL 散度衡量的是两个分布的差异。reductionbatchmean表示对 batch 内所有样本求平均。温度 T 同时作用在学生的 log_softmax 和教师的 softmax 上保证分布尺度一致。参数调整建议如果训练初期 loss 震荡大把 alpha 调到 0.5先让学生学硬标签稳定后再加蒸馏。如果学生欠拟合检查 T 是不是太大T3 时软标签已经比较平滑T5 以上可能过度平滑。学习率用 1e-3 配 Adam训练 100 到 150 个 epoch每 30 个 epoch 降一半。Batch size 根据显存定CPU 训练用 16 或 32。3.2 教师模型的加载和输出对齐教师模型如果直接用 HRNet 或 ResNet 预训练权重需要确认输出热力图的关键点顺序和你的数据集一致。300W 的 68 点顺序是0-16 下巴17-21 右眉22-26 左眉27-35 鼻梁和鼻头36-41 右眼42-47 左眼48-67 嘴巴。如果教师是在其他数据集上训的顺序可能不同需要写一个映射表重新排列通道。加载教师模型的代码示例import torch def load_teacher(ckpt_path, num_points68, devicecpu): # 这里以 HRNet-W18 为例实际结构根据你的权重文件调整 # 如果权重是 state_dict直接 load_state_dict teacher build_hrnet_w18(num_pointsnum_points) # 需要自己实现或从开源库导入 state_dict torch.load(ckpt_path, map_locationdevice) # 处理可能的 key 前缀差异 if state_dict in state_dict: state_dict state_dict[state_dict] teacher.load_state_dict(state_dict, strictFalse) teacher.to(device) teacher.eval() return teacher注意strictFalse允许部分层不匹配比如分类头被替换成热力图头。如果教师输出通道数不是 68需要在加载后替换最后一层卷积再在少量数据上微调几个 epoch让教师适应你的关键点定义。这一步容易被忽略导致蒸馏时教师输出全是噪声学生学不到东西。3.3 学生模型的推理和关键点提取训练完成后学生模型输出的是 32x32 的热力图需要提取峰值坐标再映射回原图。提取方法有两种argmax 直接取最大值位置或者用 soft-argmax 做可微分的加权平均。推理时用 argmax 就够了soft-argmax 主要在训练时做端到端坐标回归用。import torch import numpy as np def predict_keypoints(student, img_tensor, original_size, devicecpu): img_tensor: [1, 3, 128, 128] 预处理后的人脸图 original_size: (w, h) 原图尺寸 返回: [68, 2] 原图坐标系下的关键点 student.eval() with torch.no_grad(): heatmaps student(img_tensor.to(device)) # [1, 68, 32, 32] heatmaps heatmaps.squeeze(0).cpu().numpy() # [68, 32, 32] keypoints [] for i in range(heatmaps.shape[0]): # argmax 取峰值位置 idx np.argmax(heatmaps[i]) y, x np.unravel_index(idx, heatmaps[i].shape) # 映射回原图先归一化到 [0,1]再乘原图尺寸 x_norm x / (heatmaps.shape[2] - 1) y_norm y / (heatmaps.shape[1] - 1) keypoints.append([x_norm * original_size[0], y_norm * original_size[1]]) return np.array(keypoints, dtypenp.float32)参数说明original_size是人脸框裁剪前的原图尺寸如果你是在裁剪后的人脸图上做检测就传裁剪图的尺寸。argmax 的精度受热力图分辨率限制32x32 下每个像素对应原图约 4 个像素的误差如果精度不够可以在峰值附近做二次插值抛物线拟合把坐标细化到亚像素级。这个技巧在毕设答辩时是个加分项实现也简单几行代码的事。4. 避坑与排查蒸馏训练人脸关键点最常见的五个翻车点4.1 教师热力图和学生热力图尺寸不一致导致蒸馏损失爆炸现象训练 loss 一开始就是几千降不下去学生输出全是均匀分布。原因教师输出 64x64学生输出 32x32直接做 KL 散度时维度对不上PyTorch 广播机制把两个张量错误对齐算出来的 loss 没有意义。解决在计算蒸馏损失前用F.interpolate把教师热力图下采样到和学生一样的尺寸或者把学生上采样到教师尺寸。我一般统一到 32x32因为下采样教师比上采样学生省计算而且下采样不会引入额外的插值噪声。4.2 温度参数 T 设得太大导致学生学不到区分性现象学生推理时所有关键点的热力图都差不多平峰值不明显坐标提取误差大。原因T 设成了 10 以上softmax 后的分布过于平滑教师对正确位置和错误位置的置信度差异被抹平了。解决T 从 2 开始试观察学生热力图的峰值信噪比。如果峰值和背景的比值低于 3说明 T 太大。我一般用 T3配合 alpha0.4学生热力图峰值信噪比在 5 左右定位精度和泛化性平衡得比较好。4.3 数据增强时关键点索引翻转错误现象水平翻转增强后学生模型在左右对称的关键点上预测错位比如左眼预测到右眼位置。原因68 点的左右索引不是简单加 1 减 1而是有固定的映射表。比如 36-41 是右眼42-47 是左眼翻转时 36 对应 4537 对应 44以此类推。如果直接按顺序翻转索引全乱。解决提前写好翻转映射数组训练时用数组索引交换。下面是对称索引映射的代码# 68 点水平翻转的索引映射表 FLIP_INDEX [ 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, # 下巴 0-16 26, 25, 24, 23, 22, # 右眉 17-21 翻转到左眉 21, 20, 19, 18, 17, # 左眉 22-26 翻转到右眉 27, 28, 29, 30, # 鼻梁 27-30 不变 35, 34, 33, 32, 31, # 鼻头 31-35 翻转 45, 44, 43, 42, 47, 46, # 右眼 36-41 翻转到左眼 39, 38, 37, 36, 41, 40, # 左眼 42-47 翻转到右眼 54, 53, 52, 51, 50, 49, 48, # 嘴巴外圈 48-54 翻转 59, 58, 57, 56, 55, # 嘴巴内圈 55-59 翻转 64, 63, 62, 61, 60, # 嘴巴内圈 60-64 翻转 67, 66, 65 # 嘴巴内圈 65-67 翻转 ]这个表建议直接复制到你的数据集代码里翻转时keypoints_flipped keypoints[FLIP_INDEX]同时 x 坐标要变成1 - x。4.4 CPU 训练时 BatchNorm 的 running_mean 不更新现象学生模型在 CPU 上训练 loss 正常下降但推理时输出和训练时差异很大精度掉一半。原因PyTorch 的 BatchNorm 在model.train()模式下更新 running_mean 和 running_var但如果 batch size 太小比如 4 以下统计量估计不准推理时用model.eval()会出问题。解决把 batch size 提到 16 以上或者把 BatchNorm 换成 GroupNorm。GroupNorm 不依赖 batch 统计量小 batch 下更稳定。我一般在学生模型里用 GroupNorm教师模型保持 BatchNorm 不动因为教师是冻结的。4.5 蒸馏损失权重过大导致学生过拟合教师噪声现象学生模型在训练集上精度很高但验证集精度比不用蒸馏还低。原因alpha 设得太小比如 0.1蒸馏损失占主导学生把教师的预测误差也学过去了。教师虽然比学生强但不是完美的它的热力图在遮挡和极端姿态下有噪声。解决alpha 调到 0.4 到 0.5让学生损失占主导。另外可以在蒸馏损失里加一个 mask只对教师置信度高的区域做蒸馏置信度低的区域忽略。置信度可以用教师热力图的最大值衡量低于阈值的点不参与蒸馏损失计算。5. 进阶技巧用 soft-argmax 和通道剪枝把学生模型再压一半5.1 soft-argmax 替代 argmax 做端到端坐标回归argmax 不可导所以训练时只能监督热力图不能直接监督坐标。soft-argmax 用加权平均代替取最大值可导能直接把坐标损失加进总损失里。公式是对热力图做 softmax 得到概率分布然后用坐标网格做加权求和。这样学生模型可以同时学热力图和坐标定位精度更高。import torch import torch.nn.functional as F def soft_argmax(heatmaps, temperature10.0): heatmaps: [B, 68, H, W] 返回: [B, 68, 2] 归一化坐标 (x, y) B, N, H, W heatmaps.shape # 对空间维度做 softmaxtemperature 控制锐度 heatmaps_flat heatmaps.view(B, N, -1) prob F.softmax(heatmaps_flat * temperature, dim-1) prob prob.view(B, N, H, W) # 生成坐标网格 device heatmaps.device x_grid torch.arange(W, dtypetorch.float32, devicedevice).view(1, 1, 1, W) y_grid torch.arange(H, dtypetorch.float32, devicedevice).view(1, 1, H, 1) # 加权求和 x_coord (prob * x_grid).sum(dim(2, 3)) / (W - 1) # 归一化到 [0,1] y_coord (prob * y_grid).sum(dim(2, 3)) / (H - 1) coords torch.stack([x_coord, y_coord], dim-1) # [B, 68, 2] return coords参数说明temperature控制 softmax 的锐度值越大分布越尖锐soft-argmax 越接近 argmax。训练时用 10 左右推理时可以用 20 以上逼近 argmax 的效果。把 soft-argmax 输出的坐标和真实坐标做 L1 损失加到总损失里权重取 0.1 到 0.2。这样学生模型在热力图监督之外多了一个坐标监督信号收敛更快最终精度能提升 5% 到 10%。5.2 通道剪枝把学生模型压到 40KB学生模型训完后还可以做通道剪枝进一步压缩。思路是对每个卷积层的通道计算 L1 范数把范数小的通道剪掉再微调几个 epoch 恢复精度。剪枝比例一般 20% 到 30%再高精度掉得厉害。下面是剪枝的代码框架import torch import torch.nn as nn def prune_conv_layers(model, prune_ratio0.2): 对模型里所有 Conv2d 层做 L1 通道剪枝 prune_ratio: 剪掉的通道比例 for name, module in model.named_modules(): if isinstance(module, nn.Conv2d): weight module.weight.data # 计算每个输出通道的 L1 范数 channel_norms weight.abs().sum(dim(1, 2, 3)) num_channels channel_norms.shape[0] num_prune int(num_channels * prune_ratio) if num_prune 0: continue # 找到范数最小的通道索引 _, prune_indices torch.topk(channel_norms, num_prune, largestFalse) # 把这些通道的权重置零实际部署时可以用稀疏矩阵 module.weight.data[prune_indices] 0.0 return model注意这个代码只是把权重置零实际压缩需要把置零的通道真正删掉这涉及到重建网络结构。毕设里如果时间紧置零加微调也能写进论文说明剪枝策略和效果。微调时学习率降到 1e-4训练 20 个 epoch精度基本能恢复到剪枝前的 95% 以上。5.3 验证蒸馏效果的两个硬指标毕设论文里需要量化蒸馏的效果不能只说“精度提升了”。我一般用两个指标一是学生模型单独训练的 NMENormalized Mean Error二是蒸馏后学生模型的 NME。NME 计算方式是所有关键点的欧氏距离除以两眼间距或人脸框对角线长度再取平均。300W 数据集上单独训练的学生 NME 在 8% 左右蒸馏后能降到 6% 到 7%。另一个指标是模型大小和推理时间的对比教师模型 20MB 推理 200ms学生模型 80KB 推理 15ms这个对比表放在论文里很直观。验证时注意测试集要和训练集严格分开300W 的常见划分是 3148 张训练、689 张测试。如果用了数据增强测试集不能做增强。另外推理时间要在同一台机器上测取 100 次前向传播的平均值排除第一次加载的冷启动时间。5.4 我踩过的一个坑教师模型在 CPU 上推理太慢拖垮训练最后说一个血泪经验。我一开始用 ResNet-50 当教师在 CPU 上训练每个 batch 教师前向要 300ms学生前向加反向才 50ms训练一个 epoch 要两个小时根本跑不完。后来换成 HRNet-W18教师前向降到 80ms训练时间缩到 40 分钟一个 epoch。如果 CPU 实在太慢可以先把教师对所有训练数据的热力图预测缓存下来训练学生时直接读缓存不用每次前向教师。这个技巧能再省一半时间代价是占磁盘空间68 点 32x32 热力图每张约 280KB3 万张训练集约 8GB硬盘够的话完全可行。希望帮到你。本文还有配套的精品资源点击获取

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号