资讯动态

基于YOLO的课堂行为检测实战:从数据标注到部署全流程解析

发布时间:2026/10/1 23:52:09 来源:尧图企业网站定制
简介基于YOLO的课堂行为检测系统完整项目包面向计算机视觉方向毕业设计、课程设计及入门实践者解决课堂场景中学生举手、听讲、阅读、写字等行为自动识别与实时分析问题。资源共27个文件压缩包约26.85MB核心包含Python源码主程序、UI界面、视频与图片测试脚本、YOLOv8训练权重.pt、ONNX模型及相关XML配置另有UI文件、效果展示图、模型训练结果图及两份Markdown说明文档便于理解训练流程与工程结构。内置的可视化界面支持加载视频或图片进行检测适合直接部署调试验证。目前已有72人学习下载。项目还附带了模型训练记录与README可从数据标注、训练调参到模型转换ONNX进行全流程梳理帮助快速上手并二次开发是课堂行为分析方向较为完整的技术参考。1. 基于YOLO的课堂行为检测系统先弄明白这个 zip 能交付什么一节课 40 分钟督导想统计抬头率、玩手机比例、举手次数人工看录像至少要花掉三倍课程时间。标题里的“基于YOLO的课堂行为检测系统.zip”就是为解决这类统计问题打包的方案一份已经标注好的课堂视频数据集、类目配置、训练脚本、推理脚本和部署导出配置通常都在压缩包里。拿到手之后不需要重新发明检测算法核心工作变成三步把数据格式调对、把训练参数调到能收敛、把模型接上教室摄像头。适合做智慧校园、教务督导系统的工程师也适合拿行为检测当毕设课题、想快速跑通全流程的学生。门槛不在算法理解而在数据清理、训练调试和部署这几个环节下面按实际落地顺序写。2. 数据准备是重头戏课堂视频到 YOLO 标注集的三步转换数据决定模型上限。很多人在 zip 里看到 images 和 labels 两个文件夹就急着开训结果不是“No labels found”就是 mAP 虚高得不像话。压缩包里的数据多半来自别人采集的课堂视频标注格式、类别定义、数据集划分方式不一定符合你的训练目标第一步永远是先把数据盘清楚。2.1 行为类别怎么定先想清楚“检测什么”比“怎么检测”更重要第一版类别列表别拉太长。课堂行为检测最常见的类别是举手、玩手机、睡觉、站立、听讲有的项目还会加“趴桌子”“书写”“转头说话”。但注意“低头看书”和“玩手机”在教室全景里都表现为“头低着、手在桌面附近”标注员自己也容易分错这种模糊类别丢给模型只会让收敛变得更难。我一般建议第一版只保留五个高区分度类别attend听讲、hand举手、phone玩手机、sleep睡觉、stand站立。类别名建议用英文小写因为 data.yaml 里直接对应标签文件名。中文名不是不能做但后续生成混淆矩阵、推理脚本里写类别映射时会多一步转换没必要。课堂是典型的“多人小目标”场景一个 1080p 教室画面里可能有 30 到 50 个人单个目标高度经常只有 30 到 60 像素。标注时如果目标小于 20x20 像素我通常会放弃因为 YOLO 下采样到 640 分辨率后这些小框基本变成几个像素的噪声训练了反而拉低 mAP。2.2 标注工具与格式LabelImg 输出 XML 和 YOLO txt 的差别常见做法是用 LabelImg 逐帧标注因为它对新手最友好。LabelImg 默认保存的是 PascalVOC 格式的 XML里面记录 object 的 name 和 bndbox 的 xmin、ymin、xmax、ymax而 YOLO 训练要求一张图一个 txt每行是 class_id、x_center、y_center、width、height并且全部归一化到 0 到 1。很多 zip 里给的是 XML直接扔进 YOLO 训练会报“No labels found”或标签读不出来就是格式没对齐。标注时还有两个注意点。一是遮挡前排同学和后排同学经常交叠边界框只框可见部分不要脑补完整身体否则框中心会偏。二是不要混淆目标的“位置”和“类别”课堂行为检测的类别是行为不是人本身因此一张“举手”标签的框必须框住正在举手的人而不是整排人。2.3 从 VOC XML 转 YOLO txt一个转换脚本解决格式冲突把 XML 转成 YOLO 格式是拿到压缩包后第一件必做的事。下面这个脚本我一直在用处理单张图片import xml.etree.ElementTree as ET import os def convert_xml_to_yolo(xml_path, out_dir, class_map): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_map: continue cls_id class_map[name] box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) # 防止标注越界钳制到图片范围内 xmin max(0, min(xmin, img_w)) xmax max(0, min(xmax, img_w)) ymin max(0, min(ymin, img_h)) ymax max(0, min(ymax, img_h)) if xmax xmin or ymax ymin: continue x_center (xmin xmax) / 2 / img_w y_center (ymin ymax) / 2 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) if lines: out_name os.path.splitext(os.path.basename(xml_path))[0] .txt with open(os.path.join(out_dir, out_name), w) as f: f.write(\n.join(lines)) class_map { attend: 0, hand: 1, phone: 2, sleep: 3, stand: 4 } convert_xml_to_yolo(frame_001.xml, labels, class_map)逻辑说明脚本把 XML 里的绝对像素坐标转成 0-1 之间的中心点坐标和宽高。关键有两个边界处理坐标钳制xmin/xmax 可能被标出图片外和空标注过滤xmax xmin 直接跳过。这两点不做训练时会遇到“All labels are empty”或者 loss 异常。参数说明class_map 的 key 要和 XML 里的 name 完全一致大小写敏感out_dir 最好是 YOLO 要求的 labels 目录结构。单张转换没问题后用 os.walk 批量循环一遍即可。转换完抽查 3 到 5 个 txt用 cv2.rectangle 把框画回图上这是最直接的验证方法。注意转换脚本只解决格式问题不解决标注错误。如果原始 XML 里类别名本身就标乱了转换后错误会被完整带进训练集这类问题后面只能在数据清洗阶段处理。2.4 按视频做数据集划分避免同一课堂的帧串到验证集划分数据集的常见坑是随机打散。课堂视频是连续帧相邻帧画面几乎一样如果随机划分训练集里会出现验证集的“近亲帧”验证分数虚高部署立刻翻车。正确做法是按原始视频 ID 分组划分同一个视频的所有帧只进一个集合。import os import random from collections import defaultdict def split_by_video(image_dir, train_ratio0.8): files os.listdir(image_dir) video_frames defaultdict(list) for f in files: # 文件名约定video_id _ frame_id .jpg例如 A301_0001.jpg video_id f.split(_)[0] video_frames[video_id].append(f) videos list(video_frames.keys()) random.seed(42) random.shuffle(videos) n_train int(len(videos) * train_ratio) train_videos set(videos[:n_train]) train_files, val_files [], [] for v, flist in video_frames.items(): if v in train_videos: train_files.extend(flist) else: val_files.extend(flist) return train_files, val_files逻辑说明这段代码先在视频维度上做划分再把帧分配进对应集合。文件名前缀约定 video_id:frame_id如果你的压缩包命名不是这个格式改成按目录或时间戳分组。随机种子固定到 42让每次实验可以复现。参数说明train_ratio0.8 表示 80% 视频进训练集20% 进验证集。课堂视频通常只有几天采集量视频数可能只有十几个此时 0.8 的划分会让验证集过小。可以降到 0.7或者做 5 折交叉验证看波动。重点不是比例而是同一个视频的帧绝不跨集合。3. 环境搭建与首轮训练从空目录到一条可跑的 train 命令有了数据下一步是让模型跑起来。按我的经验环境搭建环节耗时不比训练短常见问题集中在 Python 版本、CUDA 版本、opencv 和 numpy 版本打架这几件事上。3.1 YOLOv8 还是 YOLOv5课堂行为场景的选型理由如果你拿到的是 .pt 权重或推理脚本先看它用的是 YOLOv5 还是 YOLOv8。两者数据格式一致但命令行参数和部署方式不完全兼容。新项目我一般用 YOLOv8理由有几个官方仓库同时维护训练、验证、导出和推理一条命令全通v8 的 neck 部分用了 C2f 模块在较多小目标的教室场景里表现通常比 v5 的 C3 好。v8 转成 anchor-free 结构后对高密度人群的重叠框抑制也好一些但代价是推理时后处理逻辑变复杂导出到 NCNN 时会多处理一个 DFL 分支。如果压缩包本身是 v5 训练好的没必要非迁到 v8重训练成本不低。课堂行为检测不是把模型换新就万事大吉数据集质量、类别定义和部署场景对结果的贡献更大。v5 社区教程多遇到问题好搜v8 官方文档全适合想要一条命令跑完的人。我的建议是手头有什么用什么能跑通先跑通。3.2 环境配置conda、依赖、预训练权重建议单独建一个虚拟环境避免把系统 Python 搞乱。下面是常用的环境搭建步骤conda create -n classyolo python3.10 -y conda activate classyolo pip install ultralytics pip install opencv-python这样装完如果显卡驱动和 CUDA 可用ultralytics 会自动调用 GPU。验证方式是在 Python 里执行 import torch; print(torch.cuda.is_available())输出 True 才继续。常见翻车点是 pip 默认装上的 opencv-python 和 numpy 版本打架报错在 import cv2 时出现“numpy.core.multiarray failed to import”解决办法是把 numpy 降到 1.26.x 或升级 opencv 到最新版两个方向一般有一个能解决。预训练权重从官方 Release 页面下载 yolov8s.pt不用自己从零训练。下载后放在项目根目录或 weights 目录里训练命令里用 modelyolov8s.pt 指向它。重点课堂数据集很小几百到几千张图用 COCO 预训练权重迁移是必要操作随机初始化权重很难在有限数据里收敛。目录结构也要提前摆好YOLO 训练默认按下面这种方式找数据classroom/ data.yaml images/ train/ val/ labels/ train/ val/data.yaml 里的 path 字段指向 classroom 目录绝对或相对路径train 和 val 字段分别指向 images/train、images/val。很多新人把 images 和 labels 放在同级不同名目录里或者漏建 val 子目录训练命令跑起来后报“No labels found”回头查全是路径问题。3.3 第一轮训练命令每个参数都是什么意思数据集目录结构确认无误后可以跑第一条训练命令。我习惯先小分辨率验证流程再上正式参数yolo detect train \ modelyolov8s.pt \ dataclassroom.yaml \ epochs60 \ imgsz640 \ batch16 \ device0 \ workers8 \ patience20逻辑说明这条命令指定用 COCO 预训练权重 yolov8s.pt 作为起点data 指向课堂数据集的配置文件imgsz640 是输入分辨率batch16 是单卡每批图数patience20 表示验证指标连续 20 轮不提升就早停。60 个 epoch 对几百张图的小数据集通常足够如果 loss 还在降可以继续训练。参数说明imgsz 是课堂场景最该调的一个。640 训练速度快显存占用低但 1080p 教室画面里的后排小目标会损失很多细节1280 能让小目标检测精度明显提升显存和训练时间大约翻倍。如果你是 8G 显存imgsz1280 配 batch16 基本会 OOM先把 batch 降到 8。如果是 V100 这类大显存卡batch32 甚至 64 都可以跑但要注意 BN 统计量在 batch 太大时反而对学习率更敏感默认 lr00.01 通常不用改。跑完第一步后不要急着看 mAP。先确认 run/detect/train 目录下 weights/best.pt 存在再看 results.png 里 train 和 val 的 loss 曲线是否下降。这一步的目的是证明流程通不是追求精度。3.4 训练报错先看哪几个日志第一轮训练最常见的三种失败。一是“CUDA out of memory”看 batch、imgsz 和 workers 三个参数把 batch 降到 8 或 4关闭 pin_memory 试试二是“No labels found in ...”这是 data.yaml 里的 train/val 路径和实际目录对不上检查 images 和 labels 的目录结构与文件名是否严格对应三是 loss 从一开始就不下降大概率是标注格式错误比如把 class_id 写成了 1 开头、坐标没有归一化。打开一个 txt 人工看一眼正常内容应该是 5 到 7 个浮点数数值全部在 0 到 1 之间class_id 除外。训练日志在 run/detect/train 下有几个文件值得优先看results.png 展示所有损失和指标曲线args.yaml 记录本次训练的全部参数方便复现weights/ 下 best.pt 和 last.pt 分别是最优权重和最后权重。模型训练不是配好参数丢进去就完事前 10 个 epoch 的曲线走向基本能代表整轮训练的成败发现异常及时停掉改参数比跑完 60 个 epoch 再回头省时间。提示如果训练中断续跑不要直接改参数先加载 last.pt 恢复。改 lr0、batch 这类参数会让优化器状态错乱反而把原本正常的训练带崩。4. 调参与评估读懂 loss 曲线、混淆矩阵和漏检来源模型能跑通只是开始真正花时间的是调参迭代。课堂行为检测的调参重点不是把 mAP 刷到小数点后三位而是让模型在教室监控的宽动态范围里不误检、不漏检。4.1 损失函数与三个关键超参学习率、batch、输入分辨率YOLOv8 的损失由三部分组成box_loss回归损失包含 CIoU 和 DFL 分支、cls_loss分类损失BCE、dfl_loss分布聚焦损失。在训练命令里它们分别由 box、cls、dfl 三个参数控制权重。默认权重box7.5, cls0.5, dfl1.5对应的是 COCO 通用目标。课堂场景的类别是“行为”框的定位精度要求没有那么极端但类别区分难度高——低头和玩手机在画面上很像。我会适当提高 cls 权重比如yolo detect train \ modelyolov8s.pt \ dataclassroom.yaml \ epochs80 \ imgsz1280 \ batch8 \ device0 \ box7.5 cls1.2 dfl1.5为什么提高 clscls_loss 权重加大会让模型更重视“框里到底是什么行为”减少同类混淆。代价是如果权重调太高比如 cls 超过 3模型可能为了分类正确而牺牲框的位置精度出现“框歪但类别对”的情况。课堂督导统计不要求像素级框准所以这个方向可以接受。剩下的三个超参里学习率 lr0 影响收敛稳定性batch 影响 BN 统计量imgsz 影响小目标细节。调参次序别搞反先固定 imgsz 为部署分辨率再调 batch 到显存能承受最后微调 lr0。如果换教室后误检率变高优先看数据域而不是损失函数权重。4.2 训练曲线怎么读val loss、mAP、recall 的联动关系训练完成后results.png 里有一摞曲线。我主要看四条train/box_loss、val/box_loss、metrics/mAP50、metrics/mAP50-95。train loss 持续下降、val loss 掉头上升是过拟合此时应加数据增强或增加训练集两条曲线同步下降但 mAP50 不涨通常是类别不平衡mAP50 涨但 mAP50-95 很低在课堂场景很常见因为目标小、框和 GT 的 IoU 很难达到 0.75 以上别急着认为模型不行。课堂场景里我更关注 recall 而不是 precision。教室督导系统漏报比误报更严重——漏掉一个举手的同学统计结果会直接出错。所以训练结束后先看 val 集的 recall。如果召回不够优先做三件事提高 imgsz、降低 confidence 阈值、补充对应类别的训练数据。precision 低可以通过提高阈值和加负样本解决但这段路比提 recall 长得多。4.3 混淆矩阵的正确打开方式为什么每列加起来不是 1很多人在训练完会打开 confusion_matrix.png发现矩阵里每列加起来不是 100%或者行和列对不上以为运算出错。实际上 YOLOv8 的混淆矩阵默认是列归一化的每一列代表一个真实类别ground truth列里的最大值代表该类别被预测成了什么整列相加是 100%但每一行的数值来自不同列行和不等于 1 是正常的。网上经常说的“混淆矩阵总合不唯一”就是没搞清归一化方向。读矩阵的正确顺序是先看对角线对角线代表正确分类。某个类的对角线比例低看它对应的那一列找出它被误分到了哪个类。课堂场景最常见的现象是 phone 列的对角线偏低大量 phone 被预测成了 attend原因是低头玩手机和低头看书太像光靠单帧图像本来就不容易区分。这个问题的解法不是改损失函数而是改类别定义——要么把“低头”合并成一个行为要么引入连续帧判断玩手机时手部有动作变化持续低头看书时相对静止。4.4 用脚本检查训练验证是否泄漏按视频分组重训第一次训练 mAP50 到 0.9 以上先别高兴检查一下 train 和 val 集合有没有同源视频帧。命令很简单import os train_dir datasets/classroom/images/train val_dir datasets/classroom/images/val def get_video_ids(path): return {f.split(_)[0] for f in os.listdir(path)} train_ids get_video_ids(train_dir) val_ids get_video_ids(val_dir) leak train_ids val_ids print(leaked videos:, leak)逻辑说明文件名按第 2 章约定的 video_id_frame_id 方式命名时取下划线前缀就能判断视频归属。交集非空说明泄漏确实存在。课堂数据集最容易犯这个错因为采集是一段段视频切帧后全部混在一起随机划分看似公平实际训练集里塞满了验证集的“连续剧”。解决方法是按视频分组重新划分回到 2.4 的脚本重跑一遍再来训练。参数说明如果文件名没有下划线分隔改成按子目录划分。另一种泄漏途径是同一节课的不同摄像头同时进了 train 和 val即使文件名前缀不同画面内容仍然高度相似。遇到这种情况公共前缀或时间戳前缀同样需要检查。5. 避坑记录课堂行为训练常见的 5 个翻车现场下面几条都是从实际训练里踩出来的问题按影响程度排序。5.1 BN 崩溃loss 突然飙到 NaN训练中断现象训练跑得正常到了某个 epoch 总 loss 突然变成 nan或者控制台出现 cuDNN 错误训练中断再续训还是在同一位置崩。原因BNBatch Normalization统计量被破坏。常见诱因有三个batch 太小比如 4 或 2导致均值和方差估计震荡学习率过大权重一步跨出正常范围warmup 预热被关掉。某些压缩包教程为了省时间把 warmup_epochs0课堂这种小数据集非常容易触发 BN 崩溃。解决先保证 batch 不小于 16显存不够用梯度累积代替把 lr0 从 0.01 降到 0.005warmup_epochs 保持默认 3.0。改完重训前 10 个 epoch 盯 loss 曲线。这不是玄学BN 对 batch 的敏感度是数学上可以解释的batch 越小方差越大越容易在训练中期被一个离群样本击穿。5.2 验证集 mAP 虚高但现场检测乱标现象训练时验证集 mAP50 高达 0.9 以上一接上教室摄像头背景、椅子、黑板全被框成人误检率高得没法用。原因大概率是数据泄漏不是模型能力问题。连续帧同源导致验证集失真另一个可能是验证集只有几百张图类别样本太少mAP 统计意义有限。解决先跑 4.4 的泄漏检查脚本确认 train 和 val 没有同视频帧。然后人工看预测结果如果模型把背景框成人可能是训练集里“人”的上下文高度重复——所有训练视频都来自同一教室的同一视角模型学的是场景而不是人。补充 2 到 3 个不同角度的教室视频或者加入空教室背景图让模型学会“没有人时不输出框”。5.3 类别极度不平衡玩手机样本是举手样本的 20 倍现象训练结束后 mAP50 尚可但 hand 类在验证集上一轮全漏。盲目提 confidence 阈值只会让 hand 类彻底消失。原因课堂真实分布决定的。一节 40 分钟的课玩手机的人可能占三分之一举手的人只有寥寥几个。训练时 cls_loss 被大样本类主导小样本类学不出来。解决先跑一段统计脚本看各类框数import os from collections import Counter label_dir datasets/classroom/labels/train counts Counter() for f in os.listdir(label_dir): if not f.endswith(.txt): continue with open(os.path.join(label_dir, f)) as fp: for line in fp: cls_id line.split()[0] counts[cls_id] 1 print(counts)逻辑说明labels 目录下每行第一个数就是类别 ID统计结果用来确认不平衡程度。差异超过 10 倍就存在这个问题。解法有两个方向一是对少数类做帧级过采样把含 hand 的图片复制多份二是调整 cls 损失权重。Ultralytics 命令行里没有直接的 class_weight 参数可以通过给 hand 类额外增加标注版本来实现或者把 hand 与 stand 合并成“主动行为”类。我实际用过“合并类别”的做法教学督导更关心互动行为总量合并后精度明显比硬分两个类高。5.4 换一个教室就误检光照和白墙导致的迁移掉点现象在采集教室的验证集上效果很好拿到另一个教室的摄像头直接部署误检率升高甚至把窗外行人当成课堂学生。原因数据域漂移。原训练集的背景、光照、摄像头角度固定模型把教室背景特征当作目标的一部分。课堂行为检测特别容易踩这个坑因为训练数据往往来自同一间教室的同一个摄像头。解决训练集合并多个教室、多个时段的视频开启 YOLO 的 HSV 增强让模型对光照变化有鲁棒性。在 ultralytics 训练参数里 hsv_h、hsv_s、hsv_v 有默认值实际可以稍微调大 hsv_v 的范围模拟不同光照。另一个更有效的做法是推理时做简单的白平衡预处理。教室摄像头经常自动白平衡漂移画面偏蓝偏黄都会触发误检。有人问我为什么同一天下午和上午效果不一样多半就是光变了。5.5 边缘部署后误检率升高RK3588 和 NCNN 的精度损失现象训练和本地推理都正常模型导出成 INT8 格式部署到 RK3588 或 NCNN 推理框架后误检率明显上升小目标漏检尤其严重。原因INT8 量化把小目标的特征量化噪声放大课堂后排学生高度只有几十像素量化后特征图信息损失严重。另一个原因是很多边缘推理框架对 YOLOv8 的 DFL 分支支持不完整后处理简化后框位置偏移。解决优先使用 FP16 部署精度损失远小于 INT8RK3588 的 NPU 对 FP16 支持也可以一定需要 INT8 时用真实课堂数据的子集作为量化校准集不要用通用目标数据校准。如果迁移到 NCNN先用 netron 查看导出的 ONNX 算子确认 DFL 相关算子没被异常替换常见做法是把导出时的 opset 版本固定到 12配合 simplify 工具减小量化误差。整条链路里误检率升高先查量化环节模型本身的问题反而少。6. 部署与进阶把检测框转成课堂行为数据的落地技巧模型在验证集上跑通后还差最后一步把它接进真实视频流输出督导能看懂的统计指标。6.1 导出轻量化模型部署前先导出常见格式是 ONNX 或针对边缘设备的 RKNN。一条导出命令yolo export modelbest.pt formatonnx imgsz640 halfTruehalfTrue 时权重转 FP16体积和速度都优化。导出后在本地用 onnxruntime 跑同一张测试图和 PyTorch 结果对比确认框一致再上设备。6.2 摄像头推理循环下面是一个最小可用的推理循环按帧抽稀避免每帧都跑模型import cv2 from ultralytics import YOLO model YOLO(best.pt) cap cv2.VideoCapture(classroom.mp4) skip 10 # 每 10 帧检测一次 frame_idx 0 logs [] while True: ok, frame cap.read() if not ok: break frame_idx 1 if frame_idx % skip ! 0: continue results model(frame, conf0.35, iou0.5, imgsz640, verboseFalse) for r in results: for cls_id, conf, box in zip(r.boxes.cls, r.boxes.conf, r.boxes.xyxy): logs.append((frame_idx, int(cls_id), float(conf), box.tolist()))逻辑说明skip 抽帧让算力压力降一个量级行为是持续性的抽帧不会影响统计结论。conf0.35 比默认 0.25 高课堂误检会少一些如果漏检明显降回 0.25。iou0.5 控制同一人重复框的合并强度教室人多建议不要低于 0.45。6.3 从框到行为指标统计逻辑检测结果要转成督导关心的指标。先统计每帧出现的总人数再把行为类别占比算出来。常见指标是举手次数、低头率、玩手机比例。持续低头超过 N 帧才记为睡觉或走神单帧偶发低头不算。窗口长度一般取 30 帧也就是大约 1 秒。如果还要支持“某学生整节课的行为轨迹”就得加跟踪用 ByteTrack 这类轻量跟踪器给每个人分配 ID再把同 ID 的检测结果串联。6.4 往多模态走单帧 YOLO 的上限是“看见了什么”连续行为语义要靠时序模型补。再往后做可以在跟踪框序列上接一个轻量的时序分类或者引入多模态信息例如语音和屏幕内容。见过不少项目在这个阶段转向 yolo 和 transformer 结合把检测结果做 token 序列建模。如果你的目标是做课堂督导报告这套扩展路径是清晰的。我从第一次做这个方向到现在最贵的教训是不要迷信压缩包自带的数据集划分和默认参数——拿到手先查泄漏、先看类别分布再动训练否则后面所有调参都在给一个脏基线打工。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