当前位置:   article > 正文

【深度学习】最强算法之:卷积神经网络(CNN)

【深度学习】最强算法之:卷积神经网络(CNN)

1、引言

小屌丝:鱼哥, 看下这个流程图,我没看明白
小鱼:啥流程图。

在这里插入图片描述
小屌丝:你看,就是这个。
小鱼:嗯,不错,不错。
小屌丝:能不能给我讲一讲这个?
小鱼:你要了解CNN ?
小屌丝:CNN 是?
小鱼:…你这… 深度学习知道吗?
小屌丝:知道啊
小鱼:你都知道深度学习,还能不知道CNN
小屌丝: 哦,我还以为是…
小鱼:我…
在这里插入图片描述

小屌丝:嘿嘿… 是我想多了
小鱼:那你都知道CNN, 还想让我说什么?
小屌丝:那就把CNN给我讲透一些,让我彻底爱上CNN
小鱼: … 你真行。

2、卷积神经网络

2.1 定义

卷积神经网络是一种特殊的深度学习模型,它尤其适用于处理具有网格结构的数据,如图像。

CNN通过一系列卷积层、池化层、全连接层等结构,对输入数据进行层层转换和抽象,从而提取出有用的特征信息,最终实现分类或识别等任务。

2.2 原理

CNN的核心思想在于局部感知和权值共享。

  • 局部感知意味着每个神经元只需对输入数据的局部区域进行感知,而无需对全局进行感知。
    • 这种局部连接的方式大大减少了模型的参数数量,降低了计算复杂度。
  • 权值共享则意味着同一个卷积核在输入数据的不同位置共享相同的权重,这进一步减少了模型的参数数量,提高了模型的泛化能力。

2.3 分类

CNN(卷积神经网络)的分类算法多种多样,它们大多基于CNN的基本结构和原理,通过调整和优化网络结构、参数设置以及训练策略,以应对不同的分类任务和数据集。以下是一些主要的CNN分类算法:

  • AlexNet:这是2012年ImageNet竞赛的冠军模型,它首次在大规模图像识别任务中展示了深度卷积神经网络的强大能力。
    • AlexNet采用了8层神经网络,包括5个卷积层和3个全连接层,使用了ReLU激活函数、数据增强、Dropout等技术,显著提高了分类性能。
  • VGGNet:VGGNet是牛津大学Visual Geometry Group提出的深度卷积神经网络,它探索了网络深度对性能的影响。
    • VGGNet有多种配置,其中最常用的是VGG16和VGG19,它们分别包含16层和19层。
    • VGGNet使用了较小的3x3卷积核和2x2池化核,通过堆叠多个卷积层来增加网络深度,提高了模型的分类精度。
  • GoogleNet(InceptionNet):GoogleNet是Google团队提出的深度卷积神经网络,它采用了Inception模块,该模块通过并行使用不同大小的卷积核和池化操作来提取多尺度特征。
    • GoogleNet还引入了辅助分类器来加速训练过程,并通过全局平均池化层来减少参数数量。
  • ResNet(残差网络):ResNet由微软研究院提出,它解决了深度神经网络在训练过程中出现的梯度消失和表示瓶颈问题。
    • ResNet通过引入残差连接(shortcut connections)来允许梯度直接回流到较早的层,从而训练出更深的网络。
    • ResNet在多个图像分类任务中取得了显著的性能提升。
  • EfficientNet:EfficientNet是一种高效、可扩展的卷积神经网络,它同时优化了网络深度、宽度和分辨率三个维度,以实现更好的性能和效率。
    • EfficientNet采用了一种复合缩放方法,可以均匀地缩放网络的所有维度,从而在保持模型复杂性的同时提高性能。

2.4 算法公式

CNN中的关键操作是卷积操作。对于二维输入数据X和卷积核W,卷积操作的公式可以表示为:
s ( i , j ) = ( X ∗ W ) ( i , j ) = ∑ m ∑ n x ( i + m , j + n ) w ( m , n ) s(i,j) = (X * W)(i,j) = ∑m∑n x(i+m,j+n)w(m,n) s(i,j)=(XW)(i,j)=mnx(i+m,j+n)w(m,n)
其中, s ( i , j ) s(i,j) s(i,j)表示输出特征图中位置(i,j)的像素值, x ( i + m , j + n ) x(i+m,j+n) x(i+m,j+n)表示输入数据中位置 ( i + m , j + n ) (i+m,j+n) (i+m,j+n)的像素值, w ( m , n ) w(m,n) w(m,n)表示卷积核中位置 ( m , n ) (m,n) (m,n)的权重值。

2.5 代码示例

# -*- coding:utf-8 -*-
# @Time   : 2024-03-17
# @Author : Carl_DJ

import torch  
import torch.nn as nn  
import torch.nn.functional as F  
  
