李哥深度学习班 图像分类
图像分类任务:
输入:图片
输出:分类
那么要解决的两个新问题就是:
1、如何把图片变成神经网络的输出,或者说神经网络要怎么处理图片
2、如何把分类的结果输出出来,或者说分类的输出应该怎么做
独热编码(One-Hot Encoding)
独热编码是一种将分类变量转换为二进制向量的方法。
对于有N个不同取值的特征,创建N个二进制特征,每个特征对应一个可能的取值。
对于每个样本,只有一个特征为1(“热”),其余都为0。
分类变量(categorical variable)是用于描述事物类别的变量,其取值是分类数据。
例如,“性别”是一个分类变量,其变量值可以是“男”或“女”;“行业”也是一个分类变量,其变量值可以是“零售业”、“旅游业”、“汽车制造业”等。
示例:
假设“颜色”特征有三个取值:红、绿、蓝
-
红 → [1, 0, 0]
-
绿 → [0, 1, 0]
-
蓝 → [0, 0, 1]
为什么要用这种编码?
如果用简单的整数编码(红=1、绿=2、蓝=3),很多算法会错误地认为:
-
蓝 > 绿 > 红(有大小关系)
-
红和蓝的距离是红和绿的2倍
也就是说,整数编码会使得机器认为,红和蓝“更不相似”,而红绿则“更相似”,这显然是错误的,这三种颜色应当是完全独立的。
独热编码则避免了这些问题,使每个类别都是正交的独立维度,这能够让距离计算更合理。
分类的输出应该怎么做?
那么知道了独热编码后,我们就找到了一种处理分类输出的方式。
上节课的回归任务最终是产生一个数值,所以模型搭建时,最后的输出层只有一个神经元,对应产生一个预测值y_pred,用pytorch写出来就是
self.fc2 = nn.Linear(128, 1)
那么分类任务是否可以用这样的方式,让神经网络输出一个数值来代表它判断输入的图片是一个什么类别?了解了独热编码后,至少我们可以认为对于像红绿蓝这样的离散的类别,这样的方式行不通。
因此,只需要把最后的输出从一个数值改成一个向量就好了

向量中各个维度的值则可以这样理解:机器认为 输入的图片 是 这个类别 的 概率 是多少
训练流程

可以看到,分类的训练流程和回归实际上没有太大的区别,都是输入数据、产生预测、进行对比、计算误差、参数优化。
图片输入处理
RGB

C = Channel 通道
每个像素点都是一个三维向量,每个分量取值范围通常是 0-255(8位/通道),共有 256³ = 16,777,216 种颜色可能
示例:[255, 0, 0] → 纯红;[0, 255, 0] → 纯绿;[0, 0, 255] → 纯蓝;[255, 255, 255] → 白色
计算机中的存储结构:三维张量表示(最常用理解方式)
一张 H×W 的RGB图片实际上是 H×W×3 的张量:
-
H:高度(行数)
-
W:宽度(列数)
-
3:RGB三个通道
# 伪代码表示
image = [
[[R,G,B], [R,G,B], ...], # 第一行
[[R,G,B], [R,G,B], ...], # 第二行
...
]
图片输入处理方式一:把图片“拉直”

直接把图片的RGB三个通道分离并全部“拉直”,变成一个极长的向量,训练时输入这个向量就可以了,这样就把图片的处理转化为了向量的处理

问题:
太暴力了,数据量太大了。当使用全连接神经网络处理大尺寸图像时,有三个非常明显的缺点:
(1)将图像展开为向量会丢失空间信息;
(2)参数过多效率低下,训练困难;
(3)大量的参数也很快会导致网络过拟合。
图片输入处理方式二:卷积神经网络
卷积神经网络则可以很好地解决以上三个问题。
一文彻底搞懂CNN - 卷积和池化(Convolution And Pooling) - 文章 - 开发者社区 - 火山引擎

