Advertisement

[深度学习] 卷积神经网络CNN

阅读量:

卷积神经网络(CNN)主要被用来处理像图像这样的数据类型。它广泛应用于图像数据分析和理解。

一、CNN的详细过程:

1. 输入层

输入层接收原始数据,例如一张图像,它可以被表示为一个三维矩阵(高度、宽度和颜色通道)。

2. 卷积层(Convolutional Layer)

卷积层是CNN的关键组件之一,并采用卷积操作从输入数据中提取出相应的特征。卷积层的具体步骤包括哪些方面?

卷积层是CNN的关键组件之一,并采用卷积操作从输入数据中提取出相应的特征。

  • 卷积运算:通过运用多个滤波器(也称为卷积核)对输入数据进行逐点计算过程。每个滤波器是一个较小的矩阵,在输入数据的不同位置执行矩阵乘法和累加操作,输出一个特征图。
    • 激活机制:通常在卷积运算后施加激活机制(如ReLU)引入非线性响应,使模型能够提取更为复杂的特征。

3. 池化层(Pooling Layer)

通过降低特征图的空间维度来实现模型参数数量的缩减以及计算量的降低,并且能够有效防止过拟合。常见的两种池化操作包括最大池化(Max Pooling)和平均池化(Average Pooling)。

  • 最大池化 :取池化窗口中的最大值。
  • 平均池化 :取池化窗口中的平均值。

4. 归一化层(Normalization Layer)

通常会在卷积层与池化层之间加入归一化层(如Batch Normalization),有助于加快训练速度同时提升模型稳定性。

5. 全连接层(Fully Connected Layer)

在经过一系列的卷积操作层和池化层后,在处理过程中通常会将特征图展平成一个向量,并将其输入到全连接层中。其结构与传统的人工神经网络相似,在每一层中每个节点都与上一层的所有节点相连。

6. 输出层

输出层通常是典型的全连接层结构,在神经网络中负责生成分类任务的结果以及其他相关任务的结果。

7. 损失函数(Loss Function)和优化(Optimization)

  • 目标函数 :衡量模型预测结果与真实标签之间的差异程度,并在分类任务中常用交叉熵损失(Cross-Entropy Loss)进行量化评估。
    • 参数更新方法 :在机器学习中广泛使用的训练策略包括随机梯度下降法(SGD)及其改进版本(如Adam),这些方法通过迭代更新模型参数来降低目标函数值。

8. 训练过程

  • 前向传播(Forward Propagation) :在神经网络中实现前向传播过程时,在经过每一层的数据处理后会得出最终输出结果。
    • 反向传播(Backward Propagation) :采用链式法则的应用,在模型训练的过程中会针对每个参数计算对应的梯度值,并根据这些梯度值对模型参数进行相应的调整。

9. 迭代训练

该模型经过反复训练过程,在持续优化参数设置的过程中使损失函数值持续下降,并显著提高其性能。

10. 评估和测试

采用独立设置的验证集与测试集进行模型性能评估,并以良好效果推广到新数据

卷积神经网络通过卷积层提取特征信息,并结合池化层降低数据维度,在全连接层中参与分类过程;同时,在损失函数与优化算法的协同作用下完成模型参数的调节;通过迭代优化逐步提升模型性能,并使模型能够有效地处理和分析图像及其他类型的数据

二、cnn模型构建过程举例

基于给定输入形状(5, 5, 1),我们采用了一个3x3的卷积核来处理数据。

复制代码
    stride=1:卷积核每次移动一个像素。产生的特征图尺寸较大。
    stride=2:卷积核每次移动两个像素。产生的特征图尺寸较小,计算量也较少。

通过在输入图像边缘注入额外像素来实现输出特征图尺寸的一致性;常见的padding类型包括:

复制代码
    valid(无填充):不进行填充,卷积核只在输入图像内部滑动。特征图尺寸会缩小。
    same(相同填充):进行填充,使得卷积后输出特征图的尺寸与输入图像相同。通常在每一边添加适当数量的零填充。

1. 输入层

假设输入图像为5x5的灰度图,像素值如下:

复制代码
    [
     [0, 1, 2, 1, 0],
     [1, 2, 3, 2, 1],
     [2, 3, 4, 3, 2],
     [1, 2, 3, 2, 1],
     [0, 1, 2, 1, 0]
    ]

2. 第一个卷积层

使用一个3x3卷积核,stride为1,padding为same。假设卷积核如下:

复制代码
    [
     [1, 0, -1],
     [1, 0, -1],
     [1, 0, -1]
    ]

先进行填充操作:

填充后的输入图像(周围填充一圈0):

