[Day 22] Facial Recognition: Google FaceNet

Google在2015年时发表了一篇论文

提出了FaceNet网路架构。

而其实在前面几天实作人脸辨识时,也都或多或少有用到FaceNet:

  • Day 19: 直接使用FaceNet作为我们的CNN网路
  • Day 21: OpenFace,网路架构与FaceNet相同,是学术研究的版本

而FaceNet最主要的重点有两个:

  • 训练模型的方式是使用triplet loss (也就是Day 17提到的triplet networks)
  • 图片的输出特徵(embeddings)可以很少,只需要128个数值就可以很好辨别

使用FaceNet预训练的模型可以很好的辨识人脸,

这个我们已经在前面学习到了。

今天,我们要来谈谈Triplet Loss的做法以及实际如何用。

本文开始

找Triplet Loss,大多都会出现这张图:
img

Anchor是当前要训练的资料,

目的是要将:

  • Anchor与Positive(相似的资料)之间的输出特徵尽可能拉近
  • Anchor与Negative(不同类型的资料)之间的输出特徵尽可能拉远

Loss是损失函数,也就是模型在"学习"的过程中如何判断当前的训练结果是好是坏;

因此Triplet Loss就是要让模型"学习"如何将相似的资料输出的特徵相近,而不相似的资料输出特徵相远。

作法听起来很简单,

但实际上它的"眉角"就在

如何选择Positive与Negative资料?

如果选择的资料是"相似资料的特徵已经很近,不相似资料的特徵已经很远"

满足Triplet Loss的目标,模型不用训练,结束。 --- 这是Easy Triplet

选择"相似资料的特徵都离很远,不相似资料的特徵都很近"

可能模型训练到最後很难有不错的结果。 --- 这是Hard Triplet

凡事过犹不及都不好,

因此出现了一种作法叫做Semi-hard Triplet


到这里为止还是太抽象了,我们实际举个例子来说:

大家都吃过「豆」吧?

当我们今天想要学习区分豌豆荷兰豆的区别,请看下面的图片:
easy_triplet

如果跟你说Anchor与Positive都是豌豆、Negative是荷兰豆

你可能会很直觉的"看到"豌豆与荷兰豆就是不一样的东西。

但你会直觉"想到"是什麽不一样吗?

.

.

.

.

.

同样的例子,再来另一个比较:
hard_triplet

如果跟你说Anchor与Positive都是豌豆、Negative是荷兰豆,你的脑袋这时应该会直觉想到:

喔~豌豆的豆仁比较饱满,而荷兰豆感觉没什麽豆仁;豌豆的豆筴好像也比较厚实,荷兰豆看起来扁扁的

这时候再跟你说中间的那张图片是你在超市一定会看到的"三色豆"其中一个 -- 青豆仁 (也就是去除豆筴後的豌豆)
荷兰豆一般都会连豆荚一起直接与其他蔬菜拌炒。

有没有恍然大悟「喔!我会区分豌豆跟荷兰豆了!」?

对 --- 上面第二个例子是说明Hard Triplet如何让人"学习"去想办法区别两个不一样的物体真正的差别。

而第一个例子就是Easy Triplet,你的"眼睛"已经直接告诉你这两个是不一样的东西。

今天我们要让电脑去学习区分也是一样的道理,

将两个是一样的东西,但看起来却几乎是不一样的

以及

两个不一样的东西,但看起来很相似

让电脑去学习特徵,来区别其中的不同。

Google发表的FaceNet就是在这样的精神下去训练模型来区别人脸,

也因为Triplet资料的选择有特别处理,让这个模型直到现在都还是相当热门且准确的模型。

最後,

由於Easy Triplet容易学不到东西,

Hard Triplet困难到学不到东西,

Semi-hard Triplet是折衷作法,

如何挑选,网路上也都有数值分析作法,有兴趣一样可以搜寻看看

就这样,对我来说FaceNet的重点一次说完罗!


<<:  Day 20 - 装个 Nessus 试试

>>:  Day 23 - 绿专案管理(Green Project Management)

#1. Hidden Search Component搜寻框弹出效果(CSS)

今天的任务: 部署至GitHub Page(後续部署在vercel) 搜寻框弹出效果 Demo Li...

[Day 30] Bug修好了 & 30天感想

经过了一天的奋斗,总算是把昨天做爆的LSTM修好了, 失败的可能原因可能为 资料未经过Normali...

Day27 - this&Object Prototypes Ch3 Objects - Review

Obgect content Getter 与 Setter : 他们是 Object 内建的 p...

单一功能原则 Single Responsibility Principle

关於物件导向程序设计的五个设计原则,大家可能会依据不同的顺序来解释,不过我想「单一功能原则」一定会被...

C# 入门之函数重载

函数重载,即使用相同的函数名,但函数的参数和数据类型不同,让程序根据需要,自动选择使用那个函数。 下...