4.4)深度卷积网络:人脸识别和神经风格转换

目录

1)What is face recognition?

2)One-shot learning

3)Siamese network

4)Triplet Loss(重点)

5)Face Verification and Binary Classification

6)What is neural style transfer?

7)What are deep ConvNets learning?

8)Cost function(理解)

9)Content cost function(重点)

10)Style cost function(重点)

11)1D and 3D generalizations f models


以下笔记是吴恩达老师深度学习课程第四门课第四周的的学习笔记:Face recognition & neural style transfer。笔记参考了黄海广博士的内容,在此表示感谢。


1)What is face recognition?

首先介绍一下人脸验证(Face Verification)人脸识别(Face Recognition)的区别:

  • 人脸验证:一般是一个一对一问题,只需要验证输入的人脸图像是否与某个已知的身份信息对应;

  • 人脸识别:一个更为复杂的一对多问题,需要验证输入的人脸图像是否与多个已知身份信息中的某一个匹配。

一般来说,由于需要匹配的身份信息更多导致错误率增加,人脸识别比人脸验证更难一些。因为假设人脸验证系统的错误率是1%,那么在人脸识别中,输出分别与K个模板都进行比较,则相应的错误率就会增加,约K%。模板个数越多,错误率越大一些。


2)One-shot learning

人脸识别所面临的一个挑战是要求系统只采集某人的一个面部样本,就能快速准确地识别出这个人,即只用一个训练样本来获得准确的预测结果。这被称为One-Shot 学习

有一种方法是假设数据库中存有 N 个人的身份信息,对于每张输入图像,用 Softmax 输出 N 种标签。然而这种方法的实际效果很差,因为过小的训练集不足以训练出一个稳健的神经网络;并且如果有新的身份信息入库,需要重新训练神经网络,不够灵活。

因此,我们通过学习一个 Similarity 函数来实现 One-Shot 学习过程。Similarity 函数定义了输入的两幅图像的差异度,其公式如下:

Similarity = d(img1, img2)

可以设置一个超参数 τ\tau作为阈值,作为判断两幅图片是否为同一个人的依据。


3)Siamese network

实现 Similarity 函数的一种方式是使用Siamese 网络,它是一种对两个不同输入运行相同的卷积网络,然后对它们的结果进行比较的神经网络。

如上图示例,将图片 x^{(1)},x^{(2)}分别输入两个相同的卷积网络中,经过全连接层后不再进行 Softmax,而是得到特征向量 f(x^{(1)}),f(x^{(2)})。这时,Similarity 函数就被定义为两个特征向量之差的 L2 范数:

d(x^{(1)}, x^{(2)}) = ||f(x^{(1)}) - f(x^{(2)})||^2

值得一提的是,不同图片的CNN网络所有结构和参数都是一样的。我们的目标就是利用梯度下降算法,不断调整网络参数,使得属于同一人的图片之间d(x(1),x(2))很小,而不同人的图片之间d(x(1),x(2))很大。

相关论文:Taigman et al., 2014, DeepFace closing the gap to human level performance


4)Triplet Loss(重点)

Triplet 损失函数用于训练出合适的参数,以获得高质量的人脸图像编码。“Triplet”一词来源于训练这个神经网络需要大量包含 Anchor(靶目标)、Positive(正例)、Negative(反例)的图片组,其中 Anchor 和 Positive 需要是同一个人的人脸图像。

对于这三张图片,应该有:

||f(A) - f(P)||^2_2 + \alpha \le ||f(A) - f(N)||^2

其中,\alpha 被称为间隔(margin),用于确保不会总是输出零向量(或者一个恒定的值)。

Triplet 损失函数的定义:

L(A, P, N) = max(||f(A) - f(P)||^2 - ||f(A) - f(N)||^2+ \alpha, 0)

其中,因为 ||f(A) - f(P)||^2 - ||f(A) - f(N)||^2+ \alpha的值需要小于等于 0,因此取它和 0 的更大值。

对于大小为m 的训练集,代价函数为:

J = \sum^m_{i=1}L(A^{(i)}, P^{(i)}, N^{(i)})

通过梯度下降最小化代价函数。

在选择训练样本时,随机选择容易使 Anchor 和 Positive 极为接近,而 Anchor 和 Negative 相差较大,以致训练出来的模型容易抓不到关键的区别。因此,最好的做法是人为增加 Anchor 和 Positive 的区别,缩小 Anchor 和 Negative 的区别,促使模型去学习不同人脸之间的关键差异。