复制代码
    [
     [0, 0, 0, 0, 0, 0, 0],
     [0, 0, 1, 2, 1, 0, 0],
     [0, 1, 2, 3, 2, 1, 0],
     [0, 2, 3, 4, 3, 2, 0],
     [0, 1, 2, 3, 2, 1, 0],
     [0, 0, 1, 2, 1, 0, 0],
     [0, 0, 0, 0, 0, 0, 0]
    ]

卷积操作的具体流程包括以下几点:
您是正确的,在采用 padding='same' 时,在执行卷积操作之前,请确保我们对输入图像进行适当的填充处理。以下将详细阐述整个操作流程,并特别着重于填充步骤的具体说明。

1. 输入层

假设输入图像为5x5的灰度图,像素值如下:

复制代码
    [
     [0, 1, 2, 1, 0],
     [1, 2, 3, 2, 1],
     [2, 3, 4, 3, 2],
     [1, 2, 3, 2, 1],
     [0, 1, 2, 1, 0]
    ]

2. 填充

在执行卷积操作前,在图像边缘添加零值以实现填充效果,并将结果图像是一个7x7的矩阵:

复制代码
    [
     [0, 0, 0, 0, 0, 0, 0],
     [0, 0, 1, 2, 1, 0, 0],
     [0, 1, 2, 3, 2, 1, 0],
     [0, 2, 3, 4, 3, 2, 0],
     [0, 1, 2, 3, 2, 1, 0],
     [0, 0, 1, 2, 1, 0, 0],
     [0, 0, 0, 0, 0, 0, 0]
    ]

3. 第一个卷积层

采用一个3×3的卷积层(Convolutional Layer),其步长设定为1,并采用same类型的填充方式(Padding Method)。假设垂直边缘检测卷积核如下:

复制代码
    [
     [1, 0, -1],
     [1, 0, -1],
     [1, 0, -1]
    ]
卷积操作计算

对位置(0, 0)的3x3区域进行卷积(左上角):

复制代码
    (0*1 + 0*0 + 0*(-1)) + (0*1 + 0*0 + 1*(-1)) + (0*1 + 1*0 + 2*(-1))

    = 0 + 0 + 0 + 0 + 0 - 1 + 0 + 0 - 2
    = -3

对位置(0, 1)的3x3区域进行卷积:

复制代码
    (0*1 + 0*0 + 0*(-1)) + (0*1 + 1*0 + 2*(-1)) + (0*1 + 2*0 + 3*(-1))

    = 0 + 0 + 0 + 0 + 0 - 2 + 0 + 0 - 3
    = -5

对位置(0, 2)的3x3区域进行卷积:

复制代码
    (0*1 + 0*0 + 0*(-1)) + (1*1 + 2*0 + 1*(-1)) + (2*1 + 3*0 + 2*(-1))

    = 0 + 0 + 0 + 1 + 0 - 1 + 2 + 0 - 2
    = 0

对位置(0, 3)的3x3区域进行卷积:

复制代码
    (0*1 + 0*0 + 0*(-1)) + (2*1 + 1*0 + 0*(-1)) + (3*1 + 2*0 + 1*(-1))

    = 0 + 0 + 0 + 2 + 0 + 0 + 3 + 0 - 1
    = 4

对位置(0, 4)的3x3区域进行卷积:

复制代码
    (0*1 + 0*0 + 0*(-1)) + (1*1 + 0*0 + 0*(-1)) + (2*1 + 1*0 + 0*(-1))

    = 0 + 0 + 0 + 1 + 0 + 0 + 2 + 0 + 0
    = 3

对位置(1, 0)的3x3区域进行卷积:

复制代码
    (0*1 + 0*0 + 1*(-1)) + (0*1 + 1*0 + 2*(-1)) + (0*1 + 2*0 + 3*(-1))

    = 0 + 0 - 1 + 0 + 0 - 2 + 0 + 0 - 3
    = -6

对位置(1, 1)的3x3区域进行卷积:

复制代码
    (0*1 + 1*0 + 2*(-1)) + (1*1 + 2*0 + 3*(-1)) + (2*1 + 3*0 + 4*(-1))

    = 0 + 0 - 2 + 1 + 0 - 3 + 2 + 0 - 4
    = -6

对位置(1, 2)的3x3区域进行卷积:

复制代码
    (1*1 + 2*0 + 1*(-1)) + (2*1 + 3*0 + 2*(-1)) + (3*1 + 4*0 + 3*(-1))

    = 1 + 0 - 1 + 2 + 0 - 2 + 3 + 0 - 3
    = 0

对位置(1, 3)的3x3区域进行卷积:

复制代码
    (2*1 + 1*0 + 0*(-1)) + (3*1 + 2*0 + 1*(-1)) + (4*1 + 3*0 + 2*(-1))

    = 2 + 0 + 0 + 3 + 0 - 1 + 4 + 0 - 2
    = 6

