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

求助:用Julia Evolutionary.jl实现差分进化优化MLP遇阻

问题:使用Evolutionary.jl通过差分进化(DE)进化MLP种群失败

问题背景

本人是Julia新手,指定差分进化(DE)算法及多层感知器(MLP)初始种群后,尝试用DE进化MLP种群,但使用Evolutionary.jl包时持续失败。未找到Julia中DE进化MLP的相关示例,不清楚代码复用方式,请求技术帮助。

现有代码

1. 加载数据集

begin
    features = Iris.features();
    slabels = Iris.labels();
    classes = unique(slabels)  # 数据集中的唯一类别
    nclasses = length(classes) # 类别数量
    d, n = size(features)      # 数据集维度与样本量
end

2. 定义MLP模型

model = Chain(Dense(d, 15, relu), Dense(15, nclasses))

3. 重写initial_population生成MLP种群

begin
    import Evolutionary.initial_population
    function initial_population(method::M, individual::Chain;
                            rng::Random.AbstractRNG=Random.default_rng(),
                            kwargs...) where {M<:Evolutionary.AbstractOptimizer}
     θ, re = Flux.destructure(individual);
        [re(randn(rng, length(θ))) for i in 1:Evolutionary.population_size(method)]
    end
end

4. 定义DE算法参数

algo2 = DE(
        populationSize=150,
        F=0.9,
        n=1,
        K=0.5*(1.9),
        selection = rouletteinv
        
    )
popu = initial_population(algo2, model)

5. optimize()函数调用问题

尝试多种optimize()调用方式均报错,不确定是否必须传入约束条件,也不清楚BoxConstraints上下界设置方法,用Nonconstraint也失败,示例代码如下:

cnst = BoxConstraints([0.5, 0.5], [2.0, 2.0])
res2 = Evolutionary.optimize(fitness,cnst,algo2,popu,opts)

已实现的辅助函数

交叉操作函数uniform_mlp

用于将MLP解构为向量、执行交叉后重构为新MLP:

function uniform_mlp(m1::T, m2::T; rng::Random.AbstractRNG=Random.default_rng()) where {T <: Chain}
    θ1, re1 = Flux.destructure(m1);
    θ2, re2 = Flux.destructure(m2);
    c1, c2 = UX(θ1,θ2; rng=rng)
    return re1(c1), re2(c2)
end

变异操作函数gaussian_mlp

function gaussian_mlp(σ::Real = 1.0)
    vop = gaussian(σ)
    function mutation(recombinant::T; rng::Random.AbstractRNG=Random.default_rng()) where{T <: Chain}  
            θ, re = Flux.destructure(recombinant)
        return re(convert(Vector{Float32}, vop(θ; rng=rng)))
    end
    return mutation
end

核心问题点

  • 不清楚Evolutionary.optimize()的正确调用方式,是否必须传入约束条件?
  • 若需约束,BoxConstraints的上下界应如何匹配MLP参数维度?
  • 如何让DE算法正确适配MLP个体的交叉、变异操作?

解决思路

  1. 约束条件的正确设置

    • 若无约束需求,直接使用Evolutionary.NoConstraints()而非错误的Nonconstraint。
    • 若使用BoxConstraints,上下界向量长度必须与MLP解构后的参数向量长度一致。可通过length(Flux.destructure(model)[1])获取参数总数,再生成对应长度的上下界数组(例如统一设为-10到10)。
  2. 适配DE算法的个体操作

    • Evolutionary.jl的DE算法默认针对数值向量,而你使用的是Chain类型个体,需重写DE的变异、交叉操作适配MLP:
      # 重写变异方法
      import Evolutionary.mutate!
      function Evolutionary.mutate!(method::DE, target::Chain, pop::Vector{Chain}, rng::Random.AbstractRNG)
          mutate_op = gaussian_mlp(0.5)
          return mutate_op(target)
      end
      
      # 重写交叉方法
      import Evolutionary.crossover!
      function Evolutionary.crossover!(method::DE, target::Chain, mutant::Chain, rng::Random.AbstractRNG)
          child, _ = uniform_mlp(target, mutant; rng=rng)
          return child
      end
      
  3. optimize()的正确调用

    • 正确调用格式示例:
      opts = Evolutionary.Options(iterations=100, show_trace=true)
      res2 = Evolutionary.optimize(fitness, Evolutionary.NoConstraints(), algo2, popu, opts)
      
    • 注意fitness函数必须接受Chain类型参数,返回标量适应度值(如分类误差的倒数或负误差)。
  4. 参数类型一致性检查

    • 变异函数中把参数转为Float32,但初始种群由randn生成Float64类型,建议统一类型(比如初始种群用randn(Float32, ...)),避免类型不稳定导致的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:10:27