|
|
|
|
@ -20,7 +20,9 @@ from .layer_function_generator import autodoc, templatedoc
|
|
|
|
|
from ..layer_helper import LayerHelper
|
|
|
|
|
from . import tensor
|
|
|
|
|
from . import nn
|
|
|
|
|
from . import ops
|
|
|
|
|
import math
|
|
|
|
|
import numpy
|
|
|
|
|
from functools import reduce
|
|
|
|
|
|
|
|
|
|
__all__ = [
|
|
|
|
|
@ -264,10 +266,11 @@ def detection_output(loc,
|
|
|
|
|
prior_box_var=prior_box_var,
|
|
|
|
|
target_box=loc,
|
|
|
|
|
code_type='decode_center_size')
|
|
|
|
|
old_shape = scores.shape
|
|
|
|
|
scores = nn.reshape(x=scores, shape=(-1, old_shape[-1]))
|
|
|
|
|
compile_shape = scores.shape
|
|
|
|
|
run_shape = ops.shape(scores)
|
|
|
|
|
scores = nn.flatten(x=scores, axis=2)
|
|
|
|
|
scores = nn.softmax(input=scores)
|
|
|
|
|
scores = nn.reshape(x=scores, shape=old_shape)
|
|
|
|
|
scores = nn.reshape(x=scores, shape=compile_shape, actual_shape=run_shape)
|
|
|
|
|
scores = nn.transpose(scores, perm=[0, 2, 1])
|
|
|
|
|
scores.stop_gradient = True
|
|
|
|
|
nmsed_outs = helper.create_tmp_variable(dtype=decoded_box.dtype)
|
|
|
|
|
@ -677,9 +680,10 @@ def ssd_loss(location,
|
|
|
|
|
raise ValueError("Only support mining_type == max_negative now.")
|
|
|
|
|
|
|
|
|
|
num, num_prior, num_class = confidence.shape
|
|
|
|
|
conf_shape = ops.shape(confidence)
|
|
|
|
|
|
|
|
|
|
def __reshape_to_2d(var):
|
|
|
|
|
return nn.reshape(x=var, shape=[-1, var.shape[-1]])
|
|
|
|
|
return nn.flatten(x=var, axis=2)
|
|
|
|
|
|
|
|
|
|
# 1. Find matched boundding box by prior box.
|
|
|
|
|
# 1.1 Compute IOU similarity between ground-truth boxes and prior boxes.
|
|
|
|
|
@ -690,7 +694,8 @@ def ssd_loss(location,
|
|
|
|
|
|
|
|
|
|
# 2. Compute confidence for mining hard examples
|
|
|
|
|
# 2.1. Get the target label based on matched indices
|
|
|
|
|
gt_label = nn.reshape(x=gt_label, shape=gt_label.shape + (1, ))
|
|
|
|
|
gt_label = nn.reshape(
|
|
|
|
|
x=gt_label, shape=(len(gt_label.shape) - 1) * (0, ) + (-1, 1))
|
|
|
|
|
gt_label.stop_gradient = True
|
|
|
|
|
target_label, _ = target_assign(
|
|
|
|
|
gt_label, matched_indices, mismatch_value=background_label)
|
|
|
|
|
@ -701,9 +706,12 @@ def ssd_loss(location,
|
|
|
|
|
target_label = __reshape_to_2d(target_label)
|
|
|
|
|
target_label.stop_gradient = True
|
|
|
|
|
conf_loss = nn.softmax_with_cross_entropy(confidence, target_label)
|
|
|
|
|
|
|
|
|
|
# 3. Mining hard examples
|
|
|
|
|
conf_loss = nn.reshape(x=conf_loss, shape=(num, num_prior))
|
|
|
|
|
conf_loss = nn.reshape(
|
|
|
|
|
x=conf_loss,
|
|
|
|
|
shape=(num, num_prior),
|
|
|
|
|
actual_shape=ops.slice(
|
|
|
|
|
conf_shape, axes=[0], starts=[0], ends=[2]))
|
|
|
|
|
conf_loss.stop_gradient = True
|
|
|
|
|
neg_indices = helper.create_tmp_variable(dtype='int32')
|
|
|
|
|
dtype = matched_indices.dtype
|
|
|
|
|
@ -772,7 +780,11 @@ def ssd_loss(location,
|
|
|
|
|
# 5.3 Compute overall weighted loss.
|
|
|
|
|
loss = conf_loss_weight * conf_loss + loc_loss_weight * loc_loss
|
|
|
|
|
# reshape to [N, Np], N is the batch size and Np is the prior box number.
|
|
|
|
|
loss = nn.reshape(x=loss, shape=[-1, num_prior])
|
|
|
|
|
loss = nn.reshape(
|
|
|
|
|
x=loss,
|
|
|
|
|
shape=(num, num_prior),
|
|
|
|
|
actual_shape=ops.slice(
|
|
|
|
|
conf_shape, axes=[0], starts=[0], ends=[2]))
|
|
|
|
|
loss = nn.reduce_sum(loss, dim=1, keep_dim=True)
|
|
|
|
|
if normalize:
|
|
|
|
|
normalizer = nn.reduce_sum(target_loc_weight)
|
|
|
|
|
@ -1005,13 +1017,7 @@ def multi_box_head(inputs,
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def _reshape_with_axis_(input, axis=1):
|
|
|
|
|
if not (axis > 0 and axis < len(input.shape)):
|
|
|
|
|
raise ValueError("The axis should be smaller than "
|
|
|
|
|
"the arity of input and bigger than 0.")
|
|
|
|
|
new_shape = [
|
|
|
|
|
-1, reduce(lambda x, y: x * y, input.shape[axis:len(input.shape)])
|
|
|
|
|
]
|
|
|
|
|
out = nn.reshape(x=input, shape=new_shape)
|
|
|
|
|
out = nn.flatten(x=input, axis=axis)
|
|
|
|
|
return out
|
|
|
|
|
|
|
|
|
|
def _is_list_or_tuple_(data):
|
|
|
|
|
@ -1101,11 +1107,13 @@ def multi_box_head(inputs,
|
|
|
|
|
stride=stride)
|
|
|
|
|
|
|
|
|
|
mbox_loc = nn.transpose(mbox_loc, perm=[0, 2, 3, 1])
|
|
|
|
|
new_shape = [
|
|
|
|
|
compile_shape = [
|
|
|
|
|
mbox_loc.shape[0],
|
|
|
|
|
mbox_loc.shape[1] * mbox_loc.shape[2] * mbox_loc.shape[3] / 4, 4
|
|
|
|
|
]
|
|
|
|
|
mbox_loc_flatten = nn.reshape(mbox_loc, shape=new_shape)
|
|
|
|
|
run_shape = tensor.assign(numpy.array([0, -1, 4]).astype("int32"))
|
|
|
|
|
mbox_loc_flatten = nn.reshape(
|
|
|
|
|
mbox_loc, shape=compile_shape, actual_shape=run_shape)
|
|
|
|
|
mbox_locs.append(mbox_loc_flatten)
|
|
|
|
|
|
|
|
|
|
# get conf
|
|
|
|
|
@ -1117,11 +1125,15 @@ def multi_box_head(inputs,
|
|
|
|
|
padding=pad,
|
|
|
|
|
stride=stride)
|
|
|
|
|
conf_loc = nn.transpose(conf_loc, perm=[0, 2, 3, 1])
|
|
|
|
|
new_shape = [
|
|
|
|
|
new_shape = [0, -1, num_classes]
|
|
|
|
|
compile_shape = [
|
|
|
|
|
conf_loc.shape[0], conf_loc.shape[1] * conf_loc.shape[2] *
|
|
|
|
|
conf_loc.shape[3] / num_classes, num_classes
|
|
|
|
|
]
|
|
|
|
|
conf_loc_flatten = nn.reshape(conf_loc, shape=new_shape)
|
|
|
|
|
run_shape = tensor.assign(
|
|
|
|
|
numpy.array([0, -1, num_classes]).astype("int32"))
|
|
|
|
|
conf_loc_flatten = nn.reshape(
|
|
|
|
|
conf_loc, shape=compile_shape, actual_shape=run_shape)
|
|
|
|
|
mbox_confs.append(conf_loc_flatten)
|
|
|
|
|
|
|
|
|
|
if len(box_results) == 1:
|
|
|
|
|
|