相关论文:Schroff et al., 2015, FaceNet: A unified embedding for face recognition and clustering


5)Face Verification and Binary Classification

除了 Triplet 损失函数,二分类结构也可用于学习参数以解决人脸识别问题。其做法是输入一对图片,将两个 Siamese 网络产生的特征向量输入至同一个 Sigmoid 单元,输出 1 则表示是识别为同一人,输出 0 则表示识别为不同的人。

Sigmoid 单元对应的表达式为:

\hat y = \sigma (\sum^K_{k=1}w_k|f(x^{(i)})_{k} - x^{(j)})_{k}| + b)

其中,w_k 和 b都是通过梯度下降算法迭代训练得到的参数。上述计算表达式也可以用另一种表达式代替:

\hat y = \sigma (\sum^K_{k=1}w_k \frac{(f(x^{(i)})_k - f(x^{(j)})_k)^2}{f(x^{(i)})_k + f(x^{(j)})_k} + b)

其中,\frac{(f(x^{(i)})_k - f(x^{(j)})_k)^2}{f(x^{(i)})_k + f(x^{(j)})_k}被称为\chi方相似度

无论是对于使用 Triplet 损失函数的网络,还是二分类结构,为了减少计算量,可以提前计算好编码输出 f(x)并保存。这样就不必存储原始图片,并且每次进行人脸识别时只需要计算测试图片的编码输出。


6)What is neural style transfer?

神经风格迁移(Neural style transfer)将参考风格图像的风格“迁移”到另外一张内容图像中,生成具有其特色的图像。 一般用C表示内容图片,S表示风格图片,G表示生成的图片。


7)What are deep ConvNets learning?

想要理解如何实现神经风格转换,首先要理解在输入图像数据后,一个深度卷积网络从中都学到了些什么。我们借助可视化来做到这一点。 典型的CNN网络如下所示:

我们通过遍历所有的训练样本,找出使该层激活函数输出最大的 9 块图像区域。可以看出,浅层的隐藏层通常检测出的是原始图像的边缘、颜色、阴影等简单信息。随着层数的增加,隐藏单元能捕捉的区域更大,学习到的特征也由从边缘到纹理再到具体物体,变得更加复杂。

相关论文:Zeiler and Fergus., 2013, Visualizing and understanding convolutional networks


8)Cost function(理解)

神经风格迁移生成图片G的cost function由两部分组成:C与G的相似程度和S与G的相似程度。

J(G) = \alpha \cdot J_{content}(C, G) + \beta \cdot J_{style}(S, G)

其中,\alpha,\beta 是用于控制相似度比重的超参数。

神经风格迁移的基本算法流程是:

首先令G为随机像素点,然后使用梯度下降算法,不断修正G的所有像素点,使得J(G)不断减小,从而使G逐渐有C的内容和G的风格,如下图所示。

相关论文:Gatys al., 2015. A neural algorithm of artistic style


9)Content cost function(重点)

上述代价函数包含一个内容代价部分和风格代价部分。我们先来讨论内容代价函数 J_{content}(C, G),它表示内容图片 C 和生成图片 G 之间的相似度。

J_{content}(C, G) 的计算过程如下:

  • 使用一个预训练好的 CNN(例如 VGG);

  • 选择一个隐藏层 l来计算内容代价。l太小则内容图片和生成图片像素级别相似,l太大则可能只有具体物体级别的相似。因此,l一般选一个中间层;

  • a^{(C)[l]}、a^{(G)[l]}为 C 和 G 在 l层的激活,则有:J_{content}(C, G) = \frac{1}{2}||(a^{(C)[l]} - a^{(G)[l]})||^2

a^{(C)[l]}a^{(G)[l]}越相似,则 J_{content}(C, G) 越小,方法就是使用梯度下降算法,不断迭代修正G的像素值。


10)Style cost function(重点)

什么是图片的风格?利用CNN网络模型,图片的风格可以定义成第l层隐藏层不同通道间激活函数的乘积(相关性)

例如我们选取第l层隐藏层,其各通道使用不同颜色标注,如下图所示。因为每个通道提取图片的特征不同,比如1通道(红色)提取的是图片的垂直纹理特征,2通道(黄色)提取的是图片的橙色背景特征。那么计算这两个通道的相关性大小,相关性越大,表示原始图片及既包含了垂直纹理也包含了该橙色背景;相关性越小,表示原始图片并没有同时包含这两个特征。也就是说,计算不同通道的相关性,反映了原始图片特征间的相互关系,从某种程度上刻画了图片的“风格”。

