首页 > 其他分享 >c4w4_人脸识别和神经风格转换

c4w4_人脸识别和神经风格转换

时间:2023-11-18 13:34:20浏览次数:31  
标签:人脸识别 函数 卷积 网络 c4w4 风格 神经 图片

特殊应用:人脸识别和神经风格转换

人脸识别

与人脸识别(Face Recognition)相关的还有活体检测(Liveness Detection)问题,在这里仅讨论前者。

人脸验证(Face Verification)人脸识别(Face Recognition)的区别:

  • 人脸验证:一般指一个1对1的问题,只需要验证输入的人脸图像是否与某个已知的身份信息对应;
  • 一个更复杂的1对多的问题,需要验证输入的人脸图像是否与多个已知身份信息的某一个匹配。

一般来说,对于人脸验证可能只需要达到99%准确率就很好了;而对于人脸识别,如果匹配一张一张图片的正确概率是0.99,直到第一百次才识别到的正确大概率就是0.99100,所以正确识别的概率就低了,因此就需要高单张图片匹配的准确率。

先学习人脸验证,当人脸验证正确率很高之后就可以应用到人脸识别。

One-shot学习

人脸识别所面临的一个挑战是要求系统之采集一次面部样本,就可以快速准确地识别出身份信息。即只用一个训练样本来获得准确的预测结果。这就被称为One-shot learning。

如果需要建立一个四人的人脸识别系统,根据我们前面学到的,可能想到可以建立一个卷积网络,最后用softmax输出四个类别,代表四个人。但是由于每个人可能只有一张照片作为训练集,训练出来的网络效果可能比较差。而且当要添加新的身份信息的时候,就需要重新训练模型,显然这不是个好的办法。

image

所以,为了更好的效果,网络需要学习的是一个相似Similarity函数,代表两张图片的差异度。如下图所示。当大于等于阈值\(\tau\),表示为同一人;当小于\(\tau\),就代表是不同的人。

image

Siamese 网络

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

image

如上图中的示例,在最后的全连接层我们不用Softmax输出,而是直接得到两个特征向量\(f(x^{(1)})\)、\(f(x^{(2)})\),称他们为\(x^{(1)}\) 、\(x^{(2)}\)的编码。并将\(x^{(1)}\) 、\(x^{(2)}\)的距离定义为两个编码之差的L2范数,即\(d((x^{(1)}),x^{(2)})=||fx^{(1)}-fx^{(2)}||_2^2\) ,这就是Siamese网络架构。

把上面的定义推广一下就得到了图片中的对\(x^{(i)}\) 、\(x^{(j)}\)的式子,用于人脸识别。

image

Triplet损失

想要通过训练神经网络的参数,达到Siamese网络获得到质量人脸编码的目标,方法之一就是定义三元组损失函数然后应用梯度下降。

为了定义Triplet Loss,需要把数据给定义成三元组的形式。即用于训练的数据是包含Anchor(靶目标)、Positive(正例)、Negative(反例)这样的三元图片组。这也是Triplet这一词的含义。

Anchor和Positive是同一人脸,Anchor与Negative是不同的人。对于三元组分别取首字母代称,即A、P、N。

image

对于这样的三张图片,应该有下面所示的

\[||f(A)-f(P)||^2 + \alpha \leq ||f(A)-f(N)||^2 \]

其中,\(\alpha\)被称为间隔(margin)他是一个超参数,用来确保当函数\(f(x)\)总是输出0或者恒定值时,不等式不成立。

上面的不等式表示训练好的神经网络输出对图片的编码要满足A和P的差异应当小于A和N的差异。如果没有间隔α,当网络输出图像的编码为0或为恒值时,满足A、P、N的差异要求,但是显然这种网络不是我们期望的,是无效的结果。因此引入了间隔超参数α

当满足上述不等式是,认为对人脸识别的预测就是准确的,损失就为0;不满不等式时,预测不准确,所以损失就应该是\(||f(A)-f(P)||^2 + \alpha - ||f(A)-f(N)||^2\)这个大于0的数字。

image

所以,Triplet损失函数的定义:

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

那么,对于大小为\(m\)的训练集,代价函数为:

\[J=\sum_{i=1}^mL(A^{(i)},P^{(i)},N^{(i)}) \]

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

对于训练样本A、P、N的选择要说明的一点是,如果随机选择很容易的导师A和P非常相似,A和N差异巨大,所以很容易满足\(d(A,P)+\alpha \leq d(A,N)\),导致训练出来的神经网络可能效果较差。

因此,应该选择$$d(A,P)+\alpha \approx d(A,N)$$ 的三元组,促使模型学习不同人脸之间的关键差异。可以的做法是,人为增加 Anchor 和 Positive 的区别,缩小 Anchor 和 Negative 的区别。

二分类结构

除了Triplet Loss 以外,二分类结构也可以应用于人脸识别问题中的参数学习。与Triplet Loss不同,二分类结构输入的训练数据是两张图片,如果是同一人y=1,不是y=0。

image

二分类结构的具体做法是,输入两张图片,将由Siamese 网络产生的两张图片的编码作为输入,传递给同一个sigmoid单元,输出预测值。

