:py:mod:`box_embeddings.parameterizations.box_tensor` ===================================================== .. py:module:: box_embeddings.parameterizations.box_tensor .. autoapi-nested-parse:: Base class for creating a wrapper around the torch.Tensor to represent boxes A BoxTensor contains single tensor which represents single or multiple boxes. note: Have to use composition instead of inheritance because currently it is not safe to interit from :class:`torch.Tensor` because creating an instance of such a class will always make it a leaf node. This works for :class:`torch.nn.Parameter` but won't work for a general BoxTensor. This most likely will change in the future as pytorch starts offical support for inheriting from a Tensor. Give this point some thought when this happens. Module Contents --------------- .. py:data:: logger .. py:data:: TBoxTensor .. py:class:: BoxTensor(data: Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]], *args: Any, **kwargs: Any) Bases: :py:obj:`object` Base class defining the interface for BoxTensor. .. py:attribute:: w2z_ratio :annotation: :int = 2 .. py:method:: reinit(self, data: Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]) -> None Constructor. :param data: Tensor of shape (..., zZ, num_dims). Here, zZ=2, where the 0th dim is for bottom left corner and 1st dim is for top right corner of the box Returns: None :raises ValueError: If new shape is different than old shape .. py:method:: kwargs(self) -> Dict :property: Configuration attribute values :returns: Dict .. py:method:: args(self) -> Tuple :property: Configuration attribute as Tuple :returns: Tuple .. py:method:: z(self) -> torch.Tensor :property: Lower left coordinate as Tensor :returns: lower left corner :rtype: Tensor .. py:method:: Z(self) -> torch.Tensor :property: Top right coordinate as Tensor :returns: top right corner :rtype: Tensor .. py:method:: centre(self) -> torch.Tensor :property: Centre coordinate as Tensor :returns: Center :rtype: Tensor .. py:method:: check_if_valid_zZ(cls: Type[TBoxTensor], z: torch.Tensor, Z: torch.Tensor) -> None :classmethod: Check of (z,Z) form a valid box. If your child class parameterization bounds the boxes to some universe box then this is the right place to check that. :param z: Lower left coordinate of shape (..., hidden_dims) :param Z: Top right coordinate of shape (..., hidden_dims) :raises ValueError: If `z` and `Z` do not have the same shape :raises ValueError: If `Z` < `z` .. py:method:: W(cls: Type[TBoxTensor], z: torch.Tensor, Z: torch.Tensor, *args: Any, **kwargs: Any) -> torch.Tensor :classmethod: Given (z,Z), it returns one set of valid box weights W, such that Box(W) = (z,Z). For the base `BoxTensor` class, we just return z and Z stacked together. If you implement any new parameterization for boxes. You most likely need to override this method. :param z: Lower left coordinate of shape (..., hidden_dims) :param Z: Top right coordinate of shape (..., hidden_dims) :param \*args: TODO :param \*\*kwargs: TODO :returns: Parameters of the box. In base class implementation, this will have shape (..., 2, hidden_dims). :rtype: Tensor .. py:method:: zZ_to_embedding(cls, z: torch.Tensor, Z: torch.Tensor, *args: Any, **kwargs: Any) -> torch.Tensor :classmethod: collapse the last two dimensions :param z: Lower left coordinate of shape (..., hidden_dims) :param Z: Top right coordinate of shape (..., hidden_dims) :param \*args: TODO :param \*\*kwargs: TODO :returns: A Box tensor with the last two dimensions z, Z collapsed .. py:method:: from_zZ(cls: Type[TBoxTensor], z: torch.Tensor, Z: torch.Tensor, *args: Any, **kwargs: Any) -> TBoxTensor :classmethod: Creates a box for the given min-max coordinates (z,Z). In the this base implementation we do this by stacking z and Z along -2 dim to form W. :param z: lower left :param Z: top right :param \*args: extra arguments for child class :param \*\*kwargs: extra arguments for child class :returns: A BoxTensor .. py:method:: like_this_from_zZ(self, z: torch.Tensor, Z: torch.Tensor) -> BoxTensor Creates a box for the given min-max coordinates (z,Z). This is similar to the class method :method:`from_zZ`, but uses the attributes on self and not external args, kwargs. For the base class, since we do not have extra attributes, we simply call from_zZ. :param z: lower left :param Z: top right :returns: A BoxTensor .. py:method:: from_vector(cls, vector: torch.Tensor, *args: Any, **kwargs: Any) -> TBoxTensor :classmethod: Creates a box for a vector. In this base implementation the vector is split into two pieces and these are used as z,Z. :param vector: tensor :param \*args: extra arguments for child class :param \*\*kwargs: extra arguments for child class :returns: A BoxTensor :raises ValueError: if last dimension is not even .. py:method:: box_shape(self) -> Tuple :property: Shape of z, Z and center. :returns: Shape of z, Z and center. .. note:: This is *not* the shape of the `data` attribute. .. py:method:: broadcast(self, target_shape: Tuple) -> None Broadcasts the internal data member in-place such that z and Z return tensors that can be automatically broadcasted to perform arithmetic operations with shape `target_shape`. Ex: target_shape = (4,5,10) 1. self.box_shape = (10,) => (1,1,10) 2. self.box_shape = (3,) => ValueError 3. self.box_shape = (4,10) => (4,1,10) 4. self.box_shape = (4,2,10) => ValueError 5. self.box_shape = (5,10) => (1,5,10) .. note:: This operation will not result in self.z, self.Z and self.center returning tensor of shape `target_shape` but it will result in return a tensor which is arithmetic compatible with `target_shape`. :param target_shape: Shape of the broadcast target. Usually will be the shape of the tensor you wish to use z, Z with. For instance, if you wish to add self box's center [shape=(batch, hidden_dim)] with other box whose center's shape is (batch, extra_dim, hidden_dim), then this function will reshape the data such that the resulting center has shape (batch, 1, hidden_dim). :raises ValueError: If bad target ..todo:: Add an extra argument `repeat` which tell the function to repeat values till target is satisfied. This is needed for gumbel_intersection, where the broadcasted tensors need to be stacked. .. py:method:: box_reshape(self, target_shape: Tuple) -> BoxTensor Reshape the z,Z and center. Ex: 1. self.box_shape = (5,10), target_shape = (-1,10), creates box_shape (5,10) 2. self.box_shape = (5,4,10), target_shape = (-1,10), creates box_shape (20,10) 4. self.box_shape = (20,10), target_shape = (10,2,10), creates box_shape (10,2,10) 3. self.box_shape = (5,), target_shape = (-1,10), raises RuntimeError 5. self.box_shape = (5,10), target_shape = (2,10), raises RuntimeError :param target_shape: TODO :returns: TBoxTensor :raises RuntimeError: If space dimensions, ie. the last dimensions do not match. :raises RuntimeError: If cannot reshape the extra dimensions and torch.reshape raises. .. py:class:: BoxFactory(name: str, kwargs_dict: Dict = None) Bases: :py:obj:`box_embeddings.common.registrable.Registrable` A factory class which will be subclassed(one for each box type). .. py:attribute:: box_registry :annotation: :Dict[str, Tuple[Type[BoxTensor], Optional[str]]] .. py:method:: register_box_class(cls, name: str, constructor: str = None, exist_ok: bool = False) -> Callable[[Type[BoxTensor]], Type[BoxTensor]] :classmethod: This is different from allennlp registrable because what this class registers is not subclasses but subclasses of BoxTensor :param name: TODO :param constructor: TODO :param exist_ok: TODO :returns: () :raises RuntimeError: