十分不依赖数学的求极值算法——模拟退火(simulated annealing)算法

最近被问到一个问题,是关于线性拟合的。但是不巧,我忘记了最小二乘法的公式表达,虽然这是一个很简单的求导再解一次方程,但在手头没有草稿纸的情况下,我还是口算不出来的。在忘记了数学的情况下,总还是有办法去求极值的,比如用梯度下降法去找误差函数
err=\sum_i(y_i-\hat{y}_i)^2
其中\hat{y}_i=f(\boldsymbol{a}; x_i)为待拟合的函数,包含m个参数a_1,a_2,\cdots a_m。对于线性拟合,\hat{y_i}=k\cdot x_i+b,对于更一般的情况,f的形式更复杂。我们可以预计,对于任意一组\boldsymbol{a},只要\boldsymbol{a}还没有满足最佳拟合,误差err就还不是最小的。因此拟合的本质就是求取一组\boldsymbol{a}使得误差函数最小。求函数的最小值可以通过求一阶导与二阶导数得到,但是这个方法可以更加无脑一些。比如我们看一个简单的函数图像

1.jpg

从任意一点x_0出发(例如图示x_0=4.5),寻找最小值。模拟退火的方法出发点在于,x_0可以在原有的基础上进行一个随机涨落,例如x_0=x_0+\Delta x,其中|\Delta x|=0.1。显然从图中可以看出,\Delta x=0.1时,函数值增大,但\Delta x=-0.1时函数值减小。对于这一次涨落,为了最小化函数值,我们接受\Delta x=-0.1,现在x_1=4.4。为了保证x最后能够走到极小值,步长\Delta x也应该是不断变化的。我们期望当x越接近最小值点x_n,步长\Delta x就越短,下面将引入【退火】的核心,也就是一个控制步长(以及方向,后面会提到)的函数。这个函数是时间依赖的,在循环刚开始运行时,它所控制的步长应该较长,而循环运行得比较久时,步长就应该稍短。一个简单的思路是令T(t)=\frac{1}{t+1}。那么模拟退火算法的伪代码可以写成:

# 对于n维情况
steps = 0
temperature(s) = 1/(s+1)
a = {a1, a2, a3, ..., an}

while temperature(s) >= T_min
    delta_a = temperature(steps) * (2*rand(n)-1)    # n维数组
    if f(a + delta_a) <= f(a)
        a = a + delta_a
    end
    steps ++
end

print(a)

我们会发现,模拟退火算法实际上完全是一个物理过程:T(t)是一个随着时间不断下降的量,在T比较大的时候,涨落\Delta x可以更大,而当T比较小的时候,\Delta x变得更小。这实际上就是【退火】名字的由来,就相当于对一个铁块降温,随着温度不断降低,铁块内部的原子排列分布也慢慢变得有规律起来。

模拟退火的思路其实和梯度下降有一点点类似,都是从一个初始值出发,不断向使得函数值减小的地方移动。它相比梯度下降更大的优点是,模拟退火在编程方面是异常简单的,完全不依赖于传统找极值的一切数学。编写一个模拟退火求极值的程序所花费的时间也是极短的。对于n个变量的模拟退火,在每轮迭代中平均需要2^n次才能找到正确的方向,而不像梯度下降那样一次就能找到,另外模拟退火的步长也可能会过短,这是它相比梯度下降的劣势。但避免数值导数这一优势是巨大的。当然,梯度下降的传统老大难问题对于上面的算法,也是同样老大难问题,比如我们把上面的函数y=-x^2\sin(x)多画一段区间

image.png

如果继续使用上面那个单调变换的算法,同样从x_0=4.5出发,最后找到的极小值点一定是局域的最小值,也就是大概在2附近的那个值。严格意义上,前面的算法还不是模拟退火的完全体,我们其实可以从物理的角度讲,如果这个函数曲线表示一个势能,例如,把这个函数曲线作为一个真正的过山车轨道0。在温度较高的时候,待拟合的数量(就像过山车)有更高的能量,或者速度,那么它很有可能有能力越过6附近的那一个峰,进入函数值更小的局域最小值。回到之前的伪代码,这意味着我们要对a = a + delta_a的判断条件进行修改

   if (f(a + delta_a) <= f(a)) or (f(a + delta_a) >= f(a) and mean(delta_a)<temperature(steps))
   # 用delta_a的平均数与温度相比
        a = a + delta_a
   end

修改后的算法允许a向使得函数值增大的地方移动,但是移动的步长取决于温度。在程序运行初期,温度较高,可以接受的反向运动步长更长;而在运行的后期,我们就不那么能接受反向运动了。这表明的模拟退火一个独特的思想:为了变得更好,可以先变得更差。通过这个方法就可以尽量回避落入局域最小值的问题。

另外一个重要的优化是,变得更差会不会一失足成千古恨?可以加入的一点是,在执行反方向运行的时候,记录当前a的值,一段时间以后再与原来的a进行对比,如果还是没有原来的a好,就换回原来的a。这实际上就像手残党玩游戏用SL大法。将这一判断加入其中,就可以避免随机涨落走到了太过离谱的地方。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容