news 2026/3/2 4:32:40

从项目入手机器学习(七)—— 模型调优

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从项目入手机器学习(七)—— 模型调优

之前的文章中,我们进行了机器学习和深度学习的尝试,并提到过一个问题:模型的参数如何选择会对模型的效果产生非常大的影响,因此本节内容主要讨论如何找出模型的最优参数

首先,我们明确一个问题,一般来说,不会存在一组参数,能让模型适配所有的任务;因此,我们所说的模型最优参数,都是针对当前任务对应的数据集来说的,如果更换任务,甚至说更好输入模型的特征,都有可能导致模型的最优参数发生变化。

因此,调优是一个很繁琐的任务,不过现在有了很多封装好的工具包和ai,大大降低了任务难度,大家需要多运用这些工具

机器学习调优——随机搜索

(所谓调优,当然要先知道模型有哪些可以调整的参数,不知道就问ai)

# 1. RandomForest调参 print("调参RandomForest...") param_dist_rf = { 'n_estimators': [100, 200, 300], 'max_depth': [None, 10, 20, 30], 'min_samples_split': [2, 5, 10], 'min_samples_leaf': [1, 2, 4] } random_search_rf = RandomizedSearchCV( RandomForestClassifier(random_state=42), param_dist_rf, n_iter=10, cv=5, random_state=42, n_jobs=-1 ) random_search_rf.fit(X_train_scaled, y_train) best_rf = random_search_rf.best_estimator_ saved_models.append(('RandomForest', best_rf, random_search_rf.best_score_)) print(f"RandomForest最佳CV分数: {random_search_rf.best_score_:.4f}") # 2. DecisionTree调参 print("调参DecisionTree...") param_dist_dt = { 'max_depth': [None, 10, 20, 30], 'min_samples_split': [2, 5, 10], 'min_samples_leaf': [1, 2, 4], 'criterion': ['gini', 'entropy'] } random_search_dt = RandomizedSearchCV( DecisionTreeClassifier(random_state=42), param_dist_dt, n_iter=10, cv=5, random_state=42, n_jobs=-1 ) random_search_dt.fit(X_train_scaled, y_train) best_dt = random_search_dt.best_estimator_ saved_models.append(('DecisionTree', best_dt, random_search_dt.best_score_)) print(f"DecisionTree最佳CV分数: {random_search_dt.best_score_:.4f}")

这里仅介绍RandomizedSearchCV(随机搜索交叉验证),它是机器学习中高效、实用的超参数调优方法,核心是在指定超参数范围内随机采样组合,结合交叉验证筛选最优参数,专门解决网格搜索(GridSearchCV)参数组合过多、耗时过长的问题。

超参数调优的核心目标是找到一组超参数,让模型在未知数据上的泛化能力最优RandomizedSearchCV实现这一目标的逻辑分为 3 步:

  1. 定义参数空间:为模型每个超参数指定一个待搜索的取值范围 / 列表(如随机森林的n_estimators指定 [100,200,300]);
  2. 随机采样参数组合:从参数空间中随机抽取指定数量(n_iter)的参数组合,而非遍历所有组合(这是和网格搜索的核心区别);
  3. 交叉验证评估:对每一组随机采样的参数,用K 折交叉验证(CV)训练模型并计算验证分数,最终选择验证分数最高的参数组合作为最佳超参数,对应的模型为最佳估计器(best_estimator_)。

两者对比如下表,更能体现随机搜索的优势:

特性RandomizedSearchCV(随机搜索)GridSearchCV(网格搜索)
参数组合遍历方式随机采样 n_iter 组遍历所有组合
时间效率高(采样数可控)低(组合数随参数维度指数增长)
调优效果接近最优(抽样覆盖关键组合)理论最优(遍历所有可能)
适用场景参数空间大、快速调优参数空间小、追求极致调优

这里简要介绍一下代码内容,其实现在的ai写这种简单的调优已经很熟练了,完全可以交给ai

深度学习调优——Optuna (以MLP为例)

