1. 使用GPU训练

一直在纠结把GPU的使用放在哪里,觉得放在pytorch那里也不太合适,所以就放在这里了。
按照唱歌和不唱歌太难区分了,所以我用星黛露和草莓熊新建的训练集:

测试集:

方法一

使用GPU训练需要在:①网络模型、②损失函数、③数据,三个地方调用.cuda()即可。严谨一点,我们需要加上判断torch.cuda.is_available()。完整代码如下:

import torch
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten
import os
from PIL import Image
from torch import nn
from torch.nn import Linear, ReLU
from torch.utils.data import Dataset, DataLoader
from torchvision.transforms import transformsclass MyModule(nn.Module):def __init__(self):super(MyModule, self).__init__()self.seq = Sequential(Conv2d(3, 32, 5, padding=2),ReLU(),MaxPool2d(2),Conv2d(32, 32, 5, padding=2),ReLU(),MaxPool2d(2),Conv2d(32, 64, 5, padding=2),ReLU(),MaxPool2d(2),Flatten(),Linear(1024, 64),Linear(64, 2))def forward(self, input):output = self.seq(input)return outputclass MyData(Dataset):def __init__(self, root_dir, label_dir):self.root_dir = root_dirself.label_dir = label_dirself.path = os.path.join(self.root_dir, self.label_dir)self.img_path = os.listdir(self.path)def __getitem__(self, idx):img_name = self.img_path[idx]# 因为target必须是tensor数据类型,而且要符合shape为(N)if img_name.startswith('Not') is True:img_label = torch.tensor(0)  # 用0表示NotSingelse:img_label = torch.tensor(1)  # 用1表示Singimg_item_path = os.path.join(self.path, img_name)img = Image.open(img_item_path)trans_tensor = transforms.ToTensor()return trans_tensor(img), img_label  # 返回tensor类型的数据集而不是PIL.imagedef __len__(self):return len(self.img_path)# 导入训练集
train_dataset = MyData("hzhfData", 'Train32')
train_loader = DataLoader(train_dataset, batch_size=1)# 导入测试集
test_dataset = MyData("hzhfData", "Test")
test_loader = DataLoader(test_dataset, batch_size=1)
total = len(test_loader)# 神经网络
module = MyModule()
if torch.cuda.is_available():module = module.cuda()# 损失函数
loss = nn.CrossEntropyLoss()
if torch.cuda.is_available():loss = loss.cuda()# 优化器
learning = 0.01
optim = torch.optim.SGD(module.parameters(), lr=learning)  # 参数直接调用网络中的parameters# 开始训练
for epoch in range(30):# 训练module.train()for data in train_loader:  # 这个for循环可以看成是做题和学习的过程,每循环一次就做一道题,就相当于一个周期imgs, targets = dataif torch.cuda.is_available():imgs = imgs.cuda()targets = targets.cuda()outputs = module(imgs)  # 将打包的图片前向传播得到得分函数result = loss(outputs, targets)  # 用得分函数和正确标签计算损失函数optim.zero_grad()  # 因为backward计算时会累加上一次的结果,我们需要清空上次计算的权重再训练result.backward()  # 利用反向传播计算权重optim.step()  # 对每个参数进行调整# 测试module.eval()right = 0  # 记录正确分类的个数with torch.no_grad():for data in test_loader:imgs, targets = dataif torch.cuda.is_available():imgs = imgs.cuda()targets = targets.cuda()outputs = module(imgs)  # 得分情况right = right + (outputs.argmax(1)==targets).sum()  # 计数accuracy = right / total  # 准确率if (epoch+1) % 5 == 0:print("第{}轮训练的正确率为:{}".format(epoch+1, accuracy))

得到结果:

由于每次初始参数是随机的,所以每次运行程序的结果不太一样。但是基本属30次就可以达到100%正确。显然我的数据集数量是不够的,反正先学会就行。

方法二

和方法一类似。我们先新建一个设备device = torch.device("cuda:0"),其中数字表示电脑的第几个显卡,如果只有一个显然只能选择0,也可以简写为device = torch.device("cuda")。然后将方法一中所有的.cuda()全部换成.to(device)即可。

2. 目标检测进阶

目标检测可以理解为是物体识别和物体定位的综合,不仅仅要识别出物体属于哪个分类,更重要的是得到物体在图片中的具体位置。

2.1 重要概念

目标检测的分类有两种方式:

  1. 是否存在候选区:按照是否存在候选区分类可以分为两阶段目标检测算法一阶段目标检测算法。两阶段目标检测算法的第一级网络用于候选区的提取,产生候选区域(region proposals),第二级网络用于对候选区进行分类和回归(一般还需要对位置精修)。一阶段目标检测算法不对候选区进行提取,只用了一级网络就完成了分类和回归。
  2. 是否存在先验框:按照是否存在先验框分类可以分为基于锚框的目标检测算法无锚框的目标检测算法。基于锚框的目标检测算法首先建立不同长宽比的检测框,然后对锚框中的内容进行分类和回归。无锚框的目标检测算法是基于中心区域和关键点的目标检测算法,取消了锚框生成机制,加快了速度。

