一种通用的蟒蛇遗传算法
naturalselection的Python项目详细描述
自然选择
一种通用的蟒蛇遗传算法,它还内置了对神经网络的超参数调整支持。
安装
$ pip install naturalselection
用法
下面是一个玩具示例,它针对除法优化了一对数字。
>>>importnaturalselectionasns>>>>>>Pair=ns.Genus(x=range(1,10000),y=range(1,10000))>>>defdivision(number):...returnnumber.x/number.y...>>>pairs=ns.Population(genus=Pair,size=100,fitness_fn=division)>>>history=pairs.evolve(generations=50,progress_bars=1)Evolvingpopulation:100%|█████████████████████|50/50[00:09<00:00,5.28it/s]>>>>>>history.fittest{'genome':{'x':9974,'y':4},'fitness':2493.5}>>>>>>history.plot()
我们还可以很容易地解决经典的onemax问题,即找到所有1的给定长度的位字符串。这里我们在evolve
函数中设置goal=100如果我们在我们设定的最大世代数10000之前达到目标,就停止。请注意,这只需要一分钟,尽管完成进化所需的世代要少得多,但较大的种群似乎需要更长的时间。
>>>importnaturalselectionasns>>>>>># Length of the bit strings>>>N=100>>>BitString=ns.Genus(**{f'x{n}':(0,1)forninrange(N)})>>>>>>defsum_bits(bitstring):...returnsum(bitstring.get_genome().values())>>>>>>bitstrings=ns.Population(...genus=BitString,...size=2,...fitness_fn=sum_bits...)>>>>>>history=bitstrings.evolve(...generations=10000,...goal=100,...progress_bars=1...)Evolvingpopulation:45%|████████|4480/10000[01:00<01:58,46.43it/s]>>>>>>history.plot()
最后,这里是一个寻找一个完全连接的前馈神经网络来建模mnist的例子。请注意,这需要每个CPU核心大约1GB的可用内存(通常是4)。如果没有此功能,请将evolve
调用中的workers
参数设置为2或3左右,或将多处理设置为false
以完全关闭并行性。
如果你是gpu的幸运拥有者,那么你也需要设置多处理=false
(并将max廑u training廑time
设置为较小的值,和/或将max廑pochs
设置为较小的值)。
>>>importnaturalselectionasns>>>>>># MNIST packages>>>fromtensorflow.keras.utilsimportto_categorical>>>importmnist>>>>>># Standard train and test sets for MNIST>>>X_train=((mnist.train_images()/255)-0.5).reshape((-1,784))>>>Y_train=to_categorical(mnist.train_labels())>>>X_val=((mnist.test_images()/255)-0.5).reshape((-1,784))>>>Y_val=to_categorical(mnist.test_labels())>>>>>>fnns=ns.FNNs(>>>size=50,>>>train_val_sets=(X_train,Y_train,X_val,Y_val),>>>loss_fn='binary_crossentropy',>>>score='accuracy',>>>output_activation='softmax',>>>max_training_time=60>>>)>>>>>>history=fnns.evolve(generations=20)Evolvingpopulation:100%|██████████████████|20/20[4:28:35<00:00,776.70s/it]Computingfitnessforgen19:100%|████████████|46/46[13:22<00:00,17.44s/it]>>>>>>history.fittest{'genome':{'optimizer':'adam','hidden_activation':'elu','batch_size':128,'initializer':'glorot_uniform','input_dropout':0.1,'neurons0':128,'dropout0':0.0,'neurons1':64,'dropout1':0.0,'neurons2':1024,dropout2': 0.1, 'neurons3': 32, 'dropout3': 0.4,'neurons4':256,'dropout4':0.1},'fitness':0.973}>>>>>>history.plot(...title="Validation accuracy by generation",...ylabel="Validation accuracy"...)
>>># Training the best model and saving it to mnist_model.h5>>>best_score=fnns.train_best(file_name='mnist_model')Epoch:0-loss:0.277,val_loss:0.179:100%|██████████|60000/60000[00:31<00:00,244.79it/s](...)>>>best_score0.9793
算法细节
该算法遵循遗传算法的标准蓝图,如在维基百科页面上所述,大致如下:
- 构造初始总体
- 计算种群中所有生物体的适应度值
- 选择一部分人群(精英人才库)。
- 选择一个种群子集(繁殖池)。
- 从繁殖池中选出一对,它们将繁殖出一种新的"子"有机体,其基因组由"父"有机体组合而成。继续繁殖,直到孩子和精英组成与原始种群大小相同的种群
- 突变库中的每个孩子都发生了突变,这意味着他们的基因组将以某种方式发生改变
- 返回步骤2
现在,我们将更详细地描述这个特定实现中的各个步骤。请注意,第3步有时会被完全忽略,但由于这只是对应于一个空的精英人才库,所以我决定保留它,以供一般使用。
第一步:构建初始种群
种群是由属决定的可能基因组值的均匀随机样本,当创建新的种群
对象时运行。或者,您可以将初始的基因组设置为您想要的任何基因组,这将使一个完全同质的群体仅由该基因组的有机体组成(突变将在每一代中产生一些多样性)。
>>>pairs=ns.Population(...genus=Pair,...size=100,...fitness_fn=division,...initial_genome={'x':9750,'y':15}...)Evolvingpopulation:100%|███████████████████|100/100[00:09<00:00,5.28it/s]>>>>>>self.fittest{'genome':{'x':9846,'y':1},'fitness':9846.0}
步骤2:计算适应值
这发生在evolve
函数调用的get_fitness
函数中。默认情况下,这些计算将为每个CPU核心并行计算,因此在上面的mnist示例中,这将需要4-5GB RAM。或者,可以通过将workers
设置为一个小值来显式设置并行计算的数量,或者通过将multiprocessing=false
设置为完全禁用并行计算。
步骤3&4:选择精英池和繁殖池
这两个池的选择方式完全相同,只是每个池中的生物体数量不同,默认的精英化率为5%,繁殖率为80%。在池的选择中,它根据密度函数的分布来选择种群,即适应值除以种群的所有适应值之和。这意味着一个有机体的适应度得分越高,就越有可能被选为游泳池的一部分。该算法的精确实现遵循在wikipedia页面上指定的算法。
第5步:繁殖
在这个实现中,父母的有机体是随机选择的,当确定孩子的基因组的值时,每个基因都是父母对该特定基因的值之间的随机选择。
步骤6:选择突变池
与其他两个基因库相比,突变库是随机选择的,否则,我们可能会突然"变异"掉许多适者有机体的好基因。默认的变异率为20%。
步骤7:突变
这种实现方式大致是位串变异,即生物的每一个基因都有1/n机会被另一个基因均匀随机替换,其中n是生物中的基因数。的基因组。这意味着,平均来说,突变会导致一个基因发生改变。
未来可能的扩展
这些是我想在未来实施的想法。检查dev
分支上正在进行的过程。
- 启用对CNN的支持
- 支持RNN,特别是LSTM
- 包括在基因之间建立依赖关系的选项。在神经网络的设置中,这可能包括作为所有层特异性基因依赖的基因的拓扑结构,这与本文中采用的方法类似。
许可证
该项目是在麻省理工学院许可证下获得许可的推荐PyPI第三方库