news 2026/10/14 9:41:22

集装箱缺陷检测数据集:4127张VOC+YOLO双格式,3类缺陷实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
集装箱缺陷检测数据集:4127张VOC+YOLO双格式,3类缺陷实战指南

简介:本资源为集装箱缺陷检测数据集,面向从事工业质检、目标检测算法训练与课程实践的研究者及开发者,可用于训练和验证集装箱表面缺陷识别模型。数据集采用Pascal VOC与YOLO双格式标注,包含4127张jpg图片,每张图片均配有对应的xml与txt标注文件,标注类别为Dent、Hole、Rust三类,总框数达10117个,其中Dent 4943框、Hole 1218框、Rust 3956框,使用labelImg按矩形框规则完成标注。压缩包为7z格式,共2000个文件,以1999个xml标注文件和1个说明txt为主,整体约163.61MB,目录结构清晰,便于直接接入主流检测框架进行训练与评估。目前已有348人学习下载,适合需要快速获取缺陷检测数据、开展模型对比实验或完成课程项目的读者参考使用。

1. 集装箱缺陷检测数据集:4127 张 VOC+YOLO 双格式,3 类缺陷怎么落地

做集装箱表面质检的同行大概率都遇到过这个尴尬:算法框架搭好了,模型结构也调通了,结果卡在数据上——网上能找到的公开缺陷数据集要么类别不对口,要么格式只有 VOC 没有 YOLO,要么标注质量参差不齐,光清洗就耗掉一周。这次拆的这份集装箱缺陷检测数据集,4127 张 jpg 图片,配套 4127 个 Pascal VOC 格式 xml 和 4127 个 YOLO 格式 txt,3 个类别 Dent(凹陷)、Hole(破洞)、Rust(锈蚀),总标注框 10117 个。标注工具是 labelImg,规则就是矩形框,没有分割路径的 txt,属于典型的检测任务数据包。它解决的核心问题很直接:省掉从原始图到标注再到格式转换的前半程,让你把时间花在模型和调参上。适合做工业质检、港口物流视觉、表面缺陷检测的从业者,也适合想跑通 YOLO 全流程的新手拿来练手。下面按「数据长什么样 → 怎么读进来 → 怎么训 → 坑在哪」的顺序拆一遍。

2. 数据集结构与标注分布:先看清 10117 个框的底牌

拿到一个 7z 压缩包,别急着解压完就往训练脚本里塞。先搞清楚目录结构、文件命名规则和类别分布,这三件事决定了后面要不要做重采样、要不要改 data.yaml、要不要处理空标注。

2.1 目录组织与文件对应关系

从项目正文给出的文件列表看,根目录下有一个「使用前必读.txt」,然后是大量firc_jizhuangxiang_数字.xml文件。这种命名方式说明图片和标注是同名不同后缀配对的:firc_jizhuangxiang_647.jpg对应firc_jizhuangxiang_647.xml和firc_jizhuangxiang_647.txt。解压后典型结构是这样:

dataset/ ├── 使用前必读.txt ├── JPEGImages/ # 4127 张 jpg │ ├── firc_jizhuangxiang_647.jpg │ └── ... ├── Annotations/ # 4127 个 VOC xml │ ├── firc_jizhuangxiang_647.xml │ └── ... └── labels/ # 4127 个 YOLO txt ├── firc_jizhuangxiang_647.txt └── ...

实际压缩包里可能没有分文件夹,而是全部平铺在一个目录,这很常见。平铺的话,写脚本按后缀分流即可。关键点是:xml 数量、txt 数量、jpg 数量三者必须都是 4127,任何一个对不上,说明有文件丢失或命名不一致,先补齐再往下走。

2.2 三个类别的框数分布与影响

摘要里给了明确的框数统计,这个信息比图片数量更重要,因为它直接反映类别不平衡程度:

类别英文名框数占比
凹陷Dent494348.9%
破洞Hole121812.0%
锈蚀Rust395639.1%
合计—10117100%

