文章目录
- 1. 直观解释
-
- 1.1 旅行问题
- 1.2 算法起源
- 1.3 算法概述
- 2. 算法原理
-
- 2.1 算法背景
- 2.2 计算过程
- 2.3 高温与低温
- 3. 算法应用
- 4. 优缺点
-
- 4.1 优点
- 4.2 缺点
- 5. 代码实现
1. 直观解释
1.1 旅行问题
要理解模拟退火(Simulated Annealing,SA),不妨设身处地思考一种情景,一位导游带着游客旅游,在A点接一群人,再去目的地B到G。去每个地方一次,需要在旅行结束时回到A点。他们的观光日程也很紧,希望你尽量缩短他们的旅行距离,以减少旅行时间。点与点之间的唯一方式是走连接的道路,在图中用线表示。应该如何优化旅行?对于较少的点来说,这似乎是一个简单的问题,但是随着添加更多的目的地和道路,复杂性迅速飙升。图2是一个完美的例子——试错法,即尝试每一条可能的路径,这可能需要花费数年的时间。选择的数量如此之多,以至于不可能在纸上解决——甚至用计算机算法来比较每一个可能的解决方案也是如此。这就是模拟退火发挥作用的地方。
模拟退火是一种用于求解全局最小值或最大值的技术,而不必检查每一个可能的解。这在解决类似前面提到的大规模优化问题时非常有用。在我们开始解释它是如何工作的之前,让我们看看这个想法是从哪里来的。
1.2 算法起源
模拟退火其实起源于冶金。在冶金中,退火是指将金属加热到高温,然后在受控环境中缓慢冷却的过程。高温使金属中的原子可以自由地四处运动。如果金属被快速冷却,当金属变热时,原子会突然静止,导致随机排列和质量差的结果。但是当金属慢慢冷却时,原子有时间逐渐找到可能的最佳方向,并排列成一个漂亮的晶格,这优于快速冷却,它使金属更具延展性,减少缺陷,并使其显著更强。一般来说,退火逐渐减少能量和运动,使物质的成分稳定在最稳定、最简单的顺序。
这个类比的另一个重要部分是热力学中的以下等式:
这个方程计算能量大小增加的概率。给定能量大小E,温度t,玻尔兹曼常数k,可以计算这个值。
鉴于此,重新考虑导游的示例,想象一下将地图上的位置随机连接成一条潜在的“最佳路线”。路线是由一系列漫无目的的匆忙连接而成的,很可能根本不是一条好路线。这类似于“快速冷却”——锁定了一些随机的选择,就像原子在金属中可能被阻止在它们的随机位置一样——这导致了一个糟糕的解决方案。然而,如果慢慢地“冷却”路线,并不断地决定用更长的道路来替换捷径,可能会逐渐减少旅行时间并找到最短的可能路径。
1.3 算法概述
谨慎的路线选择本质上是模拟退火算法的工作原理。以导游为例,首先要随机绘制出到达每个目的地的有限路径,并用总旅行时间来量化每一条路径。对于这些独一无二的路径,可以尝试类似的变化,并再次检查旅行时间。如果旅行时间减少了,就朝着正确的方向迈出了一步,更新路径!如果旅行时间增加了,怎么办?这很可能是这样一种情况,即在较长的旅行时间路径上的变化将比在现有路径上的变化更好。考虑到这一点,最初决定非常频繁地接受旅行时间较长的路线。随着尝试越来越多的路径,决定越来越不宽容那些增加旅行时间的路径。这就像金属退火中的缓慢冷却——当降低象征性的“温度”时,会变得更挑剔,并逐渐减少解决方案中的混乱情况。最终,经过一定次数的尝试后,“温度”达到了预定的最小值就不再画新的路径了。采样结束时旅行时间最短的路径就是最优路线。问题解决了!
这种重复的采样和比较工作对计算机来说是完美的。使用计算机可以让采样更多,比较更快,这增加了找到更好路线的可能性。模拟退火也不只是对旅行问题有用!它可以应用于几乎任何领域的问题,包括我们在Macromoltek所做的生物技术工作。模拟退火通常用于预测蛋白质将如何折叠(在一定的误差范围内)。有许多变量需要考虑,但是通过足够的采样和正确的参数调整,我们可以从这项技术中开发一个框架,来优化深度学习算法。
2. 算法原理
2.1 算法背景
模拟退火模拟物理退火过程,但用于优化模型中的参数。这个过程对于有很多局部极小值的情况非常有用,比如梯度下降算法。
在类似上述的问题中,如果梯度下降从指定的起点开始,它将停留在局部最小值,并且不能达到全局最小值。
2.2 计算过程
- 第一步:初始解 s=S0s = S_0s=S0?,这可以是符合可接受解标准的任何解。初始温度 t=t0t = t_0t=t0?。
- 第二步:设置降温函数 ααα。有3种主要的降温规则:
每个还原规则以不同的速率降低温度,每个方法在优化不同类型的模型方面都更好。对于第三个规则,βββ 是一个任意常数。 - 第三步:从初始温度开始,循环迭代第四步 nnn 次,然后根据 ααα 降低温度,达到终止条件时停止该循环。终止条件可以是达到某个终止温度,达到某个给定参数集的可接受的性能阈值,等等。时间到温度的映射以及温度下降的速度称为退火时间表(Annealing Schedule)。
- 第四步:给定 N(s)N(s)N(s) 个解的邻域,选择其中一个解,计算旧解和新邻域解之间的成本差异(difference in cost)。解的邻域是所有与解接近的解。例如,如果要更改五个参数中的一个,但保持其余四个不变,那么一组五个参数的邻域可能是。
- 第五步:如果新旧方案成本差异大于0(新方案更好),则接受新方案。如果成本差异小于0(旧的解决方案更好),则生成一个0和1之间的随机数,如果它低于从以前的能量大小方程计算的值,则接受它。
在“模拟退火”情况下,方程式已更改为以下形式:
其中增量 Δc\Delta cΔc 是成本的变化,ttt 是当前温度。PPP 是应该接受新解的概率。
2.3 高温与低温
由于概率的计算方式,温度越高,算法接受更差解的可能性越大。这促进了搜索空间的探索(Exploration),并允许算法更有可能沿着次优路径行进,以找到潜在地全局最大值。
当温度较低时,算法不太可能或不会接受更差的解决方案,这促进了探索(Exploration)。这意味着一旦算法在正确的搜索空间中,就不需要搜索搜索空间(search space)的其他部分,而是应该尝试收敛并找到全局最大值。
3. 算法应用
- Travelling Salesman Problem (TSP)
- Scheduling Problems
- Task Allocations
- Graph colouring and partitioning
- Non-linear function optimizations
4. 优缺点
4.1 优点
- Easy to implement and use
- Provides optimal solutions to a wide range of problems
4.2 缺点
- Can take a long time to run if the annealing schedule is very long
- There are a lot of tuneable parameters in this algorithm
5. 代码实现
""" Simulated Annealing Class """
import random
import mathclass SimulatedAnnealing:def __init__(self, initialSolution, solutionEvaluator, initialTemp, finalTemp, tempReduction, neighborOperator, iterationPerTemp=100, alpha=10, beta=5):self.solution = initialSolutionself.evaluate = solutionEvaluatorself.currTemp = initialTempself.finalTemp = finalTempself.iterationPerTemp = iterationPerTempself.alpha = alphaself.beta = betaself.neighborOperator = neighborOperatorif tempReduction == "linear":self.decrementRule = self.linearTempReductionelif tempReduction == "geometric":self.decrementRule = self.geometricTempReductionelif tempReduction == "slowDecrease":self.decrementRule = self.slowDecreaseTempReductionelse:self.decrementRule = tempReductiondef linearTempReduction(self):self.currTemp -= self.alphadef geometricTempReduction(self):self.currTemp *= (1/self.alpha)def slowDecreaseTempReduction(self):self.currTemp = self.currTemp / (1 + self.beta * self.currTemp)def isTerminationCriteriaMet(self):# can add more termination criteriareturn self.currTemp <= self.finalTemp or self.neighborOperator(self.solution) == 0def run(self):while not self.isTerminationCriteriaMet():# iterate that number of timesfor i in range(self.iterationPerTemp):# get all of the neighborsneighbors = self.neighborOperator(self.solution)# pick a random neighbornewSolution = random.choice(neighbors)# get the cost between the two solutionscost = self.evaluate(self.solution) - self.evaluate(newSolution)# if the new solution is better, accept itif cost >= 0:self.solution = newSolution# if the new solution is not better, accept it with a probability of e^(-cost/temp)else:if random.uniform(0, 1) < math.exp(-cost / self.currTemp):self.solution = newSolution# decrement the temperatureself.decrementRule()
参考:
Machine Learning and Simulated Annealing
Optimization Techniques — Simulated Annealing