# Path: utils/custom_layers.py
# def abs_smooth(x):
# def abs_smooth_2(x):
# def l2_normalization(
#         inputs,
#         scaling=False,
#         scale_initializer=init_ops.ones_initializer(),
#         reuse=None,
#         variables_collections=None,
#         outputs_collections=None,
#         data_format='NHWC',
#         trainable=True,
#         scope=None):
# def pad2d(inputs,
#           pad=(0, 0),
#           mode='CONSTANT',
#           data_format='NHWC',
#           trainable=True,
#           scope=None):
# def channel_to_last(inputs,
#                     data_format='NHWC',
#                     scope=None):
# def dropout_with_noise(net):
# 
# Path: ssd/ssd_utils.py
# def tensor_shape(x, rank=3):
# def multibox_layer(inputs, num_classes, anchor_sizes, anchor_ratios, normalization):
# def compute_jaccard(gt_bboxes, anchors):
# def anchor_one_layer(img_shape, feat_shape, sizes, ratios, step, offset=0.5, dtype=np.float32):
# def arg_scope(weight_decay=0.0005, data_format='NHWC'):
# def bboxes_encode_layer(labels,
#                         bboxes,
#                         anchors_layer,
#                         num_classes,
#                         prior_scaling=[0.1, 0.1, 0.2, 0.2],
#                         dtype=tf.float32):
#     def jaccard_with_anchors(bbox):
#     def intersection_with_anchors(bbox):
#     def condition(i, feat_labels, feat_scores,
#                   feat_ymin, feat_xmin, feat_ymax, feat_xmax):
#     def body(i, feat_labels, feat_scores,
#              feat_ymin, feat_xmin, feat_ymax, feat_xmax):
# def _bboxes_decode_layer(feat_localizations,
#                                anchors_layer,
#                                prior_scaling=[0.1, 0.1, 0.2, 0.2]):
# def bboxes_decode(feat_localizations,
#                          anchors,
#                          prior_scaling=[0.1, 0.1, 0.2, 0.2],
#                          scope='ssd_bboxes_decode'):
# def _match_no_miss(gt_anchor_labels, gt_anchor_bboxes, gt_anchor_scores, jaccard, gt_labels, gt_bboxes, num_anchors):
#     def cond(i, gt_anchors_labels, gt_anchors_bboxes, gt_anchors_scores):
#     def body(i, gt_anchors_labels, gt_anchors_bboxes, gt_anchors_scores):
# def match_no_labels(gt_anchor_labels, gt_anchor_bboxes, gt_anchor_scores, jaccard, matching_threshold,
#                       gt_labels, gt_bboxes, num_anchors):
# def match_with_labels(gt_anchor_labels, gt_anchor_bboxes, gt_anchor_scores, jaccard, matching_threshold,
#                         gt_labels, gt_bboxes, num_anchors):
# def _bboxes_select_layer(predictions_layer, localizations_layer,
#                         select_threshold=None,
#                         num_classes=21,
#                         ignore_class=0,
#                         scope=None):
# def bboxes_select(predictions_net, localizations_net,
#                   select_threshold=None,
#                   num_classes=21,
#                   ignore_class=0,
#                   scope=None):
# 
# Path: ssd/ssd_blocks.py
# def ssd300(net, end_points):
# def ssd512(net, end_points):
# 
# Path: nets/nets_factory.py
# def get_network_fn(name, num_classes, weight_decay=0.0, is_training=True):
#     def network_fn(images):
# def get_base_network_fn(name, weight_decay=0.0):
#     def base_network_fn(images):


import tensorflow as tf
import numpy as np
import math
import tf_extended as tfe
from tensorflow.python.ops import array_ops
from utils import custom_layers
from ssd import ssd_utils
from ssd import ssd_blocks
from nets import nets_factory as nf


slim = tf.contrib.slim


class SSDModel:
    """
    Implementation of the SSD network.
    """

    # ============================= PUBLIC METHODS ============================== #
    def __init__(self, feature_extractor, model_name, weight_decay, is_training=True):
        """
        Initialize an instance of the SSDModel
        :param feature_extractor: name of the feature extractor (backbone)
        :param model_name: name of the SSD model to use: ssd300 or ssd500
        """
        if feature_extractor not in nf.base_networks_map:
            raise ValueError('Feature extractor %s unknown.' % feature_extractor)
        if model_name not in ['ssd300', 'ssd512']:
            raise ValueError('Model %s unknown. Choose either ssd300 or ssd512.' % model_name)

        if model_name == 'ssd300':
            self.params = ssd_blocks.ssd300_params
            self._ssd_blocks = ssd_blocks.ssd300
        else:
            self.params = ssd_blocks.ssd512_params
            self._ssd_blocks = ssd_blocks.ssd512

        self.feature_extractor = feature_extractor

