This commit is contained in:
nttstar
2018-02-01 19:19:18 +08:00
parent 7c258ca2a5
commit bd7fcc9230
3 changed files with 124 additions and 15 deletions

View File

@@ -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:

View File

@@ -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:

View File

@@ -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))