声音合成——Foley Sound——DECASE项目——多模态智能感知与应用——Autoencoder代码实现(6)

news2025/2/25 5:02:16

文章目录

    • 概述
    • encoder的编写过程
      • 代码编写
      • 运行结果
      • 问题
      • 总结
    • decoder的编写过程
      • 知识补充
        • 关于逆卷积
      • 代码编写
      • 运行结果
      • 总结
    • Autoencoder模型编写 + compile方法 + train方法 + 保存和加载模型模块编写
      • 实现代码——autoencoder代码
      • 实现代码——train代码
      • 实现代码——保存和加载模型的代码
      • 运行结果
      • 总结
    • 总结

概述

  • 这部分是关于代码复现的,跟着学了一遍代码,确实学到了很多,也改变了以前一些不好的习惯。
  • 下面的每一个注释记录的是作者写代码的顺序,以及这样写的作用

encoder的编写过程

代码编写

from tensorflow.keras import Model
# 一般进行版本更新都是改变的包的导向,或者改变包的方法名
from tensorflow.keras.layers import Input,Conv2D,ReLU,BatchNormalization,Flatten,Dense
# 引入backend,这个用来自己定义层,将一些函数定义成特定的层
from tensorflow.keras import backend as K


class Autoencoder:
    """
    Autoencoder: 具有编码器和解码器的深度卷积自动编码器
    """

    # 1、当前类别的构造函数,
    def __init__(self,
                 input_shape,
                 conv_filters,
                 conv_kernels,
                 conv_strdes,
                 latent_space_dim
                 ):
        # 2、 将所有的属性都赋值给对应实体属性
        self.input_shape = input_shape  # [28,28,1]这里是使用minst手写数据集进行测试的
        self.conv_filters = conv_filters # [2,4,8]
        self.conv_kernels = conv_kernels # [3,5,3]
        self.conv_strdes = conv_strdes # [1,2,2]
        self.latent_space_dim = latent_space_dim # 潜在映射空间的维度,这里设置为2维度空间

        # 3、这里的习惯就很好,将一个大模型拆解成两个小模型,编程的时候,只需要对应进行修改就行了
        self.encoder = None
        self.decoder = None
        self.model = None

        # 4、将部分变量声明为隐私变量,前置单下划线,私有变量
        self._num_conv_layers = len(conv_filters)

        # 5、设置build函数,这里是实例化类的时候进行调用
        self._build()

        # 9、后续添加的变量
        self._shape_before_bottleneck = None

    def summary(self):
        """ 做测试,判定模型是否成功 """
        self.encoder.summary()

    # 6、具体实现相关的方法,这个是总的build函数,需要构建三个模块,分别是encoder、decoder和model
    def _build(self):
        self._build_encoder()
        self._build_decoder()
        self._build_autoencoder()

    # 7、从上到下,逐个子方法进行实现
    def _build_encoder(self):
        # 8、按照网络的层次,将模型串联起来,按照模块进行组装
        encoder_input =  self._add_encoder_input()
        conv_layers =  self._add_conv_layers(encoder_input)
        bottleneck = self._add_bottleneck(conv_layers)
        self.encoder = Model(encoder_input,bottleneck,name="encoder")

    # 8、从上到下,按照顺序,逐个实现_build_encoder模块中所有方法
    def _add_encoder_input(self):
        return Input(shape = self.input_shape,name= "encoder_input")

    # 8、从上到下,按照顺序,逐个实现_build_encoder模块中所有方法
    def _add_conv_layers(self,encoder_input):
        """  在编码器中增加卷积模块 """
        x = encoder_input
        # 9、这部分是按照层的顺序逐渐叠加网络层
        for layer_index in range(self._num_conv_layers):
            # 尽量将自己的模块封装在别的人的模块上
            x = self._add_conv_layer(layer_index,x)
        return x

    # 8、从里到外,完成对应的卷积模块
    def _add_conv_layer(self,layer_index,x):
        """ 增加卷积模块,每一部分构成如下,conv2d + relu + batch normalization """
        layer_num = layer_index + 1
        conv_layer = Conv2D(
            filters = self.conv_filters[layer_index],
            kernel_size = self.conv_kernels[layer_index],
            strides = self.conv_strdes[layer_index],
            padding = "same",
            name = f"encoder_conv_layer_{layer_num}"
        )
        x = conv_layer(x)
        x = ReLU(name = f"encoder_relu_{layer_num}")(x)
        x = BatchNormalization(name = f"encoder_bn_{layer_num}")(x)
        return x

    # 8、从上到下,按照顺序,逐个实现_build_encoder模块中所有方法
    def _add_bottleneck(self,x):
        # 9、第九部分进行编写
        """ 首先将数据展平,然后在传入全链接层 """
        self._shape_before_bottleneck = K.int_shape(x)[1:]  # [batch_size,height,weight,channel],这里只需要后面三个的大小
        x = Flatten()(x)
        x = Dense(self.latent_space_dim,name = "encoder_output")(x)
        return x

    # 7、从上到下,逐个子方法进行实现
    def _build_decoder(self):
        pass

    # 7、从上到下,逐个子方法进行实现
    def _build_autoencoder(self):
        pass


