A-Softmax的keras实现-《SphereFace: Deep Hypersphere Embedding for Face Recognition》

2023-05-16

A-Softmax的keras实现

参考文档:https://www.cnblogs.com/heguanyou/p/7503025.html

注:主体完成,调试中,先行记录,待续。。。已完成
注:我写的不是很好,因为模型搭建用到了batch_size这个参数,所以编译很慢;而且资料都说该方法很难收敛,比较难训练;推荐后续的改进版:

《AM : Additive Margin Softmax for Face Verification》

《AAM : Face Recognition via Centralized Coordinate Learning》

《ArcFace: ArcFace: Additive Angular Margin Loss for Deep Face Recognition》

具体的改进原理和物理解释参见:
人脸识别的LOSS(上)
人脸识别的LOSS(下)
其中,我实现了一下keras版本的《Additive Margin Softmax for Face Verification》地址:https://blog.csdn.net/yjy728/article/details/79730716
和A-Softmax的主要区别是对输入x也进行了归一化,且用加性margin:

ψ=cosθ+m ψ = c o s θ + m
替代了乘性margin:
ψ=(1)kcosmθ2k ψ = ( − 1 ) k ∗ c o s m θ − 2 k

# -*- coding: utf-8 -*-
from keras import backend as K
from keras.engine.topology import Layer
from keras.layers import Dense, Activation,BatchNormalization
from keras.layers import activations, initializers, regularizers, constraints, Lambda
from keras.engine import InputSpec
import tensorflow as tf
import numpy as np


class ASoftmax(Dense):
    def __init__(self, units, m, batch_size,
                 kernel_initializer='glorot_uniform',
                 kernel_regularizer=None,
                 kernel_constraint=None,
                 **kwargs):
        if 'input_shape' not in kwargs and 'input_dim' in kwargs:
            kwargs['input_shape'] = (kwargs.pop('input_dim'),)
        super(Dense, self).__init__(**kwargs)
        self.units = units
        self.m = m
        self.batch_size = batch_size
        self.kernel_initializer = initializers.get(kernel_initializer)
        self.kernel_regularizer = regularizers.get(kernel_regularizer)
        self.kernel_constraint = constraints.get(kernel_constraint)
        self.input_spec = InputSpec(min_ndim=2)
        self.supports_masking = True

    def build(self, input_shape):
        assert len(input_shape) >= 2
        input_dim = input_shape[-1]

        self.kernel = self.add_weight(shape=(input_dim, self.units),
                                      initializer=self.kernel_initializer,
                                      name='kernel',
                                      regularizer=self.kernel_regularizer,
                                      constraint=self.kernel_constraint)
        self.bias = None
        self.input_spec = InputSpec(min_ndim=2, axes={-1: input_dim})
        self.built = True


    def call(self, inputs):
        inputs.set_shape([self.batch_size, inputs.shape[-1]])
        inputs_norm = K.sqrt(K.sum(K.square(inputs), axis=-1, keepdims=True))
        kernel_norm = tf.nn.l2_normalize(self.kernel, dim=(0, 1))                          # W归一化
        inner_product = K.dot(inputs, kernel_norm)
        dis_cosin = inner_product / inputs_norm

        m_cosin = multipul_cos(dis_cosin, self.m)
        sum_y = K.sum(K.exp(inputs_norm * dis_cosin), axis=-1, keepdims=True)
        k = get_k(dis_cosin, self.units, self.batch_size)
        psi = np.power(-1, k) * m_cosin - 2 * k
        e_x = K.exp(inputs_norm * dis_cosin)
        e_y = K.exp(inputs_norm * psi)
        sum_x = K.sum(e_x, axis=-1, keepdims=True)
        temp = e_y - e_x
        temp = temp + sum_x

        output = e_y / temp
        return output


def multipul_cos(x, m):
    if m == 2:
        x = 2 * K.pow(x, 2) - 1
    elif m == 3:
        x = 4 * K.pow(x, 3) - 3 * x
    elif m == 4:
        x = 8 * K.pow(x, 4) - 8 * K.pow(x, 2) + 1
    else:
        raise ValueError("To high m")
    return x