Dent 和 Rust 加起来占了近 88%,Hole 只有 12%。这意味着如果直接训练,模型会明显偏向 Dent 和 Rust,Hole 的召回率大概率拉胯。常见做法是:要么在 loss 里给 Hole 加权,要么对 Hole 做过采样,要么用 mosaic、copy-paste 这类增强手段补 Hole 的样本。我一般会先跑一版 baseline,看混淆矩阵里 Hole 被误判成什么,再决定用哪种策略。

另外注意,10117 个框分布在 4127 张图上,平均每张约 2.45 个框。这个密度不算高,说明大部分图里目标不多,训练时 batch 可以适当开大一点,但要注意有些图可能只有 1 个框甚至个别图框数偏多,做 anchor 聚类时别用默认的 COCO anchor。

2.3 VOC 与 YOLO 双格式的取舍

这份数据同时给了 VOC xml 和 YOLO txt,很多人会纠结用哪个。我的建议是:训练直接用 YOLO txt,验证和可视化用 VOC xml。原因很简单,YOLO 系列读 txt 是原生支持,速度快;而 xml 里保留了图片宽高、目标尺寸等原始信息,做数据分析和可视化时更方便。

YOLO txt 每行格式是class_id x_center y_center width height,全部归一化到 0~1。VOC xml 里是绝对像素坐标xmin ymin xmax ymax。两者可以互转,但要注意归一化时的除数是图片实际宽高,不是固定值。如果图片尺寸不统一,转换脚本必须逐张读取尺寸,不能写死。

提示:解压后先跑一遍完整性校验,确认 jpg、xml、txt 三者数量一致且文件名能一一对应,再开始任何训练操作。

3. 从压缩包到可训练:解析、校验与格式转换实操

这一章是整篇的核心操作区。目标是把一个刚解压的 7z 目录,变成 YOLO 能直接吃的训练集,中间包含解析、校验、划分、配置文件生成四步。每一步都给可抄的代码。

3.1 解压与文件完整性校验

7z 在 Linux 下用7z x解压,Windows 下用 7-Zip 右键解压即可。解压后第一件事不是训练,是校验。下面这段脚本做三件事:统计三类文件数量、检查同名配对、找出孤立文件。

import os from collections import Counter root = "dataset" # 解压后的根目录 exts = {".jpg": [], ".xml": [], ".txt": []} for f in os.listdir(root): name, ext = os.path.splitext(f) if ext.lower() in exts: exts[ext.lower()].append(name) # 1. 数量统计 for ext, names in exts.items(): print(f"{ext} 文件数: {len(names)}") # 2. 同名配对检查(以 jpg 为基准) jpg_set = set(exts[".jpg"]) xml_set = set(exts[".xml"]) txt_set = set(exts[".txt"]) missing_xml = jpg_set - xml_set missing_txt = jpg_set - txt_set orphan_xml = xml_set - jpg_set orphan_txt = txt_set - jpg_set print(f"缺 xml 的图: {len(missing_xml)}") print(f"缺 txt 的图: {len(missing_txt)}") print(f"孤立 xml: {len(orphan_xml)}") print(f"孤立 txt: {len(orphan_txt)}") # 3. 打印前几个异常,方便定位 print("示例缺 xml:", list(missing_xml)[:5]) print("示例孤立 txt:", list(orphan_txt)[:5])

逻辑说明:以 jpg 为基准集合,用集合差集找出缺失和孤立文件。参数上,root改成你实际解压路径即可。如果输出里missing_xml或missing_txt不为 0,说明数据包在传输或解压时出了问题,必须先把这些图剔除或补齐,否则训练时 dataloader 会直接报错中断。

3.2 解析 VOC xml 提取类别与框信息

校验通过后,用 xml 做一次类别分布复核,确认摘要里的 4943/1218/3956 是否对得上。这一步同时能发现标注里的异常框,比如宽高为 0、坐标越界。

