0


遗传算法与深度学习实战(26)——编码卷积神经网络架构

遗传算法与深度学习实战(26)——编码卷积神经网络架构

0. 前言

我们已经学习了如何构建卷积神经网络 (Convolutional Neural Network, CNN),在本节中,我们将了解如何将

CNN

模型的网络架构编码为基因,这是将基因序列进化在为给定数据集上训练最佳模型的先决条件。

1. EvoCNN 原理

进化卷积神经网络 (

Evolutionary Convolutional Neural Network

,

EvoCNN

) 是一种结合了进化算法和卷积神经网络的方法。
我们知道进化算法是一类基于生物进化过程中的选择、变异和竞争机制的优化算法。在进化卷积神经网络中,进化算法用来优化卷积神经网络 (

Convolutional Neural Network

,

CNN

) 的结构或超参数,以提升其性能和适应特定任务的能力。

1.1 工作原理

EvoCNN

可以利用进化算法来自动设计

CNN

的网络结构,包括卷积层的数量、每层的卷积核大小、池化操作的类型等。自动设计的过程可以帮助避免人工设计网络结构时的主观偏差,并且可以根据具体任务调整网络结构。
除了网络结构外,进化算法还可以用于优化

CNN

的超参数,如学习率、批处理大小等,以提升训练效率和模型性能。

EvoCNN

的另一个优点是其适应性强,能够适应不同的任务和数据集。通过进化算法,网络可以在训练过程中动态调整,以适应变化的输入数据和任务要求。

1.2 基因编码

EvoCNN

是演化

CNN

模型架构的模型,其定义了一种将卷积网络编码为可变长度基因序列的过程,如下图所示。

EvoCNN

2. 编码卷积神经网络架构

(1) 首先,导入所需库,并加载数据集:

import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import numpy as np
import math
import time
import random

import matplotlib.pyplot as plt
from livelossplot import PlotLossesKeras

dataset = datasets.fashion_mnist
(x_train, y_train),(x_test, y_test)= dataset.load_data()# normalize and reshape data
x_train = x_train.reshape(x_train.shape[0],28,28,1).astype("float32")/255.0
x_test = x_test.reshape(x_test.shape[0],28,28,1).astype("float32")/255.0

x_train = x_train[:1000]
y_train= y_train[:1000]
x_test = x_test[:100]
y_test= y_test[:100]

class_names =['T-shirt/top','Trouser','Pullover','Dress','Coat','Sandal','Shirt','Sneaker','Bag','Ankle boot']defplot_data(num_images, images, labels):
    grid = math.ceil(math.sqrt(num_images))
    plt.figure(figsize=(grid*2,grid*2))for i inrange(num_images):
        plt.subplot(grid,grid,i+1)
        plt.xticks([])
        plt.yticks([])
        plt.grid(False)     
        plt.imshow(images[i].reshape(28,28))
        plt.xlabel(class_names[labels[i]])      
    plt.show()

plot_data(25, x_train, y_train)

构建基因序列时,我们希望定义一个基本规则,所有模型都以卷积层开始,并以全连接层作为输出层结束。为了简化问题,我们无需编码最后的输出层。

(2) 在每个主要网络层内部,我们还需要定义相应的超参数选项,例如滤波器数量和卷积核大小。为了编码多样化数据,我们需要分离主要网络层和相关超参数。设置常量用于定义网络层类型和长度以封装各种相关的超参数。定义总最大网络层数和各种网络层超参数的范围,之后,定义每种类型的块标识符及其相应的大小(该值表示每个层定义的长度,包括超参数):

max_layers =5
max_neurons =128
min_neurons =16
max_kernel =5
min_kernel =2
max_pool =3
min_pool =2

CONV_LAYER =-1
CONV_LAYER_LEN =4
POOLING_LAYER =-2
POOLING_LAYER_LEN =3
BN_LAYER =-3
BN_LAYER_LEN =1
DENSE_LAYER =-4
DENSE_LAYER_LEN =2

下图展示了编码层块及其相应超参数的基因序列。需要注意的是,负值

-1

-2

-3

-4

表示网络层的开始。然后,根据层类型,进一步定义滤波器数量和卷积核大小等超参数。

编码过程

(3) 构建个体的基因序列(染色体),

create_offspring()

函数是构建序列的基础。此代码循环遍历最大层数次,并检查是否(以

50%

的概率)添加卷积层。如果是,则进一步检查是否(以

50%

的概率)添加批归一化和池化层:

defcreate_offspring():
    ind =[]for i inrange(max_layers):if random.uniform(0,1)<.5:#add convolution layer
            ind.extend(generate_conv_layer())if random.uniform(0,1)<.5:#add batchnormalization
                ind.extend(generate_bn_layer())if random.uniform(0,1)<.5:#add max pooling layer
                ind.extend(generate_pooling_layer())
    ind.extend(generate_dense_layer())return ind

(4) 编写用于构建网络层的辅助函数:

defgenerate_neurons():return random.randint(min_neurons, max_neurons)defgenerate_kernel():
    part =[]
    part.append(random.randint(min_kernel, max_kernel))
    part.append(random.randint(min_kernel, max_kernel))return part

defgenerate_bn_layer():
    part =[BN_LAYER]return part

