神经网络与深度学习-深度学习视觉应用

1. 数据集与评价指标

2.1. 算法评估

算法评估相关概念:

TP: 被正确地划分为正例的个数,即实际为正例且被分类器划分为正例的实例数
FP: 被错误地划分为正例的个数,即实际为负例但被分类器划分为正例的实例数
FN:被错误地划分为负例的个数,即实际为正例但被分类器划分为负例的实例数
TN: 被正确地划分为负例的个数,即实际为负例且被分类器划分为负例的实例
P(精确率): TP/(TP+FP)
R(召回率): TP/(TP+FN)。召回率越高,准确度越低

在这里插入图片描述
P-R曲线:

P-R的关系曲线图,表示了召回率和准确率之间的关系:精度(准确率)越高,召回率越低

在这里插入图片描述
相关概念示例:
例子:80个男生,20个女生,做个女生识别器。结果测试了50个全部
输出女生,其中20个本来是女生,30个男生
TP: 20; FP:30 FN:0, TN: 0.
准确率:40%;
召回率:100%

示例:

  • 假设一个测试集,其中图片只由大雁和飞机两种图片组成
    在这里插入图片描述
  • True positives : 飞机的图片被正确的识别成了飞机。
  • False positives: 大雁的图片被错误地识别成了飞机。
  • False negatives: 飞机的图片没有被识别出来,系统错误地认
    为它们是大雁。
  • True negatives: 大雁的图片没有被识别出来,系统正确地认
    为它们是大雁

置信度与准确率:
调整阈值可改变准确率或召回值
在这里插入图片描述
在刚才例子中,对应某阈值,前四个样本(左侧)被分类为飞机改变阈值会改变划分,进一步影响准确率或召回值

可以通过改变阈值(也可以看作上下移动蓝色的虚线),来选择让系统识别能出多少个图片,当然阈值的变化会导致Precision与Recall值发生变化。比如,把蓝色虚线放到第一张图片下面,也就是说让系统只识别出最上面的那张飞机图片,那么Precision的值就是100%,而ecall的值则是20%。如果把蓝色虚线放到第二张图片下面,也就是说让系统只识别出最上面的前两张图片,那么Precision的值还是100%,而Recall的值则增长到是40%。

不同阈值条件下,Precision与Recall的变化情况

在这里插入图片描述
P-R曲线

在这里插入图片描述
AP计算:

  • mAP:均值平均准确率
    A P = ∑ k = 1 N P ( k ) Δ r ( k ) AP=\sum\limits^N_{k=1}P(k)\varDelta r(k) AP=k=1NP(k)Δr(k)

其中𝑁代表测试集中所有图片的个数,𝑃(𝑘)表示在能识别出𝑘个图片的时候Precision的值,而 Δ𝑟(𝑘)则表示识别图片个数从𝑘 − 1变化到𝑘时(通过调整阈值)Recall值的变化情况。

在这一例子中,AP的值