Sigmoid单元对应的表达式为

\[\hat y = \sigma(\sum_{k=1}^k w_k|f(x^{(i)}_k)-f(x^{(j)}_k)|+b) \]

其中\(w_k\)和\(b\)是通过梯度下降算法迭代训练的参数,和在Siamese 网络中训练的参数是一套参数,绑定在一起的。

上述的表达式中处理两个图片编码的公式还可以替换成其他公式。

\[\hat y = \sigma(\sum_{k=1}^k 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\)方相似度

image

无论是使用Triplet损失函数的网络,还是二分类结构,可以把Siamese 网络计算好的图片编码输出\(f(x)\)存在数据库中,这样就不必要存储原始图片了。并且每次进行人脸识别的时候,只用再通过Siamese 网络计算出要检测图片的编码拿去比较输出结果,减少了计算量。

神经风格迁移

神经风格迁移,直观上就是将一张图片的风格应用到另外一张图像的内容上,生成具有其风格图片。

监督学习需要标签(y),但风格迁移不需要标签(y),所以是无监督学习。

image

神经风格迁移的过程涉及到三张图片:Style图片提供风格,Content图片提供内容,Generated Image是生成的图片。接下来将用S、C、G分别代表三种图片。

深度卷积网络在学习什么?

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

可视化的思路:在神经网络中某一层选择一个神经元,遍历所有的训练样本,选择使得该神经元的激活函数最大限度激活的9块图像区域,使用这9块区域作为这个神经元的可视化输出。以此类推可以,可以可视化所有的神经元。

这里说的每层中的神经元是指卷积层中的每一个卷积核(filter),就拿第一层来举例,卷积核滑过图片,计算和卷积核一样大小的那块区域的卷积,然后把结果写到输出对应的格子。把这些卷积结果给到激活函数后,找这些激活函数值最大的区域是那一块。倒推会原始图片的对应区域,这就是对神经元的可视化。对于更深层的也是找到区域不断倒退到原始图片的对应区域,应该是很复杂。。

对于一层可以选择9神经元来可视化,观察这一层的神经元都学到了那些特征。

image

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

代价函数

为了构建神经风格迁移系统,需要为生成的 图片定义代价函数。通过最小化 cost function,来生成图片G。

图片G的需要兼顾内容图片的内容和风格图片的风格,因此代价函数由两部分组成,内容代价函数和风格代价函数。

那么,神经风格迁移生成图片 G 的代价函数如下:

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

其中,\(\alpha\)、\(\beta\) 是用于控制相似度权重的超参数,就是希望生成图片更偏向内容还是风格。

神经风格迁移的算法步骤如下:

  1. 随机生成图片 G 的所有像素点,得到一个白噪声图;
  2. 使用梯度下降算法使代价函数最小化,以不断修正 G 的所有像素点。

image

需要注意的是,普通cost function优化的结果是网络上的参数,而神经风格转换的代价函数去优化的是随机生成G上的每一个像素点,让G的生成和原始两张图更像。所以这里的代价函数并不会针对某个固定的神经网络。

内容代价函数

上述代价函数包含一个内容代价部分和风格代价部分。我们先来讨论内容代价函数 \(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 \]

\(J_{content}(C, G)\) 越小,\(a^{(C)[l]}\) 和 \(a^{(G)[l]}\) 越相似。

\(a^{(C)[l]}\) 和 \(a^{(G)[l]}\) 就相当于在人脸识别那块提到的对输入x的编码,并定义两个编码差的第二范数的平方,来形容其差异度,与这里定义的一模一样。

风格代价函数

如何定义一张图片的风格?当我们看到一张图片,对于风格直观的感受是,图片中大量出现的内容,比如梵高的星夜这幅画,是蓝色、黄色扭曲的漩涡这样的风格。

在卷积网络中,我们用第\(l\)层不同通道之间激活函数的相关性(Correlation)来描述风格。

不同通道之间的激活函数的相关性代表什么?简单的理解是,对于卷积网络同一层不同通道的激活函数,从对卷积层的可视化可以得知,每一个通道学到了图片的一些特征,比如线条、颜色。如果不同的两个通道之间相关性很高(相似度很高),那也就是说这两个通道学习到的内容有很多相似点(类似的地方),那其实这就是我们对图片风格的直观感受,一些图中都有的相似处,就是风格。

对于下图,红色通道学习到了一些垂直的纹理,黄色通道学到了一些橙色的内容,所以如果每个通道都学习到了橙色的垂直纹理,就说明了图片的风格是橙色带垂直纹理。因为每个通道都学到了相似的内容,所以每个通道的激活函数相关性就高。

可以想想我们上面提到了的夜空那个例子。

image

计算两个通道的相关性的具体方法如下:

对于风格图像 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\) 层的高度和宽度;\(k\)和 \(k^{'}\) 为选定的通道,其范围为 \(1\)到 \(n^{[l]}_C\);\(a^{[l](S)}_{ijk}\)为激活。

同理对于图像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} || G^{[l](S)}_{kk'} - G^{[l](G)}_{kk^{'}}||^2_F \]

