Skip to content

Commit

Permalink
update pytest
Browse files Browse the repository at this point in the history
  • Loading branch information
Xbc-gressor committed Sep 27, 2024
1 parent 17e8124 commit 6d83933
Show file tree
Hide file tree
Showing 27 changed files with 839 additions and 90 deletions.
2 changes: 1 addition & 1 deletion openbox/core/ea/adaptive_ea_advisor.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def __init__(self,
self.last_observations = []

def get_suggestion(self):
if not self.last_suggestions:
while not self.last_suggestions:
self.update_observations(self.last_observations)
self.last_observations = []
self.last_suggestions = self.get_suggestions()
Expand Down
17 changes: 16 additions & 1 deletion test/acq_optimizer/test_random_configuration_chooser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,41 @@ def test_no_cool_down_chooser_returns_expected_result(self):
self.assertTrue(chooser.check(2))
self.assertFalse(chooser.check(3))

chooser2 = ChooserNoCoolDown(1.0)
self.assertTrue(chooser2.modulus == 1.0)

def test_linear_cool_down_chooser_returns_expected_result(self):
chooser = ChooserLinearCoolDown(2.0, 0.3, np.inf)
self.assertTrue(chooser.check(2))
self.assertFalse(chooser.check(3))

chooser.next_smbo_iteration()
self.assertTrue(chooser.check(3))

def test_prob_chooser_returns_expected_result(self):
chooser = ChooserProb(0.5, self.rng)
self.assertTrue(chooser.check(1))
self.assertFalse(chooser.check(2))

def test_prob_cool_down_chooser_returns_expected_result(self):
chooser = ChooserProbCoolDown(0.5, 0.1, self.rng)
chooser = ChooserProbCoolDown(0.5, 2, self.rng)
self.assertTrue(chooser.check(1))
self.assertFalse(chooser.check(2))

chooser.next_smbo_iteration()
self.assertTrue(chooser.check(3))

def test_cosine_annealing_chooser_returns_expected_result(self):
chooser = ChooserCosineAnnealing(0.5, 0.1, 2, self.rng)
self.assertTrue(chooser.check(1))
self.assertFalse(chooser.check(2))

chooser.next_smbo_iteration()
self.assertTrue(chooser.iteration == 1)
chooser.next_smbo_iteration()
chooser.next_smbo_iteration()
self.assertTrue(chooser.iteration == 0)


if __name__ == '__main__':
unittest.main()
115 changes: 112 additions & 3 deletions test/acquisition_function/test_acquisition.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@
LCB,
Uncertainty,
)

'''
加入其他函数的测试
'''
from openbox.acquisition_function.multi_objective_acquisition import (
MaxvalueEntropySearch,
MESMO,
MESMOC,
MESMOC2,
)
class ConfigurationMock:
def __init__(self, values=None):
self.values = values
Expand All @@ -22,6 +30,13 @@ def get_array(self):
return np.array(self.values, dtype=np.float64)

