ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SVM故障诊断实战:小样本下的特征提取与参数寻优

SVM故障诊断实战:小样本下的特征提取与参数寻优 简介面向机械设备故障诊断与分类预测场景提供基于SVM支持向量机的Matlab完整源码包数据采用西储大学轴承公开数据集经特征提取后的结果运行环境为Matlab 2023适合有一定机器学习基础、希望将分类算法落地到旋转机械状态监测的读者。资源共71个文件、压缩后约1.31MB内部含Matlab核心脚本、mat数据文件以及配套libsvm-3.3工具库涵盖C/C源码、Java/Python接口、Windows可执行文件与动态库等方便读者理解算法实现并跨环境调用。内容覆盖数据加载、模型训练、测试与混淆矩阵可视化等关键环节可直接复现典型的滚动轴承故障分类流程libsvm工具库也便于进一步调整核函数、惩罚参数等开展参数对比与优化实验。目前已有153人学习下载尤其适合机械、自动化等专业学生与从事设备状态监测的工程技术人员参考。整个包体结构清晰主程序与依赖库分层放置便于按需修改和复用。1. SVM故障诊断在小样本场景下为什么比深度学习更能打一条减速器轴承的健康数据攒了上万条故障样本只有几十条。扔给深度学习模型训练结果忽高忽低换一次随机种子就差好几个点换成SVM支持向量机做故障诊断/分类预测反而能稳定落在一个可用的准确率上。这不是玄学是SVM的建模方式在样本量上更克制。经常有读者问用Matlab源码跑SVM故障诊断真的够用吗我的看法是设备健康管理这类场景故障样本难得、标注还贵数据驱动建模的第一诉求不是模型多花哨而是给一批小样本能不能出一个特征层可解释、测试集不崩的分类器。SVM恰好就是这条赛道上最不容易翻车的基线。这篇把从原始振动数据到SVM分类预测的完整套路讲清楚包括数据划分、特征提取、参数寻优和落地预测。适合刚接触故障诊断的研究生也适合产线上想快速试出一条可解释基准线的工程师。下面直接从数据准备开始这部分决定了后面八成的工作量。2. 从原始振动信号到SVM输入数据划分、特征提取、归一化三步走不管SVM训练时用什么核函数输入特征的品质决定了结果的上限。故障诊断的常见做法是从振动信号里切片段每个片段计算一组特征形成一个样本。特征怎么算、训练集怎么切直接决定你后面是省心还是反复踩坑。2.1 训练集和测试集怎么切才不算作弊先说一个很多人第一次跑故障诊断都会犯的错拿到一段连续的振动数据直接随机打乱后按比例分训练集和测试集。结果训练集准确率看着不错但一到现场预测就翻车。原因很简单——同一个故障在相邻时间片段的特征几乎一样随机划分等于把同一段信号的两个分身分别放进了训练集和测试集模型记住的是这段波形而不是这种故障。我一般的做法是按时间顺序切分前60%到80%的时间片段做训练后20%到40%做测试。如果现场有多种工况就按工况分组保证同一种工况的数据要么全在训练集要么全在测试集。下面这段代码把连续索引的样本按比例分段划分% 样本数 N特征矩阵 X标签 y N size(X, 1); train_ratio 0.7; % 训练集比例故障诊断常用 0.6~0.8 split_idx floor(N * train_ratio); train_idx 1:split_idx; % 连续取前 70% 作为训练 test_idx split_idx1:N; % 后 30% 作为测试 X_train X(train_idx, :); y_train y(train_idx, :); X_test X(test_idx, :); y_test y(test_idx, :);这里直接用索引划分而不是randperm是刻意为之故障诊断里相邻样本的时域特征高度相关按时间顺序切分能让训练集和测试集在时间上不重叠避免数据泄漏。train_ratio取0.6到0.8都可以样本越少训练比例可以越高但测试集至少留出20%才有统计意义。提示如果有多个工况文件先按文件分组再在每个文件内部做时间顺序划分。千万不要把所有文件拼在一起后统一切那样会人为制造跨工况的数据泄漏。2.2 时域和频域特征给轴承故障诊断搭一组常用特征SVM不会自己从原始波形里找规律你要先把一段信号压缩成一排特征。轴承故障诊断里最常用的时域特征包括均值、峰值、均方根值、峭度、偏度和峰值因子频域特征包括重心频率、均方根频率和频率标准差。峭度对早期冲击类故障很敏感均方根值反映整体能量水平这两项基本是必选。下面这个函数输入一段振动信号输出11维特征向量是我在轴承数据集上常用的最小特征集function feat extract_features(signal, fs) % signal: 单个样本的振动加速度信号, 列向量 % fs: 采样率, Hz n length(signal); % 时域特征 mean_val mean(signal); % 均值 peak_val max(abs(signal)); % 峰值 rms_val sqrt(mean(signal.^2)); % 均方根值 kurt kurtosis(signal); % 峭度 skew skewness(signal); % 偏度 crest peak_val / (rms_val eps); % 峰值因子 % 频域特征: 用 FFT 算幅值谱 spectrum abs(fft(signal)) / n; freq (0:n-1) * fs / n; % 频率轴 half 1:floor(n/2); % 只取正频段 spec spectrum(half); f freq(half); FC sum(f .* spec) / (sum(spec) eps); % 重心频率 RMSF sqrt(sum(f.^2 .* spec) / (sum(spec) eps)); % 均方根频率 RVF sqrt(sum((f - FC).^2 .* spec) / (sum(spec) eps)); % 频率标准差 feat [mean_val, peak_val, rms_val, kurt, skew, crest, ... FC, RMSF, RVF, sum(spec), max(spec)]; end代码里时域部分直接调用Matlab的mean、kurtosis、skewness等统计函数频域部分先用fft算幅值谱再按公式计算三个频域指标。最后的sum(spec)是总能量max(spec)是主频幅值这两个特征在区分不同故障类型时效果不错。所有除法都加了eps防除零样本幅值全为零时不会直接得到NaN。采样率fs只在计算频率轴时用到如果你只做特征不关心频率绝对位置fs传多少影响都不大但建议还是按真实采样率传方便后面做频谱核对。特征维度现阶段先保持在9到11维后面讲参数寻优时会提到特征一旦堆到二三十维SVM的调参成本会明显上升。2.3 归一化不是可选项zscore和mapminmax的两种标准写法SVM的RBF核函数要计算样本间的距离而距离对量纲极其敏感。举个例子峰值是几十的量级峭度是3附近的量级两个特征直接拼在一起距离计算基本被峰值主导峭度等于白给。所以归一化在SVM里不是可选项是必需项。我推荐用zscore按列标准化先算训练集的均值和标准差再用同一组参数去标准化测试集。最忌讳的做法是训练集和测试集各自归一化那样两套数据的均值方差不同等于人为改变了测试集的分布。% 只在训练集上计算归一化参数 mu mean(X_train, 1); % 每个特征的均值 sigma std(X_train, 0, 1); % 每个特征的标准差, 0 表示样本标准差 sigma(sigma eps) 1; % 防止常数特征除零 % 训练集和测试集使用同一套参数 X_train_norm (X_train - mu) ./ sigma; X_test_norm (X_test - mu) ./ sigma;逻辑分三步前两行计算并修正归一化参数后面两行把同一套mu和sigma应用到训练集和测试集。关键是把mu和sigma保存下来后面做模型保存时要连同模型一起存入mat文件实时预测时还要用。如果你习惯用mapminmax正确写法是先对训练集fit再把ps结构体apply到测试集% mapminmax 默认按行处理, 特征按列存储时要先转置 [X_train_norm, ps] mapminmax(X_train, 0, 1); X_train_norm X_train_norm; X_test_norm mapminmax(apply, X_test, ps);注意mapminmax有两个常见坑一是它按行操作特征矩阵是N行乘D列的时候必须先转置否则归一化的是样本而不是特征二是apply必须用训练集fit出来的ps不能对测试集重新fit。zscore写法没有行列问题所以我个人更常用zscore。3. 在Matlab里跑通SVM分类预测fitcsvm、fitcecoc和libsvm三条路线Matlab里跑SVM有两条主流路线自带工具箱的fitcsvm系列以及开源的libsvm。前者胜在开箱即用适合快速验证和工程部署后者和论文里的参数表示一致适合做对比实验。多分类场景还要在fitcsvm基础上套一层fitcecoc。3.1 fitcsvm跑二分类最小可运行代码如果只是健康/故障二分类Matlab自带的fitcsvm是最省事的路线% 假设 X_train_norm, y_train, X_test_norm, y_test 已准备好 % y 必须是二值标签, 如 1/0 或 normal/fault mdl fitcsvm(X_train_norm, y_train, ... KernelFunction, rbf, ... BoxConstraint, 1, ... KernelScale, auto, ... Standardize, false); % 特征已归一化, 不需要再设 Standardize y_pred predict(mdl, X_test_norm); acc mean(y_pred y_test) * 100; fprintf(测试集准确率: %.2f%%\n, acc);fitcsvm里最常调的三个参数是KernelFunction、BoxConstraint和KernelScale。KernelFunction选rbf是故障诊断里的默认选择对非线性关系拟合能力最强BoxConstraint对应SVM的C控制误分类的惩罚力度默认1KernelScale对应RBF核的尺度参数设auto是让Matlab自动估计省事但不是最优。需要特别提醒的是Standardize参数。因为第2章已经手动用zscore把特征归一化过这里要设false否则fitcsvm会在内部再做一次标准化虽然不影响预测但会让模型参数和手动归一化参数产生不必要的耦合。3.2 fitcecoc把二分类扩展到多分类一对一的封装用法故障诊断通常不止健康/故障两种状态比如轴承故障还要区分内圈、外圈、滚动体。fitcsvm本身只能做二分类Matlab用fitcecoc把多个二分类器组合成多分类器默认采用一对一策略K类故障训练K*(K-1)/2个二分类器预测时投票。% 多分类标签 y_multi, 取值范围 1~K % 注意 fitcecoc 要求标签是正整数或分类变量 tpl templateSVM(KernelFunction, rbf, ... BoxConstraint, 1, ... KernelScale, auto); mdl_multi fitcecoc(X_train_norm, y_train_multi, ... Learners, tpl, ... Coding, onevsone); y_pred_multi predict(mdl_multi, X_test_norm); acc_multi mean(y_pred_multi y_test_multi) * 100;fitcecoc把SVM当作一种learner封装进来所以要先构造templateSVM来统一设置核函数和正则化参数。Coding参数决定多分类策略onevsone是一对一onevsall是一对多。一对一的分类器数量多但每个子问题简单一对多的分类器数量少但容易受样本不平衡影响。故障诊断里类别数通常在3到8个我一般直接用默认的onevsone比onevsall更容易调出可用效果。注意fitcecoc内部还会给每个二分类器做概率校准所以predict返回的结果比直接调用libsvm更平滑。如果你要输出故障概率而不是类别用fitcecoc(...,FitPosterior,true)之后再用predict返回第二输出值。3.3 libsvm路线科研对比实验里更常用的完整源码libsvm是SVM领域应用最广的实现功能上比Matlab自带的多一个概率输出选项。去官网下载解压后在Matlab里编译mex文件然后addpath到搜索路径。它的调用接口和fitcsvm不太一样需要特别注意特征矩阵和标签的顺序。% libsvm 安装后, 假设路径已 addpath % 训练: svmtrain(标签, 特征, 参数) model svmtrain(y_train, X_train_norm, ... -s 0 -t 2 -c 1 -g 0.5 -q); % 预测: svmpredict(标签, 特征, 模型) [pred, acc, prob] svmpredict(y_test, X_test_norm, model); % acc 返回三列: 准确率, 平均绝对误差, 均方误差 % prob 需要模型带 -b 1 参数才会输出概率svmtrain的前两个参数是标签和特征和fitcsvm的参数顺序正好相反这是最容易犯的手误。参数列表里-s 0表示C-SVC分类器-t 2表示RBF核-c 1对应C-g 0.5对应gamma。注意libsvm的gamma就是RBF核里的gamma而fitcsvm的KernelScale是1/gamma两边换算时要留意。科研场景里用libsvm的好处是它和论文里的参数表示一致C和gamma可以直接照抄文献的值做基线。缺点是数据量大时训练速度不如Matlab自带实现而且它返回的模型是结构体预测阶段依赖libsvm的mex文件换机器时要重新编译。3.4 混淆矩阵和漏报率故障诊断里的评估不能只看准确率分类预测的结果不能只报一个准确率。故障诊断里最怕的是故障样本被预测成健康漏报一次可能意味着设备带病运行到损坏。所以我每次跑完预测都会顺手算混淆矩阵和每类召回率。% y_true: 真实标签, y_pred: 预测标签 C confusionmat(y_true, y_pred); % 计算每类召回率: 对角线 / 该行总和 recall diag(C) ./ (sum(C, 2) eps); % 可视化, 需要 Matlab R2018b 及以上 figure; confusionchart(y_true, y_pred, ... RowSummary, row-normalized, ... ColumnSummary, column-normalized);confusionmat返回的矩阵里行是真实类别列是预测类别对角线是预测正确的样本数。diag(C)除以行和就是每类的召回率也就是这类样本被找回来的比例。可视化直接用confusionchart它会自动在图表右侧和下侧显示每类召回率与精准度的汇总。如果某个故障类别样本本来就很少比如只有十几条召回率波动会很大这时候不要急着调参先看混淆矩阵里它被错分到哪些类别再回头查这些错分样本的时域波形。这个步骤能帮你判断是特征不够区分度还是样本量撑不起这个类别。4. 网格寻优定C和gammaSVM故障诊断里参数不是玄学C和gamma是SVM在故障诊断任务里最影响结果的两个旋钮。很多人上来就套默认参数预测效果一般就抱怨SVM不行其实是根本没把参数调到合适的区间。这一章给出一套完整的网格搜索代码以及结果怎么读。4.1 C和gamma各自管什么先知道方向再动手调C对应fitcsvm里的BoxConstraint是误分类的惩罚系数。C越大模型越不愿意放过任何训练样本决策边界越复杂容易过拟合C越小模型对误分类越宽容边界越平滑但可能欠拟合。故障数据不平衡时C对少数类的表现影响特别大C太小会让少数类样本被大面积牺牲掉。gamma是RBF核K(xi,xj)exp(-gamma*||xi-xj||^2)里的关键参数对应fitcsvm里的KernelScale1/gamma。gamma越大每个支持向量的影响范围越小决策边界越曲折容易把噪声也拟合进去gamma越小每个支持向量的影响范围越大边界越光滑太小的时候所有样本可能被分到同一类。方向记住一句话C管边界复杂度gamma管单点影响力两个都过大会过拟合。顺带回应一个很多人问过的点SVM能不能用梯度下降求解硬间隔SVM在推导损失函数时可以写成梯度下降的形式但工程实现里主流的求解器是SMO序列最小优化libsvm和fitcsvm内部都是这类算法不是梯度下降。所以在Matlab里训练SVM关心的不是学习率而是C和gamma。4.2 用cvpartition做5折交叉验证完整网格搜索代码网格搜索的思路很简单在C和gamma的候选值里两两组合对每个组合做交叉验证选交叉验证准确率最高的那组参数。下面是完整的Matlab代码C_list 2.^(-4:4); % C 0.0625 ~ 16 g_list 2.^(-6:2); % gamma 0.015625 ~ 4 cv cvpartition(y_train, KFold, 5); best_acc 0; best_C C_list(1); best_g g_list(1); for i 1:length(C_list) for j 1:length(g_list) mdl fitcsvm(X_train_norm, y_train, ... KernelFunction,rbf, ... BoxConstraint, C_list(i), ... KernelScale, 1/g_list(j)); cvmdl crossval(mdl, CVPartition, cv); loss kfoldLoss(cvmdl); acc (1 - loss) * 100; if acc best_acc best_acc acc; best_C C_list(i); best_g g_list(j); end end end fprintf(5折CV最优: C%.4f, gamma%.4f, CV准确率%.2f%%\n, ... best_C, best_g, best_acc);代码逻辑先构造C和gamma的候选网格值用2的幂次展开覆盖从0.06到16的常规范围再用cvpartition一次性生成5折划分最后嵌套遍历所有组合每个组合训练一个SVM并做5折交叉验证更新最优参数。参数说明C_list从2的-4次方到2的4次方共9个值gamma从2的-6次方到2的2次方共9个值合计81个组合每个组合训练5个模型共405次训练。对几千个样本的故障诊断来说这个量级在几秒到几十秒内能跑完。如果样本量超过几万建议先降采样或改用线性核。注意fitcsvm里传的是KernelScale它是1/gamma不是gamma所以写成1/g_list(j)。这个映射关系在libsvm里是-g 0.5在fitcsvm里就是KernelScale, 2搞反了会让寻优结果完全对不上论文里的结论。4.3 寻优结果怎么解读CV准确率和测试准确率的关系交叉验证准确率不是最终测试准确率。CV是在训练集内部做的验证它的作用是帮你选参数最后必须以独立测试集为准。常见现象是CV准确率95%测试集只有80%这要么是数据泄漏要么是测试集和训练集分布本身有差异。训练数据来自实验台、测试数据来自现场这种情况在故障诊断里非常普遍。判断标准我一般这么定CV和测试准确率差距在5个点以内参数选得健康差距超过10个点优先怀疑数据划分而不是继续换参数。此外最优C和gamma落在搜索网格边缘也是个信号比如C16正好是C_list的最后一个值说明网格范围不够要往这个方向继续扩展。还有一个细节容易被忽略特征维度升高后C的最优值通常会变大。因为特征维度越高样本在空间里分布越稀疏需要更强的正则化来约束边界。如果特征已经堆到30维以上建议先用PCA或者reliefF做特征筛选再回来寻优否则网格搜索会变得很慢而且搜出来的参数也不一定能在测试集上复现。5. 避坑与排查SVM故障诊断项目里最常见的5个翻车现场SVM本身是个很成熟的算法故障诊断项目里翻车基本都翻在数据处理和工程化环节而不是算法本身。这一章把最常见的5类问题按现象、原因、解决的顺序写清楚遇到类似症状可以直接对照排查。5.1 训练集准确率99%测试集只有60%头号嫌疑犯是数据泄漏现象训练集上准确率接近满分交叉验证也不差但一到独立测试集就掉到及格线以下。原因数据划分用了随机打乱同一段连续振动信号的不同片段同时混进了训练集和测试集。相邻片段的特征高度相似模型学到的是这段波形长什么样而不是这种故障和健康状态的本质区别。测试时遇到真正没见过的新数据表现立刻崩掉。解决回到第2章把划分方式改成按时间顺序或按工况分组。排查方法很简单在训练脚本里搜一下有没有randperm有就要警惕。如果数据是按文件组织的先按文件名分组再在组内切分最后拼接训练集。5.2 多分类预测结果全部落在第一类样本不平衡和决策偏向现象多分类模型训练完预测结果里绝大多数样本被判成第一类或者全部判成第一类其他类别的召回率为零。原因故障诊断数据天然不平衡健康样本可能是故障样本的几十倍。SVM的软间隔优化目标是全局误分类率最小少数类样本在总损失里占比太小决策边界被多数类整个吞掉。解决先看每类样本数再决定用哪招。样本数差距在5倍以内给fitcsvm加Prior,uniform通常就够mdl fitcsvm(X_train_norm, y_train, ... KernelFunction,rbf, ... BoxConstraint, 1, ... KernelScale,auto, ... Prior,uniform); % 让少数类和多数类同等重要注意设了Prior之后C的语义会变原来网格搜索出来的最优参数必须重新跑一遍不能沿用。如果样本数差距超过10倍光调权重不够建议对少数类做SMOTE过采样或者按故障类型分别训练二分类器再组合。5.3 样本一多训练就卡死RBF核矩阵的O(N^2)内存开销现象程序跑着跑着越来越慢内存占用飙升小数据集没事数据集一大就卡死甚至报内存不足。原因RBF核要计算所有样本两两之间的距离并缓存核矩阵N个样本就要存N×N的浮点数。1万样本是1亿个数占800MB内存几万样本直接撑爆。这是RBF核的固有代价和Matlab还是Python无关。解决三个方向任选。样本量在几万量级先降采样到训练集不超过5000条故障诊断里故障样本本来就少降采样对结果影响有限如果故障类型多到必须保留全部样本换线性核线性核不需要存核矩阵训练速度快一个量级代价是拟合非线性关系的能力弱一些用libsvm时把缓存调大-m 1024设成1024MB能减少重复计算的次数。5.4 特征维度越高准确率反而下降特征堆叠不等于信息量现象特征从12维加到30维交叉验证准确率不仅没涨反而掉了5个点。原因新增的特征很多是冗余的。比如同时加了均值、方差、标准差这三个特征高度线性相关RBF核在计算距离时冗余维度会稀释真正有判别力维度的权重。另外维度越高样本在空间里越稀疏gamma参数会变得极其敏感。解决先做特征筛选再寻优。最省事的方法是先用reliefF评一遍特征权重保留前10到15个特征重新训练也可以用PCA降到保留95%能量。降维度之后C和gamma的最优值通常会变记得重新跑一遍网格搜索。提示每次新增或删除特征后都必须重新归一化、重新寻优、重新保存模型。特征名单是模型的一部分不是可以随意替换的配置项。5.5 模型保存后加载预测结果对不上归一化参数和工具箱路径现象训练完保存的模型加载后预测结果和保存前完全不一致甚至直接报错。原因最常见的是只保存了模型对象没保存归一化用的mu和sigma。新数据进来用了新的归一化参数特征分布和训练时不一致预测结果自然对不上。另一种情况是libsvm的mex文件换机器后没重新编译加载模型后svmpredict调用失败。解决保存时把所有依赖打包进同一个mat文件save(svm_fault_model.mat, mdl, mu, sigma, best_C, best_g);加载预测时统一从mat文件读参数S load(svm_fault_model.mat); y_pred predict(S.mdl, (x_new - S.mu) ./ S.sigma);另外要注意工具箱版本。fitcsvm依赖Statistics and Machine Learning Toolbox目标机器没装这个工具箱就跑不了libsvm的模型是结构体只要mex编译版本一致就能加载但换Matlab大版本后通常要重新编译。生产线部署时如果不想折腾编译环境更推荐直接用fitcsvm加保存好的mat文件。6. 把训练好的SVM接进实时诊断模型保存、单样本预测与滑窗投票6.1 一个mat文件把模型和归一化参数全装进去模型训练完只是第一步故障诊断最终要接到实时数据流上。我习惯把模型、归一化参数、最优参数、特征名单全部打包成一个结构体存盘。这样项目交接时对方只需要这个mat文件和一份特征提取函数不需要重新训练。% 打包保存 model_package struct(); model_package.mdl mdl; model_package.mu mu; model_package.sigma sigma; model_package.best_C best_C; model_package.best_g best_g; model_package.fs fs; save(svm_fault_model.mat, model_package);加载时用一个封装函数避免每个脚本都重复写load和归一化function [label, score] predict_one_sample(model_file, signal, fs) S load(model_file); model_package S.model_package; feat extract_features(signal, fs); % 复用第2章的特征提取函数 feat_norm (feat - model_package.mu) ./ model_package.sigma; [label, score] predict(model_package.mdl, feat_norm); end6.2 单样本预测脚本实时数据流进来怎么算特征、怎么做预测实时诊断时从采集卡拿到的是一段持续振动的信号流常见做法是固定窗长滑动切片每个窗口当成一个独立样本。窗口长度要和训练时间片的长度一致通常是1024、2048或4096个采样点对应几十到几百毫秒的数据。% 实时循环示例: 每来一个窗口调用一次 window_len 2048; % 窗长, 和训练时保持一致 step 512; % 滑步, 决定诊断刷新频率 for k 1:floor((length(signal_stream) - window_len) / step) seg signal_stream((k-1)*step 1 : (k-1)*step window_len); [label(k), score(k)] predict_one_sample(svm_fault_model.mat, seg, fs); end单样本预测的坑在于特征提取函数必须和训练时完全一致。窗长改了、特征顺序换了、采样率传错了都会让预测结果失真。所以模型打包时把fs也存进去预测时从model_package里读不要每次调用都手填。6.3 滑窗投票用连续预测结果滤掉单点误报单窗口预测难免有偶发误报产线上受不了这种抖动。最简单的办法是滑窗投票取最近W个预测结果的众数作为当前诊断结论。W取奇数比如5、7、9避免平票。W 7; % 奇数窗口, 7 对应约 3.5 秒的平滑跨度 final_label mode(pred_window(end-W1:end));如果对概率输出有要求也可以用score均值替代投票设定阈值做报警。比如score连续3个窗口都大于0.8才触发报警比单窗口阈值更抗干扰。这个阈值要靠现场试不同的轴承转速和负载下最优值不一样。我现在做故障诊断项目的习惯是数据划分方案、特征名单、归一化参数、模型和寻优结果全部打包到同一个mat文件里每次出报告都从同一个文件读取不再临时跑训练脚本。换人接手也不会出现模型不知道在哪、参数不知道是啥的尴尬。这套流程不一定最炫但胜在可追溯、可复现、出了问题能快速定位。希望帮到你。本文还有配套的精品资源点击获取
返回列表