对于风格图像 S,选定网络中的第l层,则相关系数以一个 gram 矩阵的形式表示:

G^{[l](S)}_{kk'} = \sum^{n^{[l]}_H}_{i=1} \sum^{n^{[l]}_W}_{j=1} a^{[l](S)}_{ijk} a^{[l](S)}_{ijk'}

其中,i和 j 为第 l层的高度和宽度;kk'为选定的通道,其范围为 1到 n_C^{[l]}

同理,对于生成图像 G,有:

G^{[l](G)}_{kk'} = \sum^{n^{[l]}_H}_{i=1} \sum^{n^{[l]}_W}_{j=1} a^{[l](G)}_{ijk} a^{[l](G)}_{ijk'}

因此,第 l 层的风格代价函数为:

J^{[l]}_{style}(S, G) = \frac{1}{(2n^{[l]}_Hn^{[l]}_Wn^{[l]}_C)^2} \sum_k \sum_{k'}(G^{[l](S)}_{kk'} - G^{[l](G)}_{kk'})^2

如果对各层都使用风格代价函数,效果会更好。因此有:

J_{style}(S, G) = \sum_l \lambda^{[l]} J^{[l]}_{style}(S, G)

其中,\lambda是用于设置不同层所占权重的超参数。


11)1D and 3D generalizations f models

之前我们处理的都是二维图片,实际上卷积也可以延伸到一维和三维数据。我们举两个示例来说明。

EKG 数据(心电图)是由时间序列对应的每个瞬间的电压组成,是一维数据。一般来说我们会用 RNN(循环神经网络)来处理,不过如果用卷积处理,则有:

  • 输入时间序列维度:14 x 1

  • 滤波器尺寸:5 x 1,滤波器个数:16

  • 输出时间序列维度:10 x 16

而对于三维图片的示例,有

  • 输入 3D 图片维度:14 x 14 x 14 x 1

  • 滤波器尺寸:5 x 5 x 5 x 1,滤波器个数:16

  • 输出 3D 图片维度:10 x 10 x 10 x 16

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439735.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一步步编写操作系统 35 内存为何要分页

一直以来我们都直接在内存分段机制下工作,目前未出问题看似良好,的确目前咱们的应用过于简单了,就一个loader在跑,能出什么问题呢。可是想像一下,当我们物理内存不足时会怎么办呢?比如系统里的应用程序过多…

《python深度学习》代码中文注释

《python深度学习》由Keras之父、现任Google人工智能研究员的弗朗索瓦•肖莱(François Chollet)执笔,详尽介绍了用Python和Keras进行深度学习的探索实践,包括计算机视觉、自然语言处理、生成式模型等应用。书中包含30多个代码示…

【BZOJ - 4754】独特的树叶(树哈希)

题干: JYY有两棵树A和B:树A有N个点,编号为1到N;树B有N1个点,编号为1到N1。JYY知道树B恰好是由树A加上一个叶 节点,然后将节点的编号打乱后得到的。他想知道,这个多余的叶子到底是树B中的哪一个…

一步步编写操作系统 36 一级页表与虚拟地址1

