Facenet

Facenet


  • -Model(pytorch版本

《FaceNet:A Unified Embedding for Face Recognition and Clustering 》
—Facenet:一种人脸识别与聚类的统一嵌入表示
作者:Florian Schroff,Dmitry Kalenichenko
单位:Google
发表会议及时间:CVPR 2015

人脸识别与传统的深度图像识别区别还是挺大的

补充:其主要方法和损失函数依旧是业界的主流方案

补充:人脸识别模型排行榜:(其实在facenet的准确度就是99.6,哈哈,其后的很多网络,一直升到了99.8几)
在这里插入图片描述

一 论文导读


  • 人脸识别的主要任务

在这里插入图片描述
人脸识别问题可分开集和闭集(开闭集的区别就是你识别的人脸是否固定,闭集就是分类问题,开集就只用分类的思想是不行的)

人脸识别的主要难度就是对于开集如何识别


  • 人脸识别方法的演进:
    趋势:手工设计特征 —》 深度学习特征表示

在这里插入图片描述


人脸识别的挑战:

在这里插入图片描述


  • 深度学习又称表示学习

在这里插入图片描述
把人脸映射到向量
下图是最普通的欧式距离
在这里插入图片描述

在这里插入图片描述


在这里插入图片描述

2007?8-LFW:这个数据集掀起了深度学习人脸识别的序幕

2014-CASIA:第一个为现代深度学习人脸识别提供了海量样本

目前:MS-celeb-1M 和 Megaface是主要的人脸识别使用训练数据集、验证的是左侧的CALFW等


在这里插入图片描述


  • 深度学习两种主流方法:

在这里插入图片描述
facenet属于左侧


  • 损失函数

在这里插入图片描述


  • 模型排行榜

在这里插入图片描述


二 论文精读

Facene提出了两个主要问题:

在这里插入图片描述

三 代码实现

只是部分代码:

train.py

import torch
import numpy as np


def fit(train_loader, val_loader, model, loss_fn, optimizer, scheduler, n_epochs, cuda, log_interval, metrics=[],
        start_epoch=0):
    """
    Loaders, model, loss function and metrics should work together for a given task,
    i.e. The model should be able to process data output of loaders,
    loss function should process target output of loaders and outputs from the model

    Examples: Classification: batch loader, classification model, NLL loss, accuracy metric
    Siamese network: Siamese loader, siamese model, contrastive loss
    Online triplet learning: batch loader, embedding model, online triplet loss
    """
    for epoch in range(0, start_epoch):
        scheduler.step()

    for epoch in range(start_epoch, n_epochs):
        scheduler.step()

        # Train stage
        train_loss, metrics = train_epoch(train_loader, model, loss_fn, optimizer, cuda, log_interval, metrics)

        message = 'Epoch: {}/{}. Train set: Average loss: {:.4f}'.format(epoch + 1, n_epochs, train_loss)
        for metric in metrics:
            message += '\t{}: {}'.format(metric.name(), metric.value())

        val_loss, metrics = test_epoch(val_loader, model, loss_fn, cuda, metrics)
        val_loss /= len(val_loader)

        message += '\nEpoch: {}/{}. Validation set: Average loss: {:.4f}'.format(epoch + 1, n_epochs, val_loss)
            
        for metric in metrics:
            message += '\t{}: {}'.format(metric.name(), metric.value())

        print(message)


def train_epoch(train_loader, model, loss_fn, optimizer, cuda, log_interval, metrics):
    for metric in metrics:
        metric.reset()

    model.train()
    losses = []
    total_loss = 0

    for batch_idx, (data, target) in enumerate(train_loader):
        target = target if len(target) > 0 else None
        if not type(data) in (tuple, list):
            data = (data,)
        if cuda:
            data = tuple(d.cuda() for d in data)
            if target is not None:
                target = target.cuda()


        optimizer.zero_grad()
        outputs = model(*data)

        if type(outputs) not in (tuple, list):
            outputs = (outputs,)

        loss_inputs = outputs
        if target is not None:
            target = (target,)
            loss_inputs += target

        loss_outputs = loss_fn(*loss_inputs)
        loss = loss_outputs[0] if type(loss_outputs) in (tuple, list) else loss_outputs
        losses.append(loss.item())
        total_loss += loss.item()
        loss.backward()
        optimizer.step()

        for metric in metrics:
            metric(outputs, target, loss_outputs)

        if batch_idx % log_interval == 0:
            message = 'Train: [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                batch_idx * len(data[0]), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), np.mean(losses))
            for metric in metrics:
                message += '\t{}: {}'.format(metric.name(), metric.value())

            print(message)
            losses = []

    total_loss /= (batch_idx + 1)
    return total_loss, metrics


def test_epoch(val_loader, model, loss_fn, cuda, metrics):
    with torch.no_grad():
        for metric in metrics:
            metric.reset()
        model.eval()
        val_loss = 0
        for batch_idx, (data, target) in enumerate(val_loader):
            target = target if len(target) > 0 else None
            if not type(data) in (tuple, list):
                data = (data,)
            if cuda:
                data = tuple(d.cuda() for d in data)
                if target is not None:
                    target = target.cuda()

            outputs = model(*data)

            if type(outputs) not in (tuple, list):
                outputs = (outputs,)
            loss_inputs = outputs
            if target is not None:
                target = (target,)
                loss_inputs += target

            loss_outputs = loss_fn(*loss_inputs)
            loss = loss_outputs[0] if type(loss_outputs) in (tuple, list) else loss_outputs
            val_loss += loss.item()

            for metric in metrics:
                metric(outputs, target, loss_outputs)

    return val_loss, metrics

networks.py

import torch.nn as nn
import torch.nn.functional as F


class EmbeddingNet(nn.Module):
    def __init__(self):
        super(EmbeddingNet, self).__init__()
        self.convnet = nn.Sequential(nn.Conv2d(1, 32, 5), nn.PReLU(),
                                     nn.MaxPool2d(2, stride=2),
                                     nn.Conv2d(32, 64, 5), nn.PReLU(),
                                     nn.MaxPool2d(2, stride=2))

        self.fc = nn.Sequential(nn.Linear(64 * 4 * 4, 256),
                                nn.PReLU(),
                                nn.Linear(256, 256),
                                nn.PReLU(),
                                nn.Linear(256, 2)
                                )

    def forward(self, x):
        output = self.convnet(x)
        output = output.view(output.size()[0], -1)
        output = self.fc(output)
        return output

    def get_embedding(self, x):
        return self.forward(x)


class EmbeddingNetL2(EmbeddingNet):
    def __init__(self):
        super(EmbeddingNetL2, self).__init__()

    def forward(self, x):
        output = super(EmbeddingNetL2, self).forward(x)
        output /= output.pow(2).sum(1, keepdim=True).sqrt()
        return output

    def get_embedding(self, x):
        return self.forward(x)


class ClassificationNet(nn.Module):
    def __init__(self, embedding_net, n_classes):
        super(ClassificationNet, self).__init__()
        self.embedding_net = embedding_net
        self.n_classes = n_classes
        self.nonlinear = nn.PReLU()
        self.fc1 = nn.Linear(2, n_classes)

    def forward(self, x):
        output = self.embedding_net(x)
        output = self.nonlinear(output)
        scores = F.log_softmax(self.fc1(output), dim=-1)
        return scores

    def get_embedding(self, x):
        return self.nonlinear(self.embedding_net(x))


class SiameseNet(nn.Module):
    def __init__(self, embedding_net):
        super(SiameseNet, self).__init__()
        self.embedding_net = embedding_net

    def forward(self, x1, x2):
        output1 = self.embedding_net(x1)
        output2 = self.embedding_net(x2)
        return output1, output2

    def get_embedding(self, x):
        return self.embedding_net(x)


class TripletNet(nn.Module):
    def __init__(self, embedding_net):
        super(TripletNet, self).__init__()
        self.embedding_net = embedding_net

    def forward(self, x1, x2, x3):
        output1 = self.embedding_net(x1)
        output2 = self.embedding_net(x2)
        output3 = self.embedding_net(x3)
        return output1, output2, output3

    def get_embedding(self, x):
        return self.embedding_net(x)

四 问题思索

PyTorch FaceNet是基于PyTorch框架的人脸识别模型,是现代人脸识别领域中最流行和高效的模型之一。 FaceNet模型的目标是将人脸图像映射到高维特征空间,使得同一人的特征向量之间距离较近,不同人的特征向量之间距离较远。这样,通过计算特征向量之间的距离,我们可以实现人脸识别、人脸验证和人脸聚类等任务。 PyTorch是一个开源的深度学习框架,提供了丰富而强大的工具和接口,方便我们构建和训练神经网络模型。FaceNet模型的实现使用PyTorch库中的各种功能,例如卷积神经网络(CNN)构建、梯度优化算法、损失函数和数据增强等。 PyTorch FaceNet使用深度卷积神经网络来提取人脸图像的特征。首先,模型通过多层卷积和池化层来提取图像的低阶特征,然后通过全连接层将这些特征映射到一个高维特征向量。在训练过程中,FaceNet模型使用三元组损失函数来学习特征表示的紧凑性,同时最大化同一人特征向量之间的相似性,最小化不同人特征向量之间的相似性。 利用PyTorch的自动微分功能,我们可以方便地计算模型参数对损失函数的梯度,并使用优化算法(如随机梯度下降)来更新模型参数,从而不断优化模型的性能。 总之,PyTorch FaceNet将PyTorch框架和FaceNet模型结合起来,为人脸识别领域的研究和应用提供了强大的工具和方法。通过PyTorch FaceNet,我们可以方便地构建和训练高效准确的人脸识别模型。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值