如何理解候选区和先验框的区别呢? 在多分类任务中体现地比较清晰。以Faster R-CNN为例,区域建议网络RPN(Regional Proposal)不负责图像的分类,它只负责选取出图像中可能属于数据集其中一类的候选区域,接下来就是把RPN产生的候选区域输入到分类网络中进行最终的分类。先验框(详见本文2.2内容)是以每个像素为中心画框,所有这些初始框都不能确定是否包含目标物体。所以它们不是对立的,不要刻意去解决它们之间的联系,清晰的理解即可。

各类目标检测算法总结如下:

算法类别 机制 优势 局限性 适用场景 经典网络
one-stage 不生成候选区,直接进行分类和回归 实时性高 成群目标和小目标检测精度低 实时目标检测 SSD;Yolo系列;Retina-Net
two-stage 先生成候选区,再对候选区进行分类和回归 算法精确度高 实时性差,检测小目标效果差 高精度目标检测 R-CNN;SPPNet;Fast R-CNN;Faster R-CNN;Mask R-CNN
Anchor-Based 先生成锚框,对锚框进行分类和回归 技术较成熟 算法泛化能力差,训练效率低 通用目标检测 R-CNN;Fast R-CNN;Faster R-CNN;SSD
Anchor-Free 根据中心点和关键点生成边界框 算法泛化能力强,检测小目标精度高 不适合进行通用目标检测,精度低于基于锚框的算法 多尺度目标检测,小物体目标检测 Yolov1;Yolov2;CenterNet;CornorNet;Fcos

2.2 基于锚框的检测算法

一类目标检测算法是基于锚框,预测每个锚框里是否含有关注的物体,如果是,预测从这个锚框到真实边缘框的偏移。

2.2.1 IoU:交并比

Intersection over Union(IoU)是一种测量在特定数据集中检测相应物体准确度的一个标准。IoU是一个简单的测量标准,只要是在输出中得出一个预测范围(bounding boxes)的任务都可以用IoU来进行测量。


IoU用来计算两个框之间的相似度,可以用杰卡德系数(Jaccard Index)来理解。

杰卡德系数,又称为杰卡德相似系数,用于比较两个样本之间的差异性和相似性。杰卡德系数越高,则两个样本相似度越高。

给定两个集合A和B,其杰卡德系数为:

值为0表示无重叠,1表示完全重合。

2.2.2 基于锚框的检测的训练

在训练集中,我们需要给每个锚框两种类型的标签。一个是预测锚框中是否含有要检测的物体,另一个是锚框相对于边界框的偏移量(offset)。这里简单说一下算法的原理:

首先输入图片中包含感兴趣的对象以及它真实的标注,这里用绿色方框表示出来了。

我们需要设计锚框,以每个像素为中心点生成锚框是一种简单的方法。此处用白色方框表示我们设计的9个锚框,均匀地平铺在输入图像上,可以先理解为遍历每个像素,生成无数个锚框,这里只展示9个。设计锚框包括设计锚框的大小、长宽比、锚框的间隔,这些就是我们要设置的参数。我们可以设置n个缩放比(scale)表示锚框占图片的比例,和m个宽高比(aspect ratio)分别为s[n]r[m],形成锚框时,以每个像素点为中心生成不同形状的锚框。假设输入的图片尺寸为w×h,我们就以每个像素点为中心,生成缩放比为si、宽高比为rj的锚框,由于si的取值有n个,rj的取值有m个,所以共生成w*h*n*m个锚框。由于复杂度太高,所以我们只考虑包含s1r1的组合,即s1与所有r的匹配、r1与所有s的匹配,则得到w*h*(m+n-1)个锚框。

所以注意锚框不是像上图一样把图片简单的分割的,可能会有很多的锚框重叠、交叉等等,此时得到的锚框可以认为是最初的检测结果,然后需要筛选。

在训练集中,我们将每个锚框视为一个训练样本。 为了训练目标检测模型,我们需要每个锚框的类别(class)和偏移量(offset)标签,其中前者是与锚框相关的对象的类别,后者是真实边界框相对于锚框的偏移量。 在预测时,我们为每个图像生成多个锚框,预测所有锚框的类别和偏移量,根据预测的偏移量调整它们的位置以获得预测的边界框,最后只输出符合特定条件的预测边界框。


对锚框进行分类,即对这9个锚框分类哪些是背景,哪些是前景。如图,我们这里通过筛选得到了一个属于感兴趣对象的锚框,其他框就舍去了。这里简单介绍一个常用的分类算法:
我们的任务就是把锚框看成训练样本,对锚框进行分类,要么标注为背景(负类样本),要么关联上一个真实的边缘框

边缘框(bounding box) 是图片中物体的真实位置和范围,有两种表示方式,一种是边角坐标表示法,通过物体左上和右下两个角的坐标表示一个矩形框,还有一种是中心表示法,用物体的中心和宽高表示矩形框。

