0. 关于sci-opt
- 一个比较好的模拟退火教程https://www.cnblogs.com/autoloop/p/15169642.html
- 本文讲解参数使用官方用例:https://github.com/guofei9987/scikit-opt#4-sasimulated-annealing
1. sci-opt的SA算法使用
- 代价函数/ loss function,在这里是
demo_func = lambda x: x[0] ** 2 + (x[1] - 0.05) ** 2 + x[2] ** 2
- 要用SA优化/ 寻找的值是
x[0],x[1],x[2]
。 - 换句话说,它的物理意义是在三维空间中,用SA去寻找一个点,这个点要距离(0,0.05,0)最近。
- 使用SA时可以看到(省掉了
import
代码)
# 先实例化一个sa
sa = SA(func=demo_func, x0=[1, 1, 1], T_max=1, T_min=1e-9, L=300, max_stay_counter=150)
func=demo_func
表示目标函数传入,这里注意目标函数的正负,来达到“目标函数越小越好”的效果。如果目标函数是log likelihood,注意加负号变成NLLx0=[1, 1, 1]
表示初始值,因为要对3个参数x[0],x[1],x[2]
进行寻优,所以这里传的是3个数。- 从sa的执行细节可以看到寻优所经历的历史,如下,
x
确实是从[1,1,1]
开始的,并且经历了58次寻找,在最后一次找到了最优值
T_max=1, T_min=1e-9
,前者的定义是“最大温度", 这个参数实际上也是“初始温度”。这两个参数的官方默认值分别是100
和1e-7
。因此设置一个好的T_max
还是很有必要的
self.T_max = T_max # initial temperature
self.T = self.T_max
L=300
:默认值就是300
,表示“链长”:num of iteration under every temperature(also called Long of Chain),每个温度下最多允许寻找L次,可以设置为1
试试看,减少每个温度下的试探次数会大大影响结果(goes bad)max_stay_counter=150
:默认值150,表示“冷却耗时”:stop if best_y stay unchanged over max_stay_counter times (also called cooldown time),这个参数和上一个L
紧密相关,当算法在当前温度下保持不变持续了150次时,认为算法结束,找到了最优的参数x or 最低的温度y。
# run()之后返回答案
best_x, best_y = sa.run()
print('best_x:', best_x, 'best_y', best_y)
# print结果:
# best_x: [-0.08368016 -0.12619251 0.39975074] best_y 0.19784682316511348
- 可以看到实例化sa后进行run,会进行调优,然后静静收割结果就可以。之前讲过最好寻优结果下,坐标点应该无限接近于
(0,0.05,0)
,可以看到best_x
的确如此,此时对应的温度/demo_func
的值为best_y
- 具体的,sa这个实例化的对象(?这个说法正确吗)具有一些其他的优秀信息
plt.plot(pd.DataFrame(sa.best_y_history).cummin(axis=0))
plt.show()
- 最后画图,官方用的
sa.best_y_history
,我疑惑和sa.generation_best_Y
有什么区别。因为官方demo给的例子很简单,这两个list比较一下会发现完全相同,而且寻优过程很快就收敛了,等日后用复杂的优化过程时,应该就能看出来了。
时间仓促,上述如果有哪里出错的欢迎大家留言。