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

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

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

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

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

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

python 复制代码
# 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为例)

python 复制代码
# 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上表现最好

相关推荐
LittroInno2 小时前
TVMS视频管理平台 —— 目标识别跟踪
人工智能·计算机视觉·音视频
pusheng20252 小时前
燃料电池电化学传感器在硫化物固态电池安全监测中的技术优势解析
前端·人工智能·安全
小贺儿开发2 小时前
Unity3D 智慧城市管理平台
数据库·人工智能·unity·智慧城市·数据可视化
Niuguangshuo2 小时前
DALL-E 3:如何通过重构“文本描述“革新图像生成
人工智能·深度学习·计算机视觉·stable diffusion·重构·transformer
newbiai2 小时前
电商直播AI视频生成工具哪个方便快捷?
人工智能·python·音视频
zhangshuang-peta2 小时前
Kong MCP注册表与Peta:在人工智能系统中连接服务发现与运行时安全
人工智能·ai agent·mcp·peta
aopstudio2 小时前
OpenClaw 实测体验:Agent 框架现在到底能不能用?
人工智能·llm·agent·openclaw
沫儿笙2 小时前
机器人重工焊接节气
网络·人工智能·机器人
万悉科技2 小时前
万悉科技亮相博鳌企业论坛,引领中国品牌在AI搜索时代“被看见”
人工智能