您的位置:首页 > 汽车 > 新车 > 绍兴专门做网站_青岛营销型网站建设_怎么上百度搜索_seo站内优化公司

绍兴专门做网站_青岛营销型网站建设_怎么上百度搜索_seo站内优化公司

2025/1/3 9:24:06 来源:https://blog.csdn.net/LOVEmy134611/article/details/144814872  浏览:    关键词:绍兴专门做网站_青岛营销型网站建设_怎么上百度搜索_seo站内优化公司
绍兴专门做网站_青岛营销型网站建设_怎么上百度搜索_seo站内优化公司

遗传算法与深度学习实战(29)——编码卷积自编码器架构

    • 0. 前言
    • 1. 构建卷积自编码器
    • 2. 构建卷积自编码器基因序列
    • 3. 解析基因序列构建模型
    • 小结
    • 系列链接

0. 前言

使用遗传算法 (Genetic Algorithm, GA) 构建自编码器 (AutoEncoder, AE) 优化器时,第一步是构建将架构编码为基因序列的模式,借鉴使用遗传算法自动优化卷积神经网络的基因构建思想,并引入 AE 的限制条件。同时,模型通过添加 BatchNormalizationDropout 来改进自编码器模型。

1. 构建卷积自编码器

(1) 导入所需库和数据集:

import numpy as np
import tensorflow as tf
import numpy as np
import randomfrom tensorflow.keras.datasets import mnist
from tensorflow.keras import layers, models, Input, Model
from tensorflow.keras.callbacks import EarlyStoppingfrom IPython import display
from IPython.display import clear_output
import matplotlib.pyplot as plt
from tensorflow.keras.utils import plot_model
plt.gray()# load dataset
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.fashion_mnist.load_data()# split dataset
train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype("float32") / 255.0
test_images = test_images.reshape(test_images.shape[0], 28, 28, 1).astype("float32") / 255.0class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat','Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']import mathdef 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, train_images, train_labels)

(2) 构建、编译并训练模型:

# input layer
input_layer = Input(shape=(28, 28, 1))# encoding architecture
encoded_layer1 = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(input_layer)
encoded_layer1 = layers.MaxPool2D( (2, 2), padding='same')(encoded_layer1)
encoded_layer2 = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(encoded_layer1)
encoded_layer2 = layers.MaxPool2D( (2, 2), padding='same')(encoded_layer2)
encoded_layer3 = layers.Conv2D(16, (3, 3), activation='relu', padding='same')(encoded_layer2)
latent_view    = layers.MaxPool2D( (2, 2), padding='same')(encoded_layer3)#decoding architecture
decoded_layer1 = layers.Conv2D(16, (3, 3), activation='relu', padding='same')(latent_view)
decoded_layer1 = layers.UpSampling2D((2, 2))(decoded_layer1)
decoded_layer2 = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(decoded_layer1)
decoded_layer2 = layers.UpSampling2D((2, 2))(decoded_layer2)
decoded_layer3 = layers.Conv2D(64, (3, 3), activation='relu')(decoded_layer2)
decoded_layer3 = layers.UpSampling2D((2, 2))(decoded_layer3)
#output layer
output_layer   = layers.Conv2D(1, (3, 3), padding='same')(decoded_layer3)# compile the model
model = Model(input_layer, output_layer)
model.compile(optimizer='adam', loss='mse')
model.summary()
plot_model(model)history_loss = []
history_val_loss = []def add_history(history):history_loss.append(history.history["loss"])history_val_loss.append(history.history["val_loss"])def reset_history():global history_lossglobal history_val_losshistory_loss = []history_val_loss = []return []def plot_results(num_images, images, labels, history):add_history(history)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()plt.plot(history_loss, label='loss')plt.plot(history_val_loss, label='val_loss')plt.legend()
plt.show()EPOCHS = 3
history = reset_history()for i in range(EPOCHS):history = model.fit(train_images, train_images, epochs=1, batch_size=2048, validation_data=(test_images, test_images))pred_images = model.predict(test_images[:25])clear_output()
plot_results(25, pred_images[:25], test_labels[:25], history)
# input layer
input_layer = Input(shape=(28, 28, 1))# encoding architecture
x = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(input_layer)
#x = layers.BatchNormalization()(x)
x = layers.MaxPool2D( (2, 2), padding='same')(x)
#x = layers.Dropout(0.5)(x)
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(x)
#x = layers.BatchNormalization()(x)
x = layers.MaxPool2D( (2, 2), padding='same')(x)
#x = layers.Dropout(0.5)(x)
x = layers.Conv2D(16, (3, 3), activation='relu', padding='same')(x)
#x = layers.BatchNormalization()(x)
x = layers.MaxPool2D( (2, 2), padding='same')(x)
#x = layers.Dropout(0.5)(x)#decoding architecture
x = layers.Conv2D(16, (3, 3), activation='relu', padding='same')(x)
#x = layers.Dropout(0.5)(x)
x = layers.UpSampling2D((2, 2))(x)
#x = layers.BatchNormalization()(x)
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(x)
#x = layers.Dropout(0.5)(x)
x = layers.UpSampling2D((2, 2))(x)
#x = layers.BatchNormalization()(x)
x = layers.Conv2D(64, (3, 3), activation='relu')(x)
#x = layers.Dropout(0.5)(x)
x = layers.UpSampling2D((2, 2))(x)
#x = layers.BatchNormalization()(x)
#output layer
output_layer   = layers.Conv2D(1, (3, 3), padding='same')(x)# compile the model
model = Model(input_layer, output_layer)
model.compile(optimizer='adam', loss='mse')
model.summary()
plot_model(model)EPOCHS = 10
history = reset_history()for i in range(EPOCHS):history = model.fit(train_images, train_images, epochs=1, batch_size=2048, validation_data=(test_images, test_images))pred_images = model.predict(test_images[:25])clear_output()
plot_results(25, pred_images[:25], test_labels[:25], history)