import xml.etree.ElementTree as ET from collections import Counter xml_dir = "dataset/Annotations" class_counter = Counter() box_counter = Counter() abnormal = [] for f in os.listdir(xml_dir): if not f.endswith(".xml"): continue tree = ET.parse(os.path.join(xml_dir, f)) root = tree.getroot() size = root.find("size") w = int(size.find("width").text) h = int(size.find("height").text) for obj in root.findall("object"): cls_name = obj.find("name").text.strip() class_counter[cls_name] += 1 bbox = obj.find("bndbox") xmin = int(float(bbox.find("xmin").text)) ymin = int(float(bbox.find("ymin").text)) xmax = int(float(bbox.find("xmax").text)) ymax = int(float(bbox.find("ymax").text)) # 异常框检查 if xmax <= xmin or ymax <= ymin: abnormal.append((f, cls_name, "zero_area")) elif xmin < 0 or ymin < 0 or xmax > w or ymax > h: abnormal.append((f, cls_name, "out_of_bound")) print("类别分布:", dict(class_counter)) print("异常框数量:", len(abnormal)) print("异常示例:", abnormal[:5])

逻辑说明:ET.parse逐文件解析,findall("object")拿到每个标注目标。类别名用strip()去掉可能的首尾空格,这一步很关键,因为 labelImg 有时会留下空格导致类别名对不上。异常框分两类:零面积和越界。零面积框在训练时会产生 NaN loss,越界框会被某些框架裁剪或直接报错。发现异常后,要么修正坐标,要么把对应图从训练集剔除。

参数上,xml_dir指向你的 Annotations 目录。如果类别分布和摘要给的数字有出入,比如 Dent 不是 4943,那说明这份数据可能被二次编辑过,需要重新评估。

3.3 划分训练集/验证集并生成 data.yaml

YOLO 训练需要 train/val 两个列表和一份 data.yaml。划分比例常见 8:2 或 9:1,工业缺陷数据我一般用 8:2,保证验证集有足够样本覆盖三个类别。下面脚本按类别分层抽样,避免验证集里 Hole 太少。

import os, random, shutil from collections import defaultdict random.seed(42) root = "dataset" img_dir = os.path.join(root, "JPEGImages") lbl_dir = os.path.join(root, "labels") out_dir = "yolo_dataset" # 按类别分层:读取每个 txt 的主类别 cls_to_imgs = defaultdict(list) for f in os.listdir(lbl_dir): if not f.endswith(".txt"): continue name = os.path.splitext(f)[0] with open(os.path.join(lbl_dir, f)) as fp: lines = fp.readlines() if not lines: continue # 取该图出现最多的类别作为分层依据 from collections import Counter c = Counter([int(l.split()[0]) for l in lines if l.strip()]) main_cls = c.most_common(1)[0][0] cls_to_imgs[main_cls].append(name) train_list, val_list = [], [] for cls, names in cls_to_imgs.items(): random.shuffle(names) split = int(len(names) * 0.8) train_list += names[:split] val_list += names[split:] # 建立 YOLO 目录结构 for sub in ["images/train", "images/val", "labels/train", "labels/val"]: os.makedirs(os.path.join(out_dir, sub), exist_ok=True) for name in train_list: shutil.copy(os.path.join(img_dir, name + ".jpg"), os.path.join(out_dir, "images/train", name + ".jpg")) shutil.copy(os.path.join(lbl_dir, name + ".txt"), os.path.join(out_dir, "labels/train", name + ".txt")) for name in val_list: shutil.copy(os.path.join(img_dir, name + ".jpg"), os.path.join(out_dir, "images/val", name + ".jpg")) shutil.copy(os.path.join(lbl_dir, name + ".txt"), os.path.join(out_dir, "labels/val", name + ".txt")) print(f"train: {len(train_list)}, val: {len(val_list)}")

逻辑说明:先按每张图的主类别分组,再在组内按 8:2 切分,这样验证集里三个类别都有覆盖。random.seed(42)保证可复现。复制而非移动,保留原始数据不动,方便后面换划分比例重跑。

生成 data.yaml:

path: ./yolo_dataset train: images/train val: images/val nc: 3 names: ['Dent', 'Hole', 'Rust']

注意names的顺序必须和 txt 里的 class_id 对应。labelImg 导出 YOLO 格式时,类别 id 是按你标注时的类别列表顺序生成的,如果顺序和这里不一致,训练出来的类别会全错。核对方法:随便打开一个 txt,看第一列的数字,再对照 xml 里的 name,确认映射关系。