if __name__ == '__main__':
    autoencoder = Autoencoder(
        input_shape= [28,28,1],
        conv_filters = [32,64,64,64],
        conv_kernels = [3,3,3,3],
        conv_strdes = [1,2,2,1],
        latent_space_dim=2
    )

    autoencoder.summary()

运行结果

在这里插入图片描述

问题

  • 这里直接堆叠对应的卷积层,并没有计算对应的输出的张量的大小,没有根据对应的大小设置某一层的参数?
    • 卷积层并不需要任何指定,这里只需要

总结

  • 尽量将模型模块化设计,然后将你所调用的函数api,尽可能放在最底层。
    • 在作者的代码里,将整个模型封装为encoder + decoder,然后整体的模型叫做model,然后有一个build函数分别调用
  • 对于函数内部的成员,一些构造函数,要及时将之生命为私有的
  • 在编写过程中,要学会模块化测试,
    • 编写一部分,就测试一部分,使用summary函数

decoder的编写过程

知识补充

关于逆卷积

  • 对应的链接,逆卷积和卷积的说明

代码编写

运行结果

在这里插入图片描述

总结

  • 经过了第一部分之后,明确了一些编码的习惯和常识之后,更多的是理解如何根据输入层的翻转,构建新的输出层。
  • 需要理解一下的知识点
    • 反卷积层和卷积层的关系
    • 最后为什么要是sigmoid

Autoencoder模型编写 + compile方法 + train方法 + 保存和加载模型模块编写

实现代码——autoencoder代码

from tensorflow.keras import Model
# 一般进行版本更新都是改变的包的导向,或者改变包的方法名
from tensorflow.keras.layers import Input,Conv2D,ReLU,BatchNormalization,Flatten,Dense,\
    Reshape,Conv2DTranspose,Activation
# 引入backend,这个用来自己定义层,将一些函数定义成特定的层
from tensorflow.keras import backend as K
# 导入numpy,对三维数据进行操作
import numpy as np
# 导入对应优化器,注意,这里已经改变了包的地址
from tensorflow.keras.optimizers import Adam
# 导入损失函数
from tensorflow.keras.losses import MeanSquaredError
# 导入系统模块
import os
# 序列加载模块
import pickle