defgenerate_pooling_layer():
    part =[POOLING_LAYER] 
    part.append(random.randint(min_pool, max_pool))
    part.append(random.randint(min_pool, max_pool))return part

defgenerate_dense_layer():
    part =[DENSE_LAYER] 
    part.append(generate_neurons())return part

defgenerate_conv_layer():
    part =[CONV_LAYER] 
    part.append(generate_neurons())
    part.extend(generate_kernel())return part

(5) 调用

create_offspring()

生成基因序列,输出如下所示。可以多次调用该函数,观察创建的基因序列的变化:

individual = create_offspring()print(individual)# [-1, 37, 5, 2, -3, -1, 112, 4, 2, -4, 25]

(6) 获取基因序列后,继续构建模型,解析基因序列并创建

Keras

模型。

build_model

的输入是单个基因序列,利用基因序列产生

Keras

模型。定义网络层之后,根据网络层类型添加超参数:

defbuild_model(individual):
    model = models.Sequential()
    il =len(individual)
    i =0while i < il:if individual[i]== CONV_LAYER: 
            n = individual[i+1]
            k =(individual[i+2], individual[i+3])
            i += CONV_LAYER_LEN
            if i ==0:#first layer, add input shape      
                model.add(layers.Conv2D(n, k, activation='relu', padding="same", input_shape=(28,28,1)))else:
                model.add(layers.Conv2D(n, k, activation='relu', padding="same"))elif individual[i]== POOLING_LAYER:#add pooling layer
            k = k =(individual[i+1], individual[i+2])
            i += POOLING_LAYER_LEN
            model.add(layers.MaxPooling2D(k, padding="same"))elif individual[i]== BN_LAYER:#add batch normal layer
            model.add(layers.BatchNormalization())
            i +=1elif individual[i]== DENSE_LAYER:#add dense layer
            model.add(layers.Flatten())      
            model.add(layers.Dense(individual[i+1], activation='relu'))
            i +=2
    model.add(layers.Dense(10))return model

model = build_model(individual)

(7) 创建一个新的个体基因序列,根据序列构建一个模型,然后训练模型,输出训练/验证过程中模型性能:

individual = create_offspring()

model = build_model(individual) 

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

history = model.fit(x_train, y_train, epochs=10, 
                    validation_data=(x_test, y_test),
                    callbacks=[PlotLossesKeras()],
                    verbose=0)

model.summary()
model.evaluate(x_test, y_test)

模型性能的优略取决于随机初始序列,多次运行代码,以观察不同初始随机个体之间的差异。可以通过完成以下问题进一步了解网络架构编码:

  • 通过调用循环中的 create_offspring 函数,创建一个新的基因编码序列列表,打印并比较不同个体
  • 修改最大/最小范围超参数,然后生成一个新的后代列表
  • 添加一个新输入到 create_offspring 函数,将概率从 0.5 更改为其他值。然后,生成一个后代列表进行比较

小结

进化卷积神经网络 (

Evolutionary Convolutional Neural Network

,

EvoCNN

) 通过结合进化算法的优势,提供了一种自动化设计和优化深度学习模型的方法。在本节中,我们介绍了如何将卷积神经网络架构编码为基因序列,为构建进化卷积神经网络奠定基础。

系列链接

遗传算法与深度学习实战(1)——进化深度学习
遗传算法与深度学习实战(2)——生命模拟及其应用
遗传算法与深度学习实战(3)——生命模拟与进化论
遗传算法与深度学习实战(4)——遗传算法(Genetic Algorithm)详解与实现
遗传算法与深度学习实战(5)——遗传算法中常用遗传算子
遗传算法与深度学习实战(6)——遗传算法框架DEAP
遗传算法与深度学习实战(7)——DEAP框架初体验
遗传算法与深度学习实战(8)——使用遗传算法解决N皇后问题
遗传算法与深度学习实战(9)——使用遗传算法解决旅行商问题
遗传算法与深度学习实战(10)——使用遗传算法重建图像
遗传算法与深度学习实战(11)——遗传编程详解与实现
遗传算法与深度学习实战(12)——粒子群优化详解与实现
遗传算法与深度学习实战(13)——协同进化详解与实现
遗传算法与深度学习实战(14)——进化策略详解与实现
遗传算法与深度学习实战(15)——差分进化详解与实现
遗传算法与深度学习实战(16)——神经网络超参数优化
遗传算法与深度学习实战(17)——使用随机搜索自动超参数优化
遗传算法与深度学习实战(18)——使用网格搜索自动超参数优化
遗传算法与深度学习实战(19)——使用粒子群优化自动超参数优化
遗传算法与深度学习实战(20)——使用进化策略自动超参数优化
遗传算法与深度学习实战(21)——使用差分搜索自动超参数优化
遗传算法与深度学习实战(22)——使用Numpy构建神经网络
遗传算法与深度学习实战(23)——利用遗传算法优化深度学习模型
遗传算法与深度学习实战(24)——在Keras中应用神经进化优化
遗传算法与深度学习实战(25)——使用Keras构建卷积神经网络


本文转载自: https://blog.csdn.net/LOVEmy134611/article/details/144228665
版权归原作者 盼小辉丶 所有, 如有侵权,请联系我们删除。

“遗传算法与深度学习实战(26)——编码卷积神经网络架构”的评论:

还没有评论