深度学习与遗传算法的碰撞——利用遗传算法优化深度学习网络结构(详解与实现)(1)

  1. formatParams(self, params)用于格式化输出染色体

class MLPLayers:

def init(self):

self.initDataset()

def preprocess(self,x,y):

x = tf.reshape(x, [-1])

return x,y

def initDataset(self):

(self.X_train,self.y_train),(self.X_test,self.y_test) = datasets.mnist.load_data()

self.X_train = tf.convert_to_tensor(self.X_train,dtype=tf.float32) / 255.

self.X_test = tf.convert_to_tensor(self.X_test,dtype=tf.float32) / 255.

self.y_train = tf.convert_to_tensor(self.y_train,dtype=tf.int32)

self.y_test = tf.convert_to_tensor(self.y_test,dtype=tf.int32)

self.y_train = tf.one_hot(self.y_train,depth=10)

self.y_test = tf.one_hot(self.y_test,depth=10)

self.train_db = tf.data.Dataset.from_tensor_slices((self.X_train,self.y_train))

self.validation_db = tf.data.Dataset.from_tensor_slices((self.X_test,self.y_test))

self.train_db = self.train_db.shuffle(1000).map(self.preprocess).batch(128)

self.validation_db = self.validation_db.shuffle(1000).map(self.preprocess).batch(128)

def convertParams(self,params):

if round(params[1]) <= 0:

hiddenLayerSizes = round(params[0]),

elif round(params[2]) <= 0:

hiddenLayerSizes = (round(params[0]), round(params[1]))

elif round(params[3]) <= 0:

hiddenLayerSizes = (round(params[0]), round(params[1]), round(params[2]))

else:

hiddenLayerSizes = (round(params[0]), round(params[1]), round(params[2]), round(params[3]))

return hiddenLayerSizes

def getAccuracy(self,params):

#将染色体转化为可以有效构建网络的元组

hiddenLayerSizes = self.convertParams(params)

self.model = Sequential()

#构建网络

for l in hiddenLayerSizes:

self.model.add(layers.Dense(l,activation=‘relu’))

self.model.add(layers.Dense(10,activation=‘relu’))

self.model.build(input_shape=(4,28*28))

self.model.summary()

self.model.compile(optimizer=optimizers.Adam(lr=0.01),

loss=losses.CategoricalCrossentropy(from_logits=True),

metrics=[‘accuracy’])

指定训练集为db,验证集为val_db,训练5个epochs,每1个epoch验证一次

history = self.model.fit(self.train_db, epochs=5, validation_data=self.validation_db, validation_freq=1,verbose=2)

#返回最后一个epoch训练后的验证准确率,用于适应度评估

return history.history[‘val_accuracy’][-1]

def testLayer(self):

创建5层的全连接层网络

network = Sequential([layers.Dense(256, activation=‘relu’),

layers.Dense(128, activation=‘relu’),

layers.Dense(64, activation=‘relu’),

layers.Dense(32, activation=‘relu’),

layers.Dense(10)])

network.build(input_shape=(4, 28*28))

network.summary()

采用Adam优化器,学习率为0.01;采用交叉熵损失函数,包含Softmax

network.compile(optimizer=optimizers.Adam(lr=0.01),

loss=losses.CategoricalCrossentropy(from_logits=True),

metrics=[‘accuracy’] # 设置测量指标为准确率

)

指定训练集为db,验证集为val_db,训练5个epochs,每1个epoch验证一次

history = network.fit(self.train_db, epochs=5, validation_data=self.validation_db, validation_freq=1,verbose=2)

#打印结果

print(history.history[‘val_accuracy’][-1])

def formatParams(self, params):

return “‘hidden_layer_sizes’={}”.format(self.convertParams(params))

使用遗传算法优化MLP架构


现在,我们已经有了MLP的体系结构配置,以及确定每种配置的MLP准确率的方法,接下来,创建基于遗传算法的优化程序以对配置进行搜索——隐藏层的数量以及每层中的节点数量——产生最佳分类准确率。

详细的步骤在注释中进行介绍

from deap import base

from deap import creator

from deap import tools

import random

import numpy as np

import matplotlib.pyplot as plt

import seaborn as sns

#创建MlpLayersTest类的实例,用于测试隐藏层架构的各种组合

test = MLPLayers()

首先为代表隐藏层的每个float值设置上下边界。第一个隐藏层的范围为[100,300],而其余的层则从负值开始,增加终止层数的机会:

BOUNDS_LOW = [100,-25,-50,-75]

BOUNDS_HIGH = [300,200,100,50]

NUM_OF_PARAMS = len(BOUNDS_LOW)

#超参数:

POPULATION_SIZE = 50

P_CROSSOVER = 0.9

P_MUTATION = 0.5

MAX_GENERATIONS = 20

HALL_OF_FAME_SIZE = 5

CROWDING_FACTOR = 10.0

toolbox = base.Toolbox()

#定义最大化适用度策略:

creator.create(“FitnessMax”,base.Fitness,weights=(1.0,))

#基于列表创建个体类:

creator.create(“Individual”,list,fitness=creator.FitnessMax)

#由于解由一系列不同区间的浮点值表示,因此我们使用以下循环并为每个区间创建一个单独的toolbox运算符(layer_size_attribute),用于在适当范围内生成随机浮点值:

for i in range(NUM_OF_PARAMS):

#“layer_size_attribute_0”,“layer_size_attribute_1”…

toolbox.register(“layer_size_attribute_”+str(i),

random.uniform,

BOUNDS_LOW[i],

BOUNDS_HIGH[i])

#创建layer_size_attributes元组,其中包含我们刚刚为每个隐藏层创建的单独的浮点数生成器:

layer_size_attributes = ()

for i in range(NUM_OF_PARAMS):

layer_size_attributes = layer_size_attributes + (toolbox.getattribute(“layer_size_attribute_”+str(i)),)

#将此layer_size_attributes元组与DEAP的内置initCycle()运算符结合使用,以创建一个新的individualCreator运算符,该运算符将随机生成的隐藏层值组合起来填充单个实例

toolbox.register(“individualCreator”,tools.initCycle,creator.Individual,layer_size_attributes,n=1)

#定义种群创建运算符:

toolbox.register(“populationCreator”,tools.initRepeat,list,toolbox.individualCreator)

#使用类的getAccuracy()方法进行适应度评估

def classificationAccuracy(individual):

return test.getAccuracy(individual),

toolbox.register(“evaluate”,classificationAccuracy)

#遗传算子定义:对于选择运算符,使用锦标赛大小为2的锦标赛选择,使用专门用于有界浮动列表染色体的交叉和变异运算符,并为它们提供定义的上下限:

toolbox.register(“select”,tools.selTournament,tournsize=2)

toolbox.register(“mate”,tools.cxSimulatedBinaryBounded,low=BOUNDS_LOW,up=BOUNDS_HIGH,eta=CROWDING_FACTOR)

toolbox.register(“mutate”,tools.mutPolynomialBounded,low=BOUNDS_LOW,up=BOUNDS_HIGH,eta=CROWDING_FACTOR,indpb=1.0/NUM_OF_PARAMS)

带精英主义策略的遗传流程函数

使用名人堂可以用来保留进化过程中种群中曾经存在的最佳个体,并不会由于选择,交叉或变异而失去了它们,HallOfFame类在tools模块中实现。

将Halloffame对象用于实现精英主义。 Halloffame对象中包含的个体被直接注入下一代,并且不受选择,交叉和突变的遗传算子的影响

def eaSimpleWithElitism(population,

toolbox,

cxpb,

mutpb,

ngen,

stats=None,

halloffame=None,

verbose=debug):

“”"使用halloffame来实现精英机制。 包含在名人堂麦中的个体被直接注入下一代,并且不受选择,交叉和突变的遗传算子的影响。

“”"

logbook = tools.Logbook()#用于监控算法运行,和统计数据

logbook.header = [‘gen’,‘nevals’] + (stats.fields if stats else [])

计算个体适应度

invalid_ind = [ind for ind in population if not ind.fitness.valid]

fitnesses = toolbox.map(toolbox.evaluate,invalid_ind)

for ind,fit in zip(invalid_ind,fitnesses):

ind.fitness.values = fit

if halloffame is None:

raise ValueError(“halloffame parameter must not be empty!”)

#更新名人堂成员

halloffame.update(population)

hof_size = len(halloffame.items) if halloffame.items else 0

record = stats.compile(population) if stats else {}

logbook.record(gen=0,nevals=len(invalid_ind),**record)

if verbose:

print(logbook.stream)

#开始遗传流程

for gen in range(1,ngen + 1):

#选择个体数目=种群个体数-名人堂成员数

offspring = toolbox.select(population,len(population) - hof_size)

#种群更新到下一代

offspring = algorithms.varAnd(offspring,toolbox,cxpb,mutpb)

#计算个体适应度

invalid_ind = [ind for ind in offspring if not ind.fitness.valid]

fitnesses = toolbox.map(toolbox.evaluate,invalid_ind)

for ind,fit in zip(invalid_ind,fitnesses):

ind.fitness.values = fit

#将名人堂成员添加到当前代

offspring.extend(halloffame.items)

#更新名人堂

halloffame.update(offspring)

#使用当前代替换种群

population[:] = offspring

#将当前统计信息附加到日志

record = stats.compile(population) if stats else {}

logbook.record(gen=gen,nevals=len(invalid_ind),**record)

if verbose:

print(logbook.stream)

return population,logbook

遗传流程

def main():

#创建初始种群:

population = toolbox.populationCreator(n=POPULATION_SIZE)

#注册要监听的统计数据:

stats = tools.Statistics(lambda ind:ind.fitness.values)

stats.register(“max”,np.max)

stats.register(“avg”,np.mean)

#定义名人堂对象:

hof = tools.HallOfFame(HALL_OF_FAME_SIZE)

#使用精英主义策略执行遗传流程:

population,logbook = eaSimpleWithElitism(population,toolbox,

cxpb=P_CROSSOVER,mutpb=P_MUTATION,

ngen=MAX_GENERATIONS,

stats=stats,halloffame=hof,verbose=True)

打印找到的最佳解:

print("- Best solution is: “,test.formatParams(hof.items[0]),”, accuracy = ",hof.items[0].fitness.values[0])

获取统计数据:

maxFitnessValues, meanFitnessValues = logbook.select(“max”, “avg”)

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

img
  • 16
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值