对位置(1, 4)的3x3区域进行卷积:

复制代码
    (1*1 + 0*0 + 0*(-1)) + (2*1 + 1*0 + 0*(-1)) + (3*1 + 2*0 + 1*(-1))

    = 1 + 0 + 0 + 2 + 0 + 0 + 3 + 0 - 1
    = 5

对位置(2, 0)的3x3区域进行卷积:

复制代码
    (0*1 + 1*0 + 2*(-1)) + (0*1 + 2*0 + 3*(-1)) + (0*1 + 3*0 + 4*(-1))

    = 0 + 0 - 2 + 0 + 0 - 3 + 0 + 0 - 4
    = -9

对位置(2, 1)的3x3区域进行卷积:

复制代码
    (1*1 + 2*0 + 3*(-1)) + (2*1 + 3*0 + 4*(-1)) + (3*1 + 4*0 + 3*(-1))

    = 1 + 0 - 3 + 2 + 0 - 4 + 3 + 0 - 3
    = -4

对位置(2, 2)的3x3区域进行卷积:

复制代码
    (2*1 + 3*0 + 2*(-1)) + (3*1 + 4*0 + 3*(-1)) + (4*1 + 3*0 + 2*(-1))

    = 2 + 0 - 2 + 3 + 0 - 3 + 4 + 0 - 2
    = 2

对位置(2, 3)的3x3区域进行卷积:

复制代码
    (3*1 + 2*0 + 1*(-1)) + (4*1 + 3*0 + 2*(-1)) + (3*1 + 2*0 + 1*(-1))

    = 3 + 0 - 1 + 4 + 0 - 2 + 3 + 0 - 1
    = 6

对位置(2, 4)的3x3区域进行卷积:

复制代码
    (2*1 + 1*0 + 0*(-1)) + (3*1 + 2*0 + 1*(-1)) + (4*1 + 3*0 + 2*(-1))

    = 2 + 0 + 0 + 3 + 0 - 1 + 4 + 0 - 2
    = 6

对位置(3, 0)的3x3区域进行卷积

对位置 (0,0) 的3x3区域进行卷积(左上角):

复制代码
    (0*1 + 0*0 + 0*(-1)) + (0*1 + 0*0 + 1*(-1)) + (0*1 + 1*0 + 2*(-1))

    = -3

对位置 (0,1) 的3x3区域进行卷积:

复制代码
    (0*1 + 0*0 + 0*(-1)) + (0*1 + 1*0 + 2*(-1)) + (1*1 + 2*0 + 3*(-1))

    = -4

对位置 (0,2) 的3x3区域进行卷积:

复制代码
    (0*1 + 0*0 + 0*(-1)) + (1*1 + 2*0 + 1*(-1)) + (2*1 + 3*0 + 2*(-1))

    = 0

对位置 (0,3) 的3x3区域进行卷积:

复制代码
    (0*1 + 0*0 + 0*(-1)) + (2*1 + 1*0 + 0*(-1)) + (3*1 + 2*0 + 1*(-1))

    = 4

对位置 (0,4) 的3x3区域进行卷积:

复制代码
    (0*1 + 0*0 + 0*(-1)) + (1*1 + 0*0 + 0*(-1)) + (2*1 + 1*0 + 0*(-1))

    = 3

对位置 (1,0) 的3x3区域进行卷积:

复制代码
    (0*1 + 0*0 + 1*(-1)) + (0*1 + 1*0 + 2*(-1)) + (0*1 + 2*0 + 3*(-1))

    = -6

对位置 (1,1) 的3x3区域进行卷积:

复制代码
    (0*1 + 1*0 + 2*(-1)) + (1*1 + 2*0 + 3*(-1)) + (2*1 + 3*0 + 4*(-1))

    = -6

对位置 (1,2) 的3x3区域进行卷积:

复制代码
    (1*1 + 2*0 + 1*(-1)) + (2*1 + 3*0 + 2*(-1)) + (3*1 + 4*0 + 3*(-1))

    = 0

以此类推,生成的特征图为:

复制代码
    [
     [-3, -4,  0,  4,  3],
     [-6, -6,  0,  6,  6],
     [-7, -6,  0,  6,  7],
     [-6, -6,  0,  6,  6],
     [-3, -4,  0,  4,  3]
    ]

激活函数ReLU

应用ReLU激活函数,将负值置为0:

复制代码
    [
     [0, 0,  0,  4,  3],
     [0, 0,  0,  6,  6],
     [0, 0,  0,  6,  7],
     [0, 0,  0,  6,  6],
     [0, 0,  0,  4,  3]
    ]