# 3. MLP调参 (Optuna) print("调参MLP...") # 定义TunedMLP类(全局) class TunedMLP(nn.Module): def __init__(self, input_size, dropout_rate): super(TunedMLP, self).__init__() self.fc1 = nn.Linear(input_size, 128) self.bn1 = nn.BatchNorm1d(128) self.dropout1 = nn.Dropout(dropout_rate) self.fc2 = nn.Linear(128, 64) self.bn2 = nn.BatchNorm1d(64) self.dropout2 = nn.Dropout(dropout_rate) self.fc3 = nn.Linear(64, 32) self.bn3 = nn.BatchNorm1d(32) self.dropout3 = nn.Dropout(dropout_rate) self.fc4 = nn.Linear(32, 1) self.sigmoid = nn.Sigmoid() def forward(self, x): x = self.dropout1(torch.relu(self.bn1(self.fc1(x)))) x = self.dropout2(torch.relu(self.bn2(self.fc2(x)))) x = self.dropout3(torch.relu(self.bn3(self.fc3(x)))) x = self.sigmoid(self.fc4(x)) return x def objective(trial): lr = trial.suggest_float('lr', 1e-5, 1e-1, log=True) dropout_rate = trial.suggest_float('dropout', 0.1, 0.5) model = TunedMLP(X_train_scaled.shape[1], dropout_rate) optimizer = optim.Adam(model.parameters(), lr=lr) criterion = nn.BCELoss() # 简短训练 for epoch in range(20): model.train() optimizer.zero_grad() outputs = model(X_train_tensor) loss = criterion(outputs, y_train_tensor) loss.backward() optimizer.step() # 验证准确率 model.eval() with torch.no_grad(): y_pred_prob = model(X_val_tensor) y_pred = (y_pred_prob > 0.5).float() acc = accuracy_score(y_val, y_pred.numpy().flatten()) return acc study = optuna.create_study(direction='maximize') study.optimize(objective, n_trials=10) best_params = study.best_params print(f"MLP最佳参数: {best_params}, 验证准确率: {study.best_value:.4f}") # 训练最佳MLP best_mlp = TunedMLP(X_train_scaled.shape[1], best_params['dropout']) optimizer = optim.Adam(best_mlp.parameters(), lr=best_params['lr']) criterion = nn.BCELoss() for epoch in range(50): # 更长训练 best_mlp.train() optimizer.zero_grad() outputs = best_mlp(X_train_tensor) loss = criterion(outputs, y_train_tensor) loss.backward() optimizer.step() saved_models.append(('MLP', best_mlp, study.best_value))

基于 Optuna 的贝叶斯超参数优化,这是深度学习调优的主流高效方法(区别于机器学习的随机搜索 / 网格搜索),核心是通过贝叶斯推理智能搜索超参数空间,用更少的试错次数找到最优超参数。

核心:Optuna 贝叶斯优化的调优原理(区别于随机 / 网格搜索)

深度学习的超参数(如学习率、dropout 率)多为连续值 / 对数分布值,且参数间存在隐性关联(如学习率和 batch size 相互影响),传统的随机 / 网格搜索 “无记忆、无关联” 的采样方式效率极低。Optuna 的贝叶斯优化核心逻辑是边试错、边学习、边聚焦

  1. 初始化采样:先随机试几组超参数,记录每组参数的验证效果(如 MLP 验证准确率);
  2. 构建概率模型:基于已试的参数和效果,构建一个「超参数→模型效果」的概率预测模型(如高斯过程、树结构 Parzen 估计器);
  3. 智能选下一组参数:根据概率模型,优先选择最可能提升效果的超参数组合(聚焦参数空间的 “最优潜力区域”,而非盲目随机);
  4. 迭代优化:重复 2-3 步,直到达到指定试错次数(n_trials),最终选择效果最优的参数。

简单说:Optuna 会 “记住” 之前的调优结果,智能避开无效区域、聚焦最优区域,比随机搜索少用 50% 以上的试错次数就能找到更优超参数,是深度学习调优的首选工具。