卷积Convolution
卷积是一种特殊的线性运算,用于提取图像中的局部特征。
CNN通过使用一个或多个卷积核(也称为滤波器或特征检测器)在输入数据(如图像)上进行滑动窗口操作来提取特征。
- 卷积核(Convolution Kernel): 一个可学习的权重矩阵,其大小通常远小于输入图像的大小,用于在输入图像上滑动并进行元素级的乘法累加操作。
- 特征图(Feature Map):卷积操作的结果,每个特征图都代表了输入图像在不同卷积核下的特征响应。

右边的那个就叫特征图。
卷积的重要参数:
卷积的重要参数主要包括 卷积核大小(Kernel Size)、步长(Stride)以及填充(Padding) ,它们共同决定了卷积层的输出特征图的尺寸和特性。
- 卷积核大小(Kernel Size):决定了感受野的大小,即每次卷积操作能够覆盖的输入区域大小。
- 步长(Stride):决定了卷积核在输入图像或特征图上滑动的距离。步长为1表示每次滑动一个像素,步长大于1则表示每次滑动多个像素。
- 填充(Padding):在输入图像或特征图的边缘添加额外的零值,以控制输出特征图的尺寸。常见的填充方式有“valid”(无填充)和“same”(填充后输出尺寸与输入相同)。
- 通道数(Channels):对于输入图像,通道数指的是颜色通道数(如RGB图像的通道数为3)。对于卷积层,输出特征图的通道数由卷积核的数量决定。

卷积的优势
那么为什么卷积就是比全连接好呢?
通常,以我们人类的思考问题的角度来看,对于任何一个用于图像分类的网络来说,其都应该满足如下几点特性:①平移不变性;②旋转不变性;③缩放不变性;④明暗不变性
所谓平移不变性(Translation Invariance),指的是不管图片中的物体如何移动,网络总能够将其识别出来。
所谓旋转不变性(Rotation Invariance),指的是不管图片中物体的角度如何变化,网络同样能够将其识别出来。

所谓缩放不变性(Size Invariance),指的是不管图片中的物体被放大还是缩小,网络也能够将其识别出来。
所谓明暗不变性(Illumination Invariance),指的是不管图片中物体的明暗程度如何变化,网络都能够将其识别出来。
那么全连接能够实现这些特性吗?可以,但是非常麻烦,需要把图片中的物体位于不同位置的情况全都作为输入喂给网络,让它疯狂地学习,也许有一天它能学会。

例如这个,我们希望网络能够识别出这个“横折”,但是如果采用全连接神经网络,把输入的图片拉直,把所有像素都喂给它。训练集如下:

那么网络看到的就是一整张图片,而不是那个横折。
这时它会认为:“只有当横折出现在图片的中间时,它才是横折。”
这实际上就是发生了过拟合,网络对“横折”产生了不小的误会。

由于在训练样本中,“横折”相关的信息仅仅只是分布在"5,6,9,a"这四个位置上,因此这也就意味着最终只有这四个位置对应的权重参数才对识别"5,6,9,a"中是否包含有“横折”有效。换句话说,只有"5,6,9,a"这四个位置对应的权重参数才是有效的。
那怎么来解决这一问题,使得其它位置的权重参数同样有效,也能够识别“横折”呢?
对于解决这个问题,理论上至少会有两个办法:
①用大量位于不同位置的“横折”数据对网络进行训练;
②增加隐藏层的深度来提取得到更加抽象和高级的特征。
但这样做的后果显然就是训练耗时,需要事先准备大量的训练集等。
那么卷积神经网络是怎么做的呢?
这里假定横折一开始在左上角,且已经经过训练可以被识别,对应神经元(蓝0)的四个参数为w1、w2、w3、w4