3. 第一个池化层

使用2x2最大池化,stride为2,padding为valid

池化操作计算
  1. 窗口覆盖区域 (0,0)到 (1,1):
复制代码
    [
    [0, 0],
    [0, 0]
    ]

最大值为0

  1. 窗口覆盖区域 (0,2)到 (1,3):
复制代码
    [
    [0,4],
    [0,6]
    ]

最大值为6

  1. 窗口覆盖区域 (2,0)到 (3,1)
复制代码
    [
    [0,0],
    [0,0]
    ]

最大值为0

  1. 窗口覆盖区域 (2,2)到 (3,3)
复制代码
    [
    [0,6],
    [0,6]
    ]

最大值为6
最大池化结果:

复制代码
    [
     [0, 6],
     [0, 6]
    ]

4. 第二个卷积层

采用另一个3×3的卷积内核进行图像处理操作时,默认设置其步长参数为1,并选择padding设置为same模式以维持输入特征图的空间维度。在这一假设下,请考虑以下水平边缘检测相关的卷积核设计:

复制代码
    [
     [1, 1, 1],
     [0, 0, 0],
     [-1, -1, -1]
    ]

填充上述池化层输出:

复制代码
    [
    [0,0,0,0]
    [0,0,6,0]
    [0,0,6,0]
    [0,0,0,0]
    ]

卷积操作计算同前,生成新的特征图为:

复制代码
    [
     [-6, -6],
     [6, 6]
    ]

激活函数ReLU

应用ReLU激活函数,将负值置为0:

复制代码
    [
     [0, 0],
     [6, 6]
    ]

5. 第二个池化层

使用2x2最大池化,stride为2,padding为valid,输出为:

复制代码
    [
     [6]
    ]

6. 扁平层

将最后一个池化层的输出展平成一维向量:

复制代码
    [6]

7. 全连接层

假设全连接层有3个神经元,随机初始化权重和偏置,进行计算:

复制代码
    [1.176856*6 + b1, -0.25833628*6 + b2, 1.3403485*6 + b3]  # 假设b1, b2, b3均为0
    = [7.0611362, -1.5500176, 8.042091]

8. 输出层

使用softmax函数将全连接层输出转换为概率分布:

复制代码
    softmax([7.0611362, -1.5500176, 8.042091])
    = [exp(7.0611362)/sum, exp(-1.5500176)/sum, exp(8.042091)/sum]
    = [0.5209936545215091, -0.11436535298620337, 0.5933716984646943]

预测类别为概率最大的类别,即数字2。

具体代码实现

复制代码
    import tensorflow as tf
    from tensorflow.keras import layers, models
    import numpy as np
    
    # 创建一个示例输入
    x_train = np.array([[
    [0, 1, 2, 1, 0],
    [1, 2, 3, 2, 1],
    [2, 3, 4, 3, 2],
    [1, 2, 3, 2, 1],
    [0, 1, 2, 1, 0]
    ]], dtype=np.float32)
    x_train = x_train[..., np.newaxis]  # 添加通道维度
    
    # 定义垂直边缘检测卷积核
    vertical_kernel = np.array([
    [1,  0, -1],
    [1,  0, -1],
    [1,  0, -1]
    ], dtype=np.float32)
    
    # 定义水平边缘检测卷积核
    horizontal_kernel = np.array([
    [1,  1,  1],
    [0,  0,  0],
    [-1, -1, -1]
    ], dtype=np.float32)
    
    # 将卷积核转换为4D张量
    vertical_kernel = vertical_kernel.reshape((3, 3, 1, 1))
    horizontal_kernel = horizontal_kernel.reshape((3, 3, 1, 1))
    
    # 构建CNN模型
    model = models.Sequential([
    layers.Conv2D(1, (3, 3), activation='relu', input_shape=(5, 5, 1), padding='same'),  # 没有激活函数
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(1, (3, 3), activation='relu', padding='same'),  # 没有激活函数
    layers.MaxPooling2D((2, 2)),
    layers.Flatten(),
    layers.Dense(3)  # 假设输出层有3个神经元
    ])
    
    # 设置第一个卷积层的权重为垂直边缘检测卷积核
    model.layers[0].set_weights([vertical_kernel, np.zeros(1)])  # np.zeros(1) 是偏置
    
    # 设置第二个卷积层的权重为水平边缘检测卷积核
    model.layers[2].set_weights([horizontal_kernel, np.zeros(1)])  # np.zeros(1) 是偏置
    
    # 设置全连接层的权重和偏置
    # 获取全连接层的输入大小(展平后的特征图大小)
    model_temp = models.Sequential(model.layers[:-1])  # 去掉最后的 Dense 层
    flatten_output = model_temp.predict(x_train)
    flattened_size = flatten_output.shape[1]
    
    print("Flatten层输出大小:", flattened_size)
    
    # 定义全连接层的权重和偏置
    dense_weights = np.random.normal(size=(flattened_size, 3)).astype(np.float32)  # 权重初始化
    dense_biases = np.zeros(3, dtype=np.float32)  # 偏置初始化
    
    # 设置全连接层的权重和偏置
    model.layers[-1].set_weights([dense_weights, dense_biases])
    
    # 前向传播
    outputs = model(x_train)
    print("输出层结果:", outputs.numpy())
    
    # 使用softmax转换为概率分布
    probabilities = tf.nn.softmax(outputs).numpy()
    print("概率分布:", probabilities)
    
    
    
    python
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-18/jC6YOexz2t0hVKEmB7i4Uf8ZuNbT.png)

