一元函数
对于如下图所示的一元函数求解其在区间[0,7]内的最大值有多种方式。在本文中分享的是用一种启发式算法——遗传算法来完成这项工作。
大家对遗传算法不了解的话可以戳这里看简介。
首先介绍我们的主角,也就是目标函数的形式。其定义如下:
def F(x): return np.sin(5*x)+ np.cos(4*x)
由于我们在这里要找的是函数的最大值点,那么只需直接使用其函数值的大小作为适应度函数的主体即可。同时不要忘记处理边界问题:减去输入的种群个体适应度序列中的最小值以保证最终结果为非负数,再加上一个很小的值保证适应度为正值。
def Get_Fitness(val): return val - np.min(val) + 1e-6
当然,在遗传算法运行过程中,染色体以二进制序列的形式存在。为了能将他们代入到目标函数中计算对应的函数值以及进行适应度的计算,我们还要做DNA的解码:
def Translate_DNA(pop): return pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / (2**DNA_SIZE-1) * X_BOUND[1]
根据目标DNA序列的长度(长度越长,其能表示的真实值的颗粒度也就越精细,结果越精确),将二进制的DNA序列映射到对应的函数自变量上(注意取值范围)。上面代码的基本操作就是二步:
1.将二进制转换为十进制下区间[0,1]间的数。
2.将对应十进制序列的数比照相应的取值范围来缩小或放大。
下面就是遗传算法的主体部分了,首先是自然选择、优胜劣汰的过程:
def Select(pop, fitness):
index = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,p=fitness/fitness.sum())
return pop[index]
这一步可以使用numpy库中的choice函数完成,他会根据一个概率分布来随机返回序列中的值。
适应度高的个体有更高的被选中作为下一代的父辈的可能。
其次是配对,出色的个体们在这一步进行基因重组(染色体交叉联会),在保留亲代一定特性的基础上引入了新的可能性:
def Mating (parent, pop):
if np.random.rand() < MATING_RATE:
index = np.random.randint(0, POP_SIZE, size=1)
cross_points = np.random.randint(0, 2, size=DNA_SIZE)
parent[cross_points] = pop[index, cross_points]
return parent
子代会分别得到来自父母的部分基因,最终成长为一个全新的个体。
在基因重组的过程中,子代基因也有几率发生突变:
def Mutation(child):
for point in range(DNA_SIZE):
if np.random.rand() < MUTATION_RATE:
child[point] = 1 if child[point] == 0 else 0
return child
这一步只需随机地对子代基因上的某些碱基对进行改变即可(0变1或1变0)。
效果
经过若干次的迭代,我们可以看到多数个体集中在了函数的最大值点附近。说明遗传算法确实能够帮助我们解决一元函数的优化问题。不过在测试的时候也会偶尔发生以下这种状况:
可以看到,我们算法生成的个体有往局部最大值收敛的趋势,而这并不是我们想要看到的结果。对于这类在遗传算法中,求解结果很快陷入函数的局部最优解的现象,我们把它叫做早熟现象(prematurity)。由于理论上考虑的遗传算法的选择、变异、交叉等操作过程是绝对精确的,而在实际代码实现过程中会不可避免地产生精度损失。这部分误差最终导致搜索过程逐步偏离期望路径,种群中个体的多样性过早地丧失,算法迭代陷入了局部最优值。有很多相关的文献针对早熟收敛做了研究:[1]提出了可以使部分种群个体的再初始化来防止早熟的方法;[2]使用马尔可夫链来提高GA算法的收敛质量;[3]则对染色体交叉的过程做了改进。
当我们遇到如上图形式的多元函数并需要对其求最大或最小值时(比如替代梯度下降来对神经网络中的权值进行更新优化),GA算法也同样可以派上用场。只需在上述优化一元函数的代码基础上做一些修改即可得到下图的结果:
可以看到多次迭代后的种群个体基本集中在了函数图像的最高峰。
本节代码可见这里:github
参考文献
[1] E. S. Nicoară “Mechanisms to Avoid the Premature Convergence of Genetic Algorithms." Petroleum-Gas University of Ploiesti Bulletin, Mathematics-Informatics-Physics Series 61.1 (2009).
[2] L. Ming, Y. Wang, and Y. M. Cheung, “On convergence rate of aclass of genetic algorithms”. In Automation Congress, 2006.WAC’06. World (pp. 1-6). IEEE.
[3] Aldallal A S . Avoiding Premature Convergence of Genetic Algorithm in Informational Retrieval Systems[J]. international journal of intelligent systems & applications in engineering, 2015, 2(4).