# 定义一个名为ComplexCNN的卷积神经网络类,继承自nn.Module  
class ComplexCNN(nn.Module):  
    def __init__(self, num_classes=10):  
        super(ComplexCNN, self).__init__()  
          
        # 第一个卷积层,输入通道数为3(彩色图像),输出通道数为64,卷积核大小为3x3,步长为1,填充为1  
        self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1)  
        # 第二个卷积层,输入通道数为64(上一个卷积层的输出),输出通道数为128,卷积核大小为3x3,步长为1,填充为1  
        self.conv2 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)  
        # 第三个卷积层,输入通道数为128,输出通道数为256,卷积核大小为3x3,步长为1,填充为1  
        self.conv3 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1)  
          
        # 最大池化层,池化核大小为2x2,步长为2  
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)  
          
        # Dropout层,用于防止过拟合  
        self.dropout = nn.Dropout(0.5)  
          
        # 全连接层,输入特征数为flatten后的特征数量,输出特征数为512  
        self.fc1 = nn.Linear(self._get_flatten_size(256, 7, 7), 512)  
        # 输出层,全连接层,输入特征数为512,输出特征数为分类的类别数  
        self.fc2 = nn.Linear(512, num_classes)  
  
    # 辅助函数,用于计算flatten后的特征数量  
    def _get_flatten_size(self, ch, w, h):  
        return ch * w * h  
  
    # 前向传播函数  
    def forward(self, x):  
        # 卷积 + ReLU激活函数 + 最大池化  
        x = self.pool(F.relu(self.conv1(x)))  
        x = self.pool(F.relu(self.conv2(x)))  
        x = self.pool(F.relu(self.conv3(x)))  
          
        # 展平操作,将多维的特征图转换为一维向量,方便输入全连接层  
        x = torch.flatten(x, 1)  
          
        # Dropout层,防止过拟合  
        x = self.dropout(x)  
          
        # 全连接层 + ReLU激活函数  
        x = F.relu(self.fc1(x))  
          
        # 再次使用Dropout层  
        x = self.dropout(x)  
          
        # 输出层,使用softmax函数进行多分类  
        x = F.log_softmax(self.fc2(x), dim=1)  
          
        return x  
  
# 实例化模型,假设有10个分类  
model = ComplexCNN(num_classes=10)  
  
# 打印模型结构  
print(model)  
  
# 假设输入一个batch的图像数据,大小为(batch_size, 3, 32, 32)  
# 其中batch_size是批处理大小,3是图像通道数(RGB),32x32是图像大小  
input_data = torch.randn(64, 3, 32, 32)  # 假设batch_size为64  
  
# 将模型设置为训练模式  
model.train()  
  
# 前向传播,得到输出  
output = model(input_data)  
  
# 输出维度为(batch_size, num_classes),即每个样本在每个类别上的预测概率分布  
print(output.shape)  # 应输出torch.Size([64, 10])


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

代码解析

  • 类定义:ComplexCNN 类继承自 nn.Module,这是所有神经网络模块的基类。

  • 卷积层:我们定义了三个卷积层 self.conv1、self.conv2 和 self.conv3,分别使用不同数量的输出通道(即卷积核数量)。每个卷积层都使用了ReLU激活函数和最大池化层来减小特征图的空间尺寸,增加特征的抽象性。

  • 池化层:self.pool 是一个最大池化层,用于减小特征图的大小,并保留最重要的特征。

  • Dropout层:self.dropout 用于在前向传播过程中随机将一部分神经元的输出置零,防止模型过拟合。

  • 全连接层:self.fc1 和 self.fc2 是全连接层,用于将卷积层提取的特征整合成最终的分类结果。self.fc1 接收flatten后的特征向量,self.fc2 输出每个类别的预测概率。

  • 辅助函数:_get_flatten_size 用于计算flatten后的特征数量,这对于定义全连接层的输入大小是必要的。

  • 前向传播函数:forward 方法定义了数据通过网络的前向传播过程。每个卷积层后面都跟随了ReLU激活函数和最大池化层,之后是flatten操作,然后是全连接层和最终的softmax输出。

  • 实例化模型:我们创建了一个 ComplexCNN 的实例,并指定了分类的类别数。

  • 前向传播示例:我们创建了一个随机的输入数据 input_data,模拟了一个batch的图像数据,并通过模型进行了前向传播,得到了输出 output。输出是一个二维张量,其形状为 (batch_size, num_classes),表示每个样本在每个类别上的预测概率分布。

3、总结

卷积神经网络作为深度学习中的代表性算法,以其强大的特征提取和分类能力在计算机视觉领域取得了显著的成功。

通过局部感知和权值共享的原理,CNN有效地减少了模型的参数数量,提高了计算效率。

同时,通过卷积层、池化层、全连接层等结构的组合,CNN能够自动学习输入数据的特征表示,实现对输入数据的高效分类和识别。

我是小鱼

  • CSDN 博客专家
  • 阿里云 专家博主
  • 51CTO博客专家
  • 企业认证金牌面试官
  • 多个名企认证&特邀讲师等
  • 名企签约职场面试培训、职场规划师
  • 多个国内主流技术社区的认证专家博主
  • 多款主流产品(阿里云等)测评一、二等奖获得者

关注小鱼,学习机器学习领域的知识。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
  

闽ICP备14008679号