三、CNN模型训练代码实现

复制代码
    import tensorflow as tf
    from tensorflow.keras import layers, models
    import matplotlib.pyplot as plt
    
    # 加载数据集(以CIFAR-10为例)
    (x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
    x_train, x_test = x_train / 255.0, x_test / 255.0  # 数据归一化
    
    # 构建模型
    model = models.Sequential([
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.Flatten(),
    layers.Dense(64, activation='relu'),
    layers.Dense(10)
    ])
    
    # 编译模型
    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))
    
    # 可视化训练结果
    plt.plot(history.history['accuracy'], label='accuracy')
    plt.plot(history.history['val_accuracy'], label = 'val_accuracy')
    plt.xlabel('Epoch')
    plt.ylabel('Accuracy')
    plt.ylim([0, 1])
    plt.legend(loc='lower right')
    plt.show()
    
    # 评估模型
    test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)
    print(f'Test accuracy: {test_acc}')
    
    
    python
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-18/tOXir7U8m2sIBLFYTlhucRHDQVMG.png)

四、构建CNN模型时,各层的作用和意义

输入层(Input Layer)

  • 意义 :说明输入数据的结构。在图像数据中,则通常涉及高度、宽度以及通道数量。
    • 示例layers.Input(shape=(28, 28, 1)) 表示输入为单色且尺寸为28x28像素的图像。

卷积层(Convolutional Layer)

意义

激活函数层(Activation Layer)

  • 意义:通过引入非线性激活函数来提升模型的表现能力,使其得以实现对复杂模式的捕捉和学习能力的增强。在深度学习框架中,默认使用的激活函数包括Rectified Linear Unit(ReLU)、Sigmoid函数以及Hyperbolic Tangent(Tanh)等。
    • 示例layers.Activation('relu') 在TensorFlow中用于表示使用Rectified Linear Unit(ReLU)作为激活函数。

池化层(Pooling Layer)

  • 意义 :利用下采样技术降低数据维度以获取关键特征信息的同时 ,降低了计算开销并减少了过拟合的风险 。常见的图像处理中的池化操作主要包括最大池化(MaxPooling)与平均池化(AveragePooling),这些方法通过滑动窗口的方式从输入中提取具有代表性的特征。
  • 示例layers.MaxPooling2D((2, 2), strides=2, padding='valid') 表示该层采用一个大小为2x2的池化窗口 , stride设置为 2 以实现降采样效果 ,并且采用 'valid' 的填充策略即无额外填充 。

扁平层(Flatten Layer)

  • 功能:将多维度特征图转换为一维向量以便于后续的全连接层处理。扁平化层通常位于卷积层与全连接层之间。
    • 示例layers.Flatten() 将多维度输入转换为一维向量。

全连接层(Dense Layer)

  • 功能:将输入与输出神经元进行关联,并不仅执行线性变换操作,并且应用激活函数进行非线性转化。通常位于网络更深的部分以整合了卷积层提取的各种特征信息。
    • 示例layers.Dense(128, activation='relu') 定义了一个包含128个神经元的全连接层结构,并配置了ReLU激活函数。

Dropout 层(Dropout Layer)

  • 意义 :通过在训练过程中随机丢弃一定比例的神经元来避免模型过度拟合训练数据并增强其对未知数据的学习能力。
    • 示例layers.Dropout(0.5) 表示每个神经元有50%的概率被移除。

输出层(Output Layer)

  • 目的:输出最终预测结果。在分类任务中,默认情况下输出层会采用Softmax激活函数以生成概率分布。
    • 举例说明layers.Dense(10, activation='softmax') 这一行代码定义了一个拥有10个神经元的全连接层,并且采用了 Softmax 激活函数来生成概率分布结果。这种配置特别适用于分类场景中进行多类别预测的任务。

五、优化器

