人脸质量评估SER-FIQ (Quality estimation,CVPR 2020)代码解读

SER-FIQ (Quality estimation,CVPR 2020)
https://zhuanlan.zhihu.com/p/348813783

github地址
在这里插入图片描述

def get_embedding_quality(img_input, 
                        insightface_model : InsightFace, 
                        ser_fiq : SERFIQ, 
                        T:int =100, 
                        use_preprocessing: bool =True,
                        disable_tqdm: bool = False):
    """
    Calculates the SER-FIQ Quality Score for a given img using
    given insightface model and ser-fiq model.
    
    Parameters
    ----------
    img_input : numpy array shape (x,y,3)
        The image to be processed.
    insightface_model : InsightFace
        Instance of InsightFace class
    ser_fiq : SERFIQ
        Instance of SERFIQ class
    T: int, default is 100
        The amount of forward passes the SER-FIQ model should do
    use_preprocessing: bool, default is True
        True: Preprocessing of insightface model is applied (recommended)
        False: No preprocessing is used, needs an already aligned image
    disable_tqdm: bool, default is False
        If True, no tqdm progress bar is displayed

    Returns
    -------
    Arcface/Insightface embedding: numpy array, shape (512,)
    Robustness score : float


    """
    # Apply preprocessing if image is not already aligned
    # if use_preprocessing:
    #     img_input = insightface_model.get_input(img_input)

    print("直接输入对齐后的人脸")
    nimg= cv2.imread("./data/error.jpg")  #2.jpg 0.8820820700458204   4.jpg  0.8802309518003452  ,3.jpg 0.8854882678170457
    nimg = cv2.resize(nimg,(112,112))
    nimg = cv2.cvtColor(nimg, cv2.COLOR_BGR2RGB)
    img_input = np.transpose(nimg, (2, 0, 1))

    if img_input is None:
        # No face etc. could be found, no score could be calculated
        return -1.0, -1.0
     
    # Array + prediction with insightface
    dropout_emb = np.empty((1, 25088), dtype=float)
    
    embedding, dropout = insightface_model.get_feature(img_input)

    print(embedding.shape, dropout.shape)  # embedding.shape, dropout.shape  (512,) (1, 512, 7, 7)

    dropout_emb[0] = dropout.flatten()
    del dropout

    # Apply T forward passes using keras
    # 输出embedding 是insightface 模型输出的特征, 这里ser_fiq 构建了dropout 全连接 bn l2 norm 四个层,输入 insightface 模型 的 dropout 输出
    # 同样的输入,经过ser_fiq 100次( 每次由于dropout所以输出不同)  得到100个 512 维度的特征
    X = np.empty((T, 512), dtype=float)  # 运行100次  得到100次的结果,也就是100个 512 模型特征,
    for forward_pass in tqdm(range(T),
                             desc="Forward pass",
                             unit="pass",
                             disable=disable_tqdm):
        
        X[forward_pass] = ser_fiq.predict(dropout_emb)
           
    norm = normalize(X, axis=1)
    print("100次的结果normalize",norm.shape)
    
    # Only get the upper triangle of the distance matrix
    eucl_dist = euclidean_distances(norm, norm)[np.triu_indices(T, k=1)]  # 100 *100的距离矩阵,取得右上三角 矩阵位置的 距离值
    print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> out")
    print(eucl_dist)
    print(eucl_dist.shape)#4950
    print(euclidean_distances(norm, norm).shape)

   
    # Calculate score as given in the paper
    return embedding, 2*(1/(1+np.exp(np.mean(eucl_dist)))) 

eucl_dist = [0.38127607 0.38299665 0.38819512 … 0.35166767 0.35103225 0.35759382]
(4950,)

论文中的公式,距离大,那么得分小, 分是在0-1 之间,
测试 :存在部分误差, 一个不是人脸的误检图片 分数是0.82,正常的清晰人脸0.88,差距不够明显

注意:
1、代码 ser_fiq. 网络是 “ dropout + 全连接 + bn +l2 norm” , 其中输入是insightface 模型 输出特征的前一个层 dropout的特征 (该模型的dropout 参数p=0)
实际上应该是 ,模型由dropout(参数不是0) 训练, 运行100次(dropout前面的参数固定,运行一次) 通过drop 得到100个随机出来的 512 enbedding进行上述代码的计算,而不需要 ser_fiq

2、pytorch 分离开,drop out 输出和 fc 输出的方法
PyTorch | 教你用小妙招提取神经网络某一层特征

在这里插入图片描述
在这里插入图片描述

    # load model and data
    model = P3D199()
    model = model.cuda()
    model.eval()
    data=torch.autograd.Variable(torch.rand(16,3,16,160,160)).cuda() 
    # verify
    out=model(data)
    feature=model.feature  # 这里得到想要的层的特征
    out2=model.fc(feature)  # 这里分离开, 前面的输出作为下一层的输入, 执行多个 model.fc(feature),就得到了不同drop 输出
    print(out==out2)   

3、drop 怎么在 pytorch 中 测试的时候使用

在eval模式下,由于dropout未生效,利用apply函数,将Dropout单独设为train模式,dropout就生效了。
我们知道,dropout一般都在训练的时候使用,那么测试的时候如何也开启dropout呢?
在pytorch中,网络有train和eval两种模式,在train模式下,dropout和batch normalization会生效,而val模式下,dropout不生效,bn固定参数。

想要在测试的时候使用dropout,可以把dropout单独设为train模式,这里可以使用apply函数:

def apply_dropout(m):
    if type(m) == nn.Dropout:
        m.train()

net.eval()
net.apply(apply_dropout)
y = net(x)
print('apply eval result:', y)
————————————————
版权声明:本文为CSDN博主「qian99」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qian99/article/details/89052262
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值