class Autoencoder:
    """
    Autoencoder: 具有编码器和解码器的深度卷积自动编码器
    """

    # 1、当前类别的构造函数,
    def __init__(self,
                 input_shape,
                 conv_filters,
                 conv_kernels,
                 conv_strides,
                 latent_space_dim
                 ):
        # 2、 将所有的属性都赋值给对应实体属性
        self.input_shape = input_shape  # [28,28,1]这里是使用minst手写数据集进行测试的
        self.conv_filters = conv_filters # [2,4,8]
        self.conv_kernels = conv_kernels # [3,5,3]
        self.conv_strides = conv_strides # [1,2,2]
        self.latent_space_dim = latent_space_dim # 潜在映射空间的维度,这里设置为2维度空间

        # 3、这里的习惯就很好,将一个大模型拆解成两个小模型,编程的时候,只需要对应进行修改就行了
        self.encoder = None
        self.decoder = None
        self.model = None

        # 4、将部分变量声明为隐私变量,前置单下划线,私有变量
        self._num_conv_layers = len(conv_filters)

        # 5、设置build函数,这里是实例化类的时候进行调用
        self._build()

        # 9、后续添加的变量
        self._shape_before_bottleneck = None

        # 3.1 添加整体模型的输入,和encoder的输入是相同的
        self._model_input = None

    # 这个方法在三个模块都是需要修改的
    def summary(self):
        """ 做测试,判定模型是否成功 """
        self.encoder.summary()
        self.decoder.summary()
        self.model.summary()

    # 3.2 增加编译函数
    def compile(self,learning_rate = 0.0001):
        """ 指定损失函数和优化器,并对模型进行优化 """
        optimizer = Adam(learning_rate = learning_rate)
        mse_loss = MeanSquaredError()
        self.model.compile(
            optimizer = optimizer,
            loss = mse_loss
        )

    # 3.3 增加训练函数
    def train(self,x_train,batch_size,num_epochs):
        self.model.fit(
            x_train,
            x_train,
            batch_size = batch_size,
            epochs = num_epochs,
            shuffle = True
        )

    # 3.4 模型保存部分
    def save(self,save_folder = "."):
        """ 保存模型,需要创建文件,分别保存参数和权重"""
        self._create_folder_if_not_exist(save_folder)
        self._save_parameters(save_folder)
        self._save_weights(save_folder)

    # 3.5 模型加载部分,这部分要注意,是声明为类方法,不用实例化,直接可以调用
    @classmethod
    def load(cls,save_folder ="."):
        """ 加载模型,包括模型的参数设置和模型的训练权重 """
        parameters_path = os.path.join(save_folder,"parameters.pkl")
        with open(parameters_path,"rb") as f:
            parameters = pickle.load(f)
        autoencoder = Autoencoder(*parameters)
        weight_path = os.path.join(save_folder,"weights.h5")
        autoencoder.load_weights(weight_path)
        return autoencoder

    def load_weights(self,weight_path):
        self.model.load_weights(weight_path)

    def reconstruct(self,image):
        """ 重建图片,并返回生成之后的图片以及对应的特征空间 """
        latent_space = self.encoder.predict(image)
        reconstruct_image = self.decoder.predict(latent_space)
        return reconstruct_image,latent_space


    # 3.4 分别实现上述方法
    def _create_folder_if_not_exist(self,save_folder):
        if not os.path.exists(save_folder):
            os.makedirs(save_folder)

    # 3.4 分别实现上述方法
    def _save_parameters(self,save_folder):
        """ 主要是保存模型对应的参数,包括每一层具体的设置 """
        parameters = [
            self.input_shape ,
            self.conv_filters,
            self.conv_kernels,
            self.conv_strides,
            self.latent_space_dim
        ]
        save_path = os.path.join(save_folder,"parameters.pkl")
        with open(save_path,"wb") as f:
            pickle.dump(parameters,f)

    # 3.4  实现save的子方法
    def _save_weights(self,save_folder):
        save_path = os.path.join(save_folder, "weights.h5")
        self.model.save_weights(save_path)


    # 6、具体实现相关的方法,这个是总的build函数,需要构建三个模块,分别是encoder、decoder和model
    def _build(self):
        self._build_encoder()
        self._build_decoder()
        self._build_autoencoder()

    # 7、从上到下,逐个子方法进行实现
    def _build_encoder(self):
        # 8、按照网络的层次,将模型串联起来,按照模块进行组装
        encoder_input =  self._add_encoder_input()
        conv_layers =  self._add_conv_layers(encoder_input)
        bottleneck = self._add_bottleneck(conv_layers)
        self._model_input = encoder_input
        self.encoder = Model(encoder_input,bottleneck,name="encoder")

    # 8、从上到下,按照顺序,逐个实现_build_encoder模块中所有方法
    def _add_encoder_input(self):
        return Input(shape = self.input_shape,name= "encoder_input")

    # 8、从上到下,按照顺序,逐个实现_build_encoder模块中所有方法
    def _add_conv_layers(self,encoder_input):
        """  在编码器中增加卷积模块 """
        x = encoder_input
        # 9、这部分是按照层的顺序逐渐叠加网络层
        for layer_index in range(self._num_conv_layers):
            # 尽量将自己的模块封装在别的人的模块上
            x = self._add_conv_layer(layer_index,x)
        return x

    # 8、从里到外,完成对应的卷积模块
    def _add_conv_layer(self,layer_index,x):
        """ 增加卷积模块,每一部分构成如下,conv2d + relu + batch normalization """
        layer_num = layer_index + 1
        conv_layer = Conv2D(
            filters = self.conv_filters[layer_index],
            kernel_size = self.conv_kernels[layer_index],
            strides = self.conv_strides[layer_index],
            padding = "same",
            name = f"encoder_conv_layer_{layer_num}"
        )
        x = conv_layer(x)
        x = ReLU(name = f"encoder_relu_{layer_num}")(x)
        x = BatchNormalization(name = f"encoder_bn_{layer_num}")(x)
        return x

    # 8、从上到下,按照顺序,逐个实现_build_encoder模块中所有方法
    def _add_bottleneck(self,x):
        # 9、第九部分进行编写
        """ 首先将数据展平,然后在传入全链接层 """
        self._shape_before_bottleneck = K.int_shape(x)[1:]  # [batch_size,height,weight,channel],这里只需要后面三个的大小
        x = Flatten()(x)
        x = Dense(self.latent_space_dim,name = "encoder_output")(x)
        return x

    # 7、从上到下,逐个子方法进行实现
    # 2.1 完成解码器的大部分框架
    def _build_decoder(self):
        """ 创建解码器,输入层、全连阶层、恢复成三维、进行反卷积、输出层 """
        decoder_input = self._add_decoder_input()
        dense_layer = self._add_dense_layer(decoder_input)
        reshape_layer = self._add_reshape_layer(dense_layer)
        conv_transpose_layers = self._add_conv_transpose_layers(reshape_layer)
        decoder_output = self._add_decoder_output(conv_transpose_layers)
        self.decoder = Model(decoder_input,decoder_output,name = "decoder")

    # 2.2 具体实现各个子函数,下述函数都是按照顺序完成并实现的
    def _add_decoder_input(self):
        """ 解码器的输入 """
        return Input(shape = self.latent_space_dim,name = "decoder_input")

    def _add_dense_layer(self,decoder_input):
        """ 解码器的全连阶层,输出数据是二维的,这里并不知道怎么设置??"""
        # 这部分设置神经元的数量,和输出的维度而数量相同
        num_neurons = np.prod(self._shape_before_bottleneck) # 将数据恢复原始的数据[1,2,4]=>8,现在是将8转成三维的数组
        dense_layer = Dense(num_neurons,name = "decoder_dense_layer")(decoder_input)
        return dense_layer

    def _add_reshape_layer(self,dense_layer):
        """ 增加对应的调整形状层,将全链接层的输出,恢复成三维数组 """

        # 这里并不知道调用什么层进行设计
        reshape_layer = Reshape(self._shape_before_bottleneck)(dense_layer)
        return reshape_layer

    def _add_conv_transpose_layers(self,x):
        """ 增加反卷积模块 """
        # 按照相反的顺序遍历所有的卷积层,并且在第一层停下
        for layers_index in reversed(range(1,self._num_conv_layers)):
            # 理解:原来的卷积层标记[0,1,2],翻转之后的输出为[2,1,0]
            x = self._add_conv_transpose_layer(x,layers_index)
        return x

    def _add_conv_transpose_layer(self,x,layer_index):
        # 注意,这里的层序号是按照倒序来的,需要还原成正常序号
        # 一个卷积模块:卷积层+ReLu+batchnormalization
        layer_num = self._num_conv_layers - layer_index
        conv_transpose_layer  =Conv2DTranspose(
            filters = self.conv_filters[layer_index],
            kernel_size = self.conv_kernels[layer_index],
            strides = self.conv_strides[layer_index],
            padding = "same",
            name = f"decoder_conv_transpose_layer_{layer_num}"
        )
        x = conv_transpose_layer(x)
        x  =ReLU(name=f"decoder_ReLu_{layer_num}")(x)
        x = BatchNormalization(name = f"decoder_BN_{layer_num}")(x)
        return x

    def _add_decoder_output(self,x):
        """ 增加模型的输出层 """
        # 这部分要和encoder是一个完全的逆过程,而且之前的反卷积模块是少了最后一层
        # ,所以这里需要额外设置一层
        conv_transpose_layer = Conv2DTranspose(
            filters=1, # filters 对应图片中的channel.最终生成图片是一个[28,28,1]的灰度图片
            kernel_size=self.conv_kernels[0],
            strides=self.conv_strides[0],
            padding="same",
            name=f"decoder_conv_transpose_layer_{self._num_conv_layers}"
        )
        x = conv_transpose_layer(x)
        output_layer = Activation("sigmoid",name = "sigmoid_layer")(x)
        return output_layer


    # 3.1 实现整个模型而自动编码器
    # 7、从上到下,逐个子方法进行实现
    def _build_autoencoder(self):
        """ 对于自动编码器的识别,链接编码器和解码器 """
        model_input = self._model_input
        model_output = self.decoder(self.encoder(model_input))
        self.model = Model(model_input,model_output,name = "Autoencoder")


