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

打印 上一主题 下一主题

主题 1514|帖子 1514|积分 4542

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 模型架构的模型,其界说了一种将卷积网络编码为可变长度基因序列的过程,如下图所示。

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

(1) 首先,导入所需库,并加载数据集:
  1. import tensorflow as tf
  2. from tensorflow.keras import datasets, layers, models
  3. import numpy as np
  4. import math
  5. import time
  6. import random
  7. import matplotlib.pyplot as plt
  8. from livelossplot import PlotLossesKeras
  9. dataset = datasets.fashion_mnist
  10. (x_train, y_train), (x_test, y_test) = dataset.load_data()
  11. # normalize and reshape data
  12. x_train = x_train.reshape(x_train.shape[0], 28, 28, 1).astype("float32") / 255.0
  13. x_test = x_test.reshape(x_test.shape[0], 28, 28, 1).astype("float32") / 255.0
  14. x_train = x_train[:1000]
  15. y_train= y_train[:1000]
  16. x_test = x_test[:100]
  17. y_test= y_test[:100]
  18. class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
  19.                'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
  20. def plot_data(num_images, images, labels):
  21.     grid = math.ceil(math.sqrt(num_images))
  22.     plt.figure(figsize=(grid*2,grid*2))
  23.     for i in range(num_images):
  24.         plt.subplot(grid,grid,i+1)
  25.         plt.xticks([])
  26.         plt.yticks([])
  27.         plt.grid(False)     
  28.         plt.imshow(images[i].reshape(28,28))
  29.         plt.xlabel(class_names[labels[i]])      
  30.     plt.show()
  31. plot_data(25, x_train, y_train)
复制代码
构建基因序列时,我们希望界说一个基本规则,所有模型都以卷积层开始,并以全连接层作为输出层结束。为了简化题目,我们无需编码最后的输出层。
(2) 在每个重要网络层内部,我们还需要界说相应的超参数选项,比方滤波器数量和卷积核大小。为了编码多样化数据,我们需要分离重要网络层和相干超参数。设置常量用于界说网络层类型和长度以封装各种相干的超参数。界说总最大网络层数和各种网络层超参数的范围,之后,界说每种类型的块标识符及其相应的大小(该值表示每个层界说的长度,包罗超参数):
  1. max_layers = 5
  2. max_neurons = 128
  3. min_neurons = 16
  4. max_kernel = 5
  5. min_kernel = 2
  6. max_pool = 3
  7. min_pool = 2
  8. CONV_LAYER = -1
  9. CONV_LAYER_LEN = 4
  10. POOLING_LAYER = -2
  11. POOLING_LAYER_LEN = 3
  12. BN_LAYER = -3
  13. BN_LAYER_LEN = 1
  14. DENSE_LAYER = -4
  15. DENSE_LAYER_LEN = 2
复制代码
下图展示了编码层块及其相应超参数的基因序列。需要注意的是,负值 -1、-2、-3 和 -4 表示网络层的开始。然后,根据层类型,进一步界说滤波器数量和卷积核大小等超参数。

(3) 构建个体的基因序列(染色体),create_offspring() 函数是构建序列的基础。此代码循环遍历最大层数次,并检查是否(以 50% 的概率)添加卷积层。假如是,则进一步检查是否(以 50% 的概率)添加批归一化和池化层:
  1. def create_offspring():
  2.     ind = []
  3.     for i in range(max_layers):
  4.         if random.uniform(0,1)<.5:
  5.             #add convolution layer
  6.             ind.extend(generate_conv_layer())
  7.             if random.uniform(0,1)<.5:
  8.                 #add batchnormalization
  9.                 ind.extend(generate_bn_layer())
  10.             if random.uniform(0,1)<.5:
  11.                 #add max pooling layer
  12.                 ind.extend(generate_pooling_layer())
  13.     ind.extend(generate_dense_layer())
  14.     return ind
复制代码
(4) 编写用于构建网络层的辅助函数:
  1. def generate_neurons():
  2.     return random.randint(min_neurons, max_neurons)
  3. def generate_kernel():
  4.     part = []
  5.     part.append(random.randint(min_kernel, max_kernel))
  6.     part.append(random.randint(min_kernel, max_kernel))
  7.     return part
  8. def generate_bn_layer():
  9.     part = [BN_LAYER]
  10.     return part
  11. def generate_pooling_layer():
  12.     part = [POOLING_LAYER]
  13.     part.append(random.randint(min_pool, max_pool))
  14.     part.append(random.randint(min_pool, max_pool))
  15.     return part
  16. def generate_dense_layer():
  17.     part = [DENSE_LAYER]
  18.     part.append(generate_neurons())  
  19.     return part
  20. def generate_conv_layer():
  21.     part = [CONV_LAYER]
  22.     part.append(generate_neurons())
  23.     part.extend(generate_kernel())
  24.     return part
复制代码
(5) 调用 create_offspring() 生成基因序列,输出如下所示。可以多次调用该函数,观察创建的基因序列的变化:
  1. individual = create_offspring()
  2. print(individual)
  3. # [-1, 37, 5, 2, -3, -1, 112, 4, 2, -4, 25]
复制代码
(6) 获取基因序列后,继承构建模型,解析基因序列并创建 Keras 模型。build_model 的输入是单个基因序列,利用基因序列产生 Keras 模型。界说网络层之后,根据网络层类型添加超参数:
  1. def build_model(individual):
  2.     model = models.Sequential()
  3.     il = len(individual)
  4.     i = 0
  5.     while i < il:
  6.         if individual[i] == CONV_LAYER:
  7.             n = individual[i+1]
  8.             k = (individual[i+2], individual[i+3])
  9.             i += CONV_LAYER_LEN
  10.             if i == 0: #first layer, add input shape      
  11.                 model.add(layers.Conv2D(n, k, activation='relu', padding="same", input_shape=(28, 28, 1)))      
  12.             else:
  13.                 model.add(layers.Conv2D(n, k, activation='relu', padding="same"))   
  14.         elif individual[i] == POOLING_LAYER: #add pooling layer
  15.             k = k = (individual[i+1], individual[i+2])
  16.             i += POOLING_LAYER_LEN
  17.             model.add(layers.MaxPooling2D(k, padding="same"))      
  18.         elif individual[i] == BN_LAYER: #add batch normal layer
  19.             model.add(layers.BatchNormalization())
  20.             i += 1      
  21.         elif individual[i] == DENSE_LAYER: #add dense layer
  22.             model.add(layers.Flatten())      
  23.             model.add(layers.Dense(individual[i+1], activation='relu'))
  24.             i += 2
  25.     model.add(layers.Dense(10))
  26.     return model
  27. model = build_model(individual)
复制代码
(7) 创建一个新的个体基因序列,根据序列构建一个模型,然后训练模型,输出训练/验证过程中模型性能:
  1. individual = create_offspring()
  2. model = build_model(individual)
  3. model.compile(optimizer='adam',
  4.               loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
  5.               metrics=['accuracy'])
  6. history = model.fit(x_train, y_train, epochs=10,
  7.                     validation_data=(x_test, y_test),
  8.                     callbacks=[PlotLossesKeras()],
  9.                     verbose=0)
  10. model.summary()
  11. 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企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

八卦阵

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表