即两个风格矩阵的元素对应相减后求平方和。

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

如果对求所有层的风格代价函数,效果会更好,所以有:

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

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

推广至一维和三维

前面我们学到的卷积网络都是在处理图片,也就是2D数据。时间上卷积网络也可以推广到1D和3D。

image

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

  • 输入时间序列维度:14 x 1
  • 滤波器尺寸:5 x 1,滤波器个数:16
  • 输出时间序列维度:10 x 16

image

比如CT数据就是3D数据,对人体进行若干层的切片扫描,每层是一张2D的图片,所有图片组成3D数据。此时的输入数据和fitler都是3D的(注意,这里的3D和之前因多个channel画成的3D不一样)

对于三维图片的示例,有

  • 输入 3D 图片维度:14 x 14 x 14 x 1
  • 滤波器尺寸:5 x 5 x 5 x 1,滤波器个数:16
  • 输出 3D 图片维度:10 x 10 x 10 x 16

标签:人脸识别,函数,卷积,网络,c4w4,风格,神经,图片
From: https://www.cnblogs.com/newbe3three/p/17840368.html

相关文章

  • c4w1_卷积神经网络
    卷积神经网络计算机视觉问题计算机视觉(computervision)是因深度学习而快速发展的领域之一,它存进了如自动驾驶、人脸识别等应用的发展,同时计算机视觉领域的发展还可以给其他领域提供思路。计算机视觉应用的实例:图片分类(识别是不是一只猫)、目标检测(检测途中汽车行人等)、图片风格......
  • c1w4_深层神经网络
    深层神经网络什么是深层神经网络?深层的神经网络(DeepL-layerneuralnetwork)就是包含了更多隐藏层的神经网络。从某种意义上来说,logisticregression可以称为一层的神经网络“1layerNN”。当计算神经网络的层数,通常将输出层计算在内,而输出层不算,有一个隐藏层,就是2layerNN,以......
  • 深度学习算法原理实现——自写神经网络识别mnist手写数字和训练模型
    代码来自:https://weread.qq.com/web/reader/33f32c90813ab71c6g018fffkd3d322001ad3d9446802347《python深度学习》fromtensorflow.keras.datasetsimportmnistfromtensorflow.kerasimportoptimizersimporttensorflowastfimportnumpyasnpclassNaiveDense:d......
  • Python绘制神经网络模型的结构示意图的方法
      本文介绍基于Python语言,对神经网络模型的结构进行可视化绘图的方法。  最近需要进行神经网络结构模型的可视化绘图工作。查阅多种方法后,看到很多方法都比较麻烦,例如单纯利用graphviz模块,就需要手动用DOT语言进行图片描述,比较花时间;最终,发现利用第三方的ann_visualizer模块,可......
  • 神经网络中的量化与蒸馏
    前言 本文介绍了深度学习中精简模型的技术:量化和蒸馏。本文转载自DeepHubIMBA作者:Aadityaura仅用于学术分享,若侵权请联系删除欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结、最新技术跟踪、经典论文解读、CV招聘信息。CV各大方向专栏与各个部署框架最全教程整理【......
  • python深度学习——一个简单的全连接神经网络,预测mnist手写数字
    代码来自《python深度学习》第二章:fromtensorflow.keras.datasetsimportmnistfromtensorflowimportkerasfromtensorflow.kerasimportlayers(train_images,train_labels),(test_images,test_labels)=mnist.load_data()print(train_images.shape)print(len(trai......
  • “人脸识别技术的挑战与机遇:隐私保护与性能提升“
    "人脸识别技术的挑战与机遇:隐私保护与性能提升"是一个备受关注的话题,涉及到人脸识别技术在社会、商业和政府领域的广泛应用。以下是该主题可能涉及的一些关键点:1.**性能提升与准确性:**探讨当前人脸识别技术的性能水平,以及如何通过深度学习、神经网络优化等技术提升其准确性和鲁......
  • 不平衡数据集神经网络回归SMOTE、SMOGN算法:R语言代码
      本文介绍基于R语言中的UBL包,读取.csv格式的Excel表格文件,实现SMOTE算法与SMOGN算法,对机器学习、深度学习回归中,训练数据集不平衡的情况加以解决的具体方法。  在之前的文章SMOGN算法的Python实现:不平衡数据的深度学习回归中,我们介绍了基于Python语言中的smogn包,实现SMOGN算......
  • 机器学习——深度循环神经网络
    到目前为止,我们只讨论了具有一个单向隐藏层的循环神经网络。其中,隐变量和观测值与具体的函数形式的交互方式是相当随意的。只要交互类型建模具有足够的灵活性,这就不是一个大问题。然而,对一个单层来说,这可能具有相当的挑战性。之前在线性模型中,我们通过添加更多的层来解决这个......
  • 神经网络中间层特征图可视化(输入为音频)
    importlibrosaimportnumpyasnpimportutilsimporttorchimporttorch.nn.functionalasFfrommatplotlibimportpyplotaspltfromtorchvision.models.feature_extractionimportcreate_feature_extractordevice=torch.device("cuda:0"iftorch.......