浏览器|腾讯QQ浏览器2021AI算法大赛,北大冠军团队经验分享,附详细代码( 六 )


以下代码展示了基于排名的早停方法 。 首先统计各个早停轮次下已验证配置的性能并进行排序(比赛中我们使用早停轮次为第 7 轮) , 然后判断当前配置是否处于前 1/eta(比赛中为前 1/2) , 否则执行早停:
# 基于排名的早停方法 , prune_eta=2 , prune_iters=[7]
def prune_mean_rank(self, iteration_number, running_suggestions, suggestion_history):
# 统计早停阶段上已验证配置的性能并排序
bracket = dict()
for n_iteration in self.hps['prune_iters']:
bracket[n_iteration] = list()
for suggestion in running_suggestions + suggestion_history:
n_history = len(suggestion['reward'])
for n_iteration in self.hps['prune_iters']:
if n_history >= n_iteration:
bracket[n_iteration].append(suggestion['reward'][n_iteration - 1]['value'])
for n_iteration in self.hps['prune_iters']:
bracket[n_iteration].sort(reverse=True) # maximize
# 依据当前配置性能排名 , 决定是否早停
stop_list = [False] * len(running_suggestions)
for i, suggestion in enumerate(running_suggestions):
n_history = len(suggestion['reward'])
if n_history == CONFIDENCE_N_ITERATION:
# 当前配置已完整验证 , 无需早停
print('full observation. pass', i)
continue
if n_history not in self.hps['prune_iters']:
# 当前配置不处于需要早停的阶段
print('n_history: %d not in prune_iters: %s. pass %d.'
% (n_history, self.hps['prune_iters'], i))
continue
rank = bracket[n_history].index(suggestion['reward'][-1]['value'])
total_cnt = len(bracket[n_history])
# 判断当前配置性能是否处于前1/eta , 否则早停
if rank / total_cnt >= 1 / self.hps['prune_eta']:
print('n_history: %d, rank: %d/%d, eta: 1/%s. PRUNE %d!'
% (n_history, rank, total_cnt, self.hps['prune_eta'], i))
stop_list[i] = True
else:
print('n_history: %d, rank: %d/%d, eta: 1/%s. continue %d.'
% (n_history, rank, total_cnt, self.hps['prune_eta'], i))
return stop_list

浏览器|腾讯QQ浏览器2021AI算法大赛,北大冠军团队经验分享,附详细代码
文章图片

代码以图示为准
基于置信区间的早停方法可见我们的比赛开源代码库 。
数据建模方法
对于贝叶斯优化的数据建模 , 我们尝试了多精度集成代理模型 MFES-HB[6]拟合多精度观测数据 。 该方法虽然能应对低精度噪声场景 , 但在决赛极其有限的优化时间限制内 , 可能无法快速排除噪声的干扰 , 导致效果不如仅使用最高精度数据建模 。
我们最终选择只利用最高精度数据进行建模 。 为了弥补早停造成的高精度数据损失 , 我们引入插值方法 , 增加用于模型训练的数据量 , 具体来说 , 就是对早停的配置 , 设置一个完整验证时的性能均值 , 插入优化历史执行建模 。 对于插入值的选取 , 我们使用已完整验证配置的最终均值中位数进行插值 。

推荐阅读