分类的时候,我们需要对锚框标号,如图,使用一个矩阵,列表示所有的边缘框,行表示所有的锚框。例如此处的边缘框是4个,锚框是9个。用每一个锚框和每一个边缘框计算IoU值组成的矩阵x。首先要找到矩阵中的x最大值,例如此处为x23,那么就把锚框2与边缘框3关联起来。

找到边缘框3对应的锚框之后,我们需要找其他的边缘框对应的锚框。忽略边缘框3所在的列和锚框2所在的行(因为边缘框3和锚框2都已经匹配了,不可能再匹配其他的了),在剩下的矩阵值中再找最大值。

例如x71是此时的最大值,那么就把锚框7和边缘框1关联起来。以此类推,直到我们将所有的边缘框都找到一个锚框对应。而剩余的锚框可以全部看作是负类样本,但通常我们设置一个threshold(阈值),遍历剩余的所有锚框,找到每一个锚框与其他边缘框的最大IoU,如果最大IoU都小于这个阈值,那就把它看成背景,否则可以认为是该边缘框的类别(即使之前已经找到了最合适的锚框对应这个边缘框)。这里注意,如果狗用0表示,猫用1表示,即类别数组为[0, 1],在实际标记锚框的过程中,我们需要将背景表示为0,其他类别的标签均+1,即类别数组为[0, 1, 2]分别表示背景、狗、猫。

我们将锚框与边缘框对应就是标记类别的过程,显然可以直接把锚框标记为关联的边缘框表示的类别,然后就需要计算它的偏移量。


回到这个例子,得到匹配的锚框后,需要进行锚框的回归,即对它的位置和大小进行调整,使它更接近真实的标注。

鉴于数据集内不同的框的位置和大小不同,我们可以对那些相对位置和大小应用变换,使其获得分布更均匀且易于拟合的偏移量。

一种常用的方法表示偏移量是:

在修正的过程中,我们给正类样本设置掩码为[1, 1, 1, 1],负类样本设置掩码为[0, 0, 0, 0],偏移量和掩码都类似于锚框坐标的系数,所以数据与4个偏移分量对应,通过元素乘法,掩码变量中的零将在计算目标函数之前过滤掉负类偏移量。

(我的理解,不知道对不对),锚框的回归即偏移量的计算像分类问题一样,用锚框加偏移量得到的预测框与真实边界框之间的损失、锚框分类的损失共同作用为整个模型的损失,在减小损失的过程中得到参数的合适值。

全过程如下:

我们可以用回归后的锚框作为初始框再次进行学习,级联地重复这个过程,如果是多次级联称为多阶段法,多阶段法是高精度的;如果只进行一次,称为单阶段法,单阶段法是高效率的。

2.2.3 基于锚框的检测的预测

在预测时,我们先为图像生成多个锚框,再为这些锚框一一预测类别和偏移量,接着根据预测的偏移量调整锚框位置从而得到预测边界框,最后筛选需要输出的预测边界框。我们将锚框和偏移量预测作为输入,并应用逆偏移变换来返回预测的边界框坐标

我自己的理解:
在训练时,我们可以将锚框的训练和图像分类的训练分开。已知输入图像的边缘框,可以先根据边缘框训练如何画锚框,得到设计锚框的合适的相关参数。然后将真实边缘框裁剪下来作为输入,再去对它进行分割、特征提取和学习,而不是对一整个包含很多目标物体的图片进行学习。

举个例子,这是一个小鸡的训练集:

在训练的时候,我们可能以某一像素点T为中心画了很多锚框,这些锚框有不同的缩放比、宽高比。

根据“基于锚框的检测的训练”中的方法,找到了一个真实边缘框关联的锚框,然后得到了偏移量。根据多次反复的学习(因为训练集的数据量很大,会得到很多锚框的尺寸和偏移量,可以对这些数据进行拟合,找到几组合适的参数)我们就得到了设计锚框的方法。仍以第一个小鸡为例,我们去进行特征提取,这里顺便复习一下:

首先分成多个区域,由于每个区域的贡献不同,赋予不同的滤波器去提取每个区域的特征。经过学习我们就可以得到卷积核和偏置参数。

预测时,我们根据上面对于锚框的训练可以得到一些参数,这些参数是对锚框的尺寸和偏移量进行设置,能够较好地拟合数据集。我们仍使用训练锚框的方法,以每个像素为中心,以学习得到的尺寸和偏移量设置锚框,得到很多很多的锚框,每个锚框看成是一个输入,对该区域的像素进行分类,得到预测结果。然后只要将概率非常小的锚框舍弃,就可以留下一部分粗略的预测结果。

举个例子,还是小鸡。假设我们已经得到了两组设计锚框的参数,我们以每一个像素为中心去画锚框,会得到非常多的锚框。由于画出来的锚框太多了,所以这里以两个点T1和T2为例:
我们将得到的锚框作为输入,去计算这个框能够被分类为小鸡的概率。假如绿色框概率为0.86,蓝色框概率为0.90,粉色框概率为0.15,黄色框概率为0.14,显然我们可以通过设置一个阈值删掉不满足条件的锚框,即将它们视为负类锚框。留到最后的锚框,就是我们目标检测的一个粗略结果(为什么是粗略,因为还要有优化呀!但是这里只是为了理解锚框检测的过程,所以不详细讲了。)
这样就很好的将“锚框的训练和预测”与“图像的训练与预测”结合起来,得到的结果(局部)可能是这样的:

这是一组锚框参数(si, rj)以不同的像素为中心预测到的可能是小鸡类的区域。

这是我刚开始自己的理解,但是根据查阅资料,我发现锚框并不是遍历了每一个像素点。

Anchor box 通常是以CNN提取到的Feature Map 的点为中心位置

Feature Map就是图像经过滤波器处理后得到的特征图。以Faster R-CNN为例,就是说假如我们对输入的图像下采样了16倍,也就是Feature Map上的一个点对应于输入图像上的一个16×16的感受野,我们在原图上画锚框,由于Faster R-CNN给定了三组s和三组r,所以这个点最多可以在原图上画出9种锚框。由此可见和我之前想的不太一样,我们首先对图片进行卷积操作,然后标注锚框(这样可以大大减少锚框的数量),再进行分类。

回到开头,将锚框和偏移量预测作为输入,并应用逆偏移变换来返回预测的边界框坐标。这里就可以理解了,锚框是不进行偏移的,就是我们根据像素点直接生成的那个框,只是得到了锚框和偏移量,根据公式算出来的边界框才是最后的结果,然后根据这个结果再去分类。明明锚框没有动,为什么叫做逆偏移变换呢?大概是因为这里的偏移量并不是指锚框和边缘框位置的真正偏移,看公式就可以明白,远比单纯的位置改变复杂,所以“偏移”的意思不是通过移动锚框得到真实边缘框,而是通过公式将两个框结合起来,那么逆偏移自然就是通过结果和公式求解未知数的过程。

NMS:非极大值抑制

在实际预测的时候,会得到很多锚框,如图:

这些锚框都是我们预测的边缘框,使用NMS可以合并相似的预测。首先选中某一非背景类的最大值,例如dog=0.9,然后计算其他锚框与该锚框的IoU值,并设置一个阈值。若计算得到的IoU大于阈值,说明相似度太高,即这些框高度重叠,去掉这些锚框。重复上述过程,直到所有锚框要么被选中,要么被去掉。
官方的说法如下:

我在思考像上面那张图片,一个小鸡藏在另一个小鸡后面,我们用两个中心位置距离很大的锚框,其实是可以区分出来的,虽然它们重合度非常高。类比到其他分类的情况,如果两个物体很难完全重合,比如花草树木的形态可能是直立或者倾斜,又或是并排,那么我们即使是以同一中心点,绘制宽高比不同的锚框,或者以不同中心点绘制同样的锚框,也能很好地区分两个物体。可见我对于IoU会不会误判这个想法多虑了,我们绘制的锚框数量是巨大的,就算去掉了很多重复度很高的锚框,也能留下足以区分两个物体的两个锚框。

2.2.4 总结

在这里需要复述一遍基于锚框的检测算法,如果复述不下来,上面的内容再看一遍!

2.3 目标检测的评价指标【待补充】


注意正例在目标检测中一般是满足IoU>=设置阈值的。

  • 精确率(precision):如上图;
  • 召回率(recall):如上图;
  • 帧率每秒(Frames Per Second,FPS):每秒识别图像的数量,用于评估目标检测模型的检测速度;
  • P-R曲线:以Recall、Precision为横纵坐标的曲线;
  • 准确率(accuracy):?
  • 平均精度(Average Precision,AP):对不同召回率点上的精确率进行平均,在PR曲线图上表现为某一类别的 PR 曲线下的面积;
  • 平均精度均值(mean Average Precision,mAP):所有类别AP的均值。

2.4 图像的预处理操作【待补充】

2.4.1 归一化和标准化

归一化的概念:

归一化是一种简化计算的方式,即将有量纲的表达式,经过变换,化为无量纲的表达式,成为标量。 在多种计算中都经常用到这种方法。
归一化是一种无量纲处理手段,使物理系统数值的绝对值变成某种相对值关系。简化计算,缩小量值的有效办法。

归一化(Normalization):将一列数据变化到某个固定区间(范围)中,通常,这个区间是[0, 1],广义的讲,可以是各种区间,比如映射到[0,1]一样可以继续映射到其他范围,图像中可能会映射到[0,255],其他情况可能映射到[-1,1]。(我理解的,之前使用softmax分类器得到的每个类别的概率,就很像归一化的作用)最大最小值归一化(简称归一化)的变换方法为:

另一种均值归一化的变换方法为:

标准化的概念:
标准化(Standardization):将数据变换为均值为0,标准差为1的分布(标准差能够反应一个数据集的离散程度),变换后依然保留原数据分布。标准化又叫z值归一化,其变换方法为:
如何将归一化运用到计算机视觉中呢?可以使用OpenCV中的normalize()进行归一化。举个例子(以最大最小值归一化为例):

