CNN卷积神经网络算法原理
全神经网络的整体结构
输入层(x1, x2, x3…)->隐藏层(全连接)->输出层,整体就类似于一个函数,输入x,经过函数module(x)得到输出y的过程,图像可以看成一个矩阵例如128 * 128的图片就是一个128 * 128的矩阵作为输入x,这就是全连接神经网络,他是深度学习的基础。后面讲的卷积神经网络和他类似,主要将隐藏层换成卷积核
全连接神经网络的结构单元
深度学习一般是从单元到整体,然后搭建一个基础模型model,这个model可能由许多model进行排列组合构成,例如:1 * model1 + 2 * model2 + 5 * model3等等,然后通过这个model,输入x,得到y,如果发现y的结果很好,则可以根据这个model写一篇论文,这就是创新的地方。任何一个单元结构都是通过组合而成的。
输入(x1, x2, x3…)已经确定,所以优化模型的突破点在于改变w1, w2, w3…以及z,也就是找到一组最优的参数(w和b,它们都是矩阵)使得结果最优,所谓结果最优,就是最接近我们所希望的输出。
为什么要加入非线性激活函数
激活函数一般为非线性函数(非直线)。下图解释了,当激活函数为线性函数的时候出现的问题,多层的神经网络并没有起到效果,等价于一个参数,相当于只有一层,就不能发挥层数的作用。深度学习中,往往层数越多,效果越好,例如ResNet在保证深度的同时,又不会过拟合
Sigmoid激活函数
主要记忆函数图像以及导数的图像,因为导数是用来求参数(w和b)
Tanh激活函数
导数值越大,找参数(w和b)就会更快,当导数趋近为0的时候,w和b也就趋于确定
ReLu激活函数
Leaky ReLU函数
没有最优的模型,只有最合适的模型
神经网络前向传播(从左往右)
对模型(modle)输入内容x(音频图形等等,一般都是矩阵),得到输出y的过程就是神经网络前向传播
取中间的一条线,来看具体是如何计算的
训练、推理、验证、测试,这些过程都会设计导前向传播的过程。
神经网络的损失函数
损失函数就是计算前项传播,和实际希望之间的误差。利用损失函数可以说明,模型经过若干轮之后收敛了(就是loss值不断下降,区域稳定)。
f ( x i ) f(x_{i}) f(xi)是正向传播之后得到的结果, y i y_{i} yi是希望的结果,计算其均方误差的结果就是损失函数。通过损失函数反向传播(由梯度下降法实现)更新w, b,使得每一轮的效果越来越好。总结一下,训练过程中,前向传播计算误差,反向传播更新w,b。
- 回归问题:输出的值是连续的,例如:预测明天的天气是多少度?
- 分类问题:输出的值是离散的,例如:是猫还是狗?是猫为0,是狗为1。
训练模型的过程中,一开始误差会非常大,后面的误差会越来越小
梯度下降法(反向传播)-更新w 和 b
举一个下山的例子,来直观感受梯度下降法
因为x(输入的内容已经确定),所以实际 f ( x ) f(x) f(x)可以表示为 f ( w , b ) f(w, b) f(w,b),利用其求均方误差。 a a a是超参数(这里是学习率),为什么是偏导,因为w包含 w 1 , w 2 . . . w_{1}, w_{2}... w1,w2...因此,轮次越多,找到最优的w,b的参数几率越大。我们这里理解这个公式就可以了,这是梯度下降法最本质的内容。
反向传播计算样例
基础知识的总结
- 1000份数据(作为输入x),得到对应的输出1000份对应的y,得到1000份(x, y)
- 搭建模型model
- 开始训练,需要设置一些超参数,例如学习率,学习训练轮数等等,然后进行前向传播y,计算误差,反向传播更新w,n,直到训练轮次结束,最后产生model(w,b更新结束)
- 开始测试给定x,看是否符合预期的输出y
- 应用
图像在神经网络中的表示
CNN卷积神经网络,输入往往是图像或者视频(一帧一帧的图像)
图像在计算机中的本质,一般是像素矩阵(每个位置上的数字都在0-255之间)。
灰度图:单通道
彩色图:多通道(这里的通道指的是,每个特征值提取的特征)
全连接神经网络
全连接神经网络会破坏空间信息,如下图所示,需要先将图片矩阵展开,卷积神经网络(CNN)不会破坏
卷积运算过程
卷积是一种计算,卷积神经网络包含卷积运算和池化运算,可以没有池化运算,但是不能没有卷积运算。
输入x,这里是图像矩阵,卷积核就是w,卷积核的大小不会因为输入的大小改变而改变。卷积核的大小就是参数的数量。
卷积核(w)可以通过梯度下降法更新,偏置b和w的公式类似。
计算公式:输入 * 卷积核 + 偏置 ,通过激活函数得到输出
步符
这里每次移动两个单位,步符是2,最后得到的输出是2 * 2,步符和输出的大小是有一定关系的,如果步符是1,那么得到的输出结果是1 * 1
填充
步符和填充操作一起来帮助控制下一层输出特征图的大小,避免卷积块不断变小,导致后序不能运算的问题。
输入特征图和输出特征图的计算公式
前面讲解的都是单通道的,但是在实际中,多通道的才是比较常见的。来了解一下多通道输入的情况,其中每个特征图和对应的卷积核进行运算,最后将得到的若干结果进行同位置的相加。
这里c
表示通道数,
卷积核的数量可以设置,比如说FN个,如下所示。
再加上偏置
池化操作(没听明白)
池化操作不带有参数,不会改变通道数
卷积神经网络的整体结构
卷积神经网络(Convolutional Neural Networks,简称CNN)是一种深度学习模型,它在图像和视频识别、分类和分割等领域表现出色。CNN的核心思想是利用卷积层来自动、逐层地提取特征,而不需要人为设计特征。下面是卷积神经网络的基本结构和一些关键组件:
-
输入层(Input Layer):
- 这是网络的入口,通常接收原始图像数据。
-
卷积层(Convolutional Layer):
- 包含多个卷积核(或滤波器),每个卷积核负责提取输入数据中的特定特征(如边缘、纹理等)。
- 卷积操作通过滑动窗口(卷积核)在输入数据上进行,生成特征图(feature maps)。
-
激活函数(Activation Function):
- 通常在卷积层之后使用,如ReLU(Rectified Linear Unit),它可以帮助网络学习非线性特征。
-
池化层(Pooling Layer):
- 用于降低特征图的空间维度,减少参数数量和计算量,同时提高特征的不变性(如平移不变性)。
- 最常见的池化操作是最大池化(Max Pooling)。
-
归一化层(Normalization Layer):
- 可选,用于归一化特征图,减少内部协变量偏移(Internal Covariate Shift)。
-
全连接层(Fully Connected Layer):
- 也称为密集层,它将前面层提取的特征映射到最终的输出空间,如类别标签。
-
输出层(Output Layer):
- 最后一层,根据任务的不同,可以是Softmax层(用于分类任务)或其他类型的层。
-
损失函数(Loss Function):
- 用于评估模型的预测与真实标签之间的差异,常见的损失函数包括交叉熵损失(Cross-Entropy Loss)。
-
优化器(Optimizer):
- 用于更新网络权重,以最小化损失函数,常见的优化器包括SGD(随机梯度下降)、Adam等。
一个典型的CNN可能包含多个卷积层、激活层、池化层和全连接层的组合,每一层都有助于提取和抽象图像特征。随着网络的深入,特征图的深度会增加,而空间维度会减小,直到最终通过全连接层输出预测结果。
CNN的结构可以根据具体任务进行调整,例如,对于图像分割任务,可能需要使用特殊的结构如U-Net或FCN(全卷积网络)。对于视频处理,可能需要在时间维度上添加额外的卷积层来捕捉时间序列信息。
LeNet原理与实战
搭建卷积神经网络的流程
- 搭建模型
- 处理数据,并将数据送给模型
- 对模型进行测试,评估模型的性能
涉及到的文件
model.py
:网络模型的代码train.py
:训练的代码test..py
:测试的代码
其中train.py
以及test..py
几乎是不变的,只是导入的模型变换了,所以这两部分代码是很重要的。
LeNet-5诞生的背景
LeNet-5中的5表示这个网络有5层神经网络,其中每次卷积操作是一层,但是池化操作不算,因为该操作不涉及参数。
经验之谈:处理数据+训练要占到80%的时间,而搭建模型只占到20%的时间
LeNet网络结构如下:
AlexNet诞生背景
从大规模数据集中抽取部分作为训练集对模型进行训练,再抽取其他部分作为测试集,看模型训练的效果,再比赛中,AlexNet表现良好。
AlexNet网络结构
“深的多”可以理解为卷积层多了一些
AlexNet网络参数(没听懂)
基于输出公式
DropOut操作
代码实战先导
深度学习代码的组成
- model:代码量最少
- train:数据处理以及模型训练,他们往往会产生权重(w),权重包含模型结构以及训练好的w和b的数值,一般用80%的数据进行训练,10%的数据进行验证,10%的数据进行测试,将测试的结果和label进行比对,得到精度(accurate)
- test
所以,写代码的流程,一般为,搭建模型(model.py),训练(train.py),以及测试(test.py),刚开始的时候,除了关注模型的搭建,还要学习训练以及测试,因为,训练和测试一旦写完,对于后序实验一般可以直接使用,不同的实验只是模型不一样。
LeNet-5模型搭建
class类
- 初始化:
- 网络层:
- 激活函数:
- def:搭建网络模型(前向传播的过程),反向传播是train代码中的内容
import torch
from torch import nn # nn中包含一些需要的层:全连接层,卷积层,池化层
from torchsummary import summary # 用来输出一些参数
class LeNet(nn.Module):
# 模型的初始化
def __init__(self):
super(LeNet).__init__()
self.c1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5, padding=2)
self.sig = nn.Sigmoid() # 调用激活函数
self.s2 = nn.AvgPool2d(kernel_size=2, stride= 2)
self.c3 = nn.Conv2d(in_channels=6, out_channels= 16, kernel_size=5)
self.s4 = nn.AvgPool2d(kernel_size=</