当横折的位置发生变化时,想要再次识别出横折的一个有效的快速的识别方法就是,直接同样的w1、w2、w3、w4用来对"1,2,5,6"位置上的元素进行识别,判断其是否含有“横折”。
也就是说既然网络已经认识到“在这个位置出现了看着像横折的东西,那就是横折”,那么只要让网络知道,“在别的位置也出现了看着像横折的东西,那也是横折”就可以了。
这就是“权重共享”。
因此,将 具有识别某种特征的能力的 一组权重 共享到其它位置上,就是卷积操作的核心思想,它就像一个“扫描器”一样,能够逐个扫描所有位置上是否包含有“扫描器”能够识别的对应元素。
这就是卷积比全连接优越的地方,它不会丢失掉空间信息,防止像全连接中出现过拟合的情况。
卷积的计算
**************************************原来卷积是这么计算的 - 知乎**************************************
卷积计算的情况按照引文中的方式分为四类:
1、单通道单卷积核;2、单通道多卷积核;3、多通道单卷积核;4、多通道多卷积核
计算的方式以单通道单卷积核为例:


左图给出了单通道灰度图和一个卷积核,计算时,通过卷积核在输入数据上滑动,计算每个位置上的加权和(包括偏置项),并可能应用激活函数,以生成输出特征图。

右图就是按照这种方式计算出的一张特征图,是一张[3,3,1](通道数为 1 )的灰度图,大小比输入小了“一圈”,可以用前面提到的Padding来处理大小变化的问题。

不过课上给出的这个情况则是 多通道多卷积核的情况
多通道的计算方式以多通道单卷积核为例说明:


右边为卷积后的特征图(feature map),左边为一个三通道的卷积核对输入图片左上放进行卷积时的示意图。因此,对于这个部分的计算过程有:

也就是说,在多通道输入的情况下,对应的卷积核也必须是多通道的,且通道数与输入必须相同(如左图中的kernel)
而且要注意的是,此时它虽然有三个通道,但是整体仍被视为一个卷积核,对应产生的特征图也就只是一个单通道的图。
至于计算方式,则是把三个通道分别按照单通道的方式计算(不加bias),即与对应卷积核的同一个通道上的值进行相乘相加,最后把结果加起来再加bias,作为特征图在这一个位置的取值
所以最后可以知道,多通道的卷积差不多是多次进行了单通道的卷积(都只加一次bias)并叠加,多通道的卷积核(如[3,3,3]的),也被视为一个卷积核。
卷积核的个数决定了生成特征图的通道数

此时就能理解课上贴出来的这个图了,它输入了一张RGB三通道图片,经过了5个三通道卷积核,经过卷积计算,每个卷积核产生特征图的一个通道,最终得到了 一张 5通道的 特征图。
简单总结一下:
1、卷积核的通道数(深度)一定和原始特征图(输入)相同,且与特征图的深度无关
2、卷积核的个数决定了生成特征图的通道数(深度),且二者相等
用 k 个卷积核对输入进行卷积处理,那么最后得到的特征图一定就会包含有 k 个通道。
例如,输入为 [ n,n,c ],且用 k 个卷积核对其进行卷积,则卷积核的形状必定为 [ w1,w2,c,k ] ,最终得到的特征图形状必定为 [ h1,h2,k ] ;其中 w1,w2 为卷积核的宽度,h1, h2 为卷积后特征图的宽度。
3、卷积的计算像是“弱化版”的矩阵相乘,对应位置相乘相加最后再全都加在一起,只是两个矩阵的大小和形状都不一定一样,小矩阵(卷积核)在大矩阵(输入特征图)上“滚动”,滚完整张图就产生了新的特征图,新的特征图又可以重复这个流程
4、和全连接神经网络相比,卷积神经网络只激活了一部分神经元,而不是全部都算在一起