注意:如果 txt 里的 class_id 从 0 开始且只有 0/1/2 三个值,说明映射正常;如果出现 3 或更大值,说明类别数不止 3 个,数据包可能混入了其他类别。

4. 训练配置与参数调优:3 类缺陷的 YOLO 落地细节

数据准备好了,接下来是训练。这一章不讲 YOLO 原理,只讲针对这份数据的具体参数怎么设、为什么这么设、以及训练过程中看什么指标。

4.1 模型选型与输入尺寸

3 类缺陷、4127 张图,属于中小规模数据集。模型不用上太大的,YOLOv8n 或 YOLOv8s 就够,再大容易过拟合。如果追求精度且显存充足,可以上 YOLOv8m,但要做强增强。输入尺寸方面,集装箱缺陷的 Dent 和 Rust 通常面积较大,Hole 可能偏小,建议用 640×640 起步,如果 Hole 召回一直上不去,再试 960×960。

训练命令以 YOLOv8 为例:

yolo detect train \ data=data.yaml \ model=yolov8s.pt \ epochs=150 \ imgsz=640 \ batch=16 \ lr0=0.01 \ lrf=0.01 \ patience=30 \ augment=True \ mosaic=1.0 \ mixup=0.1 \ copy_paste=0.1 \ project=runs/container_defect \ name=exp1

参数说明:epochs=150配合patience=30,30 轮没提升就早停,避免浪费时间。lr0=0.01是初始学习率,lrf=0.01是最终学习率系数,余弦退火到初始的 1%。mosaic=1.0开启马赛克增强,对小目标 Hole 有帮助。mixup=0.1和copy_paste=0.1是额外增强,copy_paste 对缺陷检测特别有效,因为它能把缺陷区域复制到其他图上,相当于免费扩充 Hole 样本。

4.2 类别不平衡的处理策略

前面说过 Hole 只有 1218 个框,占比 12%。除了 copy_paste,还有两个手段:一是 loss 加权,二是过采样。YOLOv8 默认的分类 loss 没有类别权重接口,但可以在数据集层面做。最简单的方法是把含 Hole 的图在 train 列表里重复 2~3 次,让模型每轮多见几次 Hole。

# 在生成 train_list 后,对含 Hole 的图做过采样 hole_imgs = [] for name in train_list: with open(os.path.join(lbl_dir, name + ".txt")) as fp: if any(line.startswith("1 ") for line in fp): hole_imgs.append(name) # 重复 2 次,即总共出现 3 次 train_list_oversampled = train_list + hole_imgs * 2 print(f"过采样后 train: {len(train_list_oversampled)}")

逻辑说明:line.startswith("1 ")判断该图是否含 Hole(class_id=1)。重复后训练集从约 3300 张变成约 4000+ 张,Hole 的出现频率明显提升。注意不要重复太多次,否则模型会对 Hole 过拟合,把其他类误判成 Hole。

另一个手段是调整验证指标。训练时重点看metrics/mAP50-95和每个类别的metrics/mAP50,如果 Hole 的 mAP 明显低于另外两类,说明不平衡问题没解决,回去加过采样或增强。

4.3 训练过程监控与早停判断

YOLO 训练会输出一堆指标,新手容易看花眼。重点盯三个:box_loss、cls_loss、mAP50。box_loss下降说明框回归在收敛,cls_loss下降说明分类在收敛,mAP50上升说明整体在变好。如果box_loss震荡不降,可能是学习率太大或 anchor 不匹配;如果cls_loss降不下去,多半是类别不平衡或标注有噪声。

早停的判断标准:连续 30 轮mAP50-95没有提升就停。但要注意,YOLO 的早停是基于 fitness 指标,不是单纯 mAP。如果验证集太小,fitness 波动大,可能提前停。这时候可以把patience调到 50,或者手动跑满 epoch 再选最佳权重。

训练完成后,用验证集跑一次评估:

yolo detect val \ model=runs/container_defect/exp1/weights/best.pt \ data=data.yaml \ imgsz=640 \ conf=0.25 \ iou=0.5

