八卦阵 发表于 2024-12-5 07:49:04

遗传算法与深度学习实战(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 模型架构的模型,其界说了一种将卷积网络编码为可变长度基因序列的过程,如下图所示。
https://i-blog.csdnimg.cn/direct/5f18418317dc4d40998de8f80680b0f5.png#pic_center
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, 28, 28, 1).astype("float32") / 255.0
x_test = x_test.reshape(x_test.shape, 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']

def plot_data(num_images, images, labels):
    grid = math.ceil(math.sqrt(num_images))
    plt.figure(figsize=(grid*2,grid*2))
    for i in range(num_images):
      plt.subplot(grid,grid,i+1)
      plt.xticks([])
      plt.yticks([])
      plt.grid(False)   
      plt.imshow(images.reshape(28,28))
      plt.xlabel(class_names])      
    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 表示网络层的开始。然后,根据层类型,进一步界说滤波器数量和卷积核大小等超参数。
https://i-blog.csdnimg.cn/direct/e78cfea898a0444e896e526107221884.png#pic_center
(3) 构建个体的基因序列(染色体),create_offspring() 函数是构建序列的基础。此代码循环遍历最大层数次,并检查是否(以 50% 的概率)添加卷积层。假如是,则进一步检查是否(以 50% 的概率)添加批归一化和池化层:
def create_offspring():
    ind = []
    for i in range(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) 编写用于构建网络层的辅助函数:
def generate_neurons():
    return random.randint(min_neurons, max_neurons)

def generate_kernel():
    part = []
    part.append(random.randint(min_kernel, max_kernel))
    part.append(random.randint(min_kernel, max_kernel))
    return part

def generate_bn_layer():
    part =
    return part

def generate_pooling_layer():
    part =
    part.append(random.randint(min_pool, max_pool))
    part.append(random.randint(min_pool, max_pool))
    return part

def generate_dense_layer():
    part =
    part.append(generate_neurons())
    return part

def generate_conv_layer():
    part =
    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 模型。界说网络层之后,根据网络层类型添加超参数:
def build_model(individual):
    model = models.Sequential()
    il = len(individual)
    i = 0
    while i < il:
      if individual == CONV_LAYER:
            n = individual
            k = (individual, individual)
            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 == POOLING_LAYER: #add pooling layer
            k = k = (individual, individual)
            i += POOLING_LAYER_LEN
            model.add(layers.MaxPooling2D(k, padding="same"))      
      elif individual == BN_LAYER: #add batch normal layer
            model.add(layers.BatchNormalization())
            i += 1      
      elif individual == DENSE_LAYER: #add dense layer
            model.add(layers.Flatten())      
            model.add(layers.Dense(individual, 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=,
                  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构建卷积神经网络

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 遗传算法与深度学习实战(26)——编码卷积神经网络架构