def prepare_simple_model(input_tensor, loss_name, target): axis = 1 if K.image_data_format() == 'channels_first' else -1 loss = None num_channels = None activation = None if loss_name == 'sparse_categorical_crossentropy': loss = lambda y_true, y_pred: K.sparse_categorical_crossentropy( # pylint: disable=g-long-lambda y_true, y_pred, axis=axis) num_channels = np.amax(target) + 1 activation = 'softmax' elif loss_name == 'categorical_crossentropy': loss = lambda y_true, y_pred: K.categorical_crossentropy( # pylint: disable=g-long-lambda y_true, y_pred, axis=axis) num_channels = target.shape[axis] activation = 'softmax' elif loss_name == 'binary_crossentropy': loss = lambda y_true, y_pred: K.binary_crossentropy(y_true, y_pred) # pylint: disable=unnecessary-lambda num_channels = target.shape[axis] activation = 'sigmoid' predictions = Conv2D(num_channels, 1, activation=activation, kernel_initializer='ones', bias_initializer='ones')(input_tensor) simple_model = keras.models.Model(inputs=input_tensor, outputs=predictions) simple_model.compile(optimizer='rmsprop', loss=loss) return simple_model
def weighted_binary_crossentropy(y_true, y_pred): weights = tf.reduce_sum(y_true, axis=-1, keepdims=True) mask = tf.equal(weights, 1) axon_true = y_true[:, :, :, :, 0] axon_true = tf.expand_dims(axon_true, -1) axon_mask = tf.boolean_mask(axon_true, mask) background_true = y_true[:, :, :, :, 1] background_true = tf.expand_dims(background_true, -1) background_mask = tf.boolean_mask(background_true, mask) artifact_true = y_true[:, :, :, :, 2] artifact_true = tf.expand_dims(artifact_true, -1) artifact_mask = tf.boolean_mask(artifact_true, mask) edge_true = y_true[:, :, :, :, 3] edge_true = tf.expand_dims(edge_true, -1) edge_mask = tf.boolean_mask(edge_true, mask) mask_true = tf.boolean_mask(axon_true, mask) mask_pred = tf.boolean_mask(y_pred, mask) crossentropy = K.binary_crossentropy(mask_true, mask_pred) weight_vector = (axon_mask * axon_weight) + (background_mask * background_weight) + \ (artifact_mask * artifact_weight) + (edge_mask * edge_weight) weighted_crossentropy = weight_vector * crossentropy return K.mean(weighted_crossentropy)
def __init__(self, model1, model2, *args, **kwargs): super().__init__(*args, **kwargs) self.model1 = model1 self.model2 = model2 self.loss = tf.losses.BinaryCrossentropy(from_logits=True) self.nonReductionLoss = lambda y, x: K.binary_crossentropy(y, x, from_logits=True)
def focal_loss(self, y_true: tf.Tensor, y_pred: tf.Tensor): self.mask = tf.equal(y_true, 1) cross_entropy = K.binary_crossentropy(y_true, y_pred) p_t = y_true * y_pred + (tf.subtract(1.0, y_true) * tf.subtract(1.0, y_pred)) gamma_factor = tf.pow(1.0 - p_t, self.gamma) alpha_factor = y_true * self.alpha + (1.0 - y_true) * (1.0 - self.alpha) focal_loss = gamma_factor * alpha_factor * cross_entropy neg_mask = tf.equal(y_true, 0) thr = tfp.stats.percentile(tf.boolean_mask(focal_loss, neg_mask), 90.) hard_neg_mask = tf.greater(focal_loss, thr) # mask = tf.logical_or(tf.equal(y_true, 0), tf.equal(y_true, 1)) mask = tf.logical_or(self.mask, tf.logical_and(neg_mask, hard_neg_mask)) masked_loss = tf.boolean_mask(focal_loss, mask) return self.focal_weight * tf.reduce_mean(masked_loss)
def binary_crossentropy(y_true, y_pred, from_logits=False, label_smoothing=0): """Computes the binary crossentropy loss. Args: y_true: Ground truth values. shape = `[batch_size, d0, .. dN]`. y_pred: The predicted values. shape = `[batch_size, d0, .. dN]`. from_logits: Whether `y_pred` is expected to be a logits tensor. By default, we assume that `y_pred` encodes a probability distribution. label_smoothing: Float in [0, 1]. If > `0` then smooth the labels. Returns: Binary crossentropy loss value. shape = `[batch_size, d0, .. dN-1]`. """ y_pred = ops.convert_to_tensor(y_pred) y_true = math_ops.cast(y_true, y_pred.dtype) label_smoothing = ops.convert_to_tensor(label_smoothing, dtype=K.floatx()) def _smooth_labels(): return y_true * (1.0 - label_smoothing) + 0.5 * label_smoothing y_true = smart_cond.smart_cond(label_smoothing, _smooth_labels, lambda: y_true) return K.mean(K.binary_crossentropy(y_true, y_pred, from_logits=from_logits), axis=-1)
def focal(y_true, y_pred, alpha=0.25, gamma=2.0, axis=None): """Compute the focal loss given the target tensor and the predicted tensor. As defined in https://arxiv.org/abs/1708.02002 Args: y_true: Tensor of target data with shape (B, N, num_classes). y_pred: Tensor of predicted data with shape (B, N, num_classes). alpha: Scale the focal weight with alpha. gamma: Take the power of the focal weight with gamma. Returns: The focal loss of y_pred w.r.t. y_true. """ if axis is None: axis = 1 if K.image_data_format( ) == 'channels_first' else K.ndim(y_pred) - 1 # compute the focal loss alpha_factor = K.ones_like(y_true) * alpha alpha_factor = tf.where(K.equal(y_true, 1), alpha_factor, 1 - alpha_factor) focal_weight = tf.where(K.equal(y_true, 1), 1 - y_pred, y_pred) focal_weight = alpha_factor * focal_weight**gamma cls_loss = focal_weight * K.binary_crossentropy(y_true, y_pred) return K.sum(cls_loss, axis=axis)
def weighted_loss(y_true, y_pred): cross_entropy_loss = K.binary_crossentropy(y_true, y_pred, from_logits=False) n_classes_present = K.sum(y_true, axis=1, keepdims=True) cross_entropy_loss = K.minimum(80 / n_classes_present * y_true, 1) * cross_entropy_loss return K.mean(cross_entropy_loss, axis=-1)
def binary_crossentropy(y_true, y_pred, from_logits=False, label_smoothing=0): def _smooth_labels(): return y_true * (1.0 - label_smoothing) + 0.5 * label_smoothing y_true = smart_cond.smart_cond(label_smoothing, _smooth_labels, lambda: y_true) return K.mean( K.binary_crossentropy(y_true, y_pred, from_logits=from_logits), axis=-1)
def binary_crossentropy(y_true, y_pred, from_logits=False, label_smoothing=0): def _smooth_labels(): return y_true * (1.0 - label_smoothing) + 0.5 * label_smoothing y_true = smart_cond.smart_cond(label_smoothing, _smooth_labels, lambda: y_true) return K.mean( K.binary_crossentropy(y_true, y_pred, from_logits=from_logits), axis=-1)
def compute_mask_loss(boxes, masks, annotations, masks_target, width, height, iou_threshold=0.5, mask_size=(28, 28)): """compute overlap of boxes with annotations""" iou = overlap(boxes, annotations) argmax_overlaps_inds = K.argmax(iou, axis=1) max_iou = K.max(iou, axis=1) # filter those with IoU > 0.5 indices = tf.where(K.greater_equal(max_iou, iou_threshold)) boxes = tf.gather_nd(boxes, indices) masks = tf.gather_nd(masks, indices) argmax_overlaps_inds = K.cast(tf.gather_nd(argmax_overlaps_inds, indices), 'int32') labels = K.cast(K.gather(annotations[:, 4], argmax_overlaps_inds), 'int32') # make normalized boxes x1 = boxes[:, 0] y1 = boxes[:, 1] x2 = boxes[:, 2] y2 = boxes[:, 3] boxes = K.stack([ y1 / (K.cast(height, dtype=K.floatx()) - 1), x1 / (K.cast(width, dtype=K.floatx()) - 1), (y2 - 1) / (K.cast(height, dtype=K.floatx()) - 1), (x2 - 1) / (K.cast(width, dtype=K.floatx()) - 1), ], axis=1) # crop and resize masks_target # append a fake channel dimension masks_target = K.expand_dims(masks_target, axis=3) masks_target = tf.image.crop_and_resize( masks_target, boxes, argmax_overlaps_inds, mask_size ) masks_target = masks_target[:, :, :, 0] # remove fake channel dimension # gather the predicted masks using the annotation label masks = tf.transpose(masks, (0, 3, 1, 2)) label_indices = K.stack([tf.range(K.shape(labels)[0]), labels], axis=1) masks = tf.gather_nd(masks, label_indices) # compute mask loss mask_loss = K.binary_crossentropy(masks_target, masks) normalizer = K.shape(masks)[0] * K.shape(masks)[1] * K.shape(masks)[2] normalizer = K.maximum(K.cast(normalizer, K.floatx()), 1) mask_loss = K.sum(mask_loss) / normalizer return mask_loss
def hard_negative_loss(y_true, y_pred, n=128): loss = k.binary_crossentropy(y_true, y_pred) pos_index = y_true neg_index = 1. - pos_index pos_loss = pos_index * loss neg_loss = neg_index * loss neg_loss, _ = tf.nn.top_k(neg_loss, k=n) out_loss = k.concatenate([pos_loss, neg_loss], axis=-1) * 2 return out_loss
def binary_crossentropy(y_true, y_pred, from_logits=False, label_smoothing=0): # pylint: disable=missing-docstring y_pred = ops.convert_to_tensor(y_pred) y_true = math_ops.cast(y_true, y_pred.dtype) label_smoothing = ops.convert_to_tensor(label_smoothing, dtype=K.floatx()) def _smooth_labels(): return y_true * (1.0 - label_smoothing) + 0.5 * label_smoothing y_true = smart_cond.smart_cond(label_smoothing, _smooth_labels, lambda: y_true) return K.mean( K.binary_crossentropy(y_true, y_pred, from_logits=from_logits), axis=-1)
def __call__(self, y_true, y_pred): # Keras checks target/pred shapes so need to fake reshape y_true = K.reshape(y_true, [-1, 6, 2]) y_true_val = y_true[:, :, 0] mask = y_true[:, :, 1] # masked per-sample means of each loss num_items_masked = K.sum(mask, axis=-1) + 1e-6 masked_cross_entropy = ( K.sum(mask * K.binary_crossentropy(y_true_val, y_pred), axis=-1) / num_items_masked) return masked_cross_entropy
def binary_crossentropy(y_true, y_pred, from_logits=False, label_smoothing=0): # pylint: disable=missing-docstring y_pred = ops.convert_to_tensor(y_pred) y_true = math_ops.cast(y_true, y_pred.dtype) label_smoothing = ops.convert_to_tensor(label_smoothing, dtype=K.floatx()) def _smooth_labels(): return y_true * (1.0 - label_smoothing) + 0.5 * label_smoothing y_true = smart_cond.smart_cond(label_smoothing, _smooth_labels, lambda: y_true) return K.mean( K.binary_crossentropy(y_true, y_pred, from_logits=from_logits), axis=-1)
def vae_loss(y_true, y_pred): y_true_flat = K.flatten(y_true) y_pred_flat = K.flatten(y_pred) #r_loss = 10 * K.mean(K.square(y_true_flat - y_pred_flat), axis = -1) #r_loss = K.binary_crossentropy(x, x_decoded_mean) r_loss = K.binary_crossentropy(y_pred, y_true) kl_loss = -0.5 * K.mean(1 + vae_z_log_var - K.square(vae_z_mean) - K.exp(vae_z_log_var), axis=-1) #kl_loss = - 0.5 * K.sum(1 + vae_z_log_var - K.square(vae_z_mean) - K.exp(vae_z_log_var), axis = -1) return K.mean(r_loss + kl_loss)
def focal_loss(y_true, y_pred, gamma=2, alpha=0.25): cross_entropy_loss = K.binary_crossentropy(y_true, y_pred, from_logits=False) p_t = ((y_true * y_pred) + ((1 - y_true) * (1 - y_pred))) modulating_factor = 1.0 if gamma: modulating_factor = tf.pow(1.0 - p_t, gamma) alpha_weight_factor = 1.0 if alpha is not None: alpha_weight_factor = (y_true * alpha + (1 - y_true) * (1 - alpha)) focal_cross_entropy_loss = (modulating_factor * alpha_weight_factor * cross_entropy_loss) return K.mean(focal_cross_entropy_loss, axis=-1)
def focal_crossentropy(y_true, y_pred): bce = K.binary_crossentropy(y_true, y_pred) y_pred = K.clip(y_pred, K.epsilon(), 1.- K.epsilon()) p_t = (y_true*y_pred) + ((1-y_true)*(1-y_pred)) alpha_factor = 1 modulating_factor = 1 alpha_factor = y_true*alpha + ((1-alpha)*(1-y_true)) modulating_factor = K.pow((1-p_t), gamma) # compute the final loss and return return K.mean(alpha_factor*modulating_factor*bce, axis=-1)
def custom_sigmoid_focal_crossentropy( y_true: TensorLike, y_pred: TensorLike, alpha: FloatTensorLike = 0.25, gamma: FloatTensorLike = 2.0, from_logits: bool = False, ) -> tf.Tensor: if gamma and gamma < 0: raise ValueError( "Value of gamma should be greater than or equal to zero") y_pred = tf.convert_to_tensor(y_pred)[:, :, :, 0:2] y_true = tf.convert_to_tensor(y_true, dtype=y_pred.dtype)[:, :, :, 0:2] # Get the cross_entropy for each entry ce = K.binary_crossentropy(y_true, y_pred, from_logits=from_logits) # if note is not played, mask out loss term for articulation ce_p = ce[:, :, :, 0] ce_a = ce[:, :, :, 1] * y_true[:, :, :, 0] ce = tf.stack([ce_p, ce_a], axis=-1) # If logits are provided then convert the predictions into probabilities # if from_logits: # pred_prob = tf.sigmoid(y_pred) # else: # pred_prob = y_pred # if note is not played, mask out probability for articulation # pred_prob_p = pred_prob[:,:,:,0] # pred_prob_a = pred_prob[:,:,:,1] * y_true[:,:,:,0] # pred_prob = tf.stack([pred_prob_p, pred_prob_a], axis=-1) # p_t = (y_true * pred_prob) + ((1 - y_true) * (1 - pred_prob)) alpha_factor = 1.0 modulating_factor = 1.0 # if alpha: # alpha = tf.convert_to_tensor(alpha, dtype=K.floatx()) # alpha_factor = y_true * alpha + (1 - y_true) * (1 - alpha) # if gamma: # gamma = tf.convert_to_tensor(gamma, dtype=K.floatx()) # modulating_factor = tf.pow((1.0 - p_t), gamma) # compute the final loss and return Loss = tf.reduce_mean(alpha_factor * modulating_factor * ce) * 2 return Loss
def per_time_step_binary_cross_entropy(y_true: tf.Tensor, y_pred: tf.Tensor, positive_weight: float = 1 ) -> tf.Tensor: """ Calculates the cross-entropy loss between true labels and predicted labels for a time series which each time step has a binary label. :param y_true: The true label. :param y_pred: The predicted label. :param positive_weight: The weight to give to positive labels in calculating the loss (relative to negative). :return: The resulting cross entropy loss. """ y_pred = ops.convert_to_tensor(y_pred) y_true = math_ops.cast(y_true, y_pred.dtype) binary_cross_entropy = backend.binary_crossentropy(y_true, y_pred) weights = tf.where(tf.cast(y_true, dtype=tf.bool), tf.cast(positive_weight, dtype=tf.float32), tf.cast(1, dtype=tf.float32)) return binary_cross_entropy * weights
def focal_loss(self, y_true: tf.Tensor, y_pred: tf.Tensor): self.mask = tf.equal(y_true, 1) cross_entropy = K.binary_crossentropy(y_true, y_pred) p_t = y_true * y_pred + (tf.subtract(1.0, y_true) * tf.subtract(1.0, y_pred)) gamma_factor = tf.pow(1.0 - p_t, self.gamma) alpha_factor = y_true * self.alpha + (1.0 - y_true) * (1.0 - self.alpha) focal_loss = gamma_factor * alpha_factor * cross_entropy mask = tf.logical_or(tf.equal(y_true, 0), tf.equal(y_true, 1)) masked_loss = tf.boolean_mask(focal_loss, mask) return self.focal_weight * tf.reduce_mean(masked_loss)
def mrcnn_mask_loss_graph(target_masks, target_class_ids, pred_masks): """Mask binary cross-entropy loss for the masks head. target_masks: [batch, num_rois, height, width]. A float32 tensor of values 0 or 1. Uses zero padding to fill array. target_class_ids: [batch, num_rois]. Integer class IDs. Zero padded. pred_masks: [batch, proposals, height, width, num_classes] float32 tensor with values from 0 to 1. """ # Reshape for simplicity. Merge first two dimensions into one. target_class_ids = K.reshape(target_class_ids, (-1, )) mask_shape = tf.shape(target_masks) target_masks = K.reshape(target_masks, (-1, mask_shape[2], mask_shape[3])) pred_shape = tf.shape(pred_masks) pred_masks = K.reshape(pred_masks, (-1, pred_shape[2], pred_shape[3], pred_shape[4])) # Permute predicted masks to [N, num_classes, height, width] pred_masks = tf.transpose(pred_masks, [0, 3, 1, 2]) # Only positive ROIs contribute to the loss. And only # the class specific mask of each ROI. positive_ix = tf.where(target_class_ids > 0)[:, 0] positive_class_ids = tf.cast(tf.gather(target_class_ids, positive_ix), tf.int64) indices = tf.stack([positive_ix, positive_class_ids], axis=1) # Gather the masks (predicted and true) that contribute to loss y_true = tf.gather(target_masks, positive_ix) y_pred = tf.gather_nd(pred_masks, indices) # Compute binary cross entropy. If no positive ROIs, then return 0. # shape: [batch, roi, num_classes] loss = K.switch( tf.size(y_true) > 0, K.binary_crossentropy(target=y_true, output=y_pred), tf.constant(0.0)) loss = K.mean(loss) return loss
def binary_crossentropy(y_true, y_pred, from_logits=False, **kwargs): return K.mean(K.binary_crossentropy(y_true, y_pred, from_logits=from_logits), axis=-1, keepdims=True)
def vae_loss(self, y_true, y_pred): recon = self.image_size * self.image_size * K.binary_crossentropy(y_true, y_pred) kl = 0.5 * K.sum(K.exp(self.std) + K.square(self.mu) - 1. - self.std, axis=-1) return recon + kl
def binary_crossentropy(y_true, y_pred, from_logits=False): return K.mean( K.binary_crossentropy(y_true, y_pred, from_logits=from_logits), axis=-1)
def din(item_count, cate_count, hidden_units=128): ''' :param item_count: 商品数 :param cate_count: 类别数 :param hidden_units: 隐藏单元数 :return: model ''' target_item = keras.layers.Input(shape=(1, ), name='target_item', dtype="int32") # 点击的item target_cate = keras.layers.Input(shape=(1, ), name='target_cate', dtype="int32") # 点击的item对应的所属类别 label = keras.layers.Input(shape=(1, ), name='label', dtype="float32") # 是否点击 hist_item_seq = keras.layers.Input(shape=(None, ), name="hist_item_seq", dtype="int32") # 点击序列 hist_cate_seq = keras.layers.Input(shape=(None, ), name="hist_cate_seq", dtype="int32") # 点击序列对应的类别序列 hist_len = keras.layers.Input(shape=(1, ), name='hist_len', dtype="int32") # 序列本来的长度 item_emb = keras.layers.Embedding( input_dim=item_count, output_dim=hidden_units // 2, embeddings_initializer=keras.initializers.RandomNormal(mean=0.0, stddev=1e-4, seed=seed)) cate_emb = keras.layers.Embedding( input_dim=cate_count, output_dim=hidden_units // 2, embeddings_initializer=keras.initializers.RandomNormal(mean=0.0, stddev=1e-4, seed=seed)) item_b = keras.layers.Embedding( input_dim=item_count, output_dim=1, embeddings_initializer=keras.initializers.Constant(0.0)) # get target bias embedding target_item_bias_emb = item_b(target_item) # (batch_size, 1, 1) # target_item_bias_emb = keras.layers.Lambda(lambda x: K.squeeze(x, axis=1))( target_item_bias_emb) # get target embedding target_item_emb = item_emb(target_item) # (batch_size, 1, hidden_units//2) target_cate_emb = cate_emb(target_cate) # (batch_size, 1, hidden_units//2) i_emb = keras.layers.Lambda( lambda x: K.concatenate([x[0], x[1]], axis=-1))( [target_item_emb, target_cate_emb]) # (batch_size, 1, hidden_units) i_emb = keras.layers.Lambda(lambda x: K.squeeze(x, axis=1))( i_emb) # (batch_size, hidden_units) # get history item embedding hist_item_emb = item_emb( hist_item_seq) # (batch_size, max_len, hidden_units//2) hist_cate_emb = cate_emb( hist_cate_seq) # (batch_size, max_len, hidden_units//2) hist_emb = keras.layers.Lambda( lambda x: K.concatenate([x[0], x[1]], axis=-1))( [hist_item_emb, hist_cate_emb]) # (batch_size, max_len, hidden_units) # 构建点击序列与候选的attention关系 din_attention = Attention()([i_emb, hist_emb, hist_len]) # (batch_size, hidden_units) din_attention = keras.layers.Lambda( lambda x: tf.reshape(x, [-1, hidden_units]))(din_attention) # keras.layers.BatchNormalization实现暂时有坑,借用paddle相关代码实现 din_attention_fc = keras.layers.Dense(63802)( din_attention) # (batch_size, item_count + cate_count) # item_count: 63001 cate_count: 801 hidden_units: 128 (batch_size, item_count + cate_count + hidden_units) din_item = keras.layers.Lambda( lambda x: K.concatenate([x[0], x[1]], axis=1))( [i_emb, din_attention_fc]) din_item = share_weights()(din_item) # (batch_size, 1) print("logits:", din_item, target_item_bias_emb) logits = keras.layers.Add()([din_item, target_item_bias_emb]) label_model = keras.models.Model(inputs=[ hist_item_seq, hist_cate_seq, target_item, target_cate, hist_len ], outputs=[logits]) train_model = keras.models.Model(inputs=[ hist_item_seq, hist_cate_seq, target_item, target_cate, hist_len, label ], outputs=logits) # 计算损失函数 loss = K.binary_crossentropy(target=label, output=logits, from_logits=True) train_model.add_loss(loss) train_model.compile(optimizer=tf.keras.optimizers.SGD(1e-3), metrics=["accuracy"]) return train_model, label_model
def ce(y_true, y_pred): """ Sigmoid cross-entropy loss """ return K.mean(K.binary_crossentropy(target=y_true, output=y_pred, from_logits=True), axis=-1)
def binary_crossentropy(y_true, y_pred): return K.mean(K.binary_crossentropy(y_true, y_pred), axis=-1)
def binary_crossentropy(y_true, y_pred, from_logits=False): return K.mean( K.binary_crossentropy(y_true, y_pred, from_logits=from_logits), axis=-1)
def nll(y_true, y_pred): return backend.sum(backend.binary_crossentropy(y_true, y_pred), axis=-1)
def yolo_loss(args, anchors, num_classes, ignore_thresh=.5, print_loss=False): '''Return yolo_loss tensor Parameters ---------- yolo_outputs: list of tensor, the output of yolo_body or tiny_yolo_body y_true: list of array, the output of preprocess_true_boxes anchors: array, shape=(N, 2), wh num_classes: integer ignore_thresh: float, the iou threshold whether to ignore object confidence loss Returns ------- loss: tensor, shape=(1,) ''' num_layers = len(anchors) // 3 # default setting yolo_outputs = args[:num_layers] y_true = args[num_layers:] anchor_mask = [[6, 7, 8], [3, 4, 5], [0, 1, 2] ] if num_layers == 3 else [[3, 4, 5], [1, 2, 3]] input_shape = K.cast( K.shape(yolo_outputs[0])[1:3] * 32, K.dtype(y_true[0])) grid_shapes = [ K.cast(K.shape(yolo_outputs[l])[1:3], K.dtype(y_true[0])) for l in range(num_layers) ] loss = 0 m = K.shape(yolo_outputs[0])[0] # batch size, tensor mf = K.cast(m, K.dtype(yolo_outputs[0])) for l in range(num_layers): object_mask = y_true[l][..., 4:5] true_class_probs = y_true[l][..., 5:] grid, raw_pred, pred_xy, pred_wh = yolo_head(yolo_outputs[l], anchors[anchor_mask[l]], num_classes, input_shape, calc_loss=True) pred_box = K.concatenate([pred_xy, pred_wh]) # Darknet raw box to calculate loss. raw_true_xy = y_true[l][..., :2] * grid_shapes[l][::-1] - grid raw_true_wh = K.log(y_true[l][..., 2:4] / anchors[anchor_mask[l]] * input_shape[::-1]) raw_true_wh = K.switch(object_mask, raw_true_wh, K.zeros_like(raw_true_wh)) # avoid log(0)=-inf box_loss_scale = 2 - y_true[l][..., 2:3] * y_true[l][..., 3:4] # Find ignore mask, iterate over each of batch. ignore_mask = tf.TensorArray(K.dtype(y_true[0]), size=1, dynamic_size=True) object_mask_bool = K.cast(object_mask, 'bool') def loop_body(b, ignore_mask): true_box = tf.boolean_mask(y_true[l][b, ..., 0:4], object_mask_bool[b, ..., 0]) iou = box_iou(pred_box[b], true_box) best_iou = K.max(iou, axis=-1) ignore_mask = ignore_mask.write( b, K.cast(best_iou < ignore_thresh, K.dtype(true_box))) return b + 1, ignore_mask _, ignore_mask = K.control_flow_ops.while_loop(lambda b, *args: b < m, loop_body, [0, ignore_mask]) ignore_mask = ignore_mask.stack() ignore_mask = K.expand_dims(ignore_mask, -1) # K.binary_crossentropy is helpful to avoid exp overflow. xy_loss = object_mask * box_loss_scale * K.binary_crossentropy( raw_true_xy, raw_pred[..., 0:2], from_logits=True) wh_loss = object_mask * box_loss_scale * 0.5 * K.square( raw_true_wh - raw_pred[..., 2:4]) confidence_loss = object_mask * K.binary_crossentropy(object_mask, raw_pred[...,4:5], from_logits=True)+ \ (1-object_mask) * K.binary_crossentropy(object_mask, raw_pred[...,4:5], from_logits=True) * ignore_mask class_loss = object_mask * K.binary_crossentropy( true_class_probs, raw_pred[..., 5:], from_logits=True) xy_loss = K.sum(xy_loss) / mf wh_loss = K.sum(wh_loss) / mf confidence_loss = K.sum(confidence_loss) / mf class_loss = K.sum(class_loss) / mf loss += xy_loss + wh_loss + confidence_loss + class_loss if print_loss: loss = tf.Print(loss, [ loss, xy_loss, wh_loss, confidence_loss, class_loss, K.sum(ignore_mask) ], message='loss: ') return loss
def weighted_bce(y_true, y_pred): weights = (y_true * class_weights[1]) + class_weights[0] * (1 - y_true) bce = K.binary_crossentropy(y_true, y_pred) weighted_bce = K.mean(bce * weights) return weighted_bce
def _mask(y_true, y_pred, iou_threshold=0.5, mask_size=(28, 28)): # split up the different predicted blobs boxes = y_pred[:, :, :4] masks = y_pred[:, :, 4:] # split up the different blobs annotations = y_true[:, :, :5] width = K.cast(y_true[0, 0, 5], dtype='int32') height = K.cast(y_true[0, 0, 6], dtype='int32') masks_target = y_true[:, :, 7:] # reshape the masks back to their original size masks_target = K.reshape(masks_target, (K.shape(masks_target)[0] * K.shape(masks_target)[1], height, width)) masks = K.reshape(masks, (K.shape(masks)[0] * K.shape(masks)[1], mask_size[0], mask_size[1], -1)) # batch size > 1 fix boxes = K.reshape(boxes, (-1, K.shape(boxes)[2])) annotations = K.reshape(annotations, (-1, K.shape(annotations)[2])) # compute overlap of boxes with annotations iou = overlap(boxes, annotations) argmax_overlaps_inds = K.argmax(iou, axis=1) max_iou = K.max(iou, axis=1) # filter those with IoU > 0.5 indices = tf.where(K.greater_equal(max_iou, iou_threshold)) boxes = tf.gather_nd(boxes, indices) masks = tf.gather_nd(masks, indices) argmax_overlaps_inds = tf.gather_nd(argmax_overlaps_inds, indices) argmax_overlaps_inds = K.cast(argmax_overlaps_inds, 'int32') labels = K.gather(annotations[:, 4], argmax_overlaps_inds) labels = K.cast(labels, 'int32') # make normalized boxes x1 = boxes[:, 0] y1 = boxes[:, 1] x2 = boxes[:, 2] y2 = boxes[:, 3] boxes = K.stack([ y1 / (K.cast(height, dtype=K.floatx()) - 1), x1 / (K.cast(width, dtype=K.floatx()) - 1), (y2 - 1) / (K.cast(height, dtype=K.floatx()) - 1), (x2 - 1) / (K.cast(width, dtype=K.floatx()) - 1), ], axis=1) # crop and resize masks_target # append a fake channel dimension masks_target = K.expand_dims(masks_target, axis=3) masks_target = tf.image.crop_and_resize(masks_target, boxes, argmax_overlaps_inds, mask_size) # remove fake channel dimension masks_target = masks_target[:, :, :, 0] # gather the predicted masks using the annotation label masks = tf.transpose(masks, (0, 3, 1, 2)) label_indices = K.stack([tf.range(K.shape(labels)[0]), labels], axis=1) masks = tf.gather_nd(masks, label_indices) # compute mask loss mask_loss = K.binary_crossentropy(masks_target, masks) normalizer = K.shape(masks)[0] * K.shape(masks)[1] * K.shape( masks)[2] normalizer = K.maximum(K.cast(normalizer, K.floatx()), 1) mask_loss = K.sum(mask_loss) / normalizer return mask_loss
def _yolo_loss(args, anchors, num_classes, ignore_thresh, print_loss, prefix): num_layers = len(anchors) // 3 # default setting yolo_outputs = args[:num_layers] y_true = args[num_layers:] anchor_mask = [[6, 7, 8], [3, 4, 5], [0, 1, 2] ] if num_layers == 3 else [[3, 4, 5], [1, 2, 3]] input_shape = K.cast( K.shape(yolo_outputs[0])[1:3] * 32, K.dtype(y_true[0])) grid_shapes = [ K.cast(K.shape(yolo_outputs[l])[1:3], K.dtype(y_true[0])) for l in range(num_layers) ] loss = 0 m = K.shape(yolo_outputs[0])[0] # batch size, tensor mf = K.cast(m, K.dtype(yolo_outputs[0])) for l in range(num_layers): object_mask = y_true[l][..., 4:5] true_class_probs = y_true[l][..., 5:] grid, raw_pred, pred_xy, pred_wh = yolo_head(yolo_outputs[l], anchors[anchor_mask[l]], num_classes, input_shape, calc_loss=True) pred_box = K.concatenate([pred_xy, pred_wh]) # Darknet raw box to calculate loss. raw_true_xy = y_true[l][..., :2] * grid_shapes[l][::-1] - grid raw_true_wh = K.log(y_true[l][..., 2:4] / anchors[anchor_mask[l]] * input_shape[::-1]) raw_true_wh = K.switch(object_mask, raw_true_wh, K.zeros_like(raw_true_wh)) # avoid log(0)=-inf box_loss_scale = 2 - y_true[l][..., 2:3] * y_true[l][..., 3:4] # Find ignore mask, iterate over each of batch. ignore_mask = tf.TensorArray(K.dtype(y_true[0]), size=1, dynamic_size=True) object_mask_bool = K.cast(object_mask, 'bool') def loop_body(b, ignore_mask): true_box = tf.boolean_mask(y_true[l][b, ..., 0:4], object_mask_bool[b, ..., 0]) iou = box_iou(pred_box[b], true_box) best_iou = K.max(iou, axis=-1) ignore_mask = ignore_mask.write( b, K.cast(best_iou < ignore_thresh, K.dtype(true_box))) return b + 1, ignore_mask from tensorflow.python.ops import control_flow_ops _, ignore_mask = control_flow_ops.while_loop(lambda b, *args: b < m, loop_body, [0, ignore_mask]) ignore_mask = ignore_mask.stack() ignore_mask = K.expand_dims(ignore_mask, -1) # K.binary_crossentropy is helpful to avoid exp overflow. xy_loss = object_mask * box_loss_scale * K.binary_crossentropy( raw_true_xy, raw_pred[..., 0:2], from_logits=True) wh_loss = object_mask * box_loss_scale * 0.5 * K.square( raw_true_wh - raw_pred[..., 2:4]) confidence_loss = object_mask * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) + \ (1 - object_mask) * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) * ignore_mask class_loss = object_mask * K.binary_crossentropy( true_class_probs, raw_pred[..., 5:7], from_logits=True) # # extend_true_class_probs = tf.concat( # [true_class_probs, 1 - tf.reduce_sum(true_class_probs, axis=4, keepdims=True)], axis=4) # # # class_center = tf.Variable("class_center") # multi_mask = 1 - ignore_mask # # multi_mask = 1 - ignore_mask / tf.norm(ignore_mask, 1, keepdims=True) # multi_class_loss = K.squeeze(multi_mask, 4) * tf.nn.softmax_cross_entropy_with_logits( # labels=extend_true_class_probs # , logits=raw_pred[..., 7:] # ) xy_loss = K.sum(xy_loss) / mf wh_loss = K.sum(wh_loss) / mf confidence_loss = K.sum(confidence_loss) / mf class_loss = K.sum(class_loss) / mf # multi_class_loss = K.sum(multi_class_loss) / mf # TODO loss += ( xy_loss + wh_loss + confidence_loss + class_loss # + multi_class_loss ) def format(label, tensors): content_data = zip(label.split(","), tensors) return content_data if print_loss: print_op = tf.print( *format( "[xy_loss, wh_loss, confidence_loss, class_loss, multi_class_loss]", [ xy_loss, wh_loss, confidence_loss, class_loss # , multi_class_loss ]), output_stream=sys.stdout) with tf.control_dependencies([print_op]): loss = loss * 1.0 losses = dict( format( "xy_loss, wh_loss, confidence_loss, class_loss, loss", [ xy_loss, wh_loss, confidence_loss, class_loss, loss # , multi_class_loss ])) return loss, losses