conf=0.25是置信度阈值,iou=0.5是 NMS 的 IoU 阈值。这两个值直接影响召回和误报的平衡。工业场景通常更看重召回,可以适当降低 conf 到 0.15~0.2,宁可多报不可漏报。

5. 避坑与排查:标注、格式、训练里的 5 个真实翻车点

这一章全是血泪经验。数据集用起来出问题,90% 不是模型的问题,是数据和配置的问题。下面 5 条按「现象 → 原因 → 解决」写,每条都是实际踩过的。

5.1 类别名带空格导致训练报 KeyError

现象:训练启动后报KeyError: 'Dent '或类别名找不到,或者训练能跑但类别全乱。

原因:labelImg 在某些版本里导出 xml 时,<name>标签内容会带首尾空格,比如Dent而不是Dent。YOLO 解析时按字符串精确匹配,带空格的类别名对不上 data.yaml 里的names。

解决:在解析 xml 的脚本里统一strip(),或者批量清洗 xml 文件。清洗命令:

import os, xml.etree.ElementTree as ET xml_dir = "dataset/Annotations" for f in os.listdir(xml_dir): if not f.endswith(".xml"): continue path = os.path.join(xml_dir, f) tree = ET.parse(path) root = tree.getroot() changed = False for obj in root.findall("object"): name = obj.find("name") if name.text != name.text.strip(): name.text = name.text.strip() changed = True if changed: tree.write(path, encoding="utf-8", xml_declaration=True)

5.2 txt 里的 class_id 与 data.yaml 顺序不一致

现象:训练 loss 正常下降,但验证时所有 Dent 被预测成 Rust,或者混淆矩阵完全错位。

原因:labelImg 导出 YOLO 格式时,class_id 是按标注时的类别列表顺序生成的。如果标注时先标了 Rust 再标 Dent,那 Rust 的 id 可能是 0,Dent 是 1。而 data.yaml 里写的是['Dent', 'Hole', 'Rust'],顺序对不上。

解决:先确认 txt 里的 id 分布,再反推映射。打开几个 txt,看第一列的数字,对照对应 xml 里的 name。如果发现 id 0 对应的是 Rust,就把 data.yaml 改成['Rust', 'Hole', 'Dent'],或者写脚本把 txt 里的 id 重映射。

# 假设实际映射是 0->Rust, 1->Hole, 2->Dent # 目标映射是 0->Dent, 1->Hole, 2->Rust id_map = {0: 2, 1: 1, 2: 0} lbl_dir = "dataset/labels" for f in os.listdir(lbl_dir): if not f.endswith(".txt"): continue path = os.path.join(lbl_dir, f) with open(path) as fp: lines = fp.readlines() new_lines = [] for line in lines: parts = line.strip().split() if parts: parts[0] = str(id_map[int(parts[0])]) new_lines.append(" ".join(parts) + "\n") with open(path, "w") as fp: fp.writelines(new_lines)

5.3 图片尺寸不统一导致归一化坐标错乱

现象:训练时框的位置明显偏移,或者验证可视化里框画到了图片外面。

原因:YOLO txt 里的坐标是归一化的,归一化除数是图片实际宽高。如果转换脚本写死了 640×640,而实际图片是 1920×1080,坐标就全错了。

解决:转换时必须逐张读取图片尺寸。用 PIL 或 OpenCV 读:

from PIL import Image import os img_dir = "dataset/JPEGImages" for f in os.listdir(img_dir): if not f.endswith(".jpg"): continue with Image.open(os.path.join(img_dir, f)) as im: w, h = im.size # 用 w, h 做归一化,不要写死

如果已经生成了错误的 txt,只能重新从 xml 转一遍,确保归一化除数正确。

5.4 空标注图导致 dataloader 报错

现象:训练到某一步突然报IndexError或ZeroDivisionError,定位到某张图。

原因:有些图可能没有标注,对应的 txt 是空文件。YOLO 默认会跳过空 txt,但如果配置里skip_empty没开,或者空 txt 被当成有效样本,就会出问题。