if __name__ == '__main__':
    autoencoder = Autoencoder(
        input_shape= [28,28,1],
        conv_filters = [32,64,64,64],
        conv_kernels = [3,3,3,3],
        conv_strides= [1, 2, 2, 1],
        latent_space_dim=2
    )

    autoencoder.summary()

实现代码——train代码

from ae import Autoencoder
from tensorflow.keras.datasets import mnist


LEARNING_RATE = 0.0005
BATCH_SIZE = 32
EPOCHS = 32


def load_mnist():
    (x_train,y_train),(x_test,y_test) = mnist.load_data()

    # 将数据正则化,在原来的数据上在增加一个维度,形成多维度的数据
    x_train = x_train.astype("float32") / 255
    x_train = x_train.reshape(x_train.shape + (1,))
    x_test = x_test.astype("float32") / 255
    x_test = x_test.reshape(x_test.shape + (1,))
    return x_train,y_train,x_test,y_test

def train(x_train,learning_rate,batch_size,epochs):
    autoencoder = Autoencoder(
        input_shape = (28,28,1),
        conv_filters= [32,64,64,64],
        conv_kernels = [3,3,3,3],
        conv_strides = [1, 2, 2, 1],
        latent_space_dim = 2,
    )
    autoencoder.summary()
    autoencoder.compile(learning_rate)
    autoencoder.train(x_train,batch_size,epochs)

    return autoencoder

