Pymoo 使用 nan 参数生成候选对象

Pymoo generating candidates with nan parameters

我是 运行 使用 Pymoo (0.5.0) 使用 NSGA-III 进行的 运行 多 objective 优化,并且在我的新候选人群体中,一些生成的候选人有 nan 参数。这导致我的评估函数(这是对神经网络的调用)返回 nan。优化是 运行 并产生了预期的结果,但我想知道为什么一些候选参数是 nan。这是问题的代码。

问题设置:

opt_name = "sopt00001KaRxD60fLn2"
pop_size = 165
n_gen = 350
cross_over_pb = 0.9
mutation_pb = 0.1

# Fixed params
band ="KaRx"
arc = "RevF"
source_spec = "sweep99p1"
lens_diameter = 60.0
source_z = 5.0
r_lam = 0.1
use_original_transformation = 0  # false
source_x0 = 0.0
target_scans = [0, 70, 50]

# Optimisation param ranges
lens_material_delta_n = [1.5, 3.6]
lens_thick = [5, 35]
lens_radii_back = [39, 22500]
lens_radii_front = [39, 22500]
source_width = [2, 20]
source_x = [12, 20]

params_lower_lim = [lens_thick[0], lens_radii_front[0], lens_radii_back[0], source_width[0], source_x[0], source_x[0], 
                    lens_material_delta_n[0], -1, -1, -1, 0, -1, -1, -1, 0]
params_upper_lim = [lens_thick[1], lens_radii_front[1], lens_radii_back[1], source_width[1], source_x[1], source_x[1],
                    lens_material_delta_n[1], 1, 1, 1, 1, -1, -1, -1, 1]

n_var = len(params_lower_lim)
assert n_var == len(params_upper_lim), print("Upper and lower parameter limits are not equal length!")

# Other required params
if band == "KaRx":
    freq_center = 19.45
    freq_width = 3.5

计算函数:

class ProblemWrapper(Problem):
    
    def _evaluate(self, params, out, *args, **kwargs):
        res = []
        for param in params:
            source_x70 = source_x_f(param[4], param[5], source_x, 50, r_lam, target_scans, freq_center, freq_width)
            source_x50 = source_x_f(param[4], param[5], source_x, 70, r_lam, target_scans, freq_center, freq_width)
            res.append(smeep(band, 
                             lens_diameter, param[0], 
                             param[1], param[2], 
                             param[3], 
                             source_x0, source_x70, source_x50, 
                             source_z, 
                             param[6], param[7], param[8], param[9], param[10], param[11], param[12], param[13], param[14], 
                             r_lam, use_original_transformation, 
                             arc, 
                             source_spec,
                             target_scans))
        
        out['F'] = np.array(res)

算法设置:

ref_dirs = get_reference_directions("das-dennis", 3, n_partitions=12)
problem = ProblemWrapper(n_var=n_var, 
                         n_obj=len(target_scans), 
                         xl=params_lower_lim, 
                         xu=params_upper_lim)

algorithm = NSGA3(
    pop_size=pop_size, 
    ref_dirs=ref_dirs,
    sampling=get_sampling("real_random"),
    cross_over=get_crossover("real_sbx", prob=cross_over_pb),
    mutation=get_mutation("real_pm", prob=mutation_pb)
)

执行:

res = minimize(problem=problem,
               algorithm=algorithm,
               termination=("n_gen", n_gen),
               save_history=True,
               verbose=True
)

看起来唯一受影响的参数是 poly6 (param[11])、poly7 (param[12]) 和 poly8 (param[13]) 项。它因候选人而异。我承认我没有尝试过任何不同的交叉或突变方案,但这些似乎是文档中最好的。

提前致谢!

出现 nan 是因为参数 11、12 和 12 的限制相等(在所有情况下均为 -1 和 -1)。

如果您查看多项式变异 (real_pm) 的代码,您会看到以下几行:

delta1 = (X - xl) / (xu - xl)
delta2 = (xu - X) / (xu - xl)

其中 xuxl 是参数的上限和下限。在您的情况下,这将导致除以 0。

由于限制相同(如果这是正确的),它们实际上不是优化的一部分,您应该将它们从列表中删除。