import cv2
import numpyimage_path = "xdl.jpg"  # 星黛露图片的文件名
img_before = cv2.imread(image_path)
cv2.imshow("before", img_before)  # 显示图片
cv2.waitKey(0)  # 因为cv2.imshow()是会闪退的,所以要设置延迟,默认为0毫秒(表示暂停)print("This is the data before normalization:")
print(img_before)
img_before = numpy.float32(img_before)  # 进行归一化操作要把图片格式变为numpy.float32
img_after = numpy.zeros(img_before.shape, dtype=numpy.float32)  # 创建一个新的img_after存储归一化后的图片"""
cv2.normalize(src, dst, alpha=None, dtype=None, mask=None)参数说明:
src:表示输入图像,numpy类型
dst:表示归一化之后的图像,numpy类型
alpha:归一化结果范围中的最大值max,如果norm_type为NORM_MINMAX,则alpha为大值或小值;如果norm_type为其他类型时,则为归一化要乘的系数
beta:归一化结果范围中的最小值min,如果norm_type为NORM_MINMAX,则beta为和alpha对应的小值或大值;如果norm_type为其他类型beta被忽略,一般传入0
norm_type:归一化方法如NORM_MINMAX、NORM_INF、NORM_L1、NORM_L2,默认最大最小值归一化(NORM_MINMAX)
dtype:归一化之后numpy的数据类型,默认类型与src相同,一般选择cv2.CV_32F
mask:遮罩层
"""cv2.normalize(img_before, img_after, alpha=1, beta=0, norm_type=cv2.NORM_MINMAX)print("This is the data after normalization:")
print(img_after)
cv2.imshow("after", numpy.uint8(img_after))
cv2.waitKey(0)print("This is the data after normalization and ×255:")
print(img_after*255)  # 如果要得到原图,通过改变img的系数重新设置图像范围为0-255(但不能完全恢复,具体原因可分析归一化公式)
cv2.imshow("after*255", numpy.uint8(img_after*255))
cv2.waitKey(0)print("This is the data after normalization and ×150:")
print(img_after*150)
cv2.imshow("after*150", numpy.uint8(img_after*150))
cv2.waitKey(0)cv2.destroyAllWindows()  # 关闭cv

代码对应输出的四组图像和img数值分别为:




如何进行图像的标准化操作呢?仍使用OpenCV读取和显示图片举例,并使用tensorflow中的标准化函数进行操作(由于tensorflow还没有系统学习,所以代码中只作了简单注释,能看懂即可),代码和结果如下:

import cv2
import tensorflow as tfimage_path = "xdl.jpg"  # 星黛露图片的文件名
img_before = cv2.imread(image_path)
cv2.imshow("before", img_before)  # 显示图片"""
对图像标准化预处理:
tensorflow.image.per_image_standardization(image)参数说明:
image:参数表示一个三维的张量(tensor)分别对应图像高、宽、通道
"""tf.compat.v1.disable_eager_execution()  # 设置tensorflow与旧版本兼容,否则无法使用接下来的函数
image = tf.image.per_image_standardization(img_before)"""
TensorFlow中只有让Graph上的节点在Session中执行才会得到结果,而且在使用结束后必须关闭Session手动关闭的方法:
res = a + b
sess = tf.Session()
sess.run(res)  # 执行运算
sess.close()自动关闭的方法(指定Session的有效范围):
res = a + b
with tf.Session() as sess:sess.run(res)"""
# 由于tensorflow新版本移除了Session,所以改用tensorflow.compat.v1.Session()
with tf.compat.v1.Session() as sess:img_after = sess.run(image)print(img_after)cv2.imshow("after", img_after)cv2.waitKey(0)  # 一个程序窗口可以只写一个,所有图片会一起展示
cv2.dsetroyAllWindows()

2.4.2 图像噪声【待补充】

图像噪声是指存在于图像数据中的不必要的或多余的干扰信息,图像噪声的产生来自图像获取中的环境条件和传感元器件自身的质量。

什么是噪声? 噪声样本大概分为四大类:

  • 第一类是粗粒度错误,比如车标成了人;
  • 第二类是细粒度错误,一种是特征难区分(比如狼和狗),另一种是有重复的样本(比如一条泰迪可以标成“泰迪”也可以标成“狗”;
  • 第三类是背景噪声,一种是单标签图片(比如标签是“人”,但是人只占一小部分图,其他都是背景),另一种是内含多标签的图片(比如一个人抱着一条狗,图片标记为“人”,那狗就是噪声);
  • 第四类是分布不一致错误,比如真实狗数据里面出现一张卡通狗。

为什么要加入噪声? 神经网络中噪声的注入可以有很多种,如输入层,隐层,权重,输出层等。输入层注入噪声,其实可以看作是数据集增强的一种手段,本质是一种正则化,为了让训练出的模型能够对抗噪声,让神经网络更加鲁棒。真实数据中噪声是很常见的,如果训练时候不加入噪声,那么测试的时候模型在有噪声的样本上表现将会很差。

根据前面对归一化和标准化的学习,我明白其实计算机视觉方面对图像的操作都是基于每个像素值数字的改动,那么根据我的理解,给图像添加噪声,它的本质也是改变某些像素的值,这样图片上小色块的颜色应该会随之改变。只不过如何改变值、改变哪些值,是设置了约束和规范的,因此有多种添加噪声的方法。同理,不仅有加噪的操作,由于图像采集出现的噪声,我们可以通过去噪进行图像的预处理,从而便于后续对图像的操作。

一、高斯噪声

高斯噪声是指它的概率密度函数 服从高斯分布(即正态分布)的一类噪声。

连续型随机变量的概率密度函数,是一个描述这个随机变量z的输出值,“ 在某个确定的取值点附近的可能性 ” 的函数。而随机变量的取值落在某个区域之内的概率则为概率密度函数在这个区域上的积分。

高斯分布,也称正态分布,又称常态分布,记为N(μ,σ2),其中μ,σ2为分布的参数,分别为高斯分布的期望和方差。当有确定值时,p(z)也就确定了,特别当μ=0,σ2=1时,z的分布为标准正态分布。
——
在数字图像中的高斯噪声的主要来源出现在采集期间。 由于不良照明、高温引起的传感器噪声。 用于噪声去除的常规空间滤波技术包括:平均(卷积)滤波,中值滤波和高斯平滑。


其中z表示灰度值,u表示z的均值,σ表示z的标准差。当z服从高斯分布时,其值有大约70%落在范围[(u-σ),(u+σ)]内,有大约95%落在范围[(u-2σ),(u+2σ)]内。通俗地理解就是,在我这个计算机图像中,灰度值为z的噪声比例大概有PG(z)这么多。

椒盐噪声
椒盐噪声也称为脉冲噪声,是图像中经常见到的一种噪声,所谓椒盐。椒就是黑,盐就是白。它是一种随机出现的白点或者黑点,可能是亮的区域有黑色像素或是在暗的区域有白色像素(或是两者皆有),可能是影像讯号受到突如其来的强烈干扰而产生、类比数位转换器或位元传输错误等。例如失效的感应器导致像素值为最小值,饱和的感应器导致像素值为最大值。去除脉冲干扰及椒盐噪声最常用的算法是中值滤波。
————————————————
版权声明:本文为CSDN博主「星空之火」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_34244712/article/details/124306145

数据增强(Data Augmentation)

数据增强是指从给定数据导出的新数据的添加,这可能被证明对预测有益。例如,如果你使光线变亮,可能更容易在较暗的图像中看到猫,或者例如,数字识别中的9可能会稍微倾斜或旋转。在这种情况下,旋转将解决问题并提高我们的模型的准确性。

通过旋转或增亮,我们正在提高数据的质量。这被称为数据增强。

2.5 特征金字塔(FPN)

2.5.1 基本概念

  1. 尺度、尺度空间
    图像的尺度并非指图像的大小,而是指图像的模糊程度(σ) 。尺度的概念是用来模拟观察者距离物体的远近程度,具体来说,观察者距离物体远,看到物体可能只有大概的轮廓;观察者距离物体近,更可能看到物体的细节,比如纹理,表面的粗糙等等。例如,人近距离看一个物体和远距离看一个物体模糊程度是不一样的,从近距离到远距离图像越来越模糊的过程,也是图像的尺度越来越大的过程。
    图像的尺度空间是指同一图像不同尺度的集合。在构建图像尺度空间的过程中,唯一使用的核函数是高斯核(因为高斯核是唯一可以产生多尺度空间的核)。即图像的尺度空间是一幅图像经过几个不同高斯核后形成的模糊图片的集合,用来模拟人眼看到物体的远近程度以及模糊程度。

  2. 特征
    颜色特征是最为广泛的视觉特征。颜色特征无需进行大量计算,只需将数字图像中的像素值进行相应转换,表现为数值即可。
    形状特征的表达必须以对图像中物体或区域的分割为基础。 两种经典的算法是SIFT和HOG: SIFT是先找特征点,而HOG是对图片进行分割。
    纹理特征是一种反映图像中同质现象的视觉特征,它体现了物体表面的具有缓慢变化或者周期性变化的表面结构组织排列属性。
    边缘特征是检测一张数字图像中有明显变化的边缘或者不连续的区域。边缘是一幅图像中不同区域之间的边界线,通常一个边缘图像是一个二值图像。边缘检测的目的是捕捉亮度急剧变化的区域,而这些区域通常是我们关注的。

  3. 上采样和下采样
    上/下采样可对应为放/缩。 下图按金字塔的方式特征提取,以黄色特征图为基础,那么橙色就可以理解为是相对于黄色的下采样(缩),灰色就是上采样(放)。一张图片可以解析为n个(上采样特征,基值,下采样特征)向量。以眼睛的特征向量为例可以形象的解释为,上采样特征—猫的眼睛、基值—动物的眼睛、下采样特征—眼睛。

    缩小图像,我们可以更加清楚地关注到图像的全局信息(比如缩略图);放大图像,我们可以精细地了解图像的局部信息。一般在目标检测过程中,上采样为了识别较大物体,而下采样为了识别更小物体。
    特征金字塔能够将图像信息分解为局部、一般、全局信息的特征图,将这3种特征图交由计算机处理便能够进行图像信息的多尺度处理。若更关注局部,则可将局部或一般信息进行下采样,此过程称为resize,重新恢复尺寸。

2.5.2 FPN的网络结构

特征金字塔网络FPN(Feature Pyramid Networks) 是用于检测不同尺度的对象的识别系统中的基本组件。多尺度上识别目标是计算机视觉的一个挑战,通过提取多尺度的特征信息进行融合,进而提高模型精度。


a. 基础的CNN网络结构:
自底向上卷积,然后使用最后一层特征图进行预测,即仅采用网络最后一层的特征。卷积神经网络不仅可以表达高阶语义特征,在面临物体尺度变化时的表现也更加稳健。
应用举例:分类器
b. 图片金字塔:
将图像做成不同的scale(缩放成多个比例),然后不同scale的图像生成对应的不同scale的特征,用每个比例单独提取的特征图进行预测。
应用举例:Mtcnn的pent;TTA
c. 多尺度特征融合:
从网络不同层抽取不同尺度的特征做预测。
优点:不会增加额外的计算量。
应用举例:SSD(Single Shot Detector)目标检测算法
d. FPN:
在多尺度特征融合的基础上还增加了通过高层特征进行上采样和低层特征进行自顶向下的连接(特征融合),然后进行下一步预测。
优点:主要解决物体检测中的多尺度问题,在基本不增加原有模型计算量的情况下,大幅度提升了小物体检测的性能。
应用举例:Retinanet

举例说明FPN的过程,以32倍下采样和16倍下采样特征图进行FPN操作,图示如下:

其中,“特征融合”常用的两种方法是concatadd

  • concat:张量拼接,会扩充两个张量的维度。
  • add:张量相加,张量直接相加,不会扩充维度

concat能够完整地保留特征信息,比add的信息保留程度高,但是通道数会增加,卷积核参数变多。add需要保证C、H、W三个参数完全一致才能进行,concat则只需要H和W一致即可。如果采用轻量级的网络一般以add为主,add是FPN官方的特征融合方式。

FPN的动机包括:

  • 高层特征不断往底层融合,增强低层特征的表达能力,提升性能;
  • 不同尺度的目标物可以分配到不同层进行预测,分而治之。

2.5.3 下采样和上采样

下采样(subsampled),又称为降采样(downsampled)。可以通俗地理解为缩小图像,减少矩阵的采样点数。

我的理解,在卷积的过程中,卷积操作、池化操作都是下采样,因为它们可以缩小图像尺寸。除卷积操作外,另外介绍常用的下采样方法如下:

  • 隔位取值:每行每列每隔k个点取一个点
  • 合并区域:每(row/k)*(col/k)窗口内所有像素的均值作为一个像素

上采样(upsampling),又称为插值(interpolating)。可以通俗地理解为放大图像,增加矩阵的采样点数。

我们说的反卷积就是上采样,在卷积提取特征后需要通过上采样将feature map还原到原图中。反卷积常用的操作是双线性插值以及转置卷积,具体方法在【深度学习】计算机视觉(五)——神经网络详解中已经介绍过,另外介绍常用的上采样方法如下:

  • 内插值:每行每列每相邻两点间增加新的k-1个采样点,包括最邻近元法、双线性插值法、三次内插法等
  • 频域补0:根据傅里叶变换性质等同于在空域插值

丢弃【待补充】

监督学习和无监督学习【待补充】

监督学习需要具有标签(label)的训练数据。如做分类,你需要先对训练数据做标记,然后才能训练模型将数据分成标记类。
非监督学习不需要标签,它只有输入数据,目标是发现数据中的规律。

【待补充】无锚框的检测算法

看惯了论文中的Anchor-Free,同时找不到合适的中文翻译,暂且叫它无锚框吧,后续就直接用英文术语了。

首先理解一下为什么会使用Anchor-Free,即Anchor-Based有一些弊端:

  1. 对于不同数据集需要设计不同的Anchor(长宽比,尺度大小,anchor的数量),会较明显的影响最终预测效果;
  2. Anchor的匹配机制使得极端尺度(特别大和特别小的object)被匹配到的频率相对于大小适中的object被匹配到的频率更低,预置的锚点大小、比例在检测差异较大物体时不够灵活;
  3. Anchor的数量庞大,耗费巨大的算力,降低了效率;
  4. 容易导致训练时negative与positive的比例失衡(因为训练的时候好像不止需要目标物体,背景也需要参与训练,就是我们要让模型知道什么是对的,也要让它知道什么是错的,但是参与训练的正负样本的比例不好控制,负样本太多了模型没有意义)。

Anchor-Free的技术包括基于Keypoint-bsaed Detection与Dense Prediction两类

  • 基于Keypoint-bsaed Detection技术包括:CornerNetCenterNetCornerNet-Lite等;
  • 基于Segmentation技术包括:FSAFFCOSFoveaBox等。

参考来源:

【深度学习】计算机视觉(七)——使用GPU进行目标检测详解(上)相关推荐

  1. java面向对象编程集合边框_Java学习系列(七)Java面向对象之集合框架详解(上)

    Java集合 有时也将集合称为容器类,它的作用就是用来"装对象"的.这里要注意的是集合也可以是对象.下面先看一张图: HashSet:底层用一个数组存元素 --而且这个数组的长度永 ...

  2. 无人驾驶汽车系统入门(二十六)——基于深度学习的实时激光雷达点云目标检测及ROS实现

    无人驾驶汽车系统入门(二十六)--基于深度学习的实时激光雷达点云目标检测及ROS实现 在前两篇文章中,我们使用PCL实现了在点云中对地面的过滤和点云的分割聚类,通常来说,在这两步以后我们将对分割出来的 ...

  3. 深度学习 + OpenCV,Python实现实时视频目标检测

    选自PyimageSearch 机器之心编译 参与:路雪.李泽南 使用 OpenCV 和 Python 对实时视频流进行深度学习目标检测是非常简单的,我们只需要组合一些合适的代码,接入实时视频,随后加 ...

  4. 笔记 | 百度飞浆AI达人创造营:深度学习模型训练和关键参数调优详解

    笔记 | 百度飞浆AI达人创造营:深度学习模型训练和关键参数调优详解 针对特定场景任务从模型选择.模型训练.超参优化.效果展示这四个方面进行模型开发. 一.模型选择 从任务类型出发,选择最合适的模型. ...

  5. 深度学习模型训练和关键参数调优详解

    深度学习模型训练和关键参数调优详解 一.模型选择 1.回归任务 人脸关键点检测 2.分类任务 图像分类 3.场景任务 目标检测 人像分割 文字识别 二.模型训练 1.基于高层API训练模型 加载数据集 ...

  6. Keras深度学习实战(22)——生成对抗网络详解与实现

    Keras深度学习实战(22)--生成对抗网络详解与实现 0. 前言 1. 生成对抗网络原理 2. 模型分析 3. 利用生成对抗网络生成手写数字图像 小结 系列链接 0. 前言 生成对抗网络 (Gen ...

  7. Keras深度学习实战(21)——神经风格迁移详解

    Keras深度学习实战(21)--神经风格迁移详解 0. 前言 1. 神经风格迁移原理 2. 模型分析 3. 使用 Keras 实现神经风格迁移 小结 系列链接 0. 前言 在 DeepDream 图 ...

  8. Keras深度学习实战(26)——文档向量详解

    Keras深度学习实战(26)--文档向量详解 0. 前言 1. 文档向量基本概念 2. 神经网络模型与数据集分析 2.1 模型分析 2.2 数据集介绍 3. 利用 Keras 构建神经网络模型生成文 ...

  9. 【深度学习】扩散模型(Diffusion Model)详解

    [深度学习]扩散模型(Diffusion Model)详解 文章目录 [深度学习]扩散模型(Diffusion Model)详解 1. 介绍 2. 具体方法 2.1 扩散过程 2.2 逆扩散过程 2. ...

  10. 无人驾驶汽车系统入门:基于深度学习的实时激光雷达点云目标检测及ROS实现...

    参加 2018 AI开发者大会,请点击 ↑↑↑ 作者:申泽邦(Adam Shan),兰州大学在读硕士研究生,主要研究方向无人驾驶,深度学习:兰大未来计算研究院无人车团队负责人,自动驾驶全栈工程师. 近 ...

最新文章

  1. php rsa数字签名为空,如何使用PHP将数字签名(RSA,证书等)添加到任何文件?
  2. 深入浅出之函数的参数传递方式
  3. Leecode 1218. 最长定差子序列——Leecode每日一题系列
  4. Java 8 Optional不仅用于替换空值
  5. ftp服务器在线浏览,ftp服务器PDF文件在线查看的实现方法
  6. android 服务是什么问题,Android Studio 中的Service问题
  7. linux网络子系统分析(二)—— 协议栈分层框架的建立
  8. Lodop打印控件的学习
  9. 飞行计算机配置,微软飞行模拟器配置要求一览 最低/最高PC配置详情
  10. CCF NOI 2022获奖名单
  11. 计算机网络的一些小知识
  12. 计算机怎样将多行文字转换成表格,怎么把表格里的字变成两行
  13. AT89C51(Atmel)芯片制作简易的频率计
  14. 手机进水声音变小怎么办
  15. leetcode:活字印刷
  16. 从思维转变看数字化转型 IT 经营
  17. Android应用程序icon规范
  18. 六十星系之21紫微天府坐寅申
  19. css三角形 增涨,CSS3实现三角形不断放大效果
  20. 拼多多笔试 公司套餐

热门文章

  1. 一文带你了解什么是CDN?
  2. robots协议文件的几种写法及示例
  3. 智和网管平台-真正开放源码的网元管理系统(EMS)
  4. 看看什么叫穿越失败,我承认我确实笑了
  5. 【Java】使用AOP进行异常处理与日志记录
  6. Linux查询IP失败
  7. python unpack函数_Lua UnPack函数用法实例
  8. buuctf——密码学的心声
  9. linux 任意音频采样率转换
  10. 记dubbo consumer服务因订阅其他有异常的服务导致超时的问题