def get_k(m_cosin, out_num, batch_num):
    theta_yi = tf.acos(m_cosin)  #[0,pi]
    theta_yi = tf.reshape(theta_yi, [-1])
    pi = K.constant(3.1415926)

    def cond(p1, p2, k_temp, theta):
        return K.greater_equal(theta, p2)

    def body(p1, p2, k_temp, theta):
        k_temp += 1
        p1 = k_temp * pi / out_num
        p2 = (k_temp + 1) * pi / out_num
        return p1, p2, k_temp, theta

    k_list = []
    for i in range(batch_num * out_num):
        k_temp = K.constant(0)
        p1 = k_temp * pi / out_num
        p2 = (k_temp + 1) * pi / out_num
        _, _, k_temp, _ = tf.while_loop(cond, body, [p1, p2, k_temp, theta_yi[i]])
        k_list.append(k_temp)
    k = K.stack(k_list)
    k = tf.squeeze(K.reshape(k, [batch_num, out_num]))
    return k


def asoftmax_loss(y_true, y_pred):
    d1 = K.sum(tf.multiply(y_true, y_pred), axis=-1)
    p = -K.log(d1)
    loss = K.mean(p)
    K.print_tensor(loss)
    return p

主文件:

from keras import backend as K
from keras.layers import Dense,Input,Conv2D,MaxPooling2D,Activation
from keras.layers.core import Flatten
from keras.models import Model
from keras.utils.generic_utils import CustomObjectScope
from Modify_Softmax import ModifySoftmax
from A_Softmax import ASoftmax



with CustomObjectScope({'a_softmax': ASoftmax}):
    x_input = Input(shape=(10, 10, 3))
    y = Conv2D(10,2,activation='relu')(x_input)
    y= MaxPooling2D()(y)
    y = Flatten()(y)
    y = Dense(5)(y)
    #y= Dense(2, activation='relu')(y)
    y = ASoftmax(3, 3, activation='a_softmax')(y)

model = Model(inputs=x_input, outputs=y)
model.compile(optimizer='sgd',
          loss='categorical_crossentropy',
          metrics=['accuracy'])

model.summary()

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

A-Softmax的keras实现-《SphereFace: Deep Hypersphere Embedding for Face Recognition》 的相关文章