if __name__ == '__main__':
    x_train,_,_,_ = load_mnist()
    autoencoder = train(x_train[:500],LEARNING_RATE, BATCH_SIZE,EPOCHS)
    autoencoder.save("model")
    autoencoder2 = Autoencoder.load("model")
    autoencoder2.summary()

实现代码——保存和加载模型的代码

这部分的代码并不需要掌握,也不是深度学习的重点,就是常见的画图以及scatter的绘制

""" 模型分析,这部分代码是用来分析模型的训练效果的 """
import numpy as np
import matplotlib.pyplot as plt

from ae import Autoencoder
from train_ae import load_mnist


def select_images(images, labels, num_images=10):
    """ 随机选择一定数量的图片 """
    sample_images_index = np.random.choice(range(len(images)), num_images)
    sample_images = images[sample_images_index]
    sample_labels = labels[sample_images_index]
    return sample_images, sample_labels


def plot_reconstructed_images(images, reconstructed_images):
    """ 用来画出重建之后的图片 """
    fig = plt.figure(figsize=(15, 3))
    num_images = len(images)
    for i, (image, reconstructed_image) in enumerate(zip(images, reconstructed_images)):
        image = image.squeeze()
        ax = fig.add_subplot(2, num_images, i + 1)
        ax.axis("off")
        ax.imshow(image, cmap="gray_r")
        reconstructed_image = reconstructed_image.squeeze()
        ax = fig.add_subplot(2, num_images, i + num_images + 1)
        ax.axis("off")
        ax.imshow(reconstructed_image, cmap="gray_r")
    plt.show()