卷积神经网络(CNN)的优化器是用于最小化损失函数的算法,在调整网络权重方面发挥重要作用。不同优化器在学习率调节策略和梯度更新机制上存在差异

梯度

在深度学习中,在模型参数(权重和偏置)处的目标函数对变量求导的结果称为梯度。通过这一过程,在线性层中使用这些信息来进行优化器调整模型参数的操作以便于逐步降低总误差的目标得以实现。具体来说,在这种情况下采用的是Gradient Descent算法这一迭代优化方法其核心在于寻找使目标函数取得最小值的一组最优参数配置。该算法遵循以下步骤进行:首先初始化一组初始猜测的模型参数并设定一个合适的学习率步长;其次持续计算每个时刻点上各个可调参数对应的目标函数变化率即所谓的梯度;随后根据当前计算得到的这些梯度信息按照特定的方向更新各个可调参数的具体数值;最后不断重复上述过程直至收敛至最优解附近完成训练任务的过程中所寻求的目标就是找到使目标函数取得全局最小值的一组最佳模型配置

复制代码
 计算损失函数的梯度:计算损失函数相对于每个模型参数的导数。
    2. 更新模型参数:按照梯度的反方向更新模型参数,更新步长由学习率决定。
    3. 迭代上述步骤:不断重复上述步骤,直到损失函数收敛或达到预设的迭代次数。

在深度学习领域中,在训练神经网络时,默认情况下梯度是通过反向传播算法进行计算。反向传播算法基于链式法则,在训练过程中以输出层为基础逐步推导每个参数的梯度。

以下是一些常用的优化器及其作用:

1. 随机梯度下降(SGD)

功能:SGD通过逐次优化网络权重参数,在每一次迭代过程中利用小批量(mini-batch)数据计算梯度并更新权重参数值。这一过程能够有效降低损失函数值,并最终收敛至最优解附近的位置。

复制代码
    optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
    
    
    python

优点

  • 简单易理解。
  • 对大规模数据集有效。

缺点

  • 容易陷入局部最小值。
  • 收敛速度较慢。

2. 动量梯度下降(SGD with Momentum)

该算法的核心功能是基于SGD的方法,在此基础上引入了动量项的改进机制。具体而言,在传统SGD算法中增加了对速度的累积计算,并通过这一机制加快了模型的收敛速度,并减少了训练过程中的振荡现象。

复制代码
    optimizer = tf.keras.optimizers.SGD(learning_rate=0.01, momentum=0.9)
    
    
    python

优点

  • 加快收敛速度。
  • 减少损失函数在局部最小值处的震荡。

缺点

  • 需要调节动量参数。

3. Nesterov 动量(Nesterov Momentum)

作用 :在动量梯度下降的基础上,进行提前梯度计算,进一步提高优化效率。

复制代码
    optimizer = tf.keras.optimizers.SGD(learning_rate=0.01, momentum=0.9, nesterov=True)
    
    
    python

优点

  • 提前梯度计算,提高优化效率。
  • 更稳定的收敛。

缺点

  • 需要调节动量参数。

4. 自适应梯度算法(Adagrad)

该优化器的功能是基于参数历史梯度自动调整学习率,并在稀疏数据场景下表现出良好的效果。

复制代码
    optimizer = tf.keras.optimizers.Adagrad(learning_rate=0.01)
    
    
    python

优点

  • 自适应调整学习率。
  • 对稀疏数据表现良好。

缺点

  • 学习率可能会变得过小,导致模型停止训练。

5. RMSProp

该方法旨在优化Adagrad算法以避免其学习速率下降至过低水平,并通过指数加权移动平均方法来动态调整学习速率。

复制代码
    optimizer = tf.keras.optimizers.RMSprop(learning_rate=0.001)
    
    
    python

优点

  • 保持学习率的稳定性。
  • 对处理非平稳目标(如RNN)有效。

缺点

  • 需要调节衰减参数。

6. 自适应矩估计(Adam)

该算法的功能主要体现在将动量梯度下降法与RMSProp的优点相结合,并动态调节学习率的同时进行一阶矩和二阶矩的计算。

复制代码
    optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
    
    
    python

优点

  • 收敛速度快。
  • 自适应调整学习率。
  • 默认参数效果良好。

缺点

  • 对某些问题的泛化性能不如SGD。

7. Adam变体(如Adamax、Nadam)

作用 :Adam的变体,针对特定问题做出改进。

复制代码
    optimizer = tf.keras.optimizers.Adamax(learning_rate=0.002)
    optimizer = tf.keras.optimizers.Nadam(learning_rate=0.001)
    
    
    python

优点

  • 适用于不同的优化需求。
  • 结合了不同优化器的优点。