随机推荐

  • J2EE技术规范(八)——JMS(消息,域)

    老样子 xff0c 继续完善J2EE技术规范 xff0c 这次内容主要是写个JMS 理解面向消息的中间件 定义 xff1a 消息 xff08 1 xff09 消息是可编程实现两端通信的机制 xff08 2 xff09 一些消息技术如 xff
  • J2EE技术规范(九)——JMS (JMS客户端)

    上篇博客写了JMS的一些内容 xff0c 后来觉得那篇博客的内容不够阐述JMS的内容 xff0c 所以这篇博客就继续完善JMS 在WebLogic Server 环境中配置JMS WebLogic Server的JMS特性 WebLogic
  • ubuntu下载搜狗输入法并设置开机自启动

    官网下载搜狗输入法linux版deb包 下好后在下载目录里执行安装 xff1a sudo dpkg i sogoupinyin 3 4 0 9700 amd64 deb 因为我之前下载过搜狗输入法 xff0c 卸掉后fcitx输入法系统还在
  • Java基础之抽象类与接口

    很多常见的面试题都会出诸如抽象类和接口有什么区别 xff0c 什么情况下会使用抽象类和什么情况你会使用接口这样的问题 本文我们将仔细讨论这些话题 在讨论它们之间的不同点之前 xff0c 我们先看看抽象类 接口各自的特性 抽象类 抽象类是用来
  • debian系linux更新时,提示“由于没有公钥,无法验证下列签名”

    问题 在新安装的Ubuntu上 xff0c 我在使用sudo apt get update更新时 xff0c 出现如下错误 xff1a W GPG error http mirrors span class hljs number 163
  • 机器学习(周志华) 第八章集成学习

    关于周志华老师的 机器学习 这本书的学习笔记 记录学习过程 本博客记录Chapter8 1 个体与集成 集成学习 xff08 ensemble learning xff09 xff1a 通过构建多个学习器来完成学习的任务 可以分成同质集成
  • MWC(1) Multiwii 飞控程序初学者概要

    学习MWC飞控程序有一段时间了 xff0c 略有所得 xff0c 现整理一下学习思路 xff0c 略作记录 大三开始老师让我看飞控程序 xff0c 就给了一块飞控板 xff08 如下图 xff09 xff0c Cirus AIOP xff0
  • 我们约会吧魏荔嵩 不要迷恋姐,姐容易让你胃出血

    魏荔嵩是 我们约会吧 20101229期的女嘉宾 xff0c 来自上海 xff0c 家乡是内蒙古呼伦贝尔的 xff0c 27岁的魏荔嵩是一名广告策划 xff0c 曾是一名白衣天使 魏荔嵩的世纪佳缘昵称 xff1a 粉红小猪 太嗲了 xff0
  • MWC(2) Multiwii初学者详细准备

    1 1 软件准备 Arduino IDE 官方下载链接 xff1a https www arduino cc download handler php 或者Arduino社区资源 xff1a http www arduino cn thre
  • Linux(Ubuntu)下使用OneNote

    开始学习ROS xff0c 学习时遇到问题想要记录 xff0c 原来Office套件不支持Linux xff0c 大坑一 xff1a 搜了很久 xff0c 看到的无外乎以下几种 xff1a 作者 xff1a mst7 链接 xff1a ht
  • Ubuntu Anaconda 安装tensorflow及opencv3.2.0

    教程已更新 xff0c 请参照http blog csdn net yjy728 article details 78826447 一 安装Anaconda windows只支持python3 5 X xff0c ubuntu下直接下最新版
  • Ubuntu16.04下PX4 开发环境配置

    PX4 Ubuntu1604 开发环境配置 问题1 依赖错误及安装时404错误问题2 安装基于NuttX的硬件出错问题3 编译报错问题4 QT配置问题 PX4 Ubuntu16 04 开发环境配置 看到官网有详细介绍 xff08 官网安装说
  • [px4仿真]单独启动编译和Gazebo仿真器

    This article shows how to starting Gazebo and PX4 separately 按照官方教程并没有成功 中文教程和英文教程都有错误 xff0c 应该如下 span class hljs built
  • [px4仿真]px4的STIL仿真中添加向下的摄像头

    后面发现这样改有问题 xff0c 正确的修改方法参考这条提交记录 xff1a https github com TokyoClod sitl gazebo commit e61e6e46a665804f072474b2b1b085fb701
  • VISP库IBVS仿真

    示例程序1 tutorial ibvs 4pts cpp span class hljs comment example tutorial ibvs 4pts cpp span span class hljs preprocessor in
  • blender中UV贴图及导出dae文件

    设置单位meter 设置大小 按 N调出属性面板 设置 依次选择编辑模式 线框 面选择 xff1b 进入UV贴图模式 右击选中物体上表面 xff0c 按U 展开 xff1b 上方选择UV Editing模式 贴图 左下底部选择 图像 打开图
  • AprilTag视觉定位系统

    AprilTag是一个视觉基准库 xff0c 在AR xff0c 机器人 xff0c 相机校准领域广泛使用 通过特定的标志 xff08 与二维码相似 xff0c 但是降低了复杂度以满足实时性要求 xff09 xff0c 可以快速地检测标志
  • keras 多输入多输出网络

    keras中的多输入多输出网络 多输入多输出网络搭建的官网介绍 xff1a http keras cn readthedocs io en latest getting started functional API Demo span cl
  • lodash源码分析之compact中的遍历

    小时候 xff0c 乡愁是一枚小小的邮票 xff0c 我在这头 xff0c 母亲在那头 长大后 xff0c 乡愁是一张窄窄的船票 xff0c 我在这头 xff0c 新娘在那头 后来啊 xff0c 乡愁是一方矮矮的坟墓 xff0c 我在外头
  • A-Softmax的keras实现-《SphereFace: Deep Hypersphere Embedding for Face Recognition》

    A Softmax的keras实现 参考文档 xff1a https www cnblogs com heguanyou p 7503025 html 注 xff1a 主体完成 xff0c 调试中 xff0c 先行记录 xff0c 待续 已