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) 首先,导入所需库,并加载数据集:
- 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']
- 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[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% 的概率)添加批归一化和池化层:
- 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 = [BN_LAYER]
- return part
- def generate_pooling_layer():
- part = [POOLING_LAYER]
- part.append(random.randint(min_pool, max_pool))
- part.append(random.randint(min_pool, max_pool))
- return part
- def generate_dense_layer():
- part = [DENSE_LAYER]
- part.append(generate_neurons())
- return part
- def generate_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 模型。界说网络层之后,根据网络层类型添加超参数:
- def build_model(individual):
- model = models.Sequential()
- il = len(individual)
- i = 0
- while 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 += 1
- elif 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构建卷积神经网络
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |