社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

【深度学习】讲透一个强大算法模型,CNN !!

机器学习初学者 • 1 月前 • 110 次点击  

咱们今天想要和大家聊聊关于CNN的内容。

很多同学私下,和我聊起来关于深度学习的东西,我这边也想和大家分享一些基础内容出来。帮助大家入门。

CNN,全称是卷积神经网络(Convolutional Neural Network),它是一种专门用于处理图像数据的神经网络。

简单来说,CNN就像是一种能够“看”图像的计算机模型,它可以识别图像中的各种特征,比如边缘、形状、颜色等,最终能够识别出这张图像里有什么东西。

基本概念

基本组成部分

1. 卷积层(Convolutional Layer)

  • 这是CNN的核心部分。想象一下,有一个小方块在图像上面滑动,这个小方块叫做卷积核(filter)。每当卷积核滑动到一个新的位置,它会查看那个位置的像素值,并进行一些计算(比如相乘再相加)。
  • 卷积核就像是一个“特征检测器”,不同的卷积核可以检测出不同的特征,比如某个方向的边缘、颜色的变化等。

2. 激活函数(Activation Function)

  • 这个函数会对卷积层的输出进行非线性处理,通常使用的是ReLU(Rectified Linear Unit),它的作用是让结果变得更有表现力。ReLU的操作很简单:把所有小于0的数都变成0,其他的不变。

3. 池化层(Pooling Layer)

  • 池化层的作用是缩小数据的尺寸,同时保留重要信息。最常见的是最大池化(Max Pooling),它会在一个小区域内选择最大的值。这样做不仅可以减少计算量,还可以让模型对位置的变化更有鲁棒性。

4. 全连接层(Fully Connected Layer)

  • 这是CNN的最后几层,和传统的神经网络类似。它把前面的卷积层和池化层提取出来的特征综合起来,最终输出分类结果。

CNN是如何工作的?

1. 输入图像

  • 比如我们输入一张猫的图片。

2. 卷积层处理

  • 卷积核在整张图片上滑动,提取出边缘、颜色等低级特征。

3. 池化层处理

  • 对特征进行缩小,减少数据量,同时保留重要信息。

4. 重复几次卷积和池化

  • 通常会有多次卷积和池化的操作,以提取更复杂的特征。

5. 全连接层处理

  • 最后,通过全连接层,综合所有提取到的特征,进行最终的分类。

6. 输出结果

  • 比如,这张图像是“猫”的概率是90%,是“狗”的概率是10%。

总的来说,CNN是一种非常非常强大的图像识别工具,它能够自动提取图像中的各种特征,然后利用这些特征进行分类和识别。对于大多数的初学者来说,可以先理解每个组成部分的基本功能,再逐步深入了解具体的数学原理和实现细节。

理论基础

下面我来给大家详细介绍CNN卷积神经网络的数学原理、公式推理以及算法流程。

1. 卷积层(Convolutional Layer)

卷积运算

卷积运算是CNN的核心操作。对于输入图像  和卷积核(过滤器) ,卷积运算的公式:

其中:

  •  是输入图像在位置  的像素值。
  •  是卷积核在位置  的权重。
  •  是卷积结果在位置  的值。

假设输入图像大小为 ,卷积核大小为 ,没有使用填充(padding),卷积步幅(stride)为 1,那么输出图像的大小为 

填充和步幅

  • 填充(Padding):为了保持输入和输出的尺寸不变,通常在输入图像的边缘添加一圈零值,称为零填充。填充大小为  时,输出图像的大小为:

其中, 是步幅。

  • 步幅(Stride):步幅决定了卷积核在图像上滑动的步长。步幅为  时,卷积运算的输出大小为:

2. 激活函数(Activation Function)

激活函数用于引入非线性。最常用的激活函数是ReLU(Rectified Linear Unit):

3. 池化层(Pooling Layer)

