【发布时间】:2020-07-27 14:59:34
【问题描述】:
我已经实现了一个带有变异算子的遗传算法训练的神经网络,如下所示:
def mutation(chromosome, mutation_rate):
for gene in chromosome:
if random.uniform(0.00, 1.00) <= mutation_rate:
gene = random.uniform(-1.00, 1.00)
并且染色体最初是随机初始化的:
def make_chromosome(chromosome_length):
chromosome = []
for _ in range(chromosome_length):
chromosome.append(random.uniform(-1.00, 1.00))
return chromosome
在执行交叉时,后代染色体只能在区间[-1, 1] 内具有基因,因为父染色体也只能在该区间内具有基因。当一个后代发生突变时,它同样会将其基因保持在该区间内。
这似乎适用于某些问题,但不适用于其他问题。如果一个神经元的最优权重在[-1, 1]之内,那么遗传算法就可以工作,但是如果一个神经元的最优权重在不同的区间内呢?
例如,如果我使用反向传播训练了一个网络,其终止条件的分类误差低于 5%,我可以查看网络权重并查看 -1.49、1.98、2.01 等值。我的基因算法永远无法产生这些基因,因为基因在[-1, 1] 内初始化,交叉和突变也不能产生超出该范围的基因。
看来我需要更好地定义搜索空间,像这样:
# search space boundaries
S_MIN = -1.00
S_MAX = 1.00
# in mutation()
gene = random.uniform(S_MIN, S_MAX)
# in make_chromosome()
chromosome.append(random.uniform(S_MIN, S_MAX))
然后我可以根据问题设置搜索空间边界。但是如何确定搜索空间?此信息不是先验已知的,而是通过训练网络找到的。但是如果训练需要知道搜索空间,那我就停滞不前了。
我可以将搜索空间设置为任意大(例如,肯定比必要的大),但是算法收敛速度很慢。我至少需要知道搜索空间的大致数字才能使遗传算法有效。
通过反向传播,搜索空间是先验未知的,这并不重要,但对于 GA 来说是这样。
【问题讨论】:
-
也许你应该考虑一个不同的变异算子?一个不使用任何边界的?例如。
gene = random.gauss(mu=gene, sigma=scale)(+ 可能随着时间的推移而衰减scale)。无论如何,如果您对数据进行规范化,您可以期望权重处于同一数量级,即(-10, 10)应该足以作为界限。 -
@a_guest 你能详细说明数据规范化吗?最优网络权重与数据属性大小之间是否存在关系?
-
例如归一化为零均值和单位方差。根据您的网络架构,预计权重不会有太大差异,但也不能保证。您可以从一些边界值开始,如果您没有达到所需的精度,您仍然可以扩大边界。无论如何,神经网络通常使用基于梯度的优化器进行拟合是有原因的。
-
@a_guest 您的信息可以很好地作为答案,而不仅仅是评论。我发现在染色体平均值周围使用正态分布的突变似乎效果很好,在对数据进行归一化后更是如此。对于我尝试过的集合,网络权重几乎总是在
[-3, 3]左右结束,但对于更深的网络而言并非如此。我已经为更权威的答案添加了赏金,但我想为你的答案投票,因为它确实有帮助。 -
gator 当您开始通过损失更新采样分布的
mu和sigma时,您也正在接近bayesian neural networks的想法
标签: python machine-learning neural-network genetic-algorithm mutation