2. 构建卷积自编码器基因序列

在基因序列的编码模式考虑卷积/最大池化层和上采样/卷积层,表示编码器卷积层的编码标记定义为 CONV_LAYER,表示解码器的上采样/卷积层的标记定义为 UPCONV_LAYER

(1) 接下来,生成编码器层 (CONV_LAYER) 和解码器层 (UPCONV_LAYER):

max_layers = 10
max_neurons = 128
min_neurons = 16
max_kernel = 3
min_kernel = 3
max_pool = 2
min_pool = 2CONV_LAYER = -1
CONV_LAYER_LEN = 4
BN_LAYER = -3
BN_LAYER_LEN = 1
DROPOUT_LAYER = -4
DROPOUT_LAYER_LEN = 2
UPCONV_LAYER = -2
UPCONV_LAYER_LEN = 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 partdef generate_conv_layer():part = [CONV_LAYER] part.append(generate_neurons())part.extend(generate_kernel())  return partdef generate_upconv_layer():part = [UPCONV_LAYER] part.append(generate_neurons())part.extend(generate_kernel())  return part
编写函数在模型中添加BatchNormalization和dropout。
def generate_bn_layer():part = [BN_LAYER] return partdef generate_dropout_layer():part = [DROPOUT_LAYER] part.append(random.uniform(0,.5))  return part

(2) 实现 create_offspring() 函数创建基因序列,函数分为两个循环:一个用于编码器部分,另一个用于解码器部分。编码器部分遍历网络层,并随机检查是否应该添加另一个卷积层,如果添加了一个卷积层,则继续随机检查是否应该添加批归一化层或 dropout 层。并自动添加了一个最大池化层,以实现自编码器的降维架构:

def create_offspring():ind = []layers = 0for i in range(max_layers):if i==0: #first layer always convolutationalind.extend(generate_conv_layer())      layers += 1elif random.uniform(0,1)<.5:#add convolution layerind.extend(generate_conv_layer())layers += 1if random.uniform(0,1)<.5:#add batchnormalizationind.extend(generate_bn_layer())if random.uniform(0,1) < .5:ind.extend(generate_dropout_layer()) for i in range(layers):ind.extend(generate_upconv_layer())if random.uniform(0,1)<.5:#add batchnormalizationind.extend(generate_bn_layer())if random.uniform(0,1) < .5:ind.extend(generate_dropout_layer())return indindividual = create_offspring()
print(individual)

解码器部分是编码器的镜像。因此,通过与编码器相同的迭代次数进行循环,添加上采样和卷积层组合。之后,以应用概率检查添加 BatchNormalizationDropout 层。