池化层用于降采样,减少数据的尺寸,同时保留重要信息。最常用的是最大池化(Max Pooling),其公式为:

其中:

  •  是池化窗口的大小。
  •  是输入图像。
  •  是池化后的输出图像。

4. 全连接层(Fully Connected Layer)

全连接层将输入的特征向量映射到输出的类别上,通常使用的是一个线性变换,公式为:

其中:

  •  是输入的特征向量。
  •  是权重矩阵。
  •  是偏置向量。
  •  是输出向量。

5. 反向传播(Backpropagation)

反向传播用于调整卷积核和全连接层的权重,以最小化损失函数。损失函数常用交叉熵损失,公式为:

其中:

  •  是真实标签。
  •  是预测概率。

反向传播的主要步骤:

1. 计算损失函数的梯度:根据输出与真实标签的差异计算损失。

2. 反向传播误差:将误差从输出层传递到输入层,逐层计算每个参数的梯度。

3. 更新权重:使用梯度下降法更新每一层的权重。

算法流程

1. 输入图像:输入一个形状为  的图像。

2. 卷积层

  • 对输入图像应用多个卷积核,进行卷积运算,得到特征图。
  • 应用激活函数(如ReLU)。
  • 如果需要,进行填充和步幅调整。

3. 池化层

  • 对特征图进行池化操作,得到下采样后的特征图。

4. 重复卷积层和池化层:多次进行卷积和池化操作,以提取更高层次的特征。

5. 展平:将最终的特征图展平成一维向量。

6. 全连接层

  • 将展平后的向量通过一系列全连接层。
  • 应用激活函数。

7. 输出层:最后一层全连接层输出分类结果(例如,使用Softmax函数进行多分类任务)。

8. 计算损失:使用损失函数计算预测结果与真实标签之间的差异。

9. 反向传播:计算损失函数相对于各层参数的梯度,并更新参数。

10. 迭代训练:重复以上步骤,直到损失函数收敛,模型训练完成。

总结了10个步骤,CNN能够自动提取图像中的各种特征,并利用这些特征进行分类和识别。

完整案例

这个案例中,使用了真实的数据集进行图像分类,并包括数据分析、可视化以及算法优化的步骤。

数据集市经典的CIFAR-10数据集,该数据集包含60000张32x32的彩色图像,共分为10类,每类6000张图像。

下面,我来分步骤,给大家详细的进行每一步的说明:

1. 导入库和加载数据

import tensorflow as tf
from  tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt
import seaborn as sns

# 加载CIFAR-10数据集
(x_train, y_train), (x_test, y_test) = datasets.cifar10.load_data()

# 数据归一化
x_train, x_test = x_train / 255.0, x_test / 255.0

# 类别名称
class_names = ['airplane''automobile''bird''cat''deer''dog''frog''horse''ship''truck']

2. 数据可视化

# 显示训练集中的前25张图片和它们的标签
plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(x_train[i], cmap=plt.cm.binary)
    plt.xlabel(class_names[y_train[i][0]])
plt.show()

3. 构建CNN模型

model = models.Sequential([
    layers.Conv2D(32, (33), activation='relu', input_shape=(32323)),
    layers.MaxPooling2D((22)),
    layers.Conv2D(64, (33), activation='relu'),
    layers.MaxPooling2D((22)),
    layers.Conv2D(64, (33), activation='relu'),
    layers.Flatten(),
    layers.Dense(64, activation= 'relu'),
    layers.Dense(10)
])

model.summary()

4. 编译和训练模型

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))

5. 评估模型性能

plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
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}")

6. 优化模型

我们可以通过调整模型架构、改变优化器、进行数据增强等方式来优化模型。在这里,我们进行一些数据增强,并调整模型架构。

from tensorflow.keras.preprocessing.image import ImageDataGenerator

datagen = ImageDataGenerator(
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True
)

# 对训练数据进行数据增强
datagen.fit(x_train)

