SER-FIQ (Quality estimation,CVPR 2020)
https://zhuanlan.zhihu.com/p/348813783
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