# Path: utils/custom_layers.py
# def abs_smooth(x):
# def abs_smooth_2(x):
# def l2_normalization(
#         inputs,
#         scaling=False,
#         scale_initializer=init_ops.ones_initializer(),
#         reuse=None,
#         variables_collections=None,
#         outputs_collections=None,
#         data_format='NHWC',
#         trainable=True,
#         scope=None):
# def pad2d(inputs,
#           pad=(0, 0),
#           mode='CONSTANT',
#           data_format='NHWC',
#           trainable=True,
#           scope=None):
# def channel_to_last(inputs,
#                     data_format='NHWC',
#                     scope=None):
# def dropout_with_noise(net):
# 
# Path: ssd/ssd_utils.py
# def tensor_shape(x, rank=3):
# def multibox_layer(inputs, num_classes, anchor_sizes, anchor_ratios, normalization):
# def compute_jaccard(gt_bboxes, anchors):
# def anchor_one_layer(img_shape, feat_shape, sizes, ratios, step, offset=0.5, dtype=np.float32):
# def arg_scope(weight_decay=0.0005, data_format='NHWC'):
# def bboxes_encode_layer(labels,
#                         bboxes,
#                         anchors_layer,
#                         num_classes,
#                         prior_scaling=[0.1, 0.1, 0.2, 0.2],
#                         dtype=tf.float32):
#     def jaccard_with_anchors(bbox):
#     def intersection_with_anchors(bbox):
#     def condition(i, feat_labels, feat_scores,
#                   feat_ymin, feat_xmin, feat_ymax, feat_xmax):
#     def body(i, feat_labels, feat_scores,
#              feat_ymin, feat_xmin, feat_ymax, feat_xmax):
# def _bboxes_decode_layer(feat_localizations,
#                                anchors_layer,
#                                prior_scaling=[0.1, 0.1, 0.2, 0.2]):
# def bboxes_decode(feat_localizations,
#                          anchors,
#                          prior_scaling=[0.1, 0.1, 0.2, 0.2],
#                          scope='ssd_bboxes_decode'):
# def _match_no_miss(gt_anchor_labels, gt_anchor_bboxes, gt_anchor_scores, jaccard, gt_labels, gt_bboxes, num_anchors):
#     def cond(i, gt_anchors_labels, gt_anchors_bboxes, gt_anchors_scores):
#     def body(i, gt_anchors_labels, gt_anchors_bboxes, gt_anchors_scores):
# def match_no_labels(gt_anchor_labels, gt_anchor_bboxes, gt_anchor_scores, jaccard, matching_threshold,
#                       gt_labels, gt_bboxes, num_anchors):
# def match_with_labels(gt_anchor_labels, gt_anchor_bboxes, gt_anchor_scores, jaccard, matching_threshold,
#                         gt_labels, gt_bboxes, num_anchors):
# def _bboxes_select_layer(predictions_layer, localizations_layer,
#                         select_threshold=None,
#                         num_classes=21,
#                         ignore_class=0,
#                         scope=None):
# def bboxes_select(predictions_net, localizations_net,
#                   select_threshold=None,
#                   num_classes=21,
#                   ignore_class=0,
#                   scope=None):
# 
# Path: ssd/ssd_blocks.py
# def ssd300(net, end_points):
# def ssd512(net, end_points):
# 
# Path: nets/nets_factory.py
# def get_network_fn(name, num_classes, weight_decay=0.0, is_training=True):
#     def network_fn(images):
# def get_base_network_fn(name, weight_decay=0.0):
#     def base_network_fn(images):


# Path: ssd/ssdmodel.py
import tensorflow as tf
import numpy as np
import math
import tf_extended as tfe
from tensorflow.python.ops import array_ops
from utils import custom_layers
from ssd import ssd_utils
from ssd import ssd_blocks
from nets import nets_factory as nf



slim = tf.contrib.slim


class SSDModel:
    """
    Implementation of the SSD network.
    """

    # ============================= PUBLIC METHODS ============================== #
    def __init__(self, feature_extractor, model_name, weight_decay, is_training=True):
        """
        Initialize an instance of the SSDModel
        :param feature_extractor: name of the feature extractor (backbone)
        :param model_name: name of the SSD model to use: ssd300 or ssd500
        """
        if feature_extractor not in nf.base_networks_map:
            raise ValueError('Feature extractor %s unknown.' % feature_extractor)
        if model_name not in ['ssd300', 'ssd512']:
            raise ValueError('Model %s unknown. Choose either ssd300 or ssd512.' % model_name)

        if model_name == 'ssd300':
            self.params = ssd_blocks.ssd300_params
            self._ssd_blocks = ssd_blocks.ssd300
        else:
            self.params = ssd_blocks.ssd512_params
            self._ssd_blocks = ssd_blocks.ssd512

        self.feature_extractor = feature_extractor

        self._feature_extractor = nf.get_base_network_fn(feature_extractor, weight_decay=weight_decay)