mirror of
https://github.com/deepinsight/insightface.git
synced 2026-05-18 06:38:19 +00:00
fix c2c
This commit is contained in:
115
src/data.py
115
src/data.py
@@ -7,6 +7,7 @@ import random
|
||||
import logging
|
||||
import sys
|
||||
import numbers
|
||||
import math
|
||||
import sklearn
|
||||
import datetime
|
||||
import numpy as np
|
||||
@@ -72,6 +73,19 @@ class FaceImageIter(io.DataIter):
|
||||
self.imgrec = recordio.MXIndexedRecordIO(path_imgidx, path_imgrec, 'r') # pylint: disable=redefined-variable-type
|
||||
s = self.imgrec.read_idx(0)
|
||||
header, _ = recordio.unpack(s)
|
||||
self.idx2cos = {}
|
||||
self.idx2meancos = {}
|
||||
self.c2c_auto = False
|
||||
if output_c2c or c2c_threshold>0.0:
|
||||
path_c2c = os.path.join(os.path.dirname(path_imgrec), 'c2c')
|
||||
print(path_c2c)
|
||||
if os.path.exists(path_c2c):
|
||||
for line in open(path_c2c, 'r'):
|
||||
vec = line.strip().split(',')
|
||||
self.idx2cos[int(vec[0])] = float(vec[1])
|
||||
else:
|
||||
self.c2c_auto = True
|
||||
self.c2c_step = 10000
|
||||
if header.flag>0:
|
||||
print('header0 label', header.label)
|
||||
self.header0 = (int(header.label[0]), int(header.label[1]))
|
||||
@@ -82,11 +96,22 @@ class FaceImageIter(io.DataIter):
|
||||
for identity in self.seq_identity:
|
||||
s = self.imgrec.read_idx(identity)
|
||||
header, _ = recordio.unpack(s)
|
||||
a,b = int(header.label[0]), int(header.label[1])
|
||||
#print('flag', header.flag)
|
||||
#print(header.label)
|
||||
#assert(header.flag==2)
|
||||
self.id2range[identity] = (int(header.label[0]), int(header.label[1]))
|
||||
self.id2range[identity] = (a,b)
|
||||
if len(self.idx2cos)>0:
|
||||
m = 0.0
|
||||
for ii in xrange(a,b):
|
||||
m+=self.idx2cos[ii]
|
||||
m/=(b-a)
|
||||
for ii in xrange(a,b):
|
||||
self.idx2meancos[ii] = m
|
||||
#self.idx2meancos[identity] = m
|
||||
|
||||
print('id2range', len(self.id2range))
|
||||
print(len(self.idx2cos), len(self.idx2meancos))
|
||||
else:
|
||||
self.imgidx = list(self.imgrec.keys)
|
||||
if shuffle:
|
||||
@@ -159,6 +184,7 @@ class FaceImageIter(io.DataIter):
|
||||
self.triplet_oseq_reset()
|
||||
self.seq_min_size = self.batch_size*2
|
||||
self.cur = 0
|
||||
self.nbatch = 0
|
||||
self.is_init = False
|
||||
self.times = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
#self.reset()
|
||||
@@ -538,10 +564,63 @@ class FaceImageIter(io.DataIter):
|
||||
# for i in xrange(self.images_per_identity):
|
||||
# _idx = _list[i%len(_list)]
|
||||
# self.seq.append(_idx)
|
||||
def reset_c2c(self):
|
||||
self.select_triplets()
|
||||
for identity,v in self.id2range.iteritems():
|
||||
_list = range(*v)
|
||||
|
||||
for idx in _list:
|
||||
s = imgrec.read_idx(idx)
|
||||
ocontents.append(s)
|
||||
embeddings = None
|
||||
#print(len(ocontents))
|
||||
ba = 0
|
||||
while True:
|
||||
bb = min(ba+args.batch_size, len(ocontents))
|
||||
if ba>=bb:
|
||||
break
|
||||
_batch_size = bb-ba
|
||||
_batch_size2 = max(_batch_size, args.ctx_num)
|
||||
data = nd.zeros( (_batch_size2,3, image_size[0], image_size[1]) )
|
||||
label = nd.zeros( (_batch_size2,) )
|
||||
count = bb-ba
|
||||
ii=0
|
||||
for i in xrange(ba, bb):
|
||||
header, img = mx.recordio.unpack(ocontents[i])
|
||||
img = mx.image.imdecode(img)
|
||||
img = nd.transpose(img, axes=(2, 0, 1))
|
||||
data[ii][:] = img
|
||||
label[ii][:] = header.label
|
||||
ii+=1
|
||||
while ii<_batch_size2:
|
||||
data[ii][:] = data[0][:]
|
||||
label[ii][:] = label[0][:]
|
||||
ii+=1
|
||||
db = mx.io.DataBatch(data=(data,), label=(label,))
|
||||
self.mx_model.forward(db, is_train=False)
|
||||
net_out = self.mx_model.get_outputs()
|
||||
net_out = net_out[0].asnumpy()
|
||||
model.forward(db, is_train=False)
|
||||
net_out = model.get_outputs()
|
||||
net_out = net_out[0].asnumpy()
|
||||
if embeddings is None:
|
||||
embeddings = np.zeros( (len(ocontents), net_out.shape[1]))
|
||||
embeddings[ba:bb,:] = net_out[0:_batch_size,:]
|
||||
ba = bb
|
||||
embeddings = sklearn.preprocessing.normalize(embeddings)
|
||||
embedding = np.mean(embeddings, axis=0, keepdims=True)
|
||||
embedding = sklearn.preprocessing.normalize(embedding)
|
||||
sims = np.dot(embeddings, embedding).flatten()
|
||||
assert len(sims)==len(_list)
|
||||
for i in xrange(len(_list)):
|
||||
_idx = _list[i]
|
||||
self.idx2cos[_idx] = sims[i]
|
||||
|
||||
def reset(self):
|
||||
"""Resets the iterator to the beginning of the data."""
|
||||
print('call reset()')
|
||||
if self.c2c_auto:
|
||||
self.reset_c2c()
|
||||
self.cur = 0
|
||||
if self.images_per_identity>0:
|
||||
if self.triplet_mode:
|
||||
@@ -592,12 +671,14 @@ class FaceImageIter(io.DataIter):
|
||||
s = self.imgrec.read_idx(idx)
|
||||
header, img = recordio.unpack(s)
|
||||
label = header.label
|
||||
if not isinstance(header.label, numbers.Number):
|
||||
label = header.label[0]
|
||||
c = header.label[1]
|
||||
if c<self.c2c_threshold:
|
||||
if self.c2c_threshold>0.0:
|
||||
cos = self.idx2cos[idx]
|
||||
if cos<self.c2c_threshold:
|
||||
continue
|
||||
return header.label, img, None, None
|
||||
if self.output_c2c:
|
||||
meancos = self.idx2meancos[idx]
|
||||
label = [label, meancos]
|
||||
return label, img, None, None
|
||||
else:
|
||||
label, fname, bbox, landmark = self.imglist[idx]
|
||||
return label, self.read_image(fname), bbox, landmark
|
||||
@@ -655,6 +736,7 @@ class FaceImageIter(io.DataIter):
|
||||
self.is_init = True
|
||||
"""Returns the next batch of data."""
|
||||
#print('in next', self.cur, self.labelcur)
|
||||
self.nbatch+=1
|
||||
batch_size = self.batch_size
|
||||
c, h, w = self.data_shape
|
||||
batch_data = nd.empty((batch_size, c, h, w))
|
||||
@@ -706,10 +788,25 @@ class FaceImageIter(io.DataIter):
|
||||
for ll in xrange(batch_label.shape[1]):
|
||||
v = label[ll]
|
||||
if ll>0:
|
||||
v = min(0.5, max(0.25,math.log(v+1)*4-1.85))
|
||||
v = math.cos(v)
|
||||
c2c = v
|
||||
#m = min(0.55, max(0.3,math.log(c2c+1)*4-1.85))
|
||||
#v = math.cos(m)
|
||||
#v = v*v
|
||||
#_param = [0.5, 0.3, 0.85, 0.7]
|
||||
_param = [0.5, 0.25, 0.85, 0.65]
|
||||
_a = (_param[1]-_param[0])/(_param[3]-_param[2])
|
||||
m = _param[1]+_a*(c2c-_param[3])
|
||||
m = min(_param[0], max(_param[1],m))
|
||||
#m = 0.5
|
||||
#if c2c<0.77:
|
||||
# m = 0.3
|
||||
#elif c2c<0.82:
|
||||
# m = 0.4
|
||||
#elif c2c>0.88:
|
||||
# m = 0.55
|
||||
v = math.cos(m)
|
||||
v = v*v
|
||||
print('c2c', i,v)
|
||||
#print('c2c', i,c2c,m,v)
|
||||
|
||||
batch_label[i][ll] = v
|
||||
else:
|
||||
|
||||
@@ -185,7 +185,7 @@ def load_bin(path, image_size):
|
||||
print(data_list[0].shape)
|
||||
return (data_list, issame_list)
|
||||
|
||||
def test(data_set, mx_model, batch_size, data_extra = None):
|
||||
def test(data_set, mx_model, batch_size, data_extra = None, label_shape = None):
|
||||
print('testing verification..')
|
||||
data_list = data_set[0]
|
||||
issame_list = data_set[1]
|
||||
@@ -194,6 +194,10 @@ def test(data_set, mx_model, batch_size, data_extra = None):
|
||||
if data_extra is not None:
|
||||
_data_extra = nd.array(data_extra)
|
||||
time_consumed = 0.0
|
||||
if label_shape is None:
|
||||
_label = nd.ones( (batch_size,) )
|
||||
else:
|
||||
_label = nd.ones( label_shape )
|
||||
for i in xrange( len(data_list) ):
|
||||
data = data_list[i]
|
||||
embeddings = None
|
||||
@@ -202,7 +206,6 @@ def test(data_set, mx_model, batch_size, data_extra = None):
|
||||
bb = min(ba+batch_size, data.shape[0])
|
||||
count = bb-ba
|
||||
_data = nd.slice_axis(data, axis=0, begin=bb-batch_size, end=bb)
|
||||
_label = nd.ones( (batch_size,) )
|
||||
#print(_data.shape, _label.shape)
|
||||
time0 = datetime.datetime.now()
|
||||
if data_extra is None:
|
||||
|
||||
@@ -77,7 +77,10 @@ class AccMetric(mx.metric.EvalMetric):
|
||||
if pred_label.shape != label.shape:
|
||||
pred_label = mx.ndarray.argmax(pred_label, axis=self.axis)
|
||||
pred_label = pred_label.asnumpy().astype('int32').flatten()
|
||||
label = label.asnumpy().astype('int32').flatten()
|
||||
label = label.asnumpy()
|
||||
if label.ndim==2:
|
||||
label = label[:,0]
|
||||
label = label.astype('int32').flatten()
|
||||
#print(label)
|
||||
#print('label',label)
|
||||
#print('pred_label', pred_label)
|
||||
@@ -223,7 +226,9 @@ def get_symbol(args, arg_params, aux_params):
|
||||
gt_label = all_label
|
||||
else:
|
||||
gt_label = mx.symbol.slice_axis(all_label, axis=1, begin=0, end=1)
|
||||
gt_label = mx.symbol.reshape(gt_label, (args.per_batch_size,))
|
||||
c2c_label = mx.symbol.slice_axis(all_label, axis=1, begin=1, end=2)
|
||||
c2c_label = mx.symbol.reshape(c2c_label, (args.per_batch_size,))
|
||||
assert args.loss_type>=0
|
||||
extra_loss = None
|
||||
if args.loss_type==0: #softmax
|
||||
@@ -319,7 +324,7 @@ def get_symbol(args, arg_params, aux_params):
|
||||
fc7 = mx.sym.FullyConnected(data=nembedding, weight = _weight, no_bias = True, num_hidden=args.num_classes, name='fc7')
|
||||
zy = mx.sym.pick(fc7, gt_label, axis=1)
|
||||
cos_t = zy/s
|
||||
if m>0.0:
|
||||
if args.output_c2c==0:
|
||||
cos_m = math.cos(m)
|
||||
sin_m = math.sin(m)
|
||||
mm = math.sin(math.pi-m)*m
|
||||
@@ -345,7 +350,6 @@ def get_symbol(args, arg_params, aux_params):
|
||||
zy_keep = zy - s*mm
|
||||
new_zy = mx.sym.where(cond, new_zy, zy_keep)
|
||||
else:
|
||||
assert args.output_c2c
|
||||
#set c2c as cosm^2 in data.py
|
||||
cos_m = mx.sym.sqrt(c2c_label)
|
||||
sin_m = 1.0-c2c_label
|
||||
@@ -619,6 +623,9 @@ def train_net(args):
|
||||
coco_mode = True
|
||||
|
||||
label_name = 'softmax_label'
|
||||
label_shape = (args.batch_size,)
|
||||
if args.output_c2c:
|
||||
label_shape = (args.batch_size,2)
|
||||
if data_extra is None:
|
||||
model = mx.mod.Module(
|
||||
context = ctx,
|
||||
@@ -658,6 +665,7 @@ def train_net(args):
|
||||
rand_mirror = args.rand_mirror,
|
||||
mean = mean,
|
||||
c2c_threshold = args.c2c_threshold,
|
||||
output_c2c = args.output_c2c,
|
||||
ctx_num = args.ctx_num,
|
||||
images_per_identity = args.images_per_identity,
|
||||
data_extra = data_extra,
|
||||
@@ -679,6 +687,7 @@ def train_net(args):
|
||||
rand_mirror = args.rand_mirror,
|
||||
mean = mean,
|
||||
c2c_threshold = args.c2c_threshold,
|
||||
output_c2c = args.output_c2c,
|
||||
ctx_num = args.ctx_num,
|
||||
images_per_identity = args.images_per_identity,
|
||||
data_extra = data_extra,
|
||||
@@ -726,7 +735,7 @@ def train_net(args):
|
||||
def ver_test(nbatch):
|
||||
results = []
|
||||
for i in xrange(len(ver_list)):
|
||||
acc1, std1, acc2, std2, xnorm, embeddings_list = verification.test(ver_list[i], model, args.batch_size, data_extra)
|
||||
acc1, std1, acc2, std2, xnorm, embeddings_list = verification.test(ver_list[i], model, args.batch_size, data_extra, label_shape)
|
||||
print('[%s][%d]XNorm: %f' % (ver_name_list[i], nbatch, xnorm))
|
||||
#print('[%s][%d]Accuracy: %1.5f+-%1.5f' % (ver_name_list[i], nbatch, acc1, std1))
|
||||
print('[%s][%d]Accuracy-Flip: %1.5f+-%1.5f' % (ver_name_list[i], nbatch, acc2, std2))
|
||||
|
||||
Reference in New Issue
Block a user