You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在mlr3torch中动态调优神经网络的层数?

在mlr3torch中动态调优神经网络层数

要实现动态调整神经网络层数+保留每层参数独立调优的需求,核心思路是通过自定义神经网络构建函数,结合mlr3的参数依赖机制来实现。以下是具体解决方案:

核心实现思路

  1. 自定义一个神经网络构建函数,接收num_layers参数来动态生成对应数量的隐藏层。
  2. 为每个可能的层定义独立的调优参数(神经元数量、dropout比例),并通过参数依赖控制仅在层数满足条件时启用这些参数。
  3. 将自定义构建函数封装为TorchModelClassif,转换为可调优的Learner后进行超参数优化。

完整可运行代码

# 加载必要库
if (!require("pacman")) install.packages("pacman")
pacman::p_load(
  future,
  future.apply,
  magrittr,
  mlr3hyperband,
  mlr3torch,
  mlr3tuning,
  mlr3verse,
  tidyverse,
  install = TRUE
)

torch::install_torch()

# 设置随机种子
seed = 2024
set.seed(seed)

# 准备数据集
tab <- iris
colnames(tab)[which(names(tab) == "Species")] <- "target"
tab$target <- as.factor(tab$target)

# 创建分类任务
task <- TaskClassif$new(id = "iris", backend = tab, target = "target")

# 定义动态神经网络构建函数
build_dynamic_nn <- function(input_dim, num_classes, num_layers, 
                             out_features_1, out_features_2, out_features_3, out_features_4, out_features_5,
                             dropout_p_1, dropout_p_2, dropout_p_3, dropout_p_4, dropout_p_5) {
  # 收集所有层参数
  out_features_list <- c(out_features_1, out_features_2, out_features_3, out_features_4, out_features_5)
  dropout_p_list <- c(dropout_p_1, dropout_p_2, dropout_p_3, dropout_p_4, dropout_p_5)
  
  layers <- list()
  current_dim <- input_dim
  
  # 动态生成指定数量的隐藏层
  for (i in 1:num_layers) {
    layers[[length(layers)+1]] <- torch::nn_linear(current_dim, out_features_list[i])
    layers[[length(layers)+1]] <- torch::nn_dropout(dropout_p_list[i])
    layers[[length(layers)+1]] <- torch::nn_relu()
    current_dim <- out_features_list[i]
  }
  
  # 添加输出层
  layers[[length(layers)+1]] <- torch::nn_linear(current_dim, num_classes)
  
  return(torch::nn_sequential(!!!layers))
}

# 创建自定义Torch模型,包含参数依赖
custom_model <- TorchModelClassif$new(
  build = build_dynamic_nn,
  param_set = ps(
    num_layers = p_int(lower = 1, upper = 5),
    # 各层神经元数量,仅当层数达标时启用
    out_features_1 = p_int(lower = 32, upper = 512),
    out_features_2 = p_int(lower = 32, upper = 512, deps = quote(num_layers >=2)),
    out_features_3 = p_int(lower = 32, upper = 512, deps = quote(num_layers >=3)),
    out_features_4 = p_int(lower = 32, upper = 512, deps = quote(num_layers >=4)),
    out_features_5 = p_int(lower = 32, upper = 512, deps = quote(num_layers >=5)),
    # 各层dropout比例,仅当层数达标时启用
    dropout_p_1 = p_dbl(lower = 0.3, upper = 0.5),
    dropout_p_2 = p_dbl(lower = 0.3, upper = 0.5, deps = quote(num_layers >=2)),
    dropout_p_3 = p_dbl(lower = 0.3, upper = 0.5, deps = quote(num_layers >=3)),
    dropout_p_4 = p_dbl(lower = 0.3, upper = 0.5, deps = quote(num_layers >=4)),
    dropout_p_5 = p_dbl(lower = 0.3, upper = 0.5, deps = quote(num_layers >=5)),
    # 其他调优参数
    lr = p_dbl(lower = 0.001, upper = 0.01),
    epochs = p_int(lower = 100, upper = 1000, tags = "budget")
  )
)

# 转换为可训练的Learner
learner <- as_learner(custom_model)
learner$id <- "dynamic_nn_iris"
learner$predict_type <- "prob"
# 固定非调优参数
learner$param_set$values$seed <- seed
learner$param_set$values$batch_size <- 32
learner$param_set$values$device <- "cpu"
learner$param_set$values$num_threads <- 1

# 标记需要调优的参数
learner$param_set$values$num_layers <- to_tune()
learner$param_set$values$out_features_1 <- to_tune()
learner$param_set$values$out_features_2 <- to_tune()
learner$param_set$values$out_features_3 <- to_tune()
learner$param_set$values$out_features_4 <- to_tune()
learner$param_set$values$out_features_5 <- to_tune()
learner$param_set$values$dropout_p_1 <- to_tune()
learner$param_set$values$dropout_p_2 <- to_tune()
learner$param_set$values$dropout_p_3 <- to_tune()
learner$param_set$values$dropout_p_4 <- to_tune()
learner$param_set$values$dropout_p_5 <- to_tune()
learner$param_set$values$lr <- to_tune()
learner$param_set$values$epochs <- to_tune()

# 定义调优实例
terminator <- trm("evals", n_evals = 100)
resampling <- rsmp("cv", folds = 5)

instance <- ti(
  task = task, learner = learner, resampling = resampling,
  measure = msr("classif.bacc"), terminator = terminator
)

# 使用Hyperband进行超参数优化
tuner <- tnr("hyperband", eta = 3, repetitions = 1)
num_threads = 8
future::plan(multisession, workers = num_threads)
tuner$optimize(instance)

关键细节说明

  • 动态层生成:build_dynamic_nn函数根据num_layers参数循环生成对应数量的隐藏层,每层包含线性层、dropout和ReLU激活。
  • 参数依赖:通过deps参数定义各层参数的启用条件(如out_features_2仅在num_layers >=2时生效),减少无效的参数搜索空间。
  • 独立调优能力:每个层的神经元数量和dropout比例都作为独立参数,调优器会为不同层数组合搜索最优的层参数配置。

内容的提问来源于stack exchange,提问作者Livio Antonielli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 05:23:11