CosineFace实现

介绍

        CosFace: Large Margin Cosine Loss for Deep Face Recognition 是腾讯出的一篇很有名的人脸识别算法,在loss上的创新,用分类的方法实现高精度人脸识别。在github上搜索会有很多实现,有一些做的也很不错。对我来说,我觉得都不太合适,一是我要caffe版本,二是大家实现的方式都不太一样,用起来感觉不太放心,三是,我融入了一些和其他实现不一样的想法。

Normalize layer

        类似cosine face的方法,都以normalize feature 作为基础条件进行设计,normalize前向公式是很简单的,主要是反向求导比较复杂,数学公式可以到这里看:https://blog.csdn.net/Iriving_shu/article/details/78300192,其中可以考虑把y置换成x,就可以对应这个实现:https://github.com/weiliu89/caffe/tree/ssd,其他的实现,如caffe-windows都写的很复杂,要搞清楚对不对还是要花些时间的。当然用这个实现还是要去修改的,主要是把scale的学习给关掉,让它为常数1。

LMCL

        数学公式请看论文,这里只讲解代码,地址见:https://github.com/huneng/cosine_loss


template <typename Dtype>
void LMCLLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
        const vector<Blob<Dtype>*>& top) {
    Dtype scale;
    // norm weight
    if(this->phase_ == TRAIN){
        Dtype *weight = this->blobs_[0]->mutable_cpu_data();

        scale = Dtype(0.0f);
        for(int i = 0; i < N_; i ++){
            Dtype dot;
            dot = caffe_cpu_dot(K_, weight, weight);
            dot = sqrt(dot + 1e-10);
            caffe_scal(K_, Dtype(1.0) / dot, weight);
            weight += K_;

            scale += dot;
        }

        scale /= N_;

        caffe_scal(N_ * K_, scale, this->blobs_[0]->mutable_cpu_data());
    }

    // y = W * x
    caffe_cpu_gemm(CblasNoTrans, CblasTrans, M_, N_, K_,
            Dtype(1.0), bottom[0]->cpu_data(), this->blobs_[0]->cpu_data(),
            Dtype(0.0), top[0]->mutable_cpu_data());

    //*
    // margin
    if(this->phase_ == TRAIN && margin_ > Dtype(1e-5f)){
        Dtype *y = top[0]->mutable_cpu_data();
        const Dtype *ptrLabel = bottom[1]->cpu_data();

        for(int i = 0; i < M_; i ++){
            int label = int(ptrLabel[i]);
            CHECK(label < N_);
            y[label] = ((y[label] / scale) - margin_) * scale;
            y += N_;
        }
    }
    // */
}



template <typename Dtype>
void LMCLLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
        const vector<bool>& propagate_down,
        const vector<Blob<Dtype>*>& bottom) {
    if (this->param_propagate_down_[0]) {
        const Dtype* dy = top[0]->cpu_diff();
        const Dtype* x = bottom[0]->cpu_data();
        Dtype *dw = this->blobs_[0]->mutable_cpu_diff();

        caffe_cpu_gemm<Dtype>(CblasTrans, CblasNoTrans,
                N_, K_, M_,
                (Dtype)1., dy, x, (Dtype)0., dw);
    }

    if (propagate_down[0]) {
        const Dtype* dy = top[0]->cpu_diff();
        const Dtype* w = this->blobs_[0]->cpu_data();
        Dtype *dx = bottom[0]->mutable_cpu_diff();

        caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans,
                M_, K_, N_,
                (Dtype)1., dy, w, (Dtype)0., dx);
    }
}

实现需注意几个细节

1 理论上权重是要单位化,但是实际使用的时候并不需要这一层,所以仅设计训练的时候单位化权重;

2很多实现都说收敛很慢,我发现是因为权重单位化了以后,梯度的量纲(取值范围)发生了阶跃,因此统计了每个权重的模,求平均,作为一个缩放系数乘以权重矩阵,根据数学原理,并不影响后续的loss,并且能够快速收敛;

3关于margin,也就是算法的核心,需要在训练的时候根据输入的label进行叠加,因此要有条件判断;

4根据算法原理backward过程和inner product同方法。

结果

       我用vggface作为训练集,采用了一个普通pc机5ms的分类网络,在测试集上最佳阈值下,精度和召回率在95%以上,20ms网络99%以上。

       对于识别这块,我并不是专家,做这个技术的目的是为了其他方向,目前有效的解决了我的问题。因为我觉得我的实现比较简单,效果也挺好,特此记录一下。

 

本课程适合具有一定深度学习基础,希望发展为深度学习之计算机视觉方向的算法工程师和研发人员的同学们。基于深度学习的计算机视觉是目前人工智能最活跃的领域,应用非常广泛,如人脸识别和无人驾驶中的机器视觉等。该领域的发展日新月异,网络模型和算法层出不穷。如何快速入门并达到可以从事研发的高度对新手和中级水平的学生而言面临不少的挑战。精心准备的本课程希望帮助大家尽快掌握基于深度学习的计算机视觉的基本原理、核心算法和当前的领先技术,从而有望成为深度学习之计算机视觉方向的算法工程师和研发人员。本课程系统全面地讲述基于深度学习的计算机视觉技术的原理并进行项目实践。课程涵盖计算机视觉的七大任务,包括图像分类、目标检测、图像分割(语义分割、实例分割、全景分割)、人脸识别、图像描述、图像检索、图像生成(利用生成对抗网络)。本课程注重原理和实践相结合,逐篇深入解读经典和前沿论文70余篇,图文并茂破译算法难点, 使用思维导图梳理技术要点。项目实践使用Keras框架(后端为Tensorflow),学员可快速上手。通过本课程的学习,学员可把握基于深度学习的计算机视觉的技术发展脉络,掌握相关技术原理和算法,有助于开展该领域的研究与开发实战工作。另外,深度学习之计算机视觉方向的知识结构及学习建议请参见本人CSDN博客。本课程提供课程资料的课件PPT(pdf格式)和项目实践代码,方便学员学习和复习。本课程分为上下两部分,其中上部包含课程的前五章(课程介绍、深度学习基础、图像分类、目标检测、图像分割),下部包含课程的后四章(人脸识别、图像描述、图像检索、图像生成)。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值