= (1 ∗ (0.2 − 0)) + (1 ∗ (0.4 − 0.2)) + (0.66 ∗ (0.4 − 0.4)) + (0.75 ∗ (0.6
− 0.4)) + (0.6 ∗ (0.6 − 0.6)) + (0.66 ∗ (0.8 − 0.6)) + (0.57 ∗ (0.8 − 0.8)+ (0.5 ∗ (0.8 − 0.8)) + (0.44 ∗ (0.8 − 0.8)) + (0.5 ∗ (1 − 0.8)) = 0.782.
= (1 ∗ 0.2) + (1 ∗ 0.2) + (0.66 ∗ 0) + (0.75 ∗ 0.2) + (0.6 ∗ 0) + (0.66
∗ 0.2) + (0.57 ∗ 0) + (0.5 ∗ 0) + (0.44 ∗ 0) + (0.5 ∗ 0.2) = 0.782.

通过计算可以看到,那些Recall值没有变化的地方,对增加Average Precision值没有贡献

mAP计算:

  • 每一个类别均可确定对应的AP
  • 多类的检测中,取每个类AP的平均值,即为mAP

2. 目标检测与YOLO

目标检测问题:

目标检测是在给定的图片中精确找到物体所在位置,并标注出物体的类别。

物体的尺寸变化范围很大,摆放物体的角度,姿态不定,而且可以出现在图片的任何地方,并且物体还可以是多个类别。

在这里插入图片描述

目标检测问题发展

  • R-CNN
  • SPP NET
  • Fast R-CNN
  • Faster R-CNN
  • 最终实现YOLO

YOLO是一个集大成的方法,不了解之前的方法,很难掌握YOLO的思路。

3. 目标检测实现

3.1. 目标检测预备知识

目标检测基本原理:

很多时候图像里有多个我们感兴趣的目标,我们不仅想知道它们的类别,还想得到它们在图像中的具体位置。在计算机视觉里,我们将这类任务称为目标检测(object detection)或物体检测。

目标检测在多个领域中被广泛使用。例如,在无人驾驶里,我们需要通过识别拍摄到的视频图像里的车辆、行人、道路和障碍的位置来规划行进线路。机器人也常通过该任务来检测感兴趣的目标。安防领域则需要检测异常目标,如歹徒或者炸弹。

先导入实验所需的包或模块。

在这里插入图片描述
下面加载本节将使用的示例图像。可以看到图像左边是一只狗,右边是一只猫。它们是这张图像里的两个主要目标

在这里插入图片描述
在这里插入图片描述
边界框:

在目标检测里,我们通常使用边界框(bounding box)来描述目标位置。边界框是一个矩形框,可以由矩形左上角的x和y轴坐标与右下角的x和y轴坐标确定。我们根据下面的图的坐标信息来定义图中狗和猫的边界框。图中的坐标原点在图像的左上角,原点往右和往下分别为x轴和y轴的正方向。

在这里插入图片描述

我们可以在图中将边界框画出来,以检查其是否准确。画之前,我们定义一个辅助函数bbox_to_rect。它将边界框表示成matplotlib的边界框格式

在这里插入图片描述

我们将边界框加载在图像上

在这里插入图片描述
锚框:

目标检测算法通常会在输入图像中采样大量的区域,然后判断这些区域中是否包含我们感兴趣的目标,并调整区域边缘从而更准确地预测目标的真实边界框(ground-truth bounding box)。

不同的模型使用的区域采样方法可能不同。这里我们介绍其中的一种方法:它以每个像素为中心生成多个大小和宽高比(aspect ratio)不同的边界框。这些边界框被称为锚框(anchor box)。我们将在后面基于锚框实践目标检测。

先导相关包

在这里插入图片描述
生成多个锚框:

假设输入图像高为h,宽为w。我们分别以图像的每个像素为中心生成不同形状的锚框。设大小为s∈(0,1]且宽高比为r>0,那么锚框的宽和高将分别为𝑤𝑠√𝑟 和ℎ𝑠/ √𝑟。当中心位置给定时,已知宽和高的锚框是确定的。

下面我们分别设定好一组大小s1,…,sn和一组宽高比r1,…,rm。如果以每个像素为中心时使用所有的大小与宽高比的组合,输入图像将一共得到whn*m个锚框。虽然这些锚框可能覆盖了所有的真实边界框,但计算复杂度容易过高。因此,我们通常只对包含s1或r1的大小与宽高比的组合感兴趣,即

在这里插入图片描述

也就是说,以相同像素为中心的锚框的数量为n+m−1。对于整个输入图像,我们将一共生成w*h(n+m−1)个锚框。

以上生成锚框的方法实现在下面的MultiBoxPrior函数中。指定输入、一组大小和一组宽高比,该函数将返回输入的所有锚框。

在这里插入图片描述
在这里插入图片描述
shifts_x和shifts_y是将宽高进行归一化处理然后用meshgrid函数生成一个向量矩阵,最后reshape成一行向量

在这里插入图片描述
将reshape之后的向量进行stack操作,之后将得到的shift与原始的base_anchors相加从而自动生成所有的anchor

我们看到,返回锚框变量y的形状为(1,锚框个数,4)。将锚框变量y的形状变为(图像高,图像宽,以相同像素为中心的锚框个数,4)后,我们就可以通过指定像素位置来获取所有以该像素为中心的锚框了。

下面的例子里我们访问以(250,250)为中心的第一个锚框。它有4个元素,分别是锚框左上角的x和y轴坐标和右下角的x和y轴坐标,其中x和y轴的坐标值分别已除以图像的宽和高,因此值域均为0和1之间。

在这里插入图片描述
为了描绘图像中以某个像素为中心的所有锚框,我们先定义show_bboxes函数以便在图像上画出多个边界框。

在这里插入图片描述

这里将数据打包成列表

为了描绘图像中以某个像素为中心的所有锚框,我们先定义show_bboxes函数以便在图像上画出多个边界框。

在这里插入图片描述

每个bbox进行迭代然后在图像上画出边界框

刚刚我们看到,变量boxes中xx和yy轴的坐标值分别已除以图像的宽和高。在绘图时,我们需要恢复锚框的原始坐标值,并因此定义了变量bbox_scale。现在,我们可以画出图像中以(250, 250)为中心的所有锚框了。可以看到,大小为0.75且宽高比为1的锚框较好地覆盖了图像中的狗

在这里插入图片描述
在这里插入图片描述
交并比:

刚刚提到某个锚框较好地覆盖了图像中的狗。如果该目标的真实边界框已知,这里的“较好”该如何量化呢?一种直观的方法是衡量锚框和真实边界框之间的相似度。我们知道,Jaccard系数(Jaccard index)可以衡量两个集合的相似度。给定集合A和B,它们的Jaccard系数即二者交集大小除以二者并集大小

在这里插入图片描述

实际上,我们可以把边界框内的像素区域看成是像素的集合。如此一来,我们可以用两个边界框的像素集合的Jaccard系数衡量这两个边界框的相似度。

当衡量两个边界框的相似度时,我们通常将Jaccard系数称为交并比,即两个边界框相交面积与相并面积之比,如图所示。交并比的取值范围在0和1之间:0表示两个边界框无重合像素,1表示两个边界框相等

在这里插入图片描述

下面我们对其进行实现。

在这里插入图片描述
set1和set2分别为(n1,4),(n2,4)大小的张量,利用clamp函数和向量运算直接计算了相交面积大小,当二者不相交时clamp函数将二者的upper_bounds-lower_bounds置为零,IOU计算时就不会有负值

在这里插入图片描述
计算IOU来衡量锚框与真实边界框以及锚框与锚框之间的相似度。

标注训练集的锚框:

在训练集中,我们将每个锚框视为一个训练样本。为了训练目标检测模型,我们需要为每个锚框标注两类标签:一是锚框所含目标的类别,简称类别;二是真实边界框相对锚框的偏移量,简称偏移量(offset)。

在目标检测时,我们首先生成多个锚框,然后为每个锚框预测类别以及偏移量。

接着根据预测的偏移量调整锚框位置从而得到预测边界框。

最后筛选需要输出的预测边界框。

假设图像中锚框分别为
A 1 , A 2 , ⋯   , A n a A_1,A_2,\cdots,A_{n_a} A1,A2,,Ana

真实边界框分别为
B 1 , B 2 , ⋯   , B n b B_1,B_2,\cdots,B_{n_b} B1,B2,,Bnb


n a ≥ n b n_a\ge n_b nanb

定义矩阵

在这里插入图片描述
其中第i行第j列的元素 为锚框Ai与真实边界框Bj的交并比。

首先,我们找出矩阵X中最大元素,并将该元素的行索引与列索引分别记为i1,j1。我们为锚框Ai1分配真实边界框Bj1。显然,锚框Ai1和真实边界框Bj1在所有的“锚框—真实边界框”的配对中相似度最高。

接下来,将矩阵X中第i1行和第j1列上的所有元素丢弃。找出矩阵XX中剩余的最大元素,并将该元素的行索引与列索引分别记为i2,j2。我们为锚框Ai2分配真实边界框Bj2,再将矩阵X中第i2行和第j2列上的所有元素丢弃。此时矩阵X中已有两行两列的元素被丢弃。

依此类推,直到矩阵X中所有n[b]列元素全部被丢弃。这个时候,我们已为n[b]个锚框各分配了一个真实边界框。 接下来,我们只遍历剩余的n[a]−n[b]个锚框:给定其中的锚框Ai,根据矩阵X的第i行找到与Ai交并比最大的真实边界框Bj,且只有当该交并比大于预先设定的阈值时,才为锚框Ai分配真实边界框Bj。

在这里插入图片描述

如果一个锚框A被分配了真实边界框B,将锚框A的类别设为B的类别,并根据B和A的中心坐标的相对位置以及两个框的相对大小为锚框A标注偏移量。

设锚框A及其被分配的真实边界框B的中心坐标分别为(x[a],y[a])和(x[b],y[b]),A和B的宽分别为w[a]和w[b],高分别为h[a]和h[b],一个常用的技巧是将A的偏移量标注为

在这里插入图片描述
其中常数的默认值为μx=μy=μw=μh=0,σx=σy=0.1,σw=σh=0.2,如果一个锚框没有被分配真实边界框,我们只需将该锚框的类别设为背景。类别为背景的锚框通常被称为负类锚框,其余则被称为正类锚框。

下面演示一个具体的例子

在这里插入图片描述
输入gt和anchor并且在图中显示

显示出的gt和anchor

在这里插入图片描述
下面实现MultiBoxTarget函数来为锚框标注类别和偏移量。该函数将背景类别设为0,并令从零开始的目标类别的整数索引自加1(1为狗,2为猫)。

在这里插入图片描述
实现MultiBoxTarget函数来为锚框标注类别和偏移量

在这里插入图片描述
实现MultiBoxTarget函数来为锚框标注类别和偏移量

在这里插入图片描述
在这里插入图片描述

也我们通过unsqueeze函数为锚框和真实边界框添加样本维。

在这里插入图片描述

返回的结果里有3项,均为Tensor。第三项表示为锚框标注的类别。

在这里插入图片描述
我们根据锚框与真实边界框在图像中的位置来分析这些标注的类别。例如,在所有的“锚框—真实边界框”的配对中,锚框A4与猫的真实边界框的交并比最大,因此锚框A4类别标注为猫。

返回值的第二项为掩码(mask)变量,形状为(批量大小, 锚框个数的四倍)。掩码变量中的元素与每个锚框的4个偏移量一一对应。 由于我们不关心对背景的检测,有关负类的偏移量不应影响目标函数。通过按元素乘法,掩码变量中的0可以在计算目标函数之前过滤掉负类的偏移量。
l a b e l s [ 1 ] labels[1] labels[1]
输出:

在这里插入图片描述

返回的第一项是为每个锚框标注的四个偏移量,其中负类锚框的偏移量标注为0。
l a b e l s [ 0 ] labels[0] labels[0]
输出:
在这里插入图片描述
输出预测边界框:

锚框数量较多时,同一个目标上可能会输出较多相似的预测边界框。为了使结果更加简洁,我们可以移除相似的预测边界框。常用的方法叫作非极大值抑制。假设有ABCDEF6个预测边界框(已经按照得分从小到大排序)

1、从最大概率矩形框F开始,分别判断A~E与F的重叠度IOU是否大于某个设定的阈值;

2、假设B、D与F的重叠度超过阈值,那么就扔掉B、D;并标记第一个矩形框F,是我们保留下来的。

3、从剩下的矩形框A、C、E中,选择概率最大的E,然后判断E与A、C的重叠度,重叠度大于一定的阈值,那么就扔掉;并标记E是我们保留下来的第二个矩形框。

4、一直重复这个过程,找到所有曾经被保留下来的矩形框。

下面来看一个具体的例子。先构造4个锚框。简单起见,我们假设预测偏移量全是0:预测边界框即锚框。最后,我们构造每个类别的预测概率。

在这里插入图片描述

在图像上打印预测边界框和它们的置信度。

在这里插入图片描述

以下代码中:

在这里插入图片描述

下面我们实现MultiBoxDetection函数来执行非极大值抑制。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后我们运行MultiBoxDetection函数并设阈值为0.5。这里为输入都增加了样本维。

我们看到,返回的结果的形状为(批量大小, 锚框个数, 6)。其中每一行的6个元素代表同一个预测边界框的输出信息。第一个元素是索引从0开始计数的预测类别(0为狗,1为猫),其中-1表示背景或在非极大值抑制中被移除。第二个元素是预测边界框的置信度。剩余的4个元素分别是预测边界框左上角的xx和yy轴坐标以及右下角的xx和yy轴坐标(值域在0到1之间)。

在这里插入图片描述
我们移除掉类别为-1的预测边界框,并可视化非极大值抑制保留的结果。

在这里插入图片描述
结果图如下:
在这里插入图片描述

3.2. 目标检测数据集

数据集的介绍:
在目标检测领域并没有类似MNIST或Fashion-MNIST那样的小数据集。

为了快速测试模型,我们合成了一个小的数据集

  • 首先,用一个开源的皮卡丘3D模型生成了1000张不同角度和大小的皮卡丘图像。
  • 后我们收集了一系列背景图像,并在每张图的随机位置放置一张随机的皮卡丘图像。

数据集的下载:

皮卡丘数据集使用MXNet提供的im2rec工具将图像转换成了二进制的RecordIO格式,但是我们后续要使用PyTorch,所以我们先用脚本将其转换成了PNG图片并用json文件存放对应的label信息。最终pikachu文件夹的结构如下

在这里插入图片描述
数据集的读取:

首先定义一个数据集类PikachuDetDataset,数据集每个样本包含label和image。

label是一个 m×5m×5 的向量,即m个边界框,每个边界框由[class, x_min, y_min, x_max, y_max]表示,这里的皮卡丘数据集中每个图像只有一个边界框,因此m=1。

image是一个所有元素都位于[0.0, 1.0]的浮点tensor,代表图片数据数据集类PikachuDetDataset的定义如下

在这里插入图片描述
在这里插入图片描述
然后我们通过创建DataLoader实例来读取目标检测数据集。我们将以随机顺序读取训练数据集,按序读取测试数据集

在这里插入图片描述
下面我们读取一个小批量并打印图像和标签的形状。图像的形状和之前实验中的一样,依然是(批量大小, 通道数, 高, 宽)。而标签的形状则是(批量大小, m, 5),其中m等于数据集中单个图像最多含有的边界框个数。

在这里插入图片描述
图示数据:
我们用以下代码画出10张图像和它们中的边界框。
在这里插入图片描述
可以看到,皮卡丘的角度、大小和位置在每张图像中都不一样。当然,这是一个简单的人工数据集。实际中的数据通常会复杂得多

在这里插入图片描述
小节总结:

  • 合成的皮卡丘数据集可用于测试目标检测模型
  • 目标检测的数据读取跟图像分类的类似。然而,在引入边界框后,标签形状和图像增广(如随机裁剪)发生了变化

4. 语义分割

4.1. 语义分割

语义分割关注如何将图像分割成属于不同语义类别的区域。值得一提的是,这些语义区域的标注和预测都是像素级的。下图展示了语义分割中图像有关狗、猫和背景的标签。可以看到,与目标检测相比,语义分割标注的像素级的边框显然更加精细

在这里插入图片描述
计算机视觉领域还有2个与语义分割相似的重要问题,即图像分割和实例分
割。我们在这里将它们与语义分割简单区分一下。

  • 图像分割将图像分割成若干组成区域。这类问题的方法通常利用图像中像素之间的相关性。它在训练时不需要有关图像像素的标签信息,在预测时也无法保证分割出的区域具有我们希望得到的语义
  • 实例分割又叫同时检测并分割。它研究如何识别图像中各个目标实例的像素级区域。与语义分割有所不同
  • 以上一张ppt中的两只狗为例,图像分割可能将狗分割成两个区域:一个
    覆盖以黑色为主的嘴巴和眼睛,而另一个覆盖以黄色为主的其余部分身体。而实例分割不仅需要区分语义,还要区分不同的目标实例。如果图像中有两只狗,实例分割需要区分像素属于这两只狗中的哪一只

语义分割数据集:
语义分割的一个重要数据集叫作Pascal VOC2012 。为了更好地了解这个数据集,我们先导入实验所需的包或模块

在这里插入图片描述
我们先下载这个数据集的压缩包。压缩包大小是2 GB左右,下载需要一定时间。下载后解压得到VOCdevkit/VOC2012文件夹,然后将其放置在data文件夹下。

进入…/…/data/VOCdevkit/VOC2012路径后,我们可以获取数据集的不同组成部分。其中ImageSets/Segmentation路径包含了指定训练和测试样本的文本文件。

JPEGImages和SegmentationClass路径下分别包含了样本的输入图像和标签。

这里的标签也是图像格式,其尺寸和它所标注的输入图像的尺寸相同。标签中颜色相同的像素属于同一个语义类别

下面定义read_voc_images函数将输入图像和标签读进内存。

在这里插入图片描述
我们画出前5张输入图像和它们的标签。在标签图像中,白色和黑色分别代表边框和背景,而其他不同的颜色则对应不同的类别

在这里插入图片描述
接下来,我们列出标签中每个RGB颜色的值及其标注的类别

在这里插入图片描述
有了上面定义的两个常量以后,我们可以很容易地查找标签中每个像素的类别索引

在这里插入图片描述
例如,第一张样本图像中飞机头部区域的类别索引为1,而背景全是0。

在这里插入图片描述

在之前的章节中,我们通过缩放图像使其符合模型的输入形状。然而在语义分割里,这样做需要将预测的像素类别重新映射回原始尺寸的输入图像。这样的映射难以做到精确,尤其在不同语义的分割区域。

为了避免这个问题,我们将图像裁剪成固定尺寸而不是缩放。具体来说,我们使用图像增广里的随机裁剪,并对输入图像和标签裁剪相同区域。

在这里插入图片描述
在这里插入图片描述
自定义语义分割数据集类:

我们通过继承PyTorch提供的Dataset类自定义了一个语义分割数据集类VOCSegDataset。

通过实现__getitem__函数,我们可以任意访问数据集中索引为idx的输入图像及其每个像素的类别索引。

由于数据集中有些图像的尺寸可能小于随机裁剪所指定的输出尺寸,这些样本需要通过自定义的filter函数所移除。

此外,我们还对输入图像的RGB三个通道的值分别做标准化自定义语义分割数据集类VOCSegDataset

在这里插入图片描述
在这里插入图片描述

读取数据集:

我们通过自定义的VOCSegDataset类来分别创建训练集和测试集的实例。

假设我们指定随机裁剪的输出图像的形状为320×480。下面我们可以查看训练集和测试集所保留的样本个数。

在这里插入图片描述
设批量大小为64,分别定义训练集和测试集的迭代器

在这里插入图片描述
打印第一个小批量的类型和形状。不同于图像分类和目标识别,这里的标签是一个三维数组。

在这里插入图片描述
输出:

在这里插入图片描述
小节总结:

  • 语义分割关注如何将图像分割成属于不同语义类别的区域
  • 语义分割的一个重要数据集叫作Pascal VOC2012
  • 由于语义分割的输入图像和标签在像素上一一对应,所以将图像随机裁剪成固定尺寸而不是缩放
  • Deeplab v3是目前广泛使用的语义分割方法

5. 风格迁移

简介:

如果你是一位摄影爱好者,也许接触过滤镜。它能改变照片的颜色样式,从而使风景照更加锐利或者令人像更加美白。但一个滤镜通常只能改变照片的某个方面。如果要照片达到理想中的样式,经常需要尝试大量不同的组合,其复杂程度不亚于模型调参。

在本节中,我们将介绍如何使用卷积神经网络自动将某图像中的样式应用在另一图像之上,即风格迁移。

这里我们需要两张输入图像,一张是内容图像,另一张是样式图像,我们将使用神经网络修改内容图像使其在样式上接近样式图像

什么是风格迁移问题:

在这里插入图片描述
方法:

  • 首先,我们初始化合成图像,例如将其初始化成内容图像。该合成图像是样式迁移过程中唯一需要更新的变量,即样式迁移所需迭代的模型参数
  • 然后,我们选择一个预训练的卷积神经网络来抽取图像的特征,其中
    的模型参数在训练中无须更新。深度卷积神经网络凭借多个层逐级抽取图像的特征。我们可以选择其中某些层的输出作为内容特征或样式特征。

简介:
以之前放的图像为例,这里选取的预训练的神经网络含有3个卷积层,其中第二层输出图像的内容特征,而第一层和第三层的输出被作为图像的样式特征。

接下来,我们通过正向传播(实线箭头方向)计算样式迁移的损失函数,并通过反向传播(虚线箭头方向)迭代模型参数,即不断更新合成图像。

在这里插入图片描述
样式迁移常用的损失函数由3部分组成:

  • 内容损失(content loss)使合成图像与内容图像在内容特征上接近
  • 样式损失(style loss)令合成图像与样式图像在样式特征上接近
  • 总变差损失(total variation loss)则有助于减少合成图像中的噪点。

最后,当模型训练结束时,我们输出样式迁移的模型参数,即得到最终的合成图像。

内容代价函数:

  • 定义内容代价函数
    在这里插入图片描述
    风格代价函数:
  • 什么是风格

相关性

神经网络各隐藏层输出激活项的含义

在这里插入图片描述
在这里插入图片描述

  • 怎样量化风格差异

相关性的计算:

在这里插入图片描述
风格矩阵(Style matrix):

(1)什么是风格矩阵
在这里插入图片描述
(2)符号规定

在这里插入图片描述
(3)计算

在这里插入图片描述
风格代价函数:

(1)隐藏层l的风格代价函数

在这里插入图片描述
(2)总体风格代价函数

在这里插入图片描述
在这里插入图片描述
下面,我们通过实验来进一步了解样式迁移的技术细节。实验需要用到一些导入的包或模块。

在这里插入图片描述
读取内容图像和样式图像:

在这里插入图片描述
从打印出的图像坐标轴可以看出,它们的尺寸并不一样

在这里插入图片描述
预处理和后处理图像:

预处理函数preprocess对先对更改输入图像的尺寸然后再将PIL图片转成卷积神经网络接受的输入格式
再在RGB三个通道分别做标准化

由于预训练模型是在均值为[0.485, 0.456, 0.406]的图片数据上预训练的,所以我们要将图片标准化保持相同的均值和标准差。

后处理函数postprocess则将输出图像中的像素值还原回标准化之前的值。由于图像每个像素的浮点数值在0到1之间,我们使用clamp函数对小于0和大于1的值分别取0和1

在这里插入图片描述
抽取特征:
在这里插入图片描述
在这里插入图片描述
在抽取特征时,我们只需要用到VGG从输入层到最靠近输出层的内容层或样式层之间的所有层。下面构建一个新的网络net,它只保留需要用到的VGG的所有层。我们将使用net来抽取特征。
在这里插入图片描述
给定输入X,如果简单调用前向计算net(X),只能获得最后一层的输出。由于我们还需要中间层的输出,因此这里我们逐层计算,并保留内容层和样式层的输出。

在这里插入图片描述
下面定义两个函数
其中get_contents函数对内容图像抽取内容特征,由于合成图像是样式迁移所需迭代的模型参数,我们只能在训练过程中通过调用extract_features函数来抽取合成图像的内容特征和样式特征。

在这里插入图片描述
get_styles函数则对样式图像抽取样式特征。因为在训练时无须改变预训练的VGG的模型参数,所以我们可以在训练开始之前就提取出内容图像的内容特征,以及样式图像的样式特征

在这里插入图片描述
定义损失函数:

样式迁移的损失函数。它由3部分损失组成

  • 内容损失
  • 样式损失
  • 总变差损失

内容损失:
与线性回归中的损失函数类似,内容损失通过平方误差函数衡量合成图像与内容图像在内容特征上的差异。平方误差函数的两个输入均为extract_features函数计算所得到的内容层的输出
在这里插入图片描述
样式损失:
样式损失也一样通过平方误差函数衡量合成图像与样式图像在样式上的差异。为了表达样式层输出的样式,我们先通过extract_features函数计算样式层的输出。

我们用一个格拉姆矩阵表达样式层输出的样式。需要注意的是,当样本的高(h)和宽(w)的值较大时,格拉姆矩阵中的元素容易出现较大的值。此外,格拉姆矩阵的高和宽皆为通道数c。为了让样式损失不受这些值的大小影响,下面定义的gram函数将格拉姆矩阵除以了矩阵中元素的个数,即chw。

在这里插入图片描述
自然地,样式损失的平方误差函数的两个格拉姆矩阵输入分别基于合成图像与样式图像的样式层输出。这里假设基于样式图像的格拉姆矩阵gram_Y已经预先计算好了。

在这里插入图片描述
总变差损失:

有时候,我们学到的合成图像里面有大量高频噪点,即有特别亮或者特别暗的颗粒像素。一种常用的降噪方法是总变差降噪(total variation denoising)。假设 表示坐标为(i,j)的像素值,降低总变差损失

在这里插入图片描述
能够尽可能使邻近的像素值相似

在这里插入图片描述
损失函数:

样式迁移的损失函数即内容损失、样式损失和总变差损失的加权和。通过调节这些权值超参数,我们可以权衡合成图像在保留内容、迁移样式以及降噪三方面的相对重要性

在这里插入图片描述
创建和初始化合成图像:

在样式迁移中,合成图像是唯一需要更新的变量。因此,我们可以定义一个简单的模型GeneratedImage,并将合成图像视为模型参数。模型的前向计算只需返回模型参数即可

在这里插入图片描述
下面,我们定义get_inits函数。该函数创建了合成图像的模型实例,并将其初始化为图像X。样式图像在各个样式层的格拉姆矩阵styles_Y_gram将在训练前预先计算好。

在这里插入图片描述
训练:

在训练模型时,我们不断抽取合成图像的内容特征和样式特征,并计算损失函数

在这里插入图片描述
下面我们开始训练模型。首先将内容图像和样式图像的高和宽分别调整为150和225像素。合成图像将由内容图像来初始化。

在这里插入图片描述
下面我们查看一下训练好的合成图像。可以看到图中的合成图像保留了内容图像的风景和物体,并同时迁移了样式图像的色彩。因为图像尺寸较小,所以细节上依然比较模糊

在这里插入图片描述
为了得到更加清晰的合成图像,下面我们在更大的300×450300×450尺寸上训练。我们将原图的高和宽放大2倍,以初始化更大尺寸的合成图像

在这里插入图片描述
输出:

在这里插入图片描述

可以看到,由于图像尺寸更大,每一次迭代需要花费更多的时间

下面我们查看一下训练好的合成图像。

在这里插入图片描述

章节小节:

  • 样式迁移常用的损失函数由3部分组成:内容损失使合成图像与内容图像在内容特征上接近,样式损失令合成图像与样式图像在样式特征上接近,而总变差损失则有助于减少合成图像中的噪点。
  • 可以通过预训练的卷积神经网络来抽取图像的特征,并通过最小化损失函数来不断更新合成图像
  • 用格拉姆矩阵表达样式层输出的样式

6. 人脸识别

6.1. 人脸验证与人脸识别

两类问题的区别:

  • 人脸验证(Face verification)
    在这里插入图片描述
    人脸识别(Face recognition)

在这里插入图片描述
for i in 数据库中的所有照片:
调用人脸验证检测输入与数据库中照片i上的是否为同一人

6.2. 人脸验证

构建神经网络:

  • 旧有思路

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
局限性:One-shot learning

  • 相似度函数

在这里插入图片描述

  • Siamese网络

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
训练神经网络:

  • 面部验证与二分类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 训练目的

通过训练神经网络,我们希望同一人的两张照片间的相似度函数值尽可能小,不同人的两张片间的相似度函数值尽可能大,下以此为目标制作训练集、定义Loss函数

  • 制作训练集

在这里插入图片描述

  • 定义代价函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
运行神经网络:

  • 利用人脸验证实现人脸识别

对于训练完毕的神经网络,输入照片,通过简单的for循环语句
遍历数据库中存储的所有照片,依次通过相似度函数进行计算,
记录遍历过程中相似程度最大的值,在遍历结束后与预先设定的
阈值进行比较,得出预测结果,完成人脸识别

7. 视觉应用展望

7.1. 生成对抗网络

生成对抗网络:

生成对抗网络(GANs, generative adversarial networks)是由Ian Goodfellow等人在2014年的Generative Adversarial Networks一文中提出。

模型通过框架中(至少)两个模块:生成模型(Generative Model)和判别模型(Discriminative Model)的互相博弈学习产生相当好的输出。

原始 GAN 理论中,并不要求 G 和 D 都是神经网络,只需要是能拟合相应生成和判别的函数即可。但实用中一般均使用深度神经网络作为 G 和 D

一个优秀的GAN应用需要有良好的训练方法,否则可能由于神经网络模型的自由性而导致输出不理想。

生成对抗网络其整体结构如下:

在这里插入图片描述
生成对抗网络(GAN)的初始原理十分容易理解,即构造两个神经网络,一个生成器,一个鉴别器,二者互相竞争训练,最后达到一种平衡(纳什平衡)

GAN 启发自博弈论中的二人零和博弈(two-player game),GAN 模型中的两位博弈方分别由生成式模型(generativemodel,G)和判别式模型(discriminative model,D)充当。

  • 生成模型 G 捕捉样本数据的分布,用服从某一分布(均匀分布,高斯
    分布等)的噪声 z 生成一个类似真实训练数据的样本,追求效果是越
    像真实样本越好
  • 判别模型 D 是一个二分类器,估计一个样本来自于训练数据(而非生
    成数据)的概率,如果样本来自于真实的训练数据,D 输出大概率,
    否则,D 输出小概率

生成对抗网络的效果如下图所示:

在这里插入图片描述
生成对抗网络的效果如下图所示:

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值