# 构建新的CNN模型
optimized_model = models.Sequential([
    layers.Conv2D(32, (33), activation='relu', input_shape=(32323)),
    layers.MaxPooling2D((22)),
    layers.Conv2D(64, (33), activation='relu' ),
    layers.MaxPooling2D((22)),
    layers.Conv2D(128, (33), activation='relu'),
    layers.Conv2D(128, (33), activation='relu'),
    layers.Flatten(),
    layers.Dense(128, activation='relu'),
    layers.Dense(10)
])

optimized_model.compile(optimizer='adam',
                        loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                        metrics=['accuracy'])

# 训练优化后的模型
optimized_history = optimized_model.fit(datagen.flow(x_train, y_train, batch_size=64),
                                        epochs=10
                                        validation_data=(x_test, y_test))

7. 评估优化后的模型

plt.plot(optimized_history.history['accuracy'], label='Optimized Training Accuracy')
plt.plot(optimized_history.history['val_accuracy'], label='Optimized Validation Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')
plt.show()

optimized_test_loss, optimized_test_acc = optimized_model.evaluate(x_test, y_test, verbose=2)
print(f"Optimized Test Accuracy: {optimized_test_acc}")

代码中,大家可以看到训练和验证准确率的变化,并通过优化模型提升性能。数据增强、增加卷积层数和调整神经网络结构是常见的优化方法。

大家可以通过这种完整的代码流程,学习如何构建和训练CNN模型,以及通过可视化和优化来提升模型性能。

模型分析

我们从CNN的优缺点、以及与其他相似算法的对比,全面的认识CNN以及相似算法模型的适用场景

优点:

1. 特征学习:CNN能够自动学习图像中的特征,无需手工设计特征。

2. 位置不变性:CNN能够识别图像中的物体,即使物体的位置发生变化也能准确识别。

3. 参数共享:通过卷积操作,参数共享可以减少模型的参数数量,降低过拟合的风险。

4. 适用于大规模数据:CNN模型在大规模数据集上表现出色,能够处理成千上万甚至更多的图像。

缺点:

1. 计算量大:CNN模型的训练需要大量的计算资源,尤其是在大规模数据集上训练时。

2. 需要大量数据:CNN模型需要大量的标记数据来进行训练,否则容易过拟合。

3. 黑盒模型:由于CNN模型的复杂性,它往往被视为黑盒模型,难以解释其内部的工作原理。

与相似算法的对比

与传统机器学习算法的对比:

1. 特征工程:传统机器学习算法需要手工设计特征,而CNN能够自动学习特征,减少了特征工程的工作量。

2. 适用性:传统机器学习算法在小规模数据集上表现良好,而CNN模型在大规模数据集上表现更好。

3. 计算复杂度:CNN模型的计算复杂度更高,但在大规模数据集上的表现往往更好。

与其他深度学习模型的对比(如RNN、Transformer等):

1. 数据类型:CNN主要用于处理图像数据,而RNN和Transformer等模型更适用于处理序列数据。

2. 计算结构:CNN主要依赖于卷积和池化操作,而RNN主要依赖于循环结构,Transformer主要依赖于自注意力机制,每种结构都有其适用的场景。

何时选择CNN模型

1. 图像分类任务:对于图像分类、目标检测等任务,CNN是一种非常有效的选择,尤其是在处理大规模数据集时。

2. 位置不变性要求高:如果任务对于物体在图像中的位置不敏感,CNN的特征学习能力可以很好地满足这种需求。

3. 需要自动学习特征:如果任务中的特征不容易手工设计,CNN模型能够自动学习到合适的特征表示。

CNN模型在图像分类等任务中表现出色,尤其在大规模数据集上的应用广泛。然而,在某些情况下,如处理小规模数据集或需要解释性的任务中,其他算法可能更合适。

最后

感觉有帮助的朋友可以收藏、点赞、转发起来!



Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/181551
 
110 次点击