解决:先统计空 txt 数量,决定是剔除还是保留。工业数据里,纯背景图也有价值,可以保留但要在 dataloader 里正确处理。YOLOv8 默认会跳过空标签图,如果报错,检查 txt 是否真的是空文件而不是只有换行符。

empty = [] lbl_dir = "dataset/labels" for f in os.listdir(lbl_dir): if f.endswith(".txt"): with open(os.path.join(lbl_dir, f)) as fp: if not fp.read().strip(): empty.append(f) print(f"空标注文件: {len(empty)}")

5.5 验证集划分不均匀导致指标虚高

现象:验证集 mAP 很高,但实际部署时效果差很多。

原因:随机划分时,验证集可能恰好抽到了容易的图,或者某个类别在验证集里几乎没有。比如 Hole 只有 1218 个框,随机抽 20% 可能只抽到 200 个,评估结果波动大。

解决:用分层抽样,确保验证集里三个类别的框数比例和整体一致。前面 3.3 的脚本已经按主类别分层,但更严格的做法是按框数分层。如果验证集 mAP 波动超过 5 个点,说明验证集太小或不均衡,考虑增大验证集比例到 25%。

提示:每次改完数据或配置,先跑 1~2 个 epoch 看 loss 是否正常下降,再跑完整训练。别一上来就 150 epoch,浪费算力。

6. 进阶技巧:用 VOC xml 做数据增强与难例挖掘

训练跑通只是第一步,真正拉开差距的是数据层面的迭代。这份数据同时给了 VOC 和 YOLO 两种格式,很多人只用 YOLO txt 训练,把 xml 扔在一边,其实浪费了。xml 里保留了图片宽高、目标绝对坐标,做数据增强和难例分析时比 txt 方便得多。

6.1 基于 xml 的离线增强

YOLO 自带的在线增强(mosaic、mixup)已经很强,但有些增强适合离线做,比如针对 Hole 的 copy-paste。用 xml 读原图,把 Hole 区域裁剪出来,再随机贴到其他没有 Hole 的图上,同时更新 xml 和 txt。这样能定向扩充 Hole 样本,比单纯过采样更有效。

import xml.etree.ElementTree as ET from PIL import Image import random, os def crop_hole(img_path, xml_path, out_dir): tree = ET.parse(xml_path) root = tree.getroot() with Image.open(img_path) as im: for i, obj in enumerate(root.findall("object")): if obj.find("name").text.strip() != "Hole": continue bbox = obj.find("bndbox") xmin = int(float(bbox.find("xmin").text)) ymin = int(float(bbox.find("ymin").text)) xmax = int(float(bbox.find("xmax").text)) ymax = int(float(bbox.find("ymax").text)) patch = im.crop((xmin, ymin, xmax, ymax)) patch.save(os.path.join(out_dir, f"hole_{os.path.basename(img_path)}_{i}.png")) # 遍历所有含 Hole 的图,裁剪出 Hole 区域 for f in os.listdir("dataset/Annotations"): if f.endswith(".xml"): name = os.path.splitext(f)[0] xml_path = os.path.join("dataset/Annotations", f) img_path = os.path.join("dataset/JPEGImages", name + ".jpg") crop_hole(img_path, xml_path, "hole_patches")

逻辑说明:这段脚本把所有 Hole 区域裁剪成小图,存到hole_patches。然后写另一个脚本,随机选一张无 Hole 的图,把 patch 贴上去,同时生成新的 xml 和 txt。注意贴的时候要避开已有目标区域,否则框会重叠。贴完后的坐标要重新计算,归一化除数用新图的宽高。

6.2 用验证集做难例挖掘

训练完一版模型后,用验证集跑推理,把误报和漏报的图挑出来,人工复核标注。常见做法是用yolo detect predict输出带框的图,然后按置信度排序,低置信度的真阳性、高置信度的假阳性都是重点。

yolo detect predict \ model=runs/container_defect/exp1/weights/best.pt \ source=yolo_dataset/images/val \ conf=0.1 \ save_txt=True \ save_conf=True \ project=runs/predict \ name=val_check