为了给大家说清楚分页机制,我们先在宏观上说下cpu地址变换过程,先让大家有个直观的印象,如果有不明白的地方也不要着急,适时地不求甚解,有助于从全局上将知识融会贯通(这句话是我即兴说的,说得多…

动手学无人驾驶(4):基于激光雷达点云数据3D目标检测

上一篇文章《动手学无人驾驶(3):基于激光雷达3D多目标追踪》介绍了3D多目标追踪,多目标追踪里使用的传感器数据为激光雷达Lidar检测到的数据,本文就介绍如何基于激光雷达点云数据进行3D目标检测。 论文地址&#xff1a…

一步步编写操作系统 37 一级页表与虚拟地址2

接上节,分页机制是建立在分段机制之上,与其脱离不了干系,即使在分页机制下的进程也要先经过逻辑上的分段才行,每加载一个进程,操作系统按照进程中各段的起始范围,在进程自己的4GB虚拟地址空间中寻找可有空间…

PointNet:3D点集分类与分割深度学习模型

之前的一篇博客《动手学无人驾驶(4):基于激光雷达点云数据3D目标检测》里介绍到了如何基于PointRCNN模型来进行3D目标检测,作者使用的主干网是PointNet,而PointNet又是基于PointNet来实现的。今天写的这篇博客就是对Po…

计算机视觉那些事儿(1):基本任务

本文主要介绍深度学习在计算机视觉领域(Computer vision)基本任务中的应用,包括分类、检测、分割(语义与实体)。 目录 引言 分类(Classification) 目标检测(Object Detection) T…

一步步编写操作系统 38 一级页表与虚拟地址3

接上,页是地址空间的计量单位,并不是专属物理地址或线性地址,只要是4KB的地址空间都可以称为一页,所以线性地址的一页也要对应物理地址的一页。一页大小为4KB,这样一来,4GB地址空间被划分成4GB/4KB1M个页&a…

《Python编程:从入门到实践》速查表

本文是Python畅销书《Python:从入门到实践》速查表。 随书配套视频观看地址:https://www.bilibili.com/video/av35698354 目录 1.Overview 2.Lists 3.Dictionaries 4.If and While Loops 5.Functions 6.Classes 7.Files and Exceptions 8.Testin…

一步步编写操作系统 39 二级页表1

前面讲述了页表的原理,并以一级页表做为原型讲述了地址转换过程。既然有了一级页表,为什么还要搞个二级页表呢?理由如下: 一级页表中最多可容纳1M(1048576)个页表项,每个页表项是4字节&#xf…

PointNet++详解与代码

在之前的一篇文章《PointNet:3D点集分类与分割深度学习模型》中分析了PointNet网络是如何进行3D点云数据分类与分割的。但是PointNet存在的一个缺点是无法获得局部特征,这使得它很难对复杂场景进行分析。在PointNet中,作者通过两个主要的方法…

一步步编写操作系统 40 内存分页下用户程序与操作系统的关系

分页的第一步要准备好一个页表,我们的页表是什么样子呢?现在我们要设计一个页表啦。 设计页表其实就是设计内存布局,不过在规划内存布局之前,我们需要了解用户进程与操作系统之间的关系。 前面讲保护模式时,我们知道…

一步步编写操作系统 41 快表tlb 简介

分页机制虽然很灵活,但您也看到了,为了实现虚拟地址到物理地址的映射,过程还是有些麻烦的。先要从CR3寄存器中获取页目录表物理地址,然后用虚拟地址的高10位乘以4的积做为在页目录表中的偏移量去寻址目录项pde,从pde中…

50个最有用的Matplotlib数据分析与可视化图

本文介绍了数据分析与可视化中最有用的50个数据分析图,共分为7大类:Correlation、Deviation、RankIng、Distribution、Composition、Change、Groups 原文链接:https://www.machinelearningplus.com/plots/top-50-matplotlib-visualizations-t…

视觉SLAM十四讲(1):预备知识

最近在学习高翔博士的《视觉SLAM十四讲》(第二版),算是初学本书,配套资源还算蛮丰富的,有代码(第一版和第二版都有),B站上也有高翔博士对第一版录制的讲解视频,真的是很贴…

一步步编写操作系统 43 汇编语言和c语言的理解

也许有的同学喜欢用汇编语言来实现操作系统,觉得用汇编来写程序似乎更简单直接,可控性比较强,有种“一切尽在掌握”的赶脚。而用c语言实现操作系统这件事,虽然轻松很多,但似乎隐约感觉到有些慌张。因为虽然c语言相对来…

视觉SLAM十四讲(2):初识SLAM

这一讲主要介绍视觉SLAM的结构,并完成第一个SLAM程序:HelloSLAM。 目录 2.1 小萝卜的例子 单目相机 双目相机 深度相机 2.2 经典视觉SLAM框架 2.3 SLAM问题的数学表述 2.4 编程实践 Hello SLAM 使用cmake 使用库 【高翔】视觉SLAM十四讲2.1 小…

一步步编写操作系统 44 用c语言编写内核1

先来个简单的,欢迎我们神秘嘉宾——main.c。这是我们第一个c语言代码。 1 int main(void) { 2 while(1); 3 return 0; 4 }它没法再简单啦,简单的程序似乎能帮助咱们更容易的理解所学的知识,哈哈,我说的是似乎,其实&…

从零实现一个3D目标检测算法(1):3D目标检测概述

本文是根据github上的开源项目:https://github.com/open-mmlab/OpenPCDet整理而来,在此表示感谢,强烈推荐大家去关注。使用的预训练模型也为此项目中提供的模型,不过此项目已更新为v0.2版,与本文中代码略有不同。 本文…