def conf_loss(self, y_true, y_pred): """ squeezeDet loss function for object detection and classification :param y_true: ground truth with shape [batchsize, #anchors, classes+8+labels] :param y_pred: :return: a tensor of the conf loss """ mc = self.config n_outputs = mc.CLASSES + 1 + 4 y_pred = y_pred[:, :, 0:n_outputs] y_pred = K.reshape( y_pred, (mc.BATCH_SIZE, mc.N_ANCHORS_HEIGHT, mc.N_ANCHORS_WIDTH, -1)) input_mask = y_true[:, :, 0] input_mask = K.expand_dims(input_mask, axis=-1) box_input = y_true[:, :, 1:5] num_objects = K.sum(input_mask) num_class_probs = mc.ANCHOR_PER_GRID * mc.CLASSES num_confidence_scores = mc.ANCHOR_PER_GRID + num_class_probs pred_conf = K.sigmoid( K.reshape(y_pred[:, :, :, num_class_probs:num_confidence_scores], [mc.BATCH_SIZE, mc.ANCHORS])) pred_box_delta = K.reshape(y_pred[:, :, :, num_confidence_scores:], [mc.BATCH_SIZE, mc.ANCHORS, 4]) det_boxes = utils.boxes_from_deltas(pred_box_delta, mc) unstacked_boxes_pred = [] unstacked_boxes_input = [] for i in range(4): unstacked_boxes_pred.append(det_boxes[:, :, i]) unstacked_boxes_input.append(box_input[:, :, i]) ious = utils.tensor_iou(utils.bbox_transform(unstacked_boxes_pred), utils.bbox_transform(unstacked_boxes_input), input_mask, mc) input_mask = K.reshape(input_mask, [mc.BATCH_SIZE, mc.ANCHORS]) conf_loss = K.mean( K.sum(K.square((ious - pred_conf)) * (input_mask * mc.LOSS_COEF_CONF_POS / num_objects + (1 - input_mask) * mc.LOSS_COEF_CONF_NEG / (mc.ANCHORS - num_objects)), axis=[1]), ) return conf_loss
def loss_without_regularization(self, y_true, y_pred): """ squeezeDet loss function for object detection and classification :param y_true: ground truth with shape [batchsize, #anchors, classes+8+labels] :param y_pred: :return: a tensor of the total loss """ mc = self.config input_mask = y_true[:, :, 0] input_mask = K.expand_dims(input_mask, axis=-1) box_input = y_true[:, :, 1:5] box_delta_input = y_true[:, :, 5:9] labels = y_true[:, :, 9:] num_objects = K.sum(input_mask) pred_class_probs, pred_conf, pred_box_delta = utils.slice_predictions( y_pred, mc) det_boxes = utils.boxes_from_deltas(pred_box_delta, mc) unstacked_boxes_pred = [] unstacked_boxes_input = [] for i in range(4): unstacked_boxes_pred.append(det_boxes[:, :, i]) unstacked_boxes_input.append(box_input[:, :, i]) ious = utils.tensor_iou(utils.bbox_transform(unstacked_boxes_pred), utils.bbox_transform(unstacked_boxes_input), input_mask, mc) class_loss = K.sum(labels * (-K.log(pred_class_probs + mc.EPSILON)) + (1 - labels) * (-K.log(1 - pred_class_probs + mc.EPSILON)) * input_mask * mc.LOSS_COEF_CLASS) / num_objects bbox_loss = (K.sum( mc.LOSS_COEF_BBOX * K.square(input_mask * (pred_box_delta - box_delta_input))) / num_objects) input_mask = K.reshape(input_mask, [mc.BATCH_SIZE, mc.ANCHORS]) conf_loss = K.mean( K.sum(K.square((ious - pred_conf)) * (input_mask * mc.LOSS_COEF_CONF_POS / num_objects + (1 - input_mask) * mc.LOSS_COEF_CONF_NEG / (mc.ANCHORS - num_objects)), axis=[1]), ) total_loss = class_loss + conf_loss + bbox_loss return total_loss
def loss_without_regularization(self, y_true, y_pred): """ squeezeDet loss function for object detection and classification :param y_true: ground truth with shape [batchsize, #anchors, classes+8+labels] :param y_pred: :return: a tensor of the total loss """ #handle for config mc = self.config #slice y_true input_mask = y_true[:, :, 0] input_mask = K.expand_dims(input_mask, axis=-1) box_input = y_true[:, :, 1:5] box_delta_input = y_true[:, :, 5:9] labels = y_true[:, :, 9:] #number of objects. Used to normalize bbox and classification loss num_objects = K.sum(input_mask) #before computing the losses we need to slice the network outputs pred_class_probs, pred_conf, pred_box_delta = utils.slice_predictions( y_pred, mc) #compute boxes det_boxes = utils.boxes_from_deltas(pred_box_delta, mc) #again unstack is not avaible in pure keras backend unstacked_boxes_pred = [] unstacked_boxes_input = [] for i in range(4): unstacked_boxes_pred.append(det_boxes[:, :, i]) unstacked_boxes_input.append(box_input[:, :, i]) #compute the ious ious = utils.tensor_iou(utils.bbox_transform(unstacked_boxes_pred), utils.bbox_transform(unstacked_boxes_input), input_mask, mc) # cross-entropy: q * -log(p) + (1-q) * -log(1-p) # add a small value into log to prevent blowing up #compute class loss class_loss = K.sum(labels * (-K.log(pred_class_probs + mc.EPSILON)) + (1 - labels) * (-K.log(1 - pred_class_probs + mc.EPSILON)) * input_mask * mc.LOSS_COEF_CLASS) / num_objects #bounding box loss bbox_loss = (K.sum( mc.LOSS_COEF_BBOX * K.square(input_mask * (pred_box_delta - box_delta_input))) / num_objects) #reshape input for correct broadcasting input_mask = K.reshape(input_mask, [mc.BATCH_SIZE, mc.ANCHORS]) #confidence score loss conf_loss = K.mean( K.sum(K.square((ious - pred_conf)) * (input_mask * mc.LOSS_COEF_CONF_POS / num_objects + (1 - input_mask) * mc.LOSS_COEF_CONF_NEG / (mc.ANCHORS - num_objects)), axis=[1]), ) # add above losses total_loss = class_loss + conf_loss + bbox_loss return total_loss
def conf_loss(self, y_true, y_pred): """ squeezeDet loss function for object detection and classification :param y_true: ground truth with shape [batchsize, #anchors, classes+8+labels] :param y_pred: :return: a tensor of the conf loss """ #handle for config mc = self.config #calculate non padded entries n_outputs = mc.CLASSES + 1 + 4 #slice and reshape network output y_pred = y_pred[:, :, 0:n_outputs] y_pred = K.reshape( y_pred, (mc.BATCH_SIZE, mc.N_ANCHORS_HEIGHT, mc.N_ANCHORS_WIDTH, -1)) #slice y_true input_mask = y_true[:, :, 0] input_mask = K.expand_dims(input_mask, axis=-1) box_input = y_true[:, :, 1:5] #number of objects. Used to normalize bbox and classification loss num_objects = K.sum(input_mask) #before computing the losses we need to slice the network outputs #number of class probabilities, n classes for each anchor num_class_probs = mc.ANCHOR_PER_GRID * mc.CLASSES #number of confidence scores, one for each anchor + class probs num_confidence_scores = mc.ANCHOR_PER_GRID + num_class_probs #slice the confidence scores and put them trough a sigmoid for probabilities pred_conf = K.sigmoid( K.reshape(y_pred[:, :, :, num_class_probs:num_confidence_scores], [mc.BATCH_SIZE, mc.ANCHORS])) #slice remaining bounding box_deltas pred_box_delta = K.reshape(y_pred[:, :, :, num_confidence_scores:], [mc.BATCH_SIZE, mc.ANCHORS, 4]) #compute boxes det_boxes = utils.boxes_from_deltas(pred_box_delta, mc) #again unstack is not avaible in pure keras backend unstacked_boxes_pred = [] unstacked_boxes_input = [] for i in range(4): unstacked_boxes_pred.append(det_boxes[:, :, i]) unstacked_boxes_input.append(box_input[:, :, i]) #compute the ious ious = utils.tensor_iou(utils.bbox_transform(unstacked_boxes_pred), utils.bbox_transform(unstacked_boxes_input), input_mask, mc) #reshape input for correct broadcasting input_mask = K.reshape(input_mask, [mc.BATCH_SIZE, mc.ANCHORS]) #confidence score loss conf_loss = K.mean( K.sum(K.square((ious - pred_conf)) * (input_mask * mc.LOSS_COEF_CONF_POS / num_objects + (1 - input_mask) * mc.LOSS_COEF_CONF_NEG / (mc.ANCHORS - num_objects)), axis=[1]), ) return conf_loss