def plot_images_encoded_in_latent_space(latent_representations, sample_labels):
    """ 用来绘制特征空间的,显示模型的训练效果 """
    plt.figure(figsize=(10, 10))
    plt.scatter(latent_representations[:, 0],
                latent_representations[:, 1],
                cmap="rainbow",
                c=sample_labels,
                alpha=0.5,
                s=2)
    plt.colorbar()
    plt.show()


if __name__ == "__main__":
    autoencoder = Autoencoder.load("model")
    x_train, y_train, x_test, y_test = load_mnist()

    num_sample_images_to_show = 8
    sample_images, _ = select_images(x_test, y_test, num_sample_images_to_show)
    reconstructed_images, _ = autoencoder.reconstruct(sample_images)
    plot_reconstructed_images(sample_images, reconstructed_images)

    num_images = 6000
    sample_images, sample_labels = select_images(x_test, y_test, num_images)
    _, latent_representations = autoencoder.reconstruct(sample_images)
    plot_images_encoded_in_latent_space(latent_representations, sample_labels)

运行结果

在这里插入图片描述

  • 我这里训练的比较少,而且数据集也比较少,所以点比较分散,下面是模型的训练效果

总结

  • 在实现代码的过程中,尽量将别人的代码进行二次封装,在自己的代码中,尽量使使用自己的代码,因为自己的代码知道有什么借口,该用什么样的参数,这点在train文件中体现的尤为明显,train以及load_mnist两个函数都是作者自己的封装的。
  • 在调用的参数中,如果确实用不到的,就将之声明为_,说明不会使用到。不要像以前一样,全部都命名,整个代码看起来乱的不行
  • 在准备数据集中,要注意,在原来图片的维度上,在增加一个新的维度,然后形成一个大的数据集,前三个维度是图片的温度,最后一个维度是图片的序号。
  • 将列表拆成独立的参数,是通过在列表前面加上“*”实现的,不要像以前一样,一个一个拆开写。
  • 对于python中的类方法需要了解一下,就是不用声明实例,可以直接调用,比如说加载模型就是这样,直接使用类名调用对应的函数,然后返回一个实例。

总结

  • 仅仅使用自动编码器提取特征,是将样例映射为特征空间中的的点,具有如下的缺陷
    • 特征空间分布不均衡,并不是关于原点对称
    • 特征空间存在大量的空白区域,对空白区域进行采样,生成的样例特征会很差
    • 特征空间分布不均衡,所以采样点也不均衡
  • 这里可以进行修改的地方
    • 特征提取部分可以增加一些卷积模块,使用不同的方式进行提取
    • 特征空间,可以使用高维度的特征空间,二维的特征空间,包含的数据太少了,并不能很好的表现数据的特征。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/522120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【半监督学习】Match系列.3

半监督语义分割旨在利用尽可能少的有标注图像以及大量的无标注图像来学得一个较好的分割模型。其中,对有标注图像的学习一般类似于全监督语义分割,如计算预测结果与人工标注之间的交叉熵损失,问题的关键在于如何利用无标注图像。 本文简单介…

