def process_one_label_dataset(label_ds, config, output_index=None): """process one-label data set.""" logging.info("Loading one label dataset...") num_parallel_calls = config["data"]["task"]["num_parallel_calls"] classes = config["data"]["task"]["classes"] if isinstance(classes, list): if output_index is None or output_index not in range(len(classes)): raise IndexError( "output_index:{} not in the range of classes length: " "{}!".format(output_index, len(classes))) num_classes = classes[output_index]["num_classes"] label_vocab_file_path = config["data"]["task"]["label_vocab"][ output_index] else: num_classes = classes["num_classes"] label_vocab_file_path = config["data"]["task"]["label_vocab"] label_ds = label_ds.map(lambda x: tokenize_label( x, maxlen=1, label_vocab_file_path=label_vocab_file_path, pad_id=0), num_parallel_calls=num_parallel_calls) label_ds = label_ds.map( lambda l: tf.one_hot(l, num_classes, dtype=tf.int32), num_parallel_calls=num_parallel_calls) label_ds = label_ds.map(tf.squeeze, num_parallel_calls=num_parallel_calls) return label_ds
def cross_entropy(logits, labels, input_length=None, label_length=None, smoothing=0.0, reduction=tf.losses.Reduction.SUM_BY_NONZERO_WEIGHTS): ''' cross entropy function for classfication and seq classfication :param, label_length, for seq task, this for target seq length, e.g. a b c </s>, 4 ''' del input_length onehot_labels = tf.cond(pred=tf.equal( tf.rank(logits) - tf.rank(labels), 1), true_fn=lambda: tf.one_hot( labels, tf.shape(logits)[-1], dtype=tf.int32), false_fn=lambda: labels) if label_length is not None: weights = utils.len_to_mask(label_length) else: weights = 1.0 loss = tf.losses.softmax_cross_entropy(onehot_labels=onehot_labels, logits=logits, weights=weights, label_smoothing=smoothing, reduction=reduction) return loss
def test_dataset(self): ''' dataset unittest''' batch_size = 4 self.config['solver']['optimizer']['batch_size'] = batch_size task_name = self.config['data']['task']['name'] task_class = registers.task[task_name] task = task_class(self.config, utils.TRAIN) dataset = task.input_fn(utils.TRAIN, batch_size, 1)() features, labels = dataset.make_one_shot_iterator().get_next() samples = features['inputs'] filenames = features['filepath'] clip_ids = features['clipid'] soft_labels = features['soft_labels'] with self.cached_session(use_gpu=False, force_gpu=False) as sess: while True: batch_inputs, batch_labels, batch_files, batch_clipids, labels_onehot, batch_soft_labels = \ sess.run([samples, labels, filenames, clip_ids, tf.one_hot(labels, 2), soft_labels]) del labels_onehot logging.info("feat shape: {}".format(batch_inputs.shape)) logging.info("labels: {}".format(batch_labels)) logging.info("filename: {}".format(batch_files)) logging.info("clip id: {}".format(batch_clipids)) logging.info("soft_labels: {}".format(batch_soft_labels)) break
def focal_loss(logits, labels, alpha, gamma=2, name='focal_loss'): """ Focal loss for multi classification :param logits: A float32 tensor of shape [batch_size num_class]. :param labels: A int32 tensor of shape [batch_size, num_class] or [batch_size]. :param alpha: A 1D float32 tensor for focal loss alpha hyper-parameter :param gamma: A scalar for focal loss gamma hyper-parameter. Returns: A tensor of the same shape as `lables` """ if len(labels.shape) == 1: labels = tf.one_hot(labels, logits.shape[-1]) else: labels = labels labels = tf.to_float(labels) y_pred = tf.nn.softmax(logits, dim=-1) L = -labels * tf.log(y_pred) L *= alpha * ((1 - y_pred)**gamma) loss = tf.reduce_sum(L) if tf.executing_eagerly(): tf.contrib.summary.scalar(name, loss) else: tf.summary.scalar(name, loss) return loss
def arcface_loss(embedding, labels, out_num, weights=None, s=64., m=0.5, limit_to_pi=True): ''' https://github.com/auroua/InsightFace_TF/blob/master/losses/face_losses.py :param embedding: the input embedding vectors :param labels: the input labels, the shape should be eg: (batch_size, 1) :param s: scalar value default is 64 :param out_num: output class num :param weights: a tf.variable with shape (embedding.shape[-1], out_num) or None to make a new one internally. default = None :param m: the margin value, default is 0.5 :return: the final cacualted output, this output is send into the tf.nn.softmax directly ''' cos_m = math.cos(m) sin_m = math.sin(m) mm = sin_m * m # issue 1 threshold = math.cos(math.pi - m) with tf.variable_scope('arcface_loss'): # inputs and weights norm embedding_norm = tf.norm(embedding, axis=1, keep_dims=True) embedding = tf.div(embedding, embedding_norm, name='norm_embedding') if weights is None: weights = tf.get_variable( name='weights', shape=[embedding.shape[-1].value, out_num], initializer=tf.initializer.glorot_unifrom()) weights_norm = tf.norm(weights, axis=0, keep_dims=True) weights = tf.div(weights, weights_norm, name='norm_weights') # cos(theta+m) cos_t = tf.matmul(embedding, weights, name='cos_t') cos_t2 = tf.square(cos_t, name='cos_2') sin_t2 = tf.subtract(1., cos_t2, name='sin_2') sin_t = tf.sqrt(sin_t2, name='sin_t') cos_mt = s * tf.subtract(tf.multiply(cos_t, cos_m), tf.multiply(sin_t, sin_m), name='cos_mt') if limit_to_pi: # this condition controls the theta+m should in range [0, pi] # 0<=theta+m<=pi # -m<=theta<=pi-m cond_v = cos_t - threshold cond = tf.cast(tf.nn.relu(cond_v, name='if_else'), dtype=tf.bool) keep_val = s * (cos_t - mm) cos_mt_temp = tf.where(cond, cos_mt, keep_val) else: cos_mt_temp = cos_mt mask = tf.one_hot(labels, depth=out_num, name='one_hot_mask') # mask = tf.squeeze(mask, 1) inv_mask = tf.subtract(1., mask, name='inverse_mask') s_cos_t = tf.multiply(s, cos_t, name='scalar_cos_t') output = tf.add(tf.multiply(s_cos_t, inv_mask), tf.multiply(cos_mt_temp, mask), name='arcface_loss_output') return output