conf=0.1故意调低,让模型多输出一些框,方便看漏报。save_txt=True会把预测结果存成 txt,格式和标注一致,可以直接和标注对比。写个脚本算每个类别的 TP/FP/FN,找出 Hole 漏报最多的图,回去检查标注是否有遗漏或框不准。

6.3 一个具体技巧:用 Rust 的框数反推标注一致性

Rust 有 3956 个框,Dent 有 4943 个,两者数量接近,但 Rust 通常面积更大、边界更模糊,标注一致性容易出问题。我一般会抽 50 张含 Rust 的图,把 xml 里的框画出来,肉眼检查是否有漏标或框过大。如果发现某张图的 Rust 框明显偏少,说明标注员可能把锈蚀当成了背景。这种图如果留在训练集里,会教模型忽略 Rust,导致召回下降。

具体操作:用 xml 读框,用 OpenCV 画到图上,存到rust_check目录,人工过一遍。发现问题的图,要么重新标,要么从训练集剔除。这个步骤花不了半小时,但能避免后面反复调参的玄学问题。

从那以后我每次拿到新数据集,都强制走一遍「数量校验 → 类别分布复核 → 抽样可视化 → 空标注检查」这四步,再开始训练。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 9:41:02

Python农作物病虫害识别分类实战:CNN与迁移学习

简介&#xff1a;面向计算机专业毕业设计、课程设计与项目实战学习者的完整可运行资源包&#xff0c;围绕Python农作物病虫害识别与分类任务&#xff0c;提供模型训练、验证及推理所需全部代码。资源压缩包共96个文件&#xff0c;以76个py源码文件为主&#xff0c;涵盖CNN&…

作者头像 李华
网站建设 2026/10/14 9:41:02

智能体技能设计实战:从提示词到Agent能力封装

做了快两年的AI应用开发&#xff0c;我越来越觉得&#xff0c;真正决定一个智能体项目上限的&#xff0c;往往不是接入了多强的模型&#xff0c;而是“agent-skills”的设计质量。什么意思呢&#xff1f;同一个大模型&#xff0c;有人接出来的智能体能力极强&#xff0c;可以稳…

作者头像 李华
网站建设 2026/10/14 9:40:43

【AI大模型进阶】微调中的过拟合表现:训练集 loss 降了,测试集降了吗?

【AI大模型进阶】微调中的过拟合表现:训练集 loss 降了,测试集降了吗? 集 loss 降了,测试集降了吗? 写在前面 大模型微调不管是全参数微调、LoRA 微调、QLoRA 低秩微调,大家最直观的监控指标就是损失 loss。很多人训练的时候看到训练 loss 一路持续下降,就默认模型效…

作者头像 李华
网站建设 2026/10/14 9:40:01

裸机STM32移植LwIP实现PING与TCP Client

简介&#xff1a;本资源是一份面向STM32嵌入式开发者的LwIP协议栈实战工程&#xff0c;聚焦无操作系统环境下以太网外设的底层移植与通信验证&#xff0c;适用于具备C语言基础和STM32标准库开发经验的中级进阶学习者。项目基于STM32F429IGT6主控与LAN8720A PHY芯片&#xff0c;…

作者头像 李华
网站建设 2026/10/14 9:39:55

ASA原理与电子维修实战:01 什么是ASA:从电气响应到诊断证据

第1章 什么是ASA:从电气响应到诊断证据 本章导言:维修不只是测量,更是理解电路的响应 在电子设备维修中,我们经常需要回答一个问题:怎样判断一个断电电路是否存在异常? 传统维修通常从测量开始。使用万用表测量电阻、二极管压降和电容,检查电源与地之间是否短路,或者…

作者头像 李华
网站建设 2026/10/14 9:39:54

搜索结果里的舆情负面,多久能淡化

搜索结果里的舆情负面淡化时间取决于处置动作、内容形态、平台规则等多因素&#xff0c;不存在统一时限&#xff0c;需结合具体场景判断。舆情负面淡化的核心影响因素 舆情负面的淡化周期并非固定&#xff0c;核心取决于三个维度&#xff1a;一是内容本身的侵权性与传播广度&am…

作者头像 李华