def test_L2Normalization(): x = nd.ones((2, LARGE_X*2)) x[0] = 3 x[1] = 4 # Channel Mode z = x.reshape(1, 2, LARGE_X*2) y = nd.L2Normalization(z, mode='channel') assert y[0][0][0] == 0.6 assert y[0][0][-1] == 0.6 assert y[0][1][0] == 0.8 assert y[0][1][-1] == 0.8 # Instance Mode z = x.T y = nd.L2Normalization(z, mode='instance') assert y[0][0] == 0.6 assert y[0][1] == 0.8 assert y[-1][0] == 0.6 assert y[-1][1] == 0.8 # Spatial Mode z = z.reshape(1, 200000000, 2) y = nd.L2Normalization(z, mode='spatial') assert y[0][0][0] == 0.6 assert y[0][0][1] == 0.8 assert y[0][-1][0] == 0.6 assert y[0][-1][1] == 0.8
def validate(net, ctx, val_datas, targets, nfolds=10, norm=True): metric = FaceVerification(nfolds) results = [] for loader, name in zip(val_datas, targets): metric.reset() for i, batch in enumerate(loader): data0s = gluon.utils.split_and_load(batch[0][0], ctx, even_split=False) data1s = gluon.utils.split_and_load(batch[0][1], ctx, even_split=False) issame_list = gluon.utils.split_and_load(batch[1], ctx, even_split=False) embedding0s = [net(X)[0] for X in data0s] embedding1s = [net(X)[0] for X in data1s] if norm: embedding0s = [nd.L2Normalization(e) for e in embedding0s] embedding1s = [nd.L2Normalization(e) for e in embedding1s] for embedding0, embedding1, issame in zip(embedding0s, embedding1s, issame_list): metric.update(issame, embedding0, embedding1) tpr, fpr, accuracy, val, val_std, far, accuracy_std = metric.get() results.append("{}: {:.6f}+-{:.6f}".format(name, accuracy, accuracy_std)) return results
def _spectral_norm(self, weight: Tensor, u: Tensor) -> Tensor: """ Adapted from https://github.com/apache/incubator- mxnet/blob/master/example/gluon/sn_gan/model.py. """ w = weight w_mat = nd.reshape(w, [w.shape[0], -1]) _u = u _v = None for _ in range(self._num_power_iter): _v = nd.L2Normalization(nd.dot(_u, w_mat)) _u = nd.L2Normalization(nd.dot(_v, w_mat.T)) sigma = nd.sum(nd.dot(_u, w_mat) * _v) # this is different from standard spectral normalization sigma = nd.maximum(nd.ones(1, ctx=self._ctx), sigma / self._coeff) if sigma == 0.0: sigma = EPSILON with autograd.pause(): self._u.set_data(_u) return w / sigma
def forward(self, data, weight, mapping_label, depth): """ """ with autograd.record(): norm_data = nd.L2Normalization(data) norm_weight = nd.L2Normalization(weight) # fc7 = nd.dot(norm_data, norm_weight, transpose_b=True) # mapping_label_onehot = mx.nd.one_hot(indices=mapping_label, depth=depth, on_value=1.0, off_value=0.0) # cosface if self.loss_m1 == 1.0 and self.loss_m2 == 0.0: _one_hot = mapping_label_onehot * self.loss_m3 fc7 = fc7 - _one_hot else: fc7_onehot = fc7 * mapping_label_onehot cos_t = fc7_onehot t = nd.arccos(cos_t) if self.loss_m1 != 1.0: t = t * self.loss_m1 if self.loss_m2 != 0.0: t = t + self.loss_m2 margin_cos = nd.cos(t) if self.loss_m3 != 0.0: margin_cos = margin_cos - self.loss_m3 margin_fc7 = margin_cos margin_fc7_onehot = margin_fc7 * mapping_label_onehot diff = margin_fc7_onehot - fc7_onehot fc7 = fc7 + diff fc7 = fc7 * self.loss_s return fc7, mapping_label_onehot
def forward(self, data, weight, mapping_label, depth): """ """ with autograd.record(): norm_data = nd.L2Normalization(data) norm_weight = nd.L2Normalization(weight) # fc7 = nd.dot(norm_data, norm_weight, transpose_b=True) # mapping_label_onehot = mx.nd.one_hot(indices=mapping_label, depth=depth, on_value=1.0, off_value=0.0) # cosface if self.loss_m1 == 1.0 and self.loss_m2 == 0.0: _one_hot = mapping_label_onehot * self.loss_m3 fc7 = fc7 - _one_hot elif self.loss_m1 == 1.0 and self.loss_m3 == 0.0: fc7_onehot = fc7 * mapping_label_onehot cos_t = fc7_onehot t = nd.arccos(cos_t) if self.loss_m1 != 1.0: t = t * self.loss_m1 if self.loss_m2 != 0.0: t = t + self.loss_m2 margin_cos = nd.cos(t) if self.loss_m3 != 0.0: margin_cos = margin_cos - self.loss_m3 margin_fc7 = margin_cos margin_fc7_onehot = margin_fc7 * mapping_label_onehot diff = margin_fc7_onehot - fc7_onehot fc7 = fc7 + diff else: cosine = fc7 sine = nd.sqrt(1 - fc7 * fc7) m = nd.array([self.loss_m2], ctx=fc7.context) # phi = cosine * nd.cos(m) - sine * nd.sin(m) cos_t = fc7_onehot t = nd.arccos(cos_t) phi = nd.cos(t + self.loss_m2) mask = cosine > phi print('mask', mask.shape) hard_example = nd.where(cosine > phi, cosine) self.t = self.t.as_in_context(fc7.context) self.t = cosine * mapping_label_onehot.mean() * 0.01 + ( 1 - 0.01) * self.t print("cosine", cosine.shape) print(self.t.shape) print('dasdasdasdad', hard_example.shape) cosine[mask] = hard_example * (self.t + hard_example) fc7 = mapping_label_onehot * phi + cosine * ( 1.0 - mapping_label_onehot) fc7 = fc7 * self.loss_s return fc7, mapping_label_onehot
def validate(nfolds=10): metric = FaceVerification(nfolds) metric_flip = FaceVerification(nfolds) for loader, name in zip(val_datas, targets.split(",")): metric.reset() for i, batch in enumerate(loader): data0s = gluon.utils.split_and_load(batch[0][0][0], ctx, even_split=False) data1s = gluon.utils.split_and_load(batch[0][1][0], ctx, even_split=False) data0s_flip = gluon.utils.split_and_load(batch[0][0][1], ctx, even_split=False) data1s_flip = gluon.utils.split_and_load(batch[0][1][1], ctx, even_split=False) issame_list = gluon.utils.split_and_load(batch[1], ctx, even_split=False) embedding0s = [test_net(X) for X in data0s] embedding1s = [test_net(X) for X in data1s] embedding0s_flip = [test_net(X) for X in data0s_flip] embedding1s_flip = [test_net(X) for X in data1s_flip] emb0s = [ nd.L2Normalization(e, mode='instance') for e in embedding0s ] emb1s = [ nd.L2Normalization(e, mode='instance') for e in embedding1s ] for embedding0, embedding1, issame in zip(emb0s, emb1s, issame_list): metric.update(issame, embedding0, embedding1) emb0s_flip = [ nd.L2Normalization(nd.concatenate([e, ef], 1), mode='instance') for e, ef in zip(embedding0s, embedding0s_flip) ] emb1s_flip = [ nd.L2Normalization(nd.concatenate([e, ef], 1), mode='instance') for e, ef in zip(embedding1s, embedding1s_flip) ] for embedding0, embedding1, issame in zip(emb0s_flip, emb1s_flip, issame_list): metric_flip.update(issame, embedding0, embedding1) tpr, fpr, accuracy, val, val_std, far, accuracy_std = metric.get() print("{}: \t{:.6f}+-{:.6f}".format(name, accuracy, accuracy_std)) _, _, accuracy, _, _, _, accuracy_std = metric_flip.get() print("{}-flip: {:.6f}+-{:.6f}".format(name, accuracy, accuracy_std))
def initialize_from(self, pkl_path, ctx, *args): with open(pkl_path, "rb") as f: params = pickle.load(f) same_layer = map(str, [0, 1, 3, 7]) block_index = 0 res_index = 1 for name, resblock in self.features._children.items(): if name == "8": resblock.initialize(init=myInitializer(params['fc5.weight']), ctx=ctx) resblock.bias.initialize(init=mx.init.Constant( params['fc5.bias']), force_reinit=True, ctx=ctx) else: if name in same_layer: block_index += 1 res_index = 1 resblock.conv0.initialize(init=myInitializer( params['conv%d_%d.weight' % (block_index, res_index)]), ctx=ctx) resblock.conv0.conv.bias.initialize(init=mx.init.Constant( params['conv%d_%d.bias' % (block_index, res_index)]), force_reinit=True, ctx=ctx) print 'conv%d_%d.weight' % (block_index, res_index) resblock.a0.initialize(init=mx.init.Constant( params['relu%d_%d' % (block_index, res_index)][0].reshape( [1, -1, 1, 1])), force_reinit=True, ctx=ctx) res_index += 1 resblock.conv1.initialize(init=myInitializer( params['conv%d_%d.weight' % (block_index, res_index)], params['conv%d_%d.bias' % (block_index, res_index)]), ctx=ctx) resblock.a1.initialize(init=mx.init.Constant( params['relu%d_%d' % (block_index, res_index)][0].reshape( [1, -1, 1, 1])), force_reinit=True, ctx=ctx) res_index += 1 resblock.conv2.initialize(init=myInitializer( params['conv%d_%d.weight' % (block_index, res_index)], params['conv%d_%d.bias' % (block_index, res_index)]), ctx=ctx) resblock.a2.initialize(init=mx.init.Constant( params['relu%d_%d' % (block_index, res_index)][0].reshape( [1, -1, 1, 1])), force_reinit=True, ctx=ctx) res_index += 1 weight = nd.L2Normalization( nd.random.uniform( -1, 1, shape=(self.num_classes, 512))) # the weight need to be specially initialize self.classifier.initialize(init=mx.init.Constant(weight), ctx=ctx)
def _spectral_norm(self): """ spectral normalization """ w = self.params.get('weight').data(self.ctx) w_mat = nd.reshape(w, [w.shape[0], -1]) _u = self.u.data(self.ctx) _v = None for _ in range(POWER_ITERATION): _v = nd.L2Normalization(nd.dot(_u, w_mat)) _u = nd.L2Normalization(nd.dot(_v, w_mat.T)) sigma = nd.sum(nd.dot(_u, w_mat) * _v) if sigma == 0.: sigma = EPSILON self.params.setattr('u', _u) return w / sigma
def __call__(self, net, *args, **kwargs): if not self.skip_validate: self.metric.reset() for batch in self.loader: data0 = batch[0][0].as_in_context(self.ctx) data1 = batch[0][1].as_in_context(self.ctx) issame = batch[1].as_in_context(self.ctx) embedding0 = net(data0)[0] embedding1 = net(data1)[0] if self.norm: embedding0 = nd.L2Normalization(embedding0) embedding1 = nd.L2Normalization(embedding1) self.metric.update(issame, embedding0, embedding1) tpr, fpr, accuracy, val, val_std, far, accuracy_std = self.metric.get( ) text = "{}: {:.6f}+-{:.6f}".format(self.name, accuracy, accuracy_std) if self.logger is None: print(text) else: self.logger.info(text)
def hybrid_forward(self, F, x, *args, **params): # xsize=(B,F) F is feature len w = self.weight._data[0] # size=(Classnum,F) F=in_features Classnum=out_features ww = nd.L2Normalization(w) xlen = x.square().sum(axis=1, keepdims=True).sqrt() wlen = ww.square().sum(axis=1, keepdims=True).sqrt() cos_theta = nd.dot(x, ww.T) / xlen.reshape(-1, 1) / wlen.reshape(1, -1) cos_theta = cos_theta.clip(-1, 1) cos_m_theta = self.mlambda[self.m](cos_theta) theta = nd.arccos(cos_theta) k = (self.m * theta / math.pi).floor() phi_theta = (-1 ** k) * cos_m_theta - 2 * k cos_theta = cos_theta * xlen.reshape(-1, 1) phi_theta = phi_theta * xlen.reshape(-1, 1) output = (cos_theta, phi_theta) return output # size=(B,Classnum,2)
def forward(self, x): features = [] for i in range(1, 4): x = getattr(self, self._base_conv + str(i))(x) x = getattr(self, self._base_pool + str(i))(x) x = getattr(self, self._base_conv + str(4))(x) x = nd.L2Normalization(x, mode='channel') * self._conv4_scale.data() features.append(x) x = getattr(self, self._base_pool + str(4))(x) x = getattr(self, self._base_conv + str(5))(x) x = getattr(self, self._base_pool + str(5))(x) x = self.feature_conv_blk6(x) x = self.feature_conv_blk7(x) features.append(x) for i in range(8, 12): x = getattr(self, self._feature_conv + str(i))(x) features.append(x) return features
import mxnet as mx from mxnet import nd def test_index(array, idx, i): sim = nd.dot(array[i], array, transpose_b=True) index = idx[i] index = index[:30] print('===============================') print(sim[index]) sim = nd.sort(sim, is_ascend=0) print("mean all", nd.mean(sim)) print("mean 100", nd.mean(sim[:100])) print("mean 500", nd.mean(sim[:500])) print("mean 1000", nd.mean(sim[:1000])) print("mean 10000", nd.mean(sim[:10000])) print("mean 20000", nd.mean(sim[:20000])) print("mean -1000", nd.mean(sim[len(sim) - 1000:])) # print(sim.shape) if __name__ == '__main__': prefix = "/anxiang/workspace/class_center_5_15/concat_celeb_largeFC" array = nd.load("%s.param" % prefix)[0] array = nd.L2Normalization(array) idx = nd.load("%s.index" % prefix)[0] for i in [12, 32, 43, 23, 123, 554, 41213, 45, 657, 234, 54, 23]: test_index(array, idx, i)
def load(fname): _arr = nd.load(fname)[0] _arr = nd.L2Normalization(_arr) return _arr