1. 定义可调参的 MLP 模型

  • 核心设计:将需要调优的超参数(dropout_rate)作为模型初始化参数,非调参参数(如隐藏层维度 128/64/32)固定,简化调优空间;
  • 关键细节:BatchNorm1d+ReLU+Dropout的顺序是深度学习训练的黄金顺序,能有效缓解梯度消失、抑制过拟合、提升训练稳定性;
  • 适用场景:二分类任务(如本例中的泰坦尼克生存预测),最终用Sigmoid输出 0~1 的概率,符合BCELoss损失函数要求。

2. 定义 Optuna 目标函数(objective)—— 调优的核心

  • 参数建议方法trial.suggest_*系列方法,根据参数类型选择(如浮点型suggest_float、整型suggest_int、类别型suggest_categorical);
    • 学习率lr设为对数分布(log=True:深度学习中学习率的有效范围是对数级的(如 1e-4 比 0.01 更优的概率远高),对数采样能更均匀覆盖有效范围;
    • Dropout 率设为均匀分布:0.1~0.5 的范围是 MLP 的常规有效范围,均匀采样即可。
  • 简短训练:仅训练 20 轮,目的是快速评估参数效果,而非追求高精度—— 调优阶段的核心是 “筛选参数”,全量收敛训练放在后续,大幅提升调优效率;
  • 评估规范:必须用独立验证集(X_val/y_val)评估,且切换model.eval()+with torch.no_grad(),避免训练模式的 Dropout/BN 干扰验证结果,保证评估准确。

3. 启动 Optuna 超参数搜索

  • 核心参数:
    • direction:优化方向,分类任务设maximize(最大化准确率 / AUC),回归任务设minimize(最小化 MSE/RMSE);
    • n_trials:试错次数,小数据集(如泰坦尼克)设 10~20 即可,中等 / 大数据集可设 30~50,兼顾效率和效果;
  • 关键属性:
    • study.best_params:返回最优参数字典,可直接用于后续模型初始化;
    • study.best_value:返回最优参数对应的验证指标值(如准确率)。

4. 用最优参数全量训练 MLP 模型

当然,深度学习调优不仅是超参数调优,还包含模型结构、训练策略、正则化等维度,且各维度相互影响,这是和机器学习(如随机森林)调优的本质区别。Optuna的方法也不仅限于这些,条鱼的目的在于提高模型的指标和泛化能力。

Optuna运行后输出如下

经过测试,目前RF在kaggle上表现最好

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

PHP毕设项目推荐-基于php的宠物电商猫粮狗粮购物商城的设计与实现基于PHP宠物用品商城网站基于php的宠物商城网站的设计与制作【附源码+文档,调试定制服务】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/3/1 3:17:27

资讯丨ISO 14001:2026标准最终版即将生效,全条款中英文对照

ISO 14001这一全球应用最广泛的环境管理体系标准,其修订工作已迎来关键节点。最新版本ISO 14001:2026的《国际标准最终草案》(以下简称“FDIS”)现已完成,进入为期一个月的正式投票表决期,截止日期为 2026年3月2日 。…

作者头像 李华
网站建设 2026/3/1 6:21:50

SAP化工行业解决方案:以数字化赋能,破解化工企业运营痛点

化工行业作为工业经济的核心支柱,涵盖石油化工、精细化工、涂料、新能源化工等多个细分领域,其生产流程复杂、产业链绵长、合规要求严苛,同时面临着原料价格波动、安全管控难度大、供应链协同不畅、数据割裂等多重挑战。在数字化转型浪潮下&a…

作者头像 李华
网站建设 2026/3/2 1:57:42

compose 让占位图在 `AsyncImage` 中保持居中的写法

要让占位图在 AsyncImage 中保持居中,有几种方法: 1. 使用 contentAlignment 参数(最简单) AsyncImage(model imageUrl,contentDescription "Image",placeholder painterResource(R.drawable.ic_placeholder),cont…

作者头像 李华