【Unity】读写ProjectSettings、UserSettings、Library文件夹中的文件

【Unity】读写ProjectSettings、UserSettings、Library文件夹中的文件 AssetDatabase 类提供的 LoadAssetAtPath 方法和 CreateAsset 方法只能读写Assets、Packages文件夹中的资产,如果想要读写其他文件夹(ProjectSettings、UserSettings、Library等&am…

【运筹优化】元启发式算法详解:模拟退火算法(Simulated Annealing,SA)+ 案例讲解代码实战

文章目录 一、介绍二、基础知识2.1 局部搜索(或蒙特卡罗)算法2.2 Metropolis 算法2.3 模拟退火算法 三、原理3.1 Statistical Equilibrium 统计平衡3.2 Asymptotic Convergence 渐近收敛 四、实际问题4.1 Finite-Time Approximation 有限时间近似4.2 Geometric Cooling 几何冷却…

区块元素和超连结

DIV (区块元素) <div>元素&#xff08;HTML 文件区块元素&#xff09;是无标签语意的容器元素&#xff0c;虽然它不代表任何意义&#xff0c;却是使用最多的标签之一&#xff0c;主要用来把相似或者被划分为同一区块的内容包在同个div 内&#xff0c;以便后续添加css 样…

【MyBatis】一文教你学会使用MyBatis操作数据库

文章目录 1. MyBatis是什么&#xff1f;2. 为什么要学MaBatis&#xff1f;3. MyBatis环境搭建4. MyBatis的使用4.1 简单示例4.2 获取动态参数4.2.1 ${xxx}获取动态参数4.2.2 #{xxx}获取动态参数4.2.3 #{xxx}与${xxx}获取字符串类型数据4.2.4 sql注入问题4.2.5 模糊查询like4.2.…

动态规划-背包问题-背包九讲

title: 动态规划-背包问题 date: 2023-05-12 13:01:31 categories: Algorithm动态规划 tags:动态规划 01背包问题 题目 题目链接&#xff1a;https://www.acwing.com/problem/content/description/2/ 有 N N N 件物品和一个容量是 V V V 的背包。每件物品只能使用一次。 …

数据分析05——往Pandas中导入数据

1、导入Excel&#xff1a; 注意这种方法可以导入xlsx和xls两种类型的数据读入的数据会以DataFrame的格式显示举例&#xff1a;df pd.read_excel(‘./data/demo_03.xlsx’)还可以导入excel文件中具体的某一个表格&#xff1a;pd.read_excel(‘./data/demo_03.xlsx’, sheet_na…

SD-MTSP:麻雀搜索算法SSA求解单仓库多旅行商问题(提供MATLAB代码,可以修改旅行商个数及起点)

一、单仓库多旅行商问题 多旅行商问题&#xff08;Multiple Traveling Salesman Problem, MTSP&#xff09;是著名的旅行商问题&#xff08;Traveling Salesman Problem, TSP&#xff09;的延伸&#xff0c;多旅行商问题定义为&#xff1a;给定一个&#x1d45b;座城市的城市集…

postgresql源码学习(55)—— 列中的NULL值是如何存储和判断的?

问题来自 《PostgreSQL面试题集锦》学习与回答_Hehuyi_In的博客-CSDN博客 第11题 一、 NULL值存储位置 在pg元组头数据中&#xff0c;有一个t_bits数组&#xff0c;用于存储空值位图。当元组中没有null值的时候&#xff0c;t_bits可以被认为是空的&#xff0c;当元组有null值的…

javaweb学习 html+css基础1

1、学习路线 2、web网站的开发模式 课程安排 web 前端 前端学习内容 html和css的帮助网站 HTML 系列教程 (w3school.com.cn) html快速入门 使用VSCode开发工具&#xff0c;输入 &#xff01;enter&#xff0c;即可出现骨架。 ctrl/ 可以将文字转换为注释 右击一个页面…

【JavaEE】计网之IP协议+以太网+DNS

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶 网络层重点协议——IP协议&#xff0c;在复杂的网络环境中确定一个合适的路径~ 本篇文章我们来讲解什么是 IP协议及以太网&#xff0c;在IP协议中&#xff0c;有 地址管理 和 路由选择 两个…

C++中基类和派生类的构造函数与析构函数的调用顺序分析

基类为B&#xff0c;派生类为C&#xff0c;直接上代码以及运行结果。 目录 思路分析 代码一 运行结果一 代码二&#xff1a;B(i)改为b(i) 运行结果二 代码三&#xff1a;加上B(i) 运行结果三 代码四&#xff1a;删掉C类定义的B对象b&#xff0c;删除b(i) 运行结果四 思路…

Linux使用全应用

一、CentOS安装Docker Docker CE 支持 64 位版本 CentOS 7&#xff0c;并且要求内核版本不低于 3.10&#xff0c; CentOS 7 满足最低内核的要求&#xff0c;所以我们在CentOS 7安装Docker。 基础命令 搜索镜像&#xff1a;docker search mysql 下载镜像&#xff1a;docker p…

[架构之路-197]-《软考-系统分析师》- 关键技术 - 问题分析阶段重要的四个任务

目录 前言&#xff1a; 一、信息系统/软件产品的问题分析概述 二、信息系统/软件产品的问题/痛点分析四步骤 步骤1、问题领域分析&#xff1a;研究遇到问题的业务领域&#xff08;诉求&#xff09; 步骤2、 领域问题和机会分析&#xff1a;分析业务领域的问题、痛点、难点…

计算机网络学习 一 (计算机网络体系结构)

计算机网络 基本概念 计算机网络是一个将分散的,具有独立功能的计算机系统. 简单来说,计算机网络就是一些互连的,自治的计算机系统的集合 分类 广义上:是一个资源共享的系统. 资源共享上: 1.目的–资源共享 2.组成单元–分布在不同地理位置的多台独立的"自治计算机"…

第十四届蓝桥杯青少组模拟赛Python真题 (2022年11月8日)

第十四届蓝桥杯青少组模拟赛Python真题 (2022年11月8日) 编程题 第 1 题 问答题 二进制位数 十进制整数2在十进制中是1位数&#xff0c;在二进制中对应10&#xff0c;是2位数。 十进制整数22在十进制中是2位数&#xff0c;在二进制中对应10110&#xff0c;是5位数。 请问十…

Linux高级---k8s之service服务

文章目录 一、service基本概念二、service类型三、service的使用1、实验环境准备2、ClusterIP类型的Service3、HeadLiness类型的Service4、NodePort类型的Service5、LoadBalancer类型的Service6、ExternalName类型的Service 一、service基本概念 在kubernetes中&#xff0c;pod…

【Java多线程编程】线程的六种状态

前言&#xff1a; 在我们进行多线程编程&#xff0c;脑海里会想到线程运行的状态到底是什么&#xff1f;因此我整理出这线程的状态这篇博文。线程的状态分为六种&#xff1a;新建状态&#xff08;NEW&#xff09;、就绪状态&#xff08;RUNNABLE&#xff09;、阻塞状态&#xf…

1-Linux环境安装JDK

Linux环境安装JDK 准备&#xff1a; ① Linux 环境 本文中Linux环境为 CentOS Linux 7 可使用以下命令查询 linux 系统版本&#xff1a; hostnamectl② 准备JDK包 进入官网 https://www.oracle.com/java/technologies/downloads/#java17下载对应jdk包 此处使用以前下载的旧…

Linux驱动编程(驱动程序基石)(下)

一、中断的线程化处理 复杂、耗时的事情&#xff0c;尽量使用内核线程来处理。上节视频介绍的工作队列用起来挺简单&#xff0c;但是它有一个缺点&#xff1a;工作队列中有多个 work&#xff0c;前一个 work 没处理完会影响后面的 work。解决方法有很多种&#xff0c;比如干脆…