简介面向计算机视觉与工业智能化场景的煤和传送带皮带识别数据集采用COCO格式标注可用于训练目标检测模型解决煤矿运输场景中皮带状态与煤流精准识别问题。压缩包共317个文件主体为312张JPEG实景图片另含3个JSON标注文件与2个TXT说明文件总大小约39.53MB标注格式规范可直接适配主流深度学习框架。该数据集已吸引392人学习下载适合从事矿山自动化、输送系统监控的算法工程师及科研人员使用。凭借平均识别率高达99.5%的标注质量可支撑模型训练、验证与测试全流程为皮带异物检测、煤量统计等任务提供可靠数据基础。1. 煤和传送带识别数据集黑对黑场景里COCO标注能做什么煤矿输煤廊道里的监控画面底色是黑黑色橡胶输送带、黑色煤流、被煤粉染黑的托辊和墙壁。这套煤和传送带识别数据集要解决的问题就是在这种黑对黑场景里把皮带和煤各自抠出来给跑偏检测、堵煤预警、煤量估算提供最底层的视觉输入。它用COCO格式标注类别就两个——belt和coal看起来简单实际是工业视觉里典型的低对比度目标识别任务。适合正在做煤矿AI巡检、输送带视觉监测或者想用YOLOv8训练自己的数据集但担心类别只有两个就不值当的人。先说结论99.5%这个数字能不能信取决于评测口径和验证集怎么切后面会一步步拆。2. COCO格式解剖与数据面审查看懂json、看懂99.5%的前提2.1 coco2017同源三段式结构images / annotations / categories拿到这套数据第一步不是急着训练而是把标注文件打开看一遍。COCO格式的标注是一个json文件整体结构和coco2017数据集结构完全一致分三个顶层字段images、annotations、categories。用下面这段代码先摸清家底import json from collections import Counter with open(annotations/instances_train.json, r, encodingutf-8) as f: coco json.load(f) print(coco.keys()) # dict_keys([images, annotations, categories]) print(图片数:, len(coco[images])) print(标注实例数:, len(coco[annotations])) # 类别表coco里类别id一般从1开始不是0 print(coco[categories]) # 统计每个类别的实例数量 cat_ids Counter(a[category_id] for a in coco[annotations]) print(cat_ids) # 看一张图和它对应的标注 img coco[images][0] anns [a for a in coco[annotations] if a[image_id] img[id]] print(json.dumps(img, ensure_asciiFalse, indent2)) print(该图标注数:, len(anns)) print(其中一条标注:, json.dumps(anns[0], ensure_asciiFalse, indent2))这段代码的作用是把标注文件拆开看三个问题一共多少图、两个类别的实例分布是否均衡、单条annotation里到底存了什么。coco格式里images段记录图片id、file_name、width、heightannotations段的核心是image_id、category_id、bbox、segmentation、area、iscrowd。bbox是绝对像素坐标的[x, y, w, h]左上角为原点不是归一化的转换到YOLO格式时一定要除以图宽高很多转换脚本翻车就翻在这里。注意类别id的坑COCO的categories里id往往从1开始coco2017里是1到80而YOLO训练要求类别索引从0开始。如果直接拿coco的category_id去写txt模型训练时类别数会错乱。看数据时顺手检查一下category_id是否连续、是否从0开始能省后面半天排查时间。2.2 为什么要COCO不用VOC非刚性煤堆和segmentation容错有人会问就两个类别直接用VOC格式或者YOLO的txt不就行了绕一圈COCO图什么答案是煤堆这种目标没有矩形边界。煤流从皮带上滑落、堆积、被托辊弹开边缘是破碎且不规则的用矩形框标注要么框住大量背景要么把两块煤标成一个框。COCO的segmentation支持多边形标注标注员可以贴着煤堆实际轮廓画模型学到的边界特征比矩形框干净得多。COCO还提供iscrowd字段用来标记粘连成片、无法逐个分割的目标。煤矿场景里煤流经常连成一片逐块标不现实把一大片煤流标成iscrowd1训练时损失函数会对这些区域做特殊处理避免模型在标注不准的地方反复震荡。VOC格式没有这个机制。另外一层是工具链生态。CVAT、LabelMe、X-AnyLabeling、Roboflow这类标注工具都原生支持导出COCO格式拿到COCO可以无损转成VOC或YOLO的txt反过来从VOC/矩形框转COCO时segmentation信息已经丢了补不回来。所以数据交换的底线格式选COCO最稳妥即使最终训练用的是YOLO中间也建议先用COCO落盘。2.3 平均识别率99.5%先别急着信四个口径先对齐标题里的99.5%在工业视觉里是一个需要拆解的数字。目标检测领域没有统一的识别率定义至少四种口径能算出一个99.5%按帧算只要一帧里检出目标就算对、按像素算分割任务的pixel accuracy、按mAP50算检测框IoU超过0.5即命中、按mAP50:95算IoU从0.5到0.95逐档平均。四个口径难度完全不在一个量级煤矿这种大目标占画面比例高的场景按帧算出来99.5%非常容易煤堆占半个画面随便一个模型都能命中。评测口径含义对99.5%的判断帧级检出率画面里出现皮带/煤就被算作检出最容易虚高大目标场景可达98%以上像素准确率每个像素分类对错黑背景占比大时容易被全预测背景刷高mAP50检测框与真值框IoU0.5即命中有参考价值99%以上要求框大致贴边mAP50:95IoU从0.5到0.95取平均最严格细长目标通常只能到70%-85%拿到一个标着99.5%的数据集或模型我一般先问三个问题验证集怎么切的是不是和训练集同一段视频的相邻帧用的哪种口径置信度阈值设了多少。这三个问题后面会逐个展开。先记住一个判断如果对方回答的是平均识别率而不是mAP或F1那么这个数字大概率是按帧或按像素算的落地时要重新用自己的验证集评估。3. 把COCO数据集变成YOLOv8训练燃料转换脚本、数据划分与训练命令3.1 COCO转YOLO Txt这个脚本我用了三个项目YOLOv8原生训练读的是txt标签格式每行一个目标类别索引、中心点x、中心点y、宽、高全部归一化到0到1。COCO转YOLO的脚本不难但要注意bbox坐标的换算和类别id的映射。下面这段脚本是我在不同输送带项目里反复复用的一套逻辑import os import json def coco_to_yolo(coco_path, img_dir, out_dir, class_names): coco_path: 标注json路径 img_dir: 图片目录脚本只用来拿宽高 out_dir: 输出的txt标签目录文件名与图片名保持一致 class_names: 按训练顺序排列的类别名列表如 [belt, coal] with open(coco_path, r, encodingutf-8) as f: coco json.load(f) # 建立 category_id - 类别索引 的映射 id2name {c[id]: c[name] for c in coco[categories]} name2idx {name: i for i, name in enumerate(class_names)} id2idx {cid: name2idx[id2name[cid]] for cid in id2name} os.makedirs(out_dir, exist_okTrue) for img in coco[images]: txt_path os.path.join(out_dir, os.path.splitext(img[file_name])[0] .txt) lines [] anns [a for a in coco[annotations] if a[image_id] img[id]] for ann in anns: cat_idx id2idx[ann[category_id]] x, y, w, h ann[bbox] # 绝对像素 # COCO的bbox是左上角宽高YOLO要中心点宽高 cx (x w / 2.0) / img[width] cy (y h / 2.0) / img[height] nw w / img[width] nh h / img[height] # 过滤掉被归一化到负值或超过1的异常框 if cx 0 or cy 0 or nw 0 or nh 0: continue lines.append(f{cat_idx} {cx:.6f} {cy:.6f} {nw:.6f} {nh:.6f}) with open(txt_path, w, encodingutf-8) as f: f.write(\n.join(lines)) print(f转换完成: {len(coco[images])} 张图片, 输出到 {out_dir}) # 类别顺序决定yaml里的nc和names务必保持一致 coco_to_yolo(annotations/instances_train.json, images/train, labels/train, [belt, coal])转换后的txt要和图片同名YOLO才会自动配对。脚本里category_id到类别索引的映射单独抽了出来因为COCO的类别id可能从1也可能从任意值开始直接拿id当索引是新手最常见翻车点。归一化后做了范围过滤目的是把标注软件偶尔产生的越界框剔掉这类脏框进损失函数会把边界学歪。3.2 数据划分按工况分层随机划分会让99.5%变废纸这是整个流程里最容易被忽略、对最终可信度影响最大的一步。煤矿输送带监控视频天然是时间序列同一个画面里皮带纹理、煤粉分布、光照条件在相邻几十帧内几乎不变。如果用随机划分把数据集切训练集和验证集那验证集里每张图都能在训练集里找到长得几乎一样的孪生帧mAP高得毫无参考价值换一个新机位立刻原形毕露。正确做法是先给每张图打上工况标签再按工况分层划分。工况至少分成空载、轻载、满载、停机四类每类内部按时间戳排序前80%进训练、后20%进验证import random from collections import defaultdict # samples: [(图片路径, 工况标签, 拍摄时间戳)] samples [ (frame_0001.jpg, empty, 1710000001), (frame_0002.jpg, empty, 1710000002), # ... 实际数据里每张图都要带工况和时间 ] by_cond defaultdict(list) for path, cond, ts in samples: by_cond[cond].append((path, ts)) train, val [], [] for cond, items in by_cond.items(): items.sort(keylambda x: x[1]) # 按时间排天然模拟现场时序 cut int(len(items) * 0.8) train [p for p, _ in items[:cut]] val [p for p, _ in items[cut:]] random.shuffle(train) random.shuffle(val) print(ftrain: {len(train)} val: {len(val)})这段代码的核心是组内先排序再切分保证验证集里出现的煤流形态、皮带表面磨损状态是模型没见过的。划分完成后写一个简单的yaml给YOLOv8用# belt_coal.yaml path: /data/belt_coal # 数据根目录 train: images/train val: images/val nc: 2 names: [belt, coal]3.3 YOLOv8训练命令与必调参数hsv_h关掉、close_mosaic留着用YOLOv8训练自己的数据集命令很简单但煤和皮带这个场景有三个参数必须动用默认值会踩大坑。直接给一个我调过多次的训练配置from ultralytics import YOLO model YOLO(yolov8s.pt) # COCO预训练权重别从零训练 model.train( databelt_coal.yaml, epochs200, imgsz1280, # 皮带是细长目标640下特征被压没了 batch16, # 1280的图显存吃紧不够就降到8或开梯度累积 optimizerSGD, lr00.01, lrf0.01, mosaic1.0, # 开mosaic提高小目标鲁棒性 close_mosaic10, # 最后10个epoch关掉防止黑色块边界学糊 hsv_h0.0, # 色调抖动必须关 hsv_s0.0, # 饱和度抖动必须关 hsv_v0.2, # 亮度可以留一点模拟廊道灯光波动 fliplr0.0, # 左右翻转关掉煤流方向有物理意义 scale0.3, translate0.1, patience30, # 早停耐心值200轮内验证集没提升就停 )参数说明里最要紧的是hsv_h和hsv_s。煤和皮带都是黑灰色色调和饱和度本身没有可分信息打开色调抖动只会把黑色变成紫色、绿色逼模型去学根本不存在的颜色差异反而干扰对纹理和形状的学习。亮度抖动保留0.2模拟井下廊道灯光的明暗变化是有物理依据的。fliplr必须关因为煤流永远是从机尾向机头方向运动镜像之后变成反重力煤流训练集里出现这种物理上不可能的样本推理时会把逆行的检修场景误判成正常运煤。imgsz提到1280是因为皮带在画面里常是一条宽度只有几十像素的长带640输入经过5次下采样后只剩几个像素特征基本丢失。mosaic保留1.0但设置close_mosaic10让最后10个epoch回到干净的真实图片上微调避免黑色目标拼贴产生的伪边界被模型当成真特征。3.4 备选路线MMDetection直接吃COCO不转格式如果不打算用YOLO或者后面要换旋转框检测、实例分割模型MMDetection可以直接读COCO标注省掉转换这一步。它的CocoDataset类型原生支持COCO json只需要在配置文件里指定类别名# mmdetection/configs/belt_coal.py 片段 dataset_type CocoDataset data_root data/belt_coal/ train_dataloader dict( batch_size8, datasetdict( typedataset_type, ann_fileannotations/instances_train.json, data_prefixdict(imgimages/), classes(belt, coal), # 类别顺序影响模型输出保持稳定 ) )MMDet路线的好处是不做格式转换COCO里的segmentation多边形可以直接被Cascade Mask R-CNN这类实例分割模型使用对煤堆这种不规则目标的分割更友好。缺点是配置繁琐训练明显比YOLOv8慢而且煤堆和皮带这种大目标不需要复杂的多尺度模块性价比一般。我只有需要同时输出煤堆分割掩码、再计算煤流面积时才走这条路。4. 训练参数与评测设置把纸面99.5%复现到自己设备上4.1 一张参数表epoch、imgsz、batch、anchor怎么定煤和皮带识别不是通用目标检测参数不能照抄COCO基线。把几个关键参数和背后的理由列成一张表按这张表调基本不需要反复试错参数推荐值理由imgsz1280皮带细长低分辨率下特征消失batch8-161280大图显存主导宁可降batch也别降imgszepochs200两类别数据集收敛快100轮基本够200轮给足缓冲mosaic1.0 close_mosaic10增强小目标鲁棒性末期关掉避免黑块伪边界hsv_h / hsv_s0黑灰目标无色可分信息关掉防学偏hsv_v0.2保留亮度抖动模拟真实灯光波动fliplr0煤流方向固定镜像样本物理不合理scale0.3皮带尺度变化有限过大会把带子变成细线anchor重新聚类默认anchor对长宽比1:20的皮带不友好anchor的问题很多人在YOLOv8里忽略了因为yaml里有auto_anchor配置但预训练权重自带的anchor是为COCO的80类通用目标设计的最极端的宽高比也只有1:5左右。皮带一段的长度和宽度比经常超过1:15默认anchor去匹配这种目标损失函数会一直震荡。我一般先用K-Means在训练集的标注框上重新聚出6组anchorimport os import numpy as np from sklearn.cluster import KMeans # 从所有txt标签里收集宽高 wh [] for root, _, files in os.walk(labels/train): for file in files: if not file.endswith(.txt): continue for line in open(os.path.join(root, file), encodingutf-8): _, _, _, w, h map(float, line.split()) wh.append([w, h]) wh np.array(wh) * 1280 # 归一化数值还原到训练尺度 kmeans KMeans(n_clusters6, random_state0).fit(wh) anchors np.sort(kmeans.cluster_centers_, axis0) print(重新聚类的anchor(像素):) print(anchors)如果聚类结果里出现宽度小于30像素、高度超过200像素的anchor说明标注里存在整条皮带拉通的极端长宽比样本。解决方式下一章会讲先把聚类结果记录下来训练时通过模型配置里的anchors参数传入。聚类这一步能直观暴露标注质量聚出来的anchor分布乱标注一定有问题。4.2 评测脚本算mAP之外一定要算帧级检出率训练结束后跑验证集YOLOv8官方会输出mAP50和mAP50:95但煤矿现场真正关心的是另一件事这一帧里皮带到底有没有被漏掉。mAP把误检和漏检混在一个框级别指标里对现场报警逻辑没有直接参考价值。我习惯在验证阶段额外统计帧级检出率from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) hit {belt: 0, coal: 0} total 0 conf_thr 0.25 # 与现场部署阈值保持一致 for img_path in val_images: total 1 result model.predict(img_path, confconf_thr, verboseFalse)[0] if result.boxes is None: continue cls result.boxes.cls.cpu().numpy() if 0 in cls: hit[belt] 1 if 1 in cls: hit[coal] 1 print(f帧级检出率 belt: {hit[belt] / total:.4f}) print(f帧级检出率 coal: {hit[coal] / total:.4f})这段逻辑只关心目标在不在不关心框准不准。如果帧级检出率在满载和空载工况下都超过97%这个模型才有进现场的资格。mAP50高但帧级检出率低说明模型在部分工况下系统性漏检典型表现是停机状态皮带静止时检测正常皮带一跑起来煤粉飞溅就漏。遇到这种情况单独统计每个工况的帧级检出率立刻能定位是哪个工况拖的后腿。4.3 置信度阈值的生意0.25和0.7差出一倍误检置信度阈值是落地时最容易被忽略的参数。训练时的默认阈值0.25会把大量低置信度框放出来在煤和皮带这个场景里低置信度框几乎都落在两类错误上把煤堆积在皮带表面形成的黑色隆起误检成皮带边缘把皮带表面的反光斑误检成煤。把阈值拉到0.7误检能压下一大截但真正难检的、皮带被煤完全盖住的帧也会跟着漏。正确做法不是拍脑袋选一个阈值而是在独立验证集上扫一遍置信度画出每档阈值下的F1from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) for conf in [0.1, 0.25, 0.4, 0.5, 0.6, 0.7, 0.8]: tp fp fn 0 # 这里按验证集标注统计每个置信度下的正误检 # 完整实现需要读gt json核心是记录每帧是否存在真值目标 f1 2 * tp / (2 * tp fp fn) if tp else 0 print(fconf{conf:.2f} F1{f1:.4f})扫完之后取F1最大的阈值而不是用默认0.25。现场实施时如果再配合报警联动阈值还可以再提高一档因为误报警的成本远高于漏检后的人工复核。这个阈值最终写进部署配置里和训练脚本分开管理避免每次重训模型把阈值一起覆盖掉。5. 避坑煤黑皮带黑模型翻车的五处现场与处置5.1 皮带尾轮被当成煤堆标注边界含混的教训现象模型在皮带尾轮、滚筒附近频繁输出煤堆检测框煤的精确率被拉低跑偏报警乱触发。原因标注员把尾轮附近洒落的积煤、以及滚筒上附着的煤粉也标成了煤堆。滚筒是深灰色金属表面远处看和煤堆几乎同色但它在皮带走动时是转动的、有固有的圆柱外形。模型学到的是尾轮附近一大片深色区域是煤而不是有颗粒质感、会流动堆积的是煤。解决重新define标注口径——只标皮带表面及两侧实际堆积的煤流落在地面、机架、滚筒上的积煤一律不标。如果积煤本身也是关注对象把它单独建成第三个类别accum_coal比混在coal里让模型自己纠结要干净得多。标注规范里写清这条边界比事后清洗数据省力。5.2 mAP50不低、mAP50:95难看细长目标框不稳现象验证集mAP50在0.9以上mAP50:95只有0.4左右皮带检测框上下跳动边缘忽左忽右。原因皮带是长宽比极大的目标IoU对框的偏移极度敏感。一条宽度20像素、长度600像素的皮带检测框宽度偏5个像素IoU就从0.7掉到0.4。mAP50在IoU0.5处累计掩盖了这种框的漂移。解决首先在标注上做分段处理让每段皮带的长宽比控制在1:3到1:8之间细节见5.5其次训练时把验证集的IoU阈值档位看全别只盯着mAP50。如果现场允许对倾斜安装的相机做透视校正让皮带在画面里尽量水平检测框的稳定性会明显改善。5.3 测试集训练集同源相邻帧99.5%虚高的真相现象模型在随机切分的验证集上mAP50达到0.995换了另一个机位的十分钟现场录像检出率直接掉到88%。原因随机划分把同一段视频的相邻帧分到了训练和验证两边相邻帧的煤流形态、皮带位置、光照条件几乎相同验证集实际考察的是模型有没有记住这张图片的邻近帧而不是模型能不能认识皮带和煤。这是99.5%虚高最普遍的生产路径。解决按工况和时间重切数据集方法就是3.2节的代码。切完再训练一次看着mAP掉下去才安心——在煤矿视觉项目里验证集分数掉几个点是数据切分变严格的标志不是模型变差的标志。重新评估后如果帧级检出率仍能保持在95%以上这个数字才敢写进验收报告。5.4 运动模糊漏检给数据补上拖影增强现象皮带带速超过3m/s时现场相机拍出的画面里皮带边缘有1到3个像素的拖影模型在快速运行的帧上频繁漏检在静止画面上表现正常。原因工业相机多数用卷帘曝光皮带运动方向垂直于快门扫描方向时目标被拉成一条亮带边缘纹理被抹掉。煤和皮带本来就靠纹理细节区分拖影把判别信息抹掉后模型无从下手。解决先在数据增强层面补运动模糊让模型见过这种退化import cv2 import numpy as np def motion_blur(img, kernel_size15, angle0): 水平/垂直方向的运动模糊模拟角度按皮带实际运行方向调整 kernel np.zeros((kernel_size, kernel_size), dtypenp.float32) center kernel_size // 2 rad np.deg2rad(angle) for i in range(kernel_size): x int(center (i - center) * np.cos(rad)) y int(center (i - center) * np.sin(rad)) if 0 x kernel_size and 0 y kernel_size: kernel[y, x] 1.0 kernel / kernel.sum() return cv2.filter2D(img, -1, kernel) # 训练前对约20%的图片按皮带方向做模糊 # angle0 表示水平方向的拖影垂直安装相机时改为90模糊增强的kernel_size按皮带速度换算带速3m/s、曝光时间5ms时单帧拖影约15像素对应kernel_size取11到15。加完增强后如果漏检仍高再考虑硬件层面缩短曝光时间或换全局快门相机数据增强解决不了物理极限。5.5 一条皮带拉通标注长宽比悬殊让anchor失效现象模型对皮带中段的检测框不完整把一条皮带检测成两三段段与段之间间歇性漏检。原因标注员图省事把整条皮带框成一个目标长宽比达到1:30以上。YOLOv8的anchor从预训练权重继承即使重新聚类K-Means也很难同时覆盖1:3的煤堆和1:30的皮带最终模型只能用几个错位的anchor去凑皮带。解决标注时把皮带按固定间隔分段每段长度控制在4到6米对应的画面像素长宽比压到1:8以内。推理时再把同一帧内、沿皮带方向相邻的多个检测框合并成一条完整皮带合并依据是框中心线在皮带延伸方向上的距离小于阈值。分段标注不会影响跑偏检测因为跑偏计算用的是皮带框中心线的横向位置分段后取多段中心线的平均值反而更稳。6. 从识别到状态监测用皮带和煤的检出结果判断跑偏与堵煤6.1 皮带中心线偏移法跑偏量怎么从bbox算出来检测模型输出皮带的多个分段框每个框的中心点横坐标在画面里近似落在皮带中心线上。取同一帧所有皮带框中心点横坐标的平均值再减去画面里预先标定的机架参考线横坐标差值就是像素级跑偏量。乘上标定系数毫米/像素得到实际偏移。这个系数通过现场量取皮带宽度、对比画面中皮带占据的像素数来获得一个精度够用的做法# 帧处理伪代码逻辑 belt_boxes [b for b in detections if b.cls 0] centers_x [b.xyxy[0][0] (b.xyxy[0][2] - b.xyxy[0][0]) / 2 for b in belt_boxes] offset_px np.mean(centers_x) - reference_center_x offset_mm offset_px * mm_per_px注意皮带被煤完全覆盖的段落检测框的宽度会被煤撑大中心线位置出现假偏移。处理方法是只用煤检测框面积占比低于50%的皮带段参与跑偏计算煤多的段落直接跳过避免堵煤时误报跑偏。6.2 煤流面积滚动窗口堵煤和空载的判定规则煤流面积在画面里的占比用煤检测框总面积除以皮带检测框总面积得到。单帧比值波动很大要放到滚动窗口里判断时序趋势状态判定规则持续时间动作正常运煤煤占比0.2~0.7持续无空载/断煤煤占比0.0530秒提示堵煤预警煤占比0.85且皮带持续不动5秒报警跑偏风险中心线偏移量超阈值10秒联动检修用deque滑窗实现from collections import deque window deque(maxlen15) def judge_state(coal_area, belt_area): ratio coal_area / max(belt_area, 1e-6) window.append(ratio) if len(window) 15: return None avg_ratio sum(window) / len(window) if avg_ratio 0.05: return empty if avg_ratio 0.85: return blockage_alarm return normal滑窗长度15对应约3秒的帧序列既能滤掉单帧误检又不至于让真实的堵煤趋势被平滑掉。现场调试时把滑窗长度和阈值都留成配置项因为不同煤矿的皮带宽度、相机安装高度会让面积占比基线相差很大。6.3 我的落地习惯先跑10分钟现场视频再谈精度每次拿到训练好的模型我的第一件事不是看验证集报表而是拷贝一段现场真实监控视频进算法服务连续跑10分钟按帧打印每个目标的置信度和框坐标然后人工翻看输出日志。这10分钟里通常能碰到起机空载、加煤满载、停机检修这几个关键工况帧级检出率、置信度分布、误检规律全暴露在日志里比任何测试集指标都真实。我的习惯是把这10分钟视频固化下来作为回归基线每次重训模型都跑一遍对比性能有没有回退。毕竟验证集是静态的现场是动态的——煤的湿度、皮带磨损、光照角度都会让模型表现波动而这些在现场视频里才看得见。这套流程坚持下来比多调一个超参数都管用希望帮到你。本文还有配套的精品资源点击获取