class MockModel:
'''
其实axis的重点在于方向,而不是行和列。具体到各种用法而言也是如此。
当axis=1时,如果是求平均,那么是从左到右横向求平均;如果是拼接,那么也是左右横向拼接;如果是drop,那么也是横向发生变化,体现为列的减少。
mean_col_vector = np.mean(X, axis=1).reshape(-1, 1)
return mean_col_vector, mean_col_vector
这里代码重复了?
'''
def predict_marginalized_over_instances(self, X):
return np.array([np.mean(X, axis=1).reshape((1, -1))]).reshape((-1, 1)), np.array(
[np.mean(X, axis=1).reshape((1, -1))]
Expand All @@ -45,11 +60,30 @@ def __init__(self, num_targets=1):
self.num_targets = num_targets

def predict_marginalized_over_instances(self, X):
'''
这个乘法真的没有问题?不是引用?
np.full(X.shape[0], 0.0):创建一个与 X 的行数相同的全 0 数组。
>>> b=[a]
>>> b
[array([1, 2])]
>>> b*2
[array([1, 2]), array([1, 2])]
>>> c=b*2
>>> c
[array([1, 2]), array([1, 2])]
>>> c[0][0]=2
>>> c
[array([2, 2]), array([2, 2])]
>>>
'''
return np.array([np.mean(X, axis=1).reshape((1, -1))] * self.num_targets).reshape((-1, 2)), np.array(
[np.full(X.shape[0], 0.0).reshape((1, -1))] * self.num_targets
).reshape((-1, 2))

class MockConstraintModel:
'''
np.full(m.shape, 0.1):创建一个与 m 形状相同的数组,数组中的每个元素都为 0.1
'''
def predict_marginalized_over_instances(self, X):
m = -np.abs(np.mean(X, axis=1)).reshape((-1, 1))
v = np.full(m.shape, 0.1)
Expand All @@ -60,6 +94,7 @@ def predict_marginalized_over_instances(self, X):
return np.full(X.shape[0], np.nan).reshape((-1, 1)), np.full(X.shape[0], np.nan).reshape((-1, 1))

class MockModelWrongVShape:
#错的v shape?
def predict_marginalized_over_instances(self, X):
m = np.mean(X, axis=1).reshape((-1, 2))
v = np.var(X, axis=1).reshape((-1, 1))
Expand Down Expand Up @@ -150,6 +185,12 @@ def test_ei_eta_fail(model, acquisition_function):
ei.update(model=model)
configurations = [ConfigurationMock([1.0])]
with pytest.raises(ValueError):
'''
1. with pytest.raises(ValueError):
pytest.raises 是 pytest 提供的一个上下文管理器,用于检查某段代码是否抛出特定类型的异常。
ValueError 是期望的异常类型。
这段代码的含义是:在 with 语句的块内,pytest 期望执行的代码会引发 ValueError。如果代码没有抛出 ValueError,测试将会失败。
'''
ei(configurations)

def test_ei_1x1(model, acquisition_function):
Expand Down Expand Up @@ -426,7 +467,7 @@ def test_pi_1xD(model, acq_pi):
def test_pi_NxD(model, acq_pi):
pi = acq_pi
pi.update(model=model, eta=1.0)
configurations = [
configurations = [
ConfigurationMock([0.0001, 0.0001, 0.0001]),
ConfigurationMock([0.1, 0.1, 0.1]),
ConfigurationMock([1.0, 1.0, 1.0]),
Expand Down Expand Up @@ -549,4 +590,72 @@ def test_uncertainty_with_nan(model_with_nan, acq_uncer):
configurations = [ConfigurationMock([0.5])]
acq = uncertainty(configurations)

assert np.all(acq == 0)
assert np.all(acq == 0)




'''
import numpy as np
# 创建一个形状为 (2, 3, 4) 的三维数组
data = np.array([
[[1, 2, 3, 4], # 实验 1
[5, 6, 7, 8],
[9, 10, 11, 12]],
[[13, 14, 15, 16], # 实验 2
[17, 18, 19, 20],
[21, 22, 23, 24]]
])
print("原始数组:")
print(data)
mean_axis_0 = np.mean(data, axis=0)
print("沿 axis=0 计算的均值:")
print(mean_axis_0)
# 输出:
# [[ 7. 8. 9. 10.]
# [11. 12. 13. 14.]
# [15. 16. 17. 18.]]
mean_axis_1 = np.mean(data, axis=1)
print("沿 axis=1 计算的均值:")
print(mean_axis_1)
# 输出:
# [[ 5. 6. 7. 8.]
# [19. 20. 21. 22.]]
mean_axis_neg1 = np.mean(data, axis=-1)
print("沿 axis=-1 计算的均值:")
print(mean_axis_neg1)
# 输出:
# [[ 2.5 6.5 10.5]
# [14.5 18.5 22.5]]
总结
'''

'''
使用 np.expand_dims
当我们调用:
expanded = np.expand_dims(self.cell_lower_bounds, axis=(1, 2))
axis=(1, 2) 指定在第 1 和第 2 维的位置插入新维度。
变化步骤
第一次扩展 (axis=1):
原始数组形状为 (m,),在第 1 维插入一个新维度后,形状变为 (1, m):
python
复制代码
[[1, 2, 3]] # 形状为 (1, 3)
第二次扩展 (axis=2):
在新数组的第 2 维插入新维度,形状变为 (1, m, 1):
python
复制代码
[[[1],
[2],
[3]]] # 形状为 (1, 3, 1)
总结
因此,经过两次扩展后,self.cell_lower_bounds 的形状最终变为 (1, m, 1),表示有一个批次(第一维为 1),m 个目标(第二维为 m),
以及每个目标的单个值(第三维为 1)。这种形状使得该数组可以与其他三维数组(如 Y_samples)进行有效的广播和运算。
'''
28 changes: 23 additions & 5 deletions test/core/ea/test_adaptive_ea_advisor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@

def test_adaptive_ea_advisor(configspace_tiny):
config_space = configspace_tiny
advisor = AdaptiveEAAdvisor(config_space, population_size=4, subset_size=2, num_objectives=2, pc=1, pm=1)
advisor = AdaptiveEAAdvisor(config_space, population_size=8, subset_size=2, num_objectives=2, pc=1, pm=1)
#换一个oldest策略再来一次?
'''
目前看来这个只支持单目标优化,这里的多目标似乎是假的
'''
advisor_oldest = AdaptiveEAAdvisor(config_space, strategy='oldest', population_size=8, subset_size=2, num_objectives=2, pc=1, pm=1)
assert advisor.config_space == config_space
assert advisor.subset_size == 2
assert advisor.epsilon == 0.2
Expand All @@ -20,13 +25,23 @@ def test_adaptive_ea_advisor(configspace_tiny):
assert advisor.k4 == 0.3
assert advisor.last_suggestions == []
assert advisor.last_observations == []

perfs = [[2, 1], [1, 2], [2, 2], [1, 1], [1, 2]]
for i in range(4):
'''
多assert
'''
perfs = [[2, 1], [1, 2], [2, 2], [1, 1], [1, 2], [1, 1], [1, 1], [1, 1], [1, 1], [2, 3], [4, 5], [6, 7], [3, 6]]
#修改为10次 ref_point多给点
for i in range(13):
suggestion1 = advisor.get_suggestion()
assert isinstance(suggestion1, Configuration)
observation1 = Observation(suggestion1, perfs[i], trial_state=SUCCESS, elapsed_time=2.0, extra_info={})
advisor.update_observation(observation1)
'''
oldest strategy
'''
suggestion1 = advisor_oldest.get_suggestion()
assert isinstance(suggestion1, Configuration)
observation1 = Observation(suggestion1, perfs[i], trial_state=SUCCESS, elapsed_time=2.0, extra_info={})
advisor_oldest.update_observation(observation1)

config_a = config_space.sample_configuration()
config_b = config_space.sample_configuration()
Expand All @@ -35,4 +50,7 @@ def test_adaptive_ea_advisor(configspace_tiny):

config = config_space.sample_configuration()
next_config = advisor.mutation(config)
assert isinstance(next_config, Configuration)
## 测试None
# config = None
# next_config = advisor.mutation(config)
# assert isinstance(next_config, Configuration)
35 changes: 31 additions & 4 deletions test/core/ea/test_differential_ea_advisor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,19 @@
from openbox.utils.constants import MAXINT, SUCCESS


def test_cmaes_ea_advisor_initialization(configspace_tiny):
def test_cmaes_ea_advisor_initialization(configspace_tiny, configspace_cat):
config_space = configspace_tiny
advisor = DifferentialEAAdvisor(config_space, num_objectives=2, population_size=4)
config_cat = configspace_cat
#添加变化的f以及cr

'''
在单目标优化中,允许使用动态的 f 和 cr 来提升算法的表现。
在多目标优化中,为了保持多个目标的平衡,限制动态调整 f 和 cr,因此在这种情况下需要固定这些参数。
断言的目的是避免算法在不合适的情况下使用动态参数,确保差分进化算法在不同优化问题上的一致性和正确性。
'''
advisor_vary = DifferentialEAAdvisor(config_space, f=(0,1), cr=(0,1), num_objectives=1, population_size=4)
advisor_cat = DifferentialEAAdvisor(config_cat, num_objectives=1, population_size=4)
assert advisor.config_space == config_space
assert advisor.num_objectives == 2
assert advisor.num_constraints == 0
Expand All @@ -24,13 +34,23 @@ def test_cmaes_ea_advisor_initialization(configspace_tiny):
assert advisor.filter_gen_population is None
assert advisor.keep_unexpected_population is True
assert advisor.save_cached_configuration is True

perfs = [[2, 1], [1, 2], [2, 2], [1, 1], [1, 2]]
for i in range(5):
perfs = [[2, 1], [1, 2], [2, 2], [1, 1], [1, 2], [1, 1], [1, 1], [-1, 1]]
for i in range(8):
suggestion1 = advisor.get_suggestion()
assert isinstance(suggestion1, Configuration)
observation1 = Observation(suggestion1, perfs[i], trial_state=SUCCESS, elapsed_time=2.0, extra_info={})
#这个update内有next_population的更新,会把suggestion1也就是gen的config加入sub,让sel能使用sub
advisor.update_observation(observation1)

suggestion2 = advisor_vary.get_suggestion()
assert isinstance(suggestion2, Configuration)
observation2 = Observation(suggestion2, [perfs[i][0]], trial_state=SUCCESS, elapsed_time=2.0, extra_info={})
advisor_vary.update_observation(observation2)

# suggestion3 = advisor_cat.get_suggestion()
# assert isinstance(suggestion3, Configuration)
# observation3 = Observation(suggestion3, [1], trial_state=SUCCESS, elapsed_time=2.0, extra_info={})
# advisor_cat.update_observation(observation3)

config_a = config_space.sample_configuration()
config_b = config_space.sample_configuration()
Expand All @@ -40,3 +60,10 @@ def test_cmaes_ea_advisor_initialization(configspace_tiny):

config = advisor.cross_over(config_a, config_b, 0.5)
assert isinstance(config, Configuration)


config_a = config_cat.sample_configuration()
config_b = config_cat.sample_configuration()
config_c = config_cat.sample_configuration()
config = advisor_cat.mutate(config_a, config_b, config_c, 0.5)
#这里的prefs对应ref_point吧?传到Observation中对应objectives属性
18 changes: 16 additions & 2 deletions test/core/ea/test_nsga2_ea_advisor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from openbox.utils.constants import MAXINT, SUCCESS


def test_nsga2_ea_advisor_initialization(configspace_tiny):
def test_nsga2_ea_advisor_initialization(configspace_tiny, configspace_huge):
config_space = configspace_tiny
advisor = NSGA2EAdvisor(config_space, num_objectives=2, subset_size=2, population_size=4)
assert advisor.config_space == config_space
Expand All @@ -25,4 +25,18 @@ def test_nsga2_ea_advisor_initialization(configspace_tiny):
suggestion1 = advisor.get_suggestion()
assert isinstance(suggestion1, Configuration)
observation1 = Observation(suggestion1, perfs[i], trial_state=SUCCESS, elapsed_time=2.0, extra_info={})
advisor.update_observation(observation1)
advisor.update_observation(observation1)

obs = list()
for i in range(5):
configs = advisor.get_suggestions()
for config in configs:
obs.append(Observation(config, perfs[i], trial_state=SUCCESS, elapsed_time=2.0, extra_info={}))
advisor.update_observations(obs)


#test cross_over
advisor_2 = NSGA2EAdvisor(config_space=configspace_huge)
for i in range(5):
config = advisor_2.cross_over(configspace_huge.sample_configuration(), configspace_huge.sample_configuration())
assert config.configuration_space == configspace_huge
Loading

0 comments on commit 6d83933

Please sign in to comment.