5、卷积神经网络中可训练的参数就是卷积核,卷积核中含有的参数量就是k*(w*h*c)
(k为卷积核个数)
6、在了解了上述知识后就可以进行相关的手算了。
已知输入特征图 [ w1, h1, c1 ]、卷积核 [ w2, h2, c2, k ](k为卷积核个数)、输出特征图 [ w3, h3, c3 ]三者之二,即可求出剩余之一
可以总结为以下各式:(s为步长Stride、P为Padding补上的长度)
w3 = (w1 - w2 + 2P )/ s + 1; h3 = (h1 - h2 + 2P)/ s + 1; c3 = k; c1 = c2;
注意:向下取整
下采样
即使使用卷积神经网络,数据量仍然是巨大的。
相对于全连接神经网络,虽然已经通过卷积的方式减少了参数量,但是如果增加卷积层数的同时,又维持特征图大小不变,最终就会导致参数量发生大量增长。
参数量过大首先就会带来更大的计算压力,而且会导致过拟合等。总而言之,在这种情况下就要寻找减少参数量的办法,那么一个思路就是使特征图的大小变得更小一些,如把224×224缩小成112×112,参数量就直接减少为原来的1/4,就像相册中的缩略图。
一、下采样的本质定义
下采样(Downsampling) 是指降低数据空间分辨率(尺寸)的同时,试图保留重要信息的过程。就像把高清照片缩小为缩略图,但希望关键内容仍可辨认。
二、下采样的实现方式
其一:先前提到的增加卷积步长

其二:池化(Pooling)
所谓池化,可以将其看作是一个信息筛选或者过滤的操作。
池化操作使用某一位置的相邻输出的总体特征来代替网络在该位置的输出。
例如最大池化(max pooling)会给出相邻矩形区域内的最大值作为该位置的输出。除此之外还有最小池化(min pooling)和平均池化(average pooling)等,顾名思义就是取最小值或平均值代替某一片像素。

到这里,我们已经了解了卷积和池化等知识,那么就拥有了搭建卷积神经网络的积木,把卷积和池化等操作交叉使用,卷完了池,池了再卷,就这样搓出来一个神经网络,就像之前的线性回归,一层层的全连接层看心情搭就好了。
例如,怎么把3×224×224的RGB图片变成1024×7×7的呢?(第一个数是深度(通道数))

通过一系列的卷积和池化就行了。
最后的分类:
全连接
回想一下前面为什么说到了卷积,
最开始我们想,能不能直接把图片“拉直”成一个很长的向量,然后直接用全连接神经网络进行训练。目标就是按照独热编码做成的那些向量。
但是因为数据量太大,空间信息丢失(要是图片上的物品变了个位置或者旋转一下可能就识别不了了),以及过拟合等问题,最终没有实施。
那么现在,通过卷积,上述这些问题都解决了,该上全连接了。

也就是说,在卷积神经网络已经得到足够多且足够深入的特征之后,再把它输入到全连接神经网络中,全连接神经网络就没那么容易像最开始那样“产生误会”了。
此时让全连接神经网络说出“这样的图片是什么类别”就可以实现我们最初的目标:分类。

归一化
在计算loss时,还要先把通过全连接计算出的预测值向量给归一化,使对应位置的值能够表达出“是某种物体的概率”的含义

对于多分类问题,一种常用的方法是Softmax函数,它可以预测每个类别的概率,选择预测值最高的类别作为结果即可。Softmax的公式如下,其中是Z一个向量,Zi 和 Zj 是其中的一个元素。

图中,softmax转化了一个向量。
Softmax函数可以将上一层的原始数据进行归一化,转化为一个 ( 0 , 1 ) 之间的数值,这些数值可以被当做概率分布,用来作为多分类的目标预测值。Softmax函数一般作为神经网络的最后一层,接受来自上一层网络的输入值,然后将其转化为概率。
实际上,Sigmod函数是Softmax函数的一个特例,Sigmod函数只能用于预测值为0或1的二元分类。
loss的计算
采用交叉熵损失(CrossEntropy Loss)


更多推荐
所有评论(0)