3. 解析基因序列构建模型

(1) 接下来,通过解析基因序列构建模型。首先循环遍历每个基因,并检查它是否与一个网络层标记匹配。如果匹配,则将相应的层和选项添加到模型中。对于编码器卷积层 (CONV_LAYER),如果输入形状大于 (7, 7),添加一个最大池化层,用于确保模型保持降维架构:

def padding(gene):return "same" if gene == 1 else "valid"def build_model(individual):input_layer = Input(shape=(28, 28, 1))  il = len(individual)i = 0x = input_layerwhile i < il:    if individual[i] == CONV_LAYER:      pad="same" n = individual[i+1]k = (individual[i+2], individual[i+3])i += CONV_LAYER_LEN        x = layers.Conv2D(n, k, activation='relu', padding=pad)(x) if x.shape[1] > 7:x = layers.MaxPool2D( (2, 2), padding='same')(x)

(2) 继续检查标记添加网络层,对于 UPCONV_LAYER 解码器层,检查模型输出是否与输入大小相同:

        elif individual[i] == BN_LAYER: #add batchnormal layerx = layers.BatchNormalization()(x)i += BN_LAYER_LEN      elif individual[i] == DROPOUT_LAYER: #add dropout layer            x = layers.Dropout(individual[i+1])(x) i += DROPOUT_LAYER_LENelif individual[i] == UPCONV_LAYER:pad="same"n = individual[i+1]k = (individual[i+2], individual[i+3])        x = layers.Conv2D(n, k, activation='relu', padding=pad)(x)   x = layers.UpSampling2D((2, 2))(x)   i += CONV_LAYER_LEN   if x.shape[1] == (28):break #model is completeelse:break

build_model() 函数构建、编译模型并返回模型。在返回之前,通过检查最后一个解码器层的形状来确认模型输出,如果输出尺寸较小,通过添加一个上采样层,将输出大小从 (14, 14) 加倍到 (28, 28)

为了测试 build_model() 函数,创建 100 个随机后代,并评估模型的大小。生成随机的个体基因序列,然后根据这些序列构建相应的模型。在此过程中,跟踪生成的最小和最大模型:

    if x.shape[1] == 14:x = layers.UpSampling2D((2, 2))(x)output_layer = layers.Conv2D(1, (3, 3), padding='same')(x)model = Model(input_layer, output_layer)model.compile(optimizer='adam', loss='mse')return modelmodel = build_model(individual) 
model.summary()

(3) 使用最小参数模型进行 10epochs 的训练,输出如下图所示:

max_model = None
min_model = None
maxp = 0
minp = 10000000for i in range(100):individual = create_offspring() model = build_model(individual)p = model.count_params() if p > maxp:maxp = pmax_model = modelif p < minp:minp = pmin_model = model max_model.summary(line_length=100)
min_model.summary(line_length=100)EPOCHS = 10
history = reset_history()#model = max_model
model = min_modelfor i in range(EPOCHS):history = model.fit(train_images, train_images, epochs=1, batch_size=2048, validation_data=(test_images, test_images))pred_images = model.predict(test_images[:25])clear_output()plot_results(25, pred_images[:25], test_labels[:25], history)

运行结果

可以看到,使用 create_offspring()build_model() 随机生成的模型比我们手动优化的自编码器更好,这表明了使用遗传算法优化自编码器模型的有效性。
同样,我们可以测试最大参数模型。可以通过完成以下问题进一步了解网络架构编码:

  • 调用 create_offspring() 函数创建个体列表,打印并比较不同模型
  • 将概率从 0.5 修改为其他值,观察对生成的模型有什么影响

小结

使用卷积层的复杂自编码器可能较难构建,可以使用神经进化构建定义编码器和解码器部分的分层架构。在编码器和解码器中使用卷积层需要额外的上采样层和匹配的层配置,这些配置可以编码成自定义的遗传序列。

系列链接

遗传算法与深度学习实战(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构建卷积神经网络
遗传算法与深度学习实战(26)——编码卷积神经网络架构
遗传算法与深度学习实战(27)——进化卷积神经网络
遗传算法与深度学习实战(28)——卷积自编码器详解与实现

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com