Skip to content

Module kerod.layers.anchors

None

None

View Source
import tensorflow as tf

from kerod.core.constants import MAX_IMAGE_DIMENSION

from kerod.utils.documentation import remove_unwanted_doc

__pdoc__ = {}

def generate_anchors(stride: int, scales: tf.Tensor, ratios: tf.Tensor, max_size: int):

    """Will generate a determistic grid based on the input images dimension.

    The anchors will be generated once and for all on the biggest possible image.

    At each forward according to the shape of the tensor we can extract the corresponding anchors.

    Arguments:

        stride: Downscaling ratio compared to the original image. At stride 16 your original

            image will be 16 times bigger than your actual tensor

        scales: The scale of the anchors e.g: 8, 16, 32

        ratios: The ratios are the different shapes that you want to apply on your anchors.

            e.g: (0.5, 1, 2)

        max_size: Maximum size of the input image. The anchors will computed once and for all.

    Returns:

        A tensor of shape [num_scales * num_ratios * height * width, 4].

        The anchors have the format [y_min, x_min, y_max, x_max].

    """

    ratios, scales = tf.meshgrid(ratios, scales)

    scales = tf.reshape(scales, [-1])

    ratios = tf.reshape(ratios, [-1])

    ratio_sqrts = tf.sqrt(ratios)

    widths = scales / ratio_sqrts

    heights = ratios * widths

    base_anchors = tf.stack([-widths, -heights, widths, heights], axis=-1) * 0.5

    max_stride = tf.math.ceil(max_size / stride)

    y_centers = tf.cast(tf.range(max_stride), dtype=scales.dtype) * stride

    x_centers = tf.cast(tf.range(max_stride), dtype=scales.dtype) * stride

    x_centers, y_centers = tf.meshgrid(x_centers, y_centers)

    shifts = tf.stack([x_centers, y_centers, x_centers, y_centers], axis=-1)

    anchors = tf.expand_dims(base_anchors, 0) + tf.expand_dims(shifts, 2)

    return tf.gather(anchors, [1, 0, 3, 2], axis=-1)

class Anchors(tf.keras.layers.Layer):

    """Will generate a determistic grid and store it in memory to avoid recompute it at each run.

     At each forward according to the shape of the tensor we can extract the corresponding anchors.

    Arguments:

        stride: Downscaling ratio compared to the original image. At stride 16 your original

            image will be 16 times bigger than your actual tensor

        scales: The scale of the anchors e.g: 8, 16, 32

        ratios: The ratios are the different shapes that you want to apply on your anchors.

            e.g: (0.5, 1, 2)

        max_size: Maximum size of the input image. The anchors will computed once and for all.

    Call arguments:

        inputs: A tensor of shape [batch_size, height, widht, channel]

    Call returns:

        tf.Tensor: A tensor of shape [num_scales * num_ratios * height * width, 4].

            The anchors have the format [y_min, x_min, y_max, x_max].

    """

    def __init__(self, stride, scales, ratios, **kwargs):

        super().__init__(**kwargs)

        self._stride = stride

        self._scales = scales

        self._ratios = ratios

        self._anchors = generate_anchors(stride,

                                         tf.constant([scales], self._compute_dtype),

                                         tf.constant(ratios, self._compute_dtype),

                                         max_size=MAX_IMAGE_DIMENSION)

    def call(self, inputs):

        """Return anchors based on the shape of the input tensors

        Arguments:

            inputs: A tensor of shape [batch_size, height, widht, channel]

        Returns:

            tf.Tensor: A tensor of shape [num_scales * num_ratios * height * width, 4].

                The anchors have the format [y_min, x_min, y_max, x_max].

        """

        shape = tf.shape(inputs)

        height, width = shape[1], shape[2]

        anchors = self._anchors[:height, :width]

        return tf.reshape(anchors, (-1, 4))

    def get_config(self):

        config = super().get_config()

        config['stride'] = self._stride

        config['scales'] = self._scales

        config['ratios'] = self._ratios

        return config

remove_unwanted_doc(Anchors, __pdoc__)

Variables

MAX_IMAGE_DIMENSION

Functions

generate_anchors

def generate_anchors(
    stride: int,
    scales: tensorflow.python.framework.ops.Tensor,
    ratios: tensorflow.python.framework.ops.Tensor,
    max_size: int
)

Will generate a determistic grid based on the input images dimension.

The anchors will be generated once and for all on the biggest possible image. At each forward according to the shape of the tensor we can extract the corresponding anchors.

Parameters:

Name Description
stride Downscaling ratio compared to the original image. At stride 16 your original
image will be 16 times bigger than your actual tensor
scales The scale of the anchors e.g: 8, 16, 32
ratios The ratios are the different shapes that you want to apply on your anchors.
e.g: (0.5, 1, 2)
max_size Maximum size of the input image. The anchors will computed once and for all.

Returns:

Type Description
None A tensor of shape [num_scales * num_ratios * height * width, 4].
The anchors have the format [y_min, x_min, y_max, x_max].
View Source
def generate_anchors(stride: int, scales: tf.Tensor, ratios: tf.Tensor, max_size: int):

    """Will generate a determistic grid based on the input images dimension.

    The anchors will be generated once and for all on the biggest possible image.

    At each forward according to the shape of the tensor we can extract the corresponding anchors.

    Arguments:

        stride: Downscaling ratio compared to the original image. At stride 16 your original

            image will be 16 times bigger than your actual tensor

        scales: The scale of the anchors e.g: 8, 16, 32

        ratios: The ratios are the different shapes that you want to apply on your anchors.

            e.g: (0.5, 1, 2)

        max_size: Maximum size of the input image. The anchors will computed once and for all.

    Returns:

        A tensor of shape [num_scales * num_ratios * height * width, 4].

        The anchors have the format [y_min, x_min, y_max, x_max].

    """

    ratios, scales = tf.meshgrid(ratios, scales)

    scales = tf.reshape(scales, [-1])

    ratios = tf.reshape(ratios, [-1])

    ratio_sqrts = tf.sqrt(ratios)

    widths = scales / ratio_sqrts

    heights = ratios * widths

    base_anchors = tf.stack([-widths, -heights, widths, heights], axis=-1) * 0.5

    max_stride = tf.math.ceil(max_size / stride)

    y_centers = tf.cast(tf.range(max_stride), dtype=scales.dtype) * stride

    x_centers = tf.cast(tf.range(max_stride), dtype=scales.dtype) * stride

    x_centers, y_centers = tf.meshgrid(x_centers, y_centers)

    shifts = tf.stack([x_centers, y_centers, x_centers, y_centers], axis=-1)

    anchors = tf.expand_dims(base_anchors, 0) + tf.expand_dims(shifts, 2)

    return tf.gather(anchors, [1, 0, 3, 2], axis=-1)

Classes

Anchors

class Anchors(
    stride,
    scales,
    ratios,
    **kwargs
)

At each forward according to the shape of the tensor we can extract the corresponding anchors.

Arguments

Name Description
stride Downscaling ratio compared to the original image. At stride 16 your original
image will be 16 times bigger than your actual tensor
scales The scale of the anchors e.g: 8, 16, 32
ratios The ratios are the different shapes that you want to apply on your anchors.
e.g: (0.5, 1, 2)
max_size Maximum size of the input image. The anchors will computed once and for all.

Call arguments

Name Description
inputs A tensor of shape [batch_size, height, widht, channel]

Call returns

Type Description
tf.Tensor A tensor of shape [num_scales * num_ratios * height * width, 4].
The anchors have the format [y_min, x_min, y_max, x_max].

Ancestors (in MRO)

  • tensorflow.python.keras.engine.base_layer.Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • tensorflow.python.keras.utils.version_utils.LayerVersionSelector

Methods

call

def call(
    self,
    inputs
)

Return anchors based on the shape of the input tensors

Parameters:

Name Description
inputs A tensor of shape [batch_size, height, widht, channel]

Returns:

Type Description
tf.Tensor A tensor of shape [num_scales * num_ratios * height * width, 4].
The anchors have the format [y_min, x_min, y_max, x_max].
View Source
    def call(self, inputs):

        """Return anchors based on the shape of the input tensors

        Arguments:

            inputs: A tensor of shape [batch_size, height, widht, channel]

        Returns:

            tf.Tensor: A tensor of shape [num_scales * num_ratios * height * width, 4].

                The anchors have the format [y_min, x_min, y_max, x_max].

        """

        shape = tf.shape(inputs)

        height, width = shape[1], shape[2]

        anchors = self._anchors[:height, :width]

        return tf.reshape(anchors, (-1, 4))