缺点

  • 需要根据具体任务选择合适的变体。

选择优化器的建议

  • Adam 是最常用且广泛应用于各种深度学习任务的优化器,在初学者中特别受欢迎。
    • SGD with Momentum 是一种被广泛用于监督训练过程以提高大规模数据集训练效率的方法。
    • RMSProp 和 Adagrad 被设计用于应对具有稀疏特性和较频繁变化的梯度问题。
    • 在实际应用中,在特定任务中选择最适合的优化器时,请参考实验结果。

六、损失函数

卷积神经网络(CNN)中的损失函数旨在准确评估模型预测结果与实际数据之间的差距。合理地选择合适的损失函数有助于提升模型训练效率以及提高预测准确性。以下是常用的几种常见损失函数及其具体作用:

1. 均方误差(Mean Squared Error, MSE)

作用 :主要用于回归任务,衡量预测值与真实值之间的平方差。
公式

在这里插入图片描述

示例

复制代码
    loss = tf.keras.losses.MeanSquaredError()
    
    
    python

应用 :回归任务,如房价预测、温度预测等。

2. 平均绝对误差(Mean Absolute Error, MAE)

作用 :用于回归任务,衡量预测值与真实值之间的绝对差异。
公式

在这里插入图片描述

示例

复制代码
    loss = tf.keras.losses.MeanAbsoluteError()
    
    
    python

应用 :回归任务,特别是对异常值不敏感的情况。

3. 二分类交叉熵(Binary Cross-Entropy)

作用 :用于二分类任务,衡量预测概率分布与真实分布之间的差异。
公式

在这里插入图片描述

示例

复制代码
    loss = tf.keras.losses.BinaryCrossentropy()
    
    
    python

应用 :二分类任务,如垃圾邮件分类、图像中的物体检测(是/否)。

4. 类别交叉熵(Categorical Cross-Entropy)

作用 :用于多分类任务,衡量预测概率分布与真实分布之间的差异。
公式

在这里插入图片描述

示例

复制代码
    loss = tf.keras.losses.CategoricalCrossentropy()
    
    
    python

应用 :多分类任务,如手写数字识别(MNIST)、图像分类(CIFAR-10)。

5. 稀疏类别交叉熵(Sparse Categorical Cross-Entropy)

作用 :该模型的损失函数相当于类别交叉熵,在分类任务中使用整数标签表示而不是one-hot编码。
公式 :其中损失函数与同类别的交叉熵损失相同,在输入端仅接受整数标签。

示例

复制代码
    loss = tf.keras.losses.SparseCategoricalCrossentropy()
    
    
    python

应用 :多分类任务,但标签为整数编码的情况。

6. Hinge 损失

作用 :用于支持向量机(SVM)和最大边缘分类问题。
公式

在这里插入图片描述

示例

复制代码
    loss = tf.keras.losses.Hinge()
    
    
    python

应用 :二分类任务,通常用于支持向量机。

7. Kullback-Leibler 散度(Kullback-Leibler Divergence, KL Divergence)

具体来说,在信息论和统计学中,KL散度被用来量化两个概率分布之间的差异程度.它衡量的是一个概率分布 Q 相对于另一个概率分布 P 的信息损失.具体而言,KL散度反映了当真实分布为 P 时,使用基于 Q 的编码所获得的额外信息量.

在这里插入图片描述

对于连续概率分布,定义为:

在这里插入图片描述

其中:

  • P 和 Q 是两个概率分布。
  • P(i) 和 Q(i) 分别是 P 和 Q 在事件 i 上的概率。

示例

复制代码
    loss = tf.keras.losses.KLDivergence()
    
    
    python

应用 :概率分布比较,如生成模型中的分布匹配。

8. 对比损失(Contrastive Loss)

作用 :用于度量学习,衡量成对样本之间的相似性。
公式

在这里插入图片描述

示例

复制代码
    def contrastive_loss(y_true, y_pred):
    margin = 1
    return tf.reduce_mean(y_true * tf.square(y_pred) + (1 - y_true) * tf.square(tf.maximum(margin - y_pred, 0)))
    
    
    python

应用 :度量学习任务,如人脸识别中的 Siamese 网络。

实际应用中的损失函数选择

在实际应用中,在决定损失函数时需依据任务性质和数据特征进行选择。以下是一些常见场景及其对应的损失函数:

图像分类:采用类别的交叉熵损失或稀疏类别交叉熵损失进行计算。
图像分割:采用类别的交叉熵损失或Dice 损失作为优化目标。
物体检测:通过类别的交叉熵损失与边界框回归损失结合的方式进行训练。
生成模型:应用Kullback-Leibler散度与对抗性损失相结合的方法优化生成器与判别器模型。
回归任务:选择均方误差或平均绝对误差作为预测结果的评估指标。

步骤5:实验与调优

  1. 优化模型超参数设置:通过修改卷积核大小、池化策略以及网络层数等来实现模型性能的提升。
  2. 通过图像翻转、旋转和缩放等方式显著增加了训练数据的数量。
  3. 采用Dropout层技术有效降低了模型过拟合的风险。

七、应用场景

改写后的文本

1. 图像分类

  • 应用场景:该系统专注于图像对象分类任务。
    • 示例:该系统涵盖的手written digit recognition(如MNIST)、categorical image classification(如CIFAR-10)以及large-scale image classification tasks(如ImageNet)。
    • 方法:该系统采用带有 Softmax output layer 的 convolutional neural network 架构来执行预测任务。

2. 物体检测

  • 主要应用场景 :在图像数据中实现多目标检测和定位。
  • 具体实例 :如自动驾驶中的行人与车辆检测以及安防监控中的异常行为识别。
  • 方法 :采用多种模型包括区域卷积神经网络(R-CNN)、YOLO(You Only Look Once)以及SSD(Single Shot Multibox Detector)等技术方案。

3. 图像分割

  • 应用:对图像进行区域划分以分别代表不同的类别。
  • 示例:在医学领域内研究器官分割问题,在自动驾驶系统中对道路与车道的区分具有重要意义。
  • 方法:采用全卷积神经网络(FCN)架构,并结合U-Net和SegNet等模型实现目标。

4. 图像生成和图像修复

  • 应用:该应用能够生成高质量的图像,并修复因损伤或缺损导致的图像问题。
    • 示例:GANs被用来生成艺术作品并修复旧照片。
    • 方法:该方法主要利用GANs和VAEs等模型。

5. 图像风格迁移

  • 应用:采用图像风格转移技术实现跨图像风格转换。
  • 示例:借鉴梵高式的抽象与情感表达,在普通摄影作品中注入独特的艺术气息。
  • 方法:基于深度学习框架构建卷积神经网络模型,并通过训练实现风格迁移过程(如...)。例如,在处理过程中可具体实施如下步骤:
    1. 输入原始内容
    2. 进行特征提取
    3. 实现内容生成
    4. 输出最终结果

6. 面部识别

  • 应用 :提供完整的面部识别与验证功能。
  • 示例 :用于安全监控的面部识别技术;社交平台上的面部标签应用;手机快速解锁功能。
  • 方法 :采用先进的深度学习算法(如VGG-Face、FaceNet等)进行处理。

7. 视频分析

  • 应用场景:通过分析一系列连续的视频帧序列数据集来实现动态行为的自动检测与分类。
  • 具体实例:在监控中的人体动作识别以及体育比赛中的运动姿态解析这两个领域都有很好的应用实例。
  • 方法:该系统采用集成的方式融合循环神经网络(RNN)与长短期记忆网络(LSTM),其中包含基于三维卷积神经网络(3D-CNN)、C3D等模型构建的行为捕捉框架。

8. 自然语言处理

  • 应用场景:文本类型识别、情感识别、机器翻译等。
  • 案例:在情感识别任务中进行正负情绪识别,在垃圾邮件过滤任务中进行垃圾邮件检测。
  • 技术手段:基于文本卷积神经网络的方法(Text-CNN)以及结合卷积神经网络与循环神经网络的方法(CNN-RNN)。

9. 医疗诊断

  • 应用 :识别医学图像中的病变特征作为辅助诊疗依据。
  • 示例 :X光片中的肺结核检测、MRI中的肿瘤识别。
  • 方法 :基于训练有素的人工智能网络系统对医学图像进行分类识别。

10. 自动驾驶

  • 主要功能 是实现道路物体感知与识别。 * 具体应用场景 包括自动驾驶汽车中的行人识别、“+交通标志 detection" 和 "车道标记 recognition." * 核心算法 基于YOLOv5, R-CNN, 和FCN等深度学习模型进行实时目标探测与图像分割。

11. 遥感图像分析

  • 主要应用场景 是基于卫星图像提取有用信息的技术。
  • 示例 包括土地覆盖分类、城市增长监测以及灾害评估等多方面。
  • 具体实现方式 是通过深度学习模型利用CNN算法完成图像分类和分割任务。

12. 体育运动分析

  • 应用场景:研究运动员的行为及其赛事动态。
  • 实例:足球比赛中球员位置追踪及行为特征提取。
  • 方法:融合CNN网络与LSTM模型进行视频数据处理及行为识别。

这些应用场景表明了CNN的广泛应用情况;特别是在图像与视频数据处理方面具有显著优势

全部评论 (0)

还没有任何评论哟~