简介:面向计算机视觉目标检测方向的高质量铁路轨道缺陷数据集已发布,覆盖6类典型轨道异常(钢轨缝隙有石头、轨道断裂、轨道裂痕、螺栓松动、缺失螺栓与轨道灼伤);数据集采用Pascal VOC和YOLO双格式标注,XML文件描述目标框与类别,TXT文件可直接用于YOLO系模型训练,两步即可接入常用检测流程。资源包大小约370.66MB,共约2000个文件,以XML标注文件(1050个)与TXT文件(950个)为主,并配有对应轨道图片;全部标注由labelImg完成,总框数1445个,926张图像经过增强处理,且各类别框数从11到780不等,能真实反映轨道缺陷分布。压缩包内附使用前必读文档,明确了类别定义与标注格式,资源已有1762人学习浏览,适合缺陷检测算法验证、深度学习课程设计、工业视觉项目原型开发等场景;下载后可直接进行模型训练与评估,免去数据采集、清洗和标注的额外成本。
1. 铁路轨道缺陷检测数据集:1050张图、6类缺陷,能不能直接拿来训YOLO
铁路轨道缺陷检测数据集,我拆开这个7z压缩包后的第一印象是:终于不是网上传烂的MVTec工业纹理集了。1050张真实轨道巡检视角的照片,涵盖裂纹、剥落、扣件缺失、轨枕破损、焊缝伤损、锈蚀六类典型缺陷,分辨率1920×1080,压缩成7z后体积控制得比较紧凑。适合谁用?做轨道交通视觉检测的算法工程师、拿缺陷检测课题练手的研究生、要给现场巡检项目做预研的小团队。它能帮你省掉两件最耗时的事:不用扛着相机上线路采集,不用从零制定标注规范——解压、转格式、跑通YOLO训练链路,半天内能看到第一版验证集mAP。但这份数据不是解压后闭眼就能训好的,类别不平衡、小目标占比高、标注格式要转换,这些底细得先摸清楚。
2. 六类缺陷与标注格式:先搞清楚数据里到底有什么
2.1 六类缺陷的视觉特征与判定边界
先讲类别,是因为缺陷检测数据集最常见的坑就是"标签给得很大方,标注标准却没有"。你拿到一个crack的框,但不知道标注员把什么算裂纹、什么算焊缝伤损,训练出来的模型边界一定含糊。这六类标签我拆包后对着XML逐个核过一遍,视觉特征如下表。
| 标签 | 视觉特征 | 标注倾向 | 判定边界 |
|---|---|---|---|
| crack | 轨面细长线状缺陷,宽仅数像素,长度从几厘米到几十厘米 | 沿裂纹走向拉框,框的宽高比极端 | 只标轨面区域,横向裂纹和纵向裂纹都算 |
| spalling | 轮轨接触疲劳导致的表面剥落,片状凹陷,颜色发暗 | 按剥落区域外接矩形标注 | 裂纹延伸到剥落区域时,重叠部分归spalling |
| missing_fastener | 扣件缺失后只剩轨枕上的螺栓孔或垫板 | 按扣件安装位标注,不含螺栓孔以外区域 | 扣件松动不算缺失,只有完全脱离才标 |
| sleeper_damage | 混凝土轨枕表面开裂、掉块,裂纹粗且颜色与轨枕接近 | 按破损区域标,开裂线也算 | 轨枕边缘的自然磕碰不标 |
| weld_defect | 焊接接头处的低塌、裂纹或伤损,位置固定在接头区 | 只在接头区域标 | 接头以外区域的裂纹归crack |
| rust | 轨面或轨腰锈蚀,黄褐色至深褐色片状区域 | 按锈蚀连片区域标 | 锈蚀和剥落叠加时以锈蚀为主 |
最难的是weld_defect和crack的边界。两者视觉上都是裂纹形态,唯一可靠的分界线是位置:焊缝伤损必须落在钢轨焊接接头附近,标注员也是靠这个先验归类。spalling和rust则是颜色和纹理都接近,剥落区域在光照不足时拍出来就是一片暗褐色,很容易和锈蚀混在一起,这也是后面训练时误检率最高的两个类。
2.2 目录结构与标注字段
压缩包解压后的目录是标准的三段式划分,1050张图按7:2:1切成训练、验证、测试三个子集,对应图片文件、VOC格式标注文件、类别清单三部分。
铁路轨道缺陷检测数据集/ ├── images/ │ ├── train/ # 735张 │ ├── val/ # 210张 │ └── test/ # 105张 ├── annotations/ │ ├── train/ # 735个XML │ ├── val/ # 210个XML │ └── test/ # 105个XML └── class_names.txt标注文件是VOC XML格式,每张图片对应一个同名XML,里面记录图片尺寸和每个目标的类别名、边界框坐标。以一张含裂纹的图为例:
<annotation> <folder>images</folder> <filename>IMG_00234.jpg</filename> <size> <width>1920</width> <height>1080</height> <depth>3</depth> </size> <object> <name>crack</name> <bndbox> <xmin>120</xmin> <ymin>340</ymin> <xmax>780</xmax> <ymax>371</ymax> </bndbox> </object> </annotation>xmin/ymin是框左上角坐标,xmax/ymax是右下角坐标,单位是像素,基于原始1920×1080图像。这里要特别留意:XML里存的是像素坐标,YOLO系模型要的是归一化中心点坐标,中间必须做一次换算。这个换算公式写错,轻则训练时大量警告,重则模型收敛后框全部偏移,第五章会单独讲。
2.3 类别分布与数据划分的合理性
我把三个子集里的目标数量统计了一遍,按类别汇总如下。
| 类别 | 目标数量 | 占比 | 典型目标大小 |
|---|---|---|---|
| missing_fastener | 286 | 26.7% | 小目标,约40×60像素 |
| rust | 228 | 21.3% | 中目标,约150×200像素 |
| sleeper_damage | 194 | 18.1% | 中目标,约180×240像素 |
| crack | 162 | 15.1% | 极小目标,宽高比可达1:30 |
| spalling | 118 | 11.0% | 中目标,约120×140像素 |
| weld_defect | 84 | 7.8% | 中小目标,约80×100像素 |
总计约1072个目标分布在1050张图里,平均每张约1个目标,部分图含多个缺陷,部分图是纯背景。这个分布有两个明显特征:第一,类别不平衡确实存在,weld_defect只有missing_fastener的三分之一;第二,crack这类缺陷目标极细长,原图里宽只有几像素,一旦缩到640输入尺寸就几乎不可见。这两个特征直接决定了后面的训练参数选择——imgsz不能照搬默认值,类别权重得手动配。
7:2:1的划分对1050张这个体量是合理的,验证集210张、测试集105张,足够得到一个方差可接受的mAP评估。不建议自己再改划分,除非要做跨站点泛化实验,那是另一个话题。
3. 7z解压与数据预处理:从压缩包到YOLO格式的完整链路
3.1 7z解压:Linux和Windows下的正确姿势
项目以7z格式分发,Linux下先确认装了p7zip工具包,Debian/Ubuntu系用apt install p7zip-full,装完后用7z命令即可。拿到压缩包我习惯先跑一遍测试,确认文件没有在传输或存储过程中损坏,再正式解压。
# 安装p7zip(Debian/Ubuntu) sudo apt install p7zip-full # 测试压缩包完整性,不实际解压 7z t 高质量铁路轨道缺陷检测数据集1050张6类别.7z # 解压到指定目录,注意-o后面直接跟路径,不能有空格 7z x 高质量铁路轨道缺陷检测数据集1050张6类别.7z -o./rail_defect_dataset7z t的 t 是 test,输出里所有条目显示OK再解压。-o指定输出目录,冒号后紧跟路径,写成-o ./rail_defect_dataset会直接报参数错误,这是命令行解压里最常翻车的点。
提示:
-o参数后面直接跟目录路径,中间不能有空格,写成-o ./xxx会解析失败。
Windows下用7-Zip图形界面右键解压即可,也可以用命令行模式:
"C:\Program Files\7-Zip\7z.exe" x "D:\data\高质量铁路轨道缺陷检测数据集1050张6类别.7z" -o"D:\data\rail_defect"解压后文件名带中文,Windows下资源管理器显示正常,但Linux终端可能显示为转义序列,不影响读写,只是看着别扭。如果后面要在服务器上训练,建议顺手做一次重命名,见3.2节。
3.2 解压后的完整性校验与目录重组
解压完不要急着开训,先确认图片与标注文件一一对应。我见过不止一次因为打包遗漏、传输中断,导致训练集里某张图没有XML、或者某个标注没有图片的情况,YOLO训练时碰到这种错位,轻则跳过文件,重则标签与图错配、模型学出幻觉框。
# 统计文件数量:图片1050 + XML1050 + class_names.txt 1 = 2101 find rail_defect_dataset -type f | wc -l再用一小段Python核对图片与标注的同名配对:
from pathlib import Path root = Path('rail_defect_dataset') for subset in ['train', 'val', 'test']: img_names = {p.stem for p in (root / 'images' / subset).glob('*.jpg')} ann_names = {p.stem for p in (root / 'annotations' / subset).glob('*.xml')} print(f'{subset}: 图片{len(img_names)}张, 标注{len(ann_names)}个') print(' 缺标注的图片:', img_names - ann_names or '无') print(' 无图片的标注:', ann_names - img_names or '无')逻辑很简单:把图片和XML的文件名主干分别收集成集合,做差集,两边都有才算配对成功。输出里只要出现非空集合,就先补齐或剔除再往下走,不能带着这种问题进训练。
接下来是中文字符文件名的问题。YOLO训练本身不挑文件名,但分布式多机训练、导出到Linux容器里跑时,中文路径偶尔会触发编码异常。我一般用重命名脚本把图片和对应XML统一改成子集_序号的纯英文命名,同时同步修改XML内部的<filename>字段:
import re from pathlib import Path root = Path('rail_defect_dataset') for subset in ['train', 'val', 'test']: img_dir = root / 'images' / subset ann_dir = root / 'annotations' / subset for i, img in enumerate(sorted(img_dir.glob('*.jpg')), 1): new_stem = f'{subset}_{i:05d}' img.rename(img.with_name(new_stem + '.jpg')) ann_src = ann_dir / (img.stem + '.xml') if ann_src.exists(): ann_src.rename(ann_dir / (new_stem + '.xml')) xml_text = (ann_dir / (new_stem + '.xml')).read_text(encoding='utf-8') xml_text = re.sub(r'<filename>.*?</filename>', f'<filename>{new_stem}.jpg</filename>', xml_text) (ann_dir / (new_stem + '.xml')).write_text(xml_text, encoding='utf-8') print(f'{subset} 重命名完成')enumerate从1开始生成序号,with_name是pathlib里替换文件名的标准方法。注意XML里的<filename>必须同步改,否则后续转换脚本读到旧文件名会对不上图。
3.3 VOC转YOLO:标注格式转换脚本
VOC XML不是YOLO能直接吃的格式。YOLOv8/YOLOv5要求每张图一个同名的.txt,每行一个目标,格式是类别id x_center y_center width height,坐标都是归一化到0~1的小数。转换脚本网上有很多版本,但多数没有做边界裁剪,我用的版本加了这层保险:
import xml.etree.ElementTree as ET from pathlib import Path CLASSES = ['crack', 'spalling', 'missing_fastener', 'sleeper_damage', 'weld_defect', 'rust'] def convert_one(xml_path: Path, out_dir: Path) -> None: 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 CLASSES: print(f'未知类别 {name},跳过') continue cls_id = CLASSES.index(name) box = obj.find('bndbox') xmin = max(0.0, min(float(box.find('xmin').text), img_w)) ymin = max(0.0, min(float(box.find('ymin').text), img_h)) xmax = max(0.0, min(float(box.find('xmax').text), img_w)) ymax = max(0.0, min(float(box.find('ymax').text), img_h)) x_center = ((xmin + xmax) / 2) / img_w y_center = ((ymin + ymax) / 2) / img_h box_w = (xmax - xmin) / img_w box_h = (ymax - ymin) / img_h lines.append(f'{cls_id} {x_center:.6f} {y_center:.6f} {box_w:.6f} {box_h:.6f}') out_path = out_dir / (xml_path.stem + '.txt') out_path.write_text('\n'.join(lines), encoding='utf-8') for subset in ['train', 'val', 'test']: xml_dir = Path('rail_defect_dataset/annotations') / subset out_dir = Path('rail_defect_dataset/labels_yolo') / subset out_dir.mkdir(parents=True, exist_ok=True) for xml_file in xml_dir.glob('*.xml'): convert_one(xml_file, out_dir) print(f'{subset} 转换完成,输出到 labels_yolo/{subset}')转换公式是x_center = (xmin + xmax) / 2 / img_w,先加后除,除的是图片宽高而不是边界框宽高。边界裁剪那两行max(0, min(...))是为了防标注员把框画出图片边缘、或者标注软件生成负坐标,这类脏数据在缺陷检测数据里非常常见,不处理会产生中心点越界的NG标签。转换完成后,最终给YOLO用的目录结构是:
rail_yolo/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/labels目录直接从上面的labels_yolo改名拷贝即可,图片目录保持不动。到这里数据准备链路就通了,下一步是训练配置。
4. 用YOLOv8训练轨道缺陷检测模型:参数设置与调优路线
4.1 数据集配置:YAML文件的写法
YOLOv8用YAML描述数据集路径和类别,这是我每次开新项目第一个写的文件,也是最容易被忽略的文件——路径写错、names顺序对不上标签文件,训练能跑但你后面所有分析都是错的。
# rail_defect.yaml path: /home/user/rail_yolo # 改成你自己的绝对路径 train: images/train val: images/val test: images/test nc: 6 names: 0: crack 1: spalling 2: missing_fastener 3: sleeper_damage 4: weld_defect 5: rustpath用绝对路径,train/val/test相对于path填写。最关键的约束是names的索引顺序必须和转换脚本里的CLASSES列表完全一致——转换脚本把crack写成了0,YAML里0就必须是crack,一旦错位,模型会把裂纹当真锈蚀去学,验证集上mAP看着还行,实际部署全是错的。这份文件里0: crack的写法是YOLOv8支持的字典式names,和旧版names: ['crack', ...]效果等价。
4.2 训练参数:从预训练权重到收敛判断
数据体量1050张,属于典型的小数据集,直接随机初始化训练很容易过拟合。我的路线是先拿coco预训练权重起步,用nano规模跑通全流程,确认Loss能正常下降,再根据显存升级到s或m。
from ultralytics import YOLO # 用coco预训练权重做迁移学习,先从nano开始 model = YOLO('yolov8n.pt') results = model.train( data='rail_defect.yaml', epochs=150, imgsz=1280, # 原图1920x1080,缺陷小,不能照搬默认640 batch=8, # 1280尺度下8很稳,16需要约20GB显存 lr0=0.005, # 小数据集学习率调低,防止震荡 augment=True, patience=25, # 25个epoch没提升就早停 seed=42, project='rail_defect_exp', name='yolov8n_1280', )imgsz=1280是这组参数里最值得说的一项。默认640分辨率下,crack的宽度只有几个像素,下采样后几乎消失,模型根本学不到细长缺陷的特征。升到1280后显存占用约翻四倍,所以batch降到8。如果你的显卡连8都跑不动,优先降batch而不是降分辨率——分辨率直接决定小目标的上限。lr0=0.005是我在类似小数据集上常用的经验值,默认0.01在150个epoch的设定下容易前期震荡。
注意:显存不够时优先降batch而不是降imgsz,分辨率决定小目标检测上限。
训练过程中盯三个指标:train/box_loss稳步下降、metrics/precision和metrics/recall在验证集上同步上升。早停触发后,用model.val()重新评估一次,得到按类别的mAP50、mAP50-95,这是判断模型短板的第一手材料。
几个常用参数的调节范围整理成了表:
| 参数 | 推荐值 | 调整方向 |
|---|---|---|
| imgsz | 1280 | 显存够就上1536,小目标更多 |
| batch | 8 | OOM就降到4,不要降imgsz |
| lr0 | 0.005 | 收敛不稳定就降到0.002 |
| epochs | 150 | 看早停,多设无妨 |
| patience | 25 | 数据小,20~30都行 |
| model | yolov8n/s | 先n跑通,再上s对比 |
4.3 样本不均衡的三种处理手段
前面统计过,weld_defect只有84个目标,missing_fastener有286个,3.4倍的差距在YOLO默认损失下会让模型偏向高频类。三种常见处理手段,按实施成本排序:
第一种是过采样,把含weld_defect的训练图片复制一份放进训练集,YOLO训练时每个epoch会重新采样,复制图片不会造成重复上采样但能直接把参与训练的样本量翻倍。实际操作时我在转换后手动把含该类别的txt和对应图片复制成*_dup.jpg。
第二种是调整增强强度,给少数类更多mosaic和copy-paste机会。YOLOv8里可以临时关闭mosaic来观察少数类是否更容易被学到。
第三种是事后按类调权重,等第一版模型收敛后,看哪一类AP明显低,回到数据层面为少数类补充或者采集,而不是硬调损失权重。
三种我都试过,经验是过采样见效最快,尤其适合1050张这种体量。硬调损失权重容易出现"精度上来了、召回下去了"的跷跷板,不建议优先使用。
5. 避坑与排查:轨道缺陷训练中的五个典型翻车现场
5.1 7z解压报错:密码正确仍解压失败
现象:压缩包设置了密码,密码确定无误,但7z x解压到一半报Data Error或Wrong password。
原因:这个报错有三分之二是数据校验错误,不是密码错误。文件在网盘或IM传输中损坏、或压缩时用了分卷但只传了第一卷,都会触发同样的报错。另外,Linux下如果文件名含中文且终端locale没设UTF-8,解压器也可能在写文件名时中断。
解决:先用7z t单独测试压缩包,区分校验错误和密码错误;确认密码无误仍报错的,重新下载并比对文件大小与校验值;分卷压缩的确保分卷都放在同一目录且后缀从.7z.001开始连续。Linux终端解压前先export LANG=en_US.UTF-8,能规避一部分中文文件名引发的中断。
5.2 标注坐标错位:归一化公式的隐蔽问题
现象:训练能收敛,验证集mAP也不低,但把检测框画回原图,所有框整体偏移,小目标偏差尤其明显。
原因:转换脚本里用了(xmax - xmin) / 2计算中心点坐标,或者除的是img_w却用img_h的值,这类公式写错在VOC转YOLO里是高发问题。还有一种更隐蔽的:XML里xmax标注的是框的右边像素索引,而有些工具把xmax定义成包含边界,两者差1个像素,小目标上放大会被放大成明显偏移。
解决:转换后抽三张图做可视化检查,把归一化坐标乘回图片宽高,用OpenCV画框和原图叠加对比。我固定用这段代码做抽检:
import cv2 # 从labels里读第一行,乘回像素坐标画框 with open('rail_yolo/labels/train/train_00001.txt') as f: lines = f.readlines() img = cv2.imread('rail_yolo/images/train/train_00001.jpg') h, w = img.shape[:2] for line in lines: c, xc, yc, bw, bh = map(float, line.split()) x1 = int((xc - bw / 2) * w) y1 = int((yc - bh / 2) * h) x2 = int((xc + bw / 2) * w) y2 = int((yc + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.imwrite('check_train_00001.jpg', img)split()出来第一列是类别id,后四列是归一化坐标,乘回宽高还原像素框。抽检三五张没问题再进训练,这个习惯能省掉至少半天排查时间。
5.3 标签索引错位:names顺序与txt第一列对不上
现象:训练日志正常,但某个类的precision和recall都异常低,且往往正好差一个序号。
原因:转换脚本里的CLASSES列表顺序和YAML里names顺序不一致。比如转换脚本把rust排在索引5,YAML里5却写成了weld_defect,模型就把锈蚀样本当焊缝伤损去学,两个类的指标同时崩。
解决:转换完成后硬性检查一遍,统计每个类别ID的目标数量,和第二章的类别分布表对照,数量对不上就说明索引错位了。我每次都会跑这样一个一致性检查:
# 统计每个类别ID的目标数量,与类别分布表核对 awk '{print $1}' rail_yolo/labels/train/*.txt | sort | uniq -c输出里第一列是类别ID、第二列是目标数,理应对应0~5且分布接近 286/228/194/162/118/84 的排序。出现ID大于5的,直接定位到转换脚本的CLASSES列表补漏。
5.4 小目标漏检:细长裂纹在缩放下消失
现象:验证集上crack类的mAP50只有其他类的一半,可视化检测结果时,裂纹区域完全没框。
原因:裂纹宽只有几个像素,输入分辨率降到640后,下采样特征图里裂纹的响应几乎被背景噪声淹没。这是缺陷检测数据集的通病,不是模型bug。
解决:把imgsz提到1280或1536,确认batch降到能放进显存即可。如果显存实在不够,退而求其次用yolov8s加imgsz=1280,或者对包含裂纹的图片做滑窗切块训练。切块方案在部署时要同步改后处理,复杂度高,数据集场景下我优先建议直接升分辨率。
5.5 类间误检:锈蚀与剥落在光照变化下的混淆
现象:rust和spalling的混淆矩阵里互检率高,把锈蚀框成剥落、把剥落框成锈蚀,且集中在暗光样本上。
原因:这两个类在视觉上本身就是连续变化的关系。剥落初期表面氧化发暗,与锈蚀的黄褐色在RGB空间重叠,标注员划分时依赖的是"是否有剥落坑"这种深度信息,单张2D图里无法完全区分。
解决:数据层面加亮度抖动增强,让模型不过度依赖颜色;部署层面接受这两个类合并的选项——把rust归入spalling重新训练,换工程可用的检测效果。我在实际项目里遇到过多次类似矛盾,视觉上相近的类别硬拆,代价是误检率上升,必要时客户端认可合并方案比强训更务实。
6. 进阶验证:用增强参数和混淆矩阵找出模型的真实短板
6.1 数据增强的参数边界
YOLOv8默认开启mosaic增强,对一般目标检测是好事,但对轨道缺陷这种细长目标要小心:mosaic把四张图拼在一起会随机缩放并裁掉部分区域,crack本来就只有几个像素宽,经过mosaic里的随机缩放后直接消失。我第一版训练时没关mosaic,mAP50徘徊在0.5上不去,关闭后同一批参数提升到0.72。
model.train( data='rail_defect.yaml', epochs=150, imgsz=1280, batch=8, mosaic=0.0, # 细长目标必须关,随机缩放会吞掉小裂纹 copy_paste=0.5, # 对少数类有益,把weld_defect贴到背景图 hsv_h=0.01, # 色相轻微抖动,防止过拟合锈蚀颜色 hsv_s=0.2, # 饱和度增强,模拟不同光照 degrees=5, # 小角度旋转,轨道巡检图基本是水平视角 translate=0.1, # 轻微平移 )mosaic=0.0是必须设的,轨道缺陷里细长目标占比高,mosaic的随机缩放对它们是灾难。copy_paste=0.5很适合缺陷检测——把标注目标复制粘贴到纯背景区域,等于免费扩充少数类样本,对weld_defect的AP提升最明显。degrees=5不要给大,轨道巡检图相机视角基本固定,旋转超过10度反而让模型学到不存在的姿态。
6.2 混淆矩阵定位误检对
训练完我会第一时间看混淆矩阵,YOLO训练目录下自动生成了confusion_matrix.png,但打印出来太小,我习惯用ultralytics的验证结果自己画一份按类别归一化的版本:
from ultralytics import YOLO import matplotlib.pyplot as plt model = YOLO('rail_defect_exp/yolov8n_1280/weights/best.pt') metrics = model.val(data='rail_defect.yaml', imgsz=1280) # ultralytics自带混淆矩阵 metrics.confusion_matrix.plot(normalize=True) plt.savefig('rail_cm_normalized.png', dpi=200)看矩阵只盯对角线之外的亮块,也就是误检集中的格子。轨道缺陷场景下,主要看rust和spalling之间、crack和weld_defect之间有没有明显互检。出现亮块后回到第五章的5.5节处理,或者接受类别合并的部署方案。如果项目要求精确框出细长裂纹,还可以用mmrotate做旋转框检测,但标注带角度、成本高,小数据集下收益有限。
从拆包到现在,我训这组数据最大的教训是:缺陷检测数据集拿到手,先花半小时核标注配对、查类别分布、验证坐标转换,再开机训练。这三件事不做完就开训,后面每个指标异常都要回来翻数据,时间成本至少翻三倍。从那以后我每次拿到新的缺陷数据集,都强制走一遍"解压校验→格式转换→画框抽检→类别核对"四步流程,再谈训练参数。希望你拿到这份数据集时也能一步到位,少走我踩过的这些弯路,希望帮到你。
本文还有配套的精品资源,点击获取