예제 #1
0
def test_intersection_with_broadcasting() -> None:
    box1 = BoxTensor(
        torch.tensor([[[1, 1], [3, 5]], [[1, 1], [3, 3]]]).float()
    )  # box_shape (2,2)
    box2 = BoxTensor(torch.tensor([[2, 0], [6, 2]]).float())  # box_shape (2,)
    res = BoxTensor(torch.tensor([[[2, 1], [3, 2]], [[2, 1], [3, 2]]]).float())
    assert res == hard_intersection(box1, box2)
    assert res == hard_intersection(box2, box1)
예제 #2
0
def test_intersection() -> None:
    box1 = BoxTensor(
        torch.tensor([[[1, 1], [3, 5]], [[1, 1], [3, 3]]]).float()
    )
    box2 = BoxTensor(
        torch.tensor([[[2, 0], [6, 2]], [[3, 2], [4, 4]]]).float()
    )
    res = BoxTensor(torch.tensor([[[2, 1], [3, 2]], [[3, 2], [3, 3]]]).float())
    assert res == hard_intersection(box1, box2)
예제 #3
0
def test_shape_validation_during_creation():
    tensor = torch.tensor(np.random.rand(3))
    with pytest.raises(ValueError):
        box_tensor = BoxTensor(tensor)
    tensor = torch.tensor(np.random.rand(3, 11))
    with pytest.raises(ValueError):
        box_tensor = BoxTensor(tensor)
    tensor = torch.tensor(np.random.rand(3, 3, 3))
    with pytest.raises(ValueError):
        box_tensor = BoxTensor(tensor)
 def test_volume(self, inp1: np.ndarray, inp2: np.ndarray, beta: float,
                 log_scale: bool) -> None:
     inp1[...,
          1] = (np.absolute(inp1[..., 1]) + inp1[..., 0])  # make sure Z >z
     inp2[...,
          1] = (np.absolute(inp2[..., 1]) + inp2[..., 0])  # make sure Z >z
     box1 = BoxTensor(torch.tensor(inp1))
     box2 = BoxTensor(torch.tensor(inp2))
     hard_volume1 = HardVolume(log_scale=log_scale, beta=beta)(box1)
     soft_volume1 = SoftVolume(log_scale=log_scale, beta=beta)(box1)
예제 #5
0
def test_reshape(sample):
    target_shape, input_data_shape, self_shape, expected = sample
    box = BoxTensor(torch.tensor(np.random.rand(*input_data_shape)))
    assert box.box_shape == self_shape

    if expected == RuntimeError:
        with pytest.raises(expected):
            box.box_reshape(target_shape)
    else:
        new = box.box_reshape(target_shape)
        assert new.box_shape == expected
예제 #6
0
def test_simple_creation() -> None:
    tensor = torch.tensor(np.random.rand(3, 2, 3))
    box_tensor = BoxTensor(tensor)
    assert (
        tensor.data.numpy() == box_tensor.data.numpy()).all()  # type: ignore
    assert isinstance(box_tensor, BoxTensor)
    tensor = torch.tensor(np.random.rand(2, 10))
    box_tensor = BoxTensor(tensor)
    assert (
        tensor.data.numpy() == box_tensor.data.numpy()).all()  # type: ignore
    assert isinstance(box_tensor, BoxTensor)
예제 #7
0
def test_volume() -> None:
    box1 = BoxTensor(
        torch.tensor([[[1, 1], [3, 5]], [[1, 1], [3, 3]]]).float()
    )
    box2 = BoxTensor(
        torch.tensor([[[2, 0], [6, 2]], [[3, 2], [4, 4]]]).float()
    )
    volume_layer = BesselApproxVolume(log_scale=False)
    expected1 = torch.tensor([3.490526, 1.4467278]).float()
    expected2 = torch.tensor([3.490526, 0.7444129]).float()
    res1 = volume_layer(box1)
    res2 = volume_layer(box2)
    assert torch.allclose(res1, expected1, rtol=1e-4)
    assert torch.allclose(res2, expected2, rtol=1e-4)
예제 #8
0
def test_log_volume() -> None:
    box1 = BoxTensor(
        torch.tensor([[[1, 1], [3, 5]], [[1, 1], [3, 3]]]).float()
    )
    box2 = BoxTensor(
        torch.tensor([[[2, 0], [6, 2]], [[3, 2], [4, 4]]]).float()
    )
    volume_layer = BesselApproxVolume(log_scale=True)
    expected1 = torch.tensor([1.25004, 0.36924]).float()
    expected2 = torch.tensor([1.25004, -0.29517]).float()
    res1 = volume_layer(box1)
    res2 = volume_layer(box2)
    assert torch.allclose(res1, expected1, rtol=1e-4)
    assert torch.allclose(res2, expected2, rtol=1e-4)
예제 #9
0
def test_volume() -> None:
    box1 = BoxTensor(
        torch.tensor([[[1, 1], [3, 5]], [[1, 1], [3, 3]]]).float()
    )
    box2 = BoxTensor(
        torch.tensor([[[2, 0], [6, 2]], [[3, 2], [4, 4]]]).float()
    )
    volume_layer = HardVolume(log_scale=False)
    expected1 = torch.tensor([8, 4]).float()
    expected2 = torch.tensor([8, 2]).float()
    res1 = volume_layer(box1)
    res2 = volume_layer(box2)
    assert torch.allclose(res1, expected1)
    assert torch.allclose(res2, expected2)
예제 #10
0
def test_log_volume() -> None:
    box1 = BoxTensor(
        torch.tensor([[[1, 1], [3, 5]], [[1, 1], [3, 3]]]).float()
    )
    box2 = BoxTensor(
        torch.tensor([[[2, 0], [6, 2]], [[3, 2], [4, 4]]]).float()
    )
    volume_layer = HardVolume(log_scale=True)
    expected1 = torch.tensor([2.07944, 1.3862]).float()
    expected2 = torch.tensor([2.07944, 0.69314]).float()
    res1 = volume_layer(box1)
    res2 = volume_layer(box2)
    assert torch.allclose(res1, expected1, rtol=1e-4)
    assert torch.allclose(res2, expected2, rtol=1e-4)
예제 #11
0
def test_creation_from_zZ():
    shape = (3, 1, 5)
    z = torch.tensor(np.random.rand(*shape))
    Z = z + torch.tensor(np.random.rand(*shape))
    box = BoxTensor.from_zZ(z, Z)
    assert box.z.shape == (3, 1, 5)
    assert box.data is None
예제 #12
0
def test_creation_from_vector():
    shape = (3, 1, 5)
    z = torch.tensor(np.random.rand(*shape))
    delta = torch.tensor(np.random.rand(*shape))
    v = torch.cat((z, z + delta.abs()), dim=-1)
    box = BoxTensor.from_vector(v)
    assert box.Z.shape == (3, 1, 5)
예제 #13
0
def test_intersection_with_broadcasting_module2() -> None:
    box1 = BoxTensor(
        torch.tensor([[[[1, 1], [4, 4]], [[2, 2], [5, 5]]]]).float()
    )  # box_shape (1, 2,2)
    assert box1.box_shape == (1, 2, 2)
    box2 = BoxTensor(
        torch.tensor([[[[3, 3], [7, 6]]], [[[1, 3], [3, 4]]]]).float()
    )
    assert box2.box_shape == (2, 1, 2)
    expected = BoxTensor(
        torch.tensor(
            [
                [[[3, 3], [4, 4]], [[3, 3], [5, 5]]],
                [[[1, 3], [3, 4]], [[2, 3], [3, 4]]],
            ]
        ).float()
    )
    assert expected == HardIntersection()(box1, box2)
    box1 = BoxTensor(
        torch.tensor([[[[1, 1], [4, 4]], [[2, 2], [5, 5]]]]).float()
    )  # box_shape (1, 2,2)
    assert box1.box_shape == (1, 2, 2)
    box2 = BoxTensor(
        torch.tensor([[[[3, 3], [7, 6]]], [[[1, 3], [3, 4]]]]).float()
    )
    assert box2.box_shape == (2, 1, 2)
    expected = BoxTensor(
        torch.tensor(
            [
                [[[3, 3], [4, 4]], [[3, 3], [5, 5]]],
                [[[1, 3], [3, 4]], [[2, 3], [3, 4]]],
            ]
        ).float()
    )
    assert expected == HardIntersection()(box2, box1)
예제 #14
0
def hard_intersection_pooler(
    boxes: BoxTensor,
    mask: torch.BoolTensor = None,
    dim: int = 0,
    keepdim: bool = False,
) -> BoxTensor:
    box_z = boxes.z
    box_Z = boxes.Z

    if mask is not None:
        box_z[mask] -= float("inf")
        box_Z[mask] += float("inf")
    z = torch.max(box_z, dim=dim, keepdim=keepdim)[0]
    Z = torch.min(box_Z, dim=dim, keepdim=keepdim)[0]

    return boxes.like_this_from_zZ(z, Z)
예제 #15
0
def test_broadcasting(sample):
    target_shape, input_data_shape, self_shape, expected = sample
    box = BoxTensor(torch.tensor(np.random.rand(*input_data_shape)))
    assert box.box_shape == self_shape

    if isinstance(expected, tuple):
        box.broadcast(target_shape)
        assert box.box_shape == expected
    else:
        with pytest.raises(expected):
            box.broadcast(target_shape)
def gumbel_intersection_pooler(
    boxes: BoxTensor,
    beta: float = 1e-4,
    mask: torch.BoolTensor = None,
    dim: int = 0,
    keepdim: bool = False,
) -> BoxTensor:
    box_z = boxes.z
    box_Z = boxes.Z

    if mask is not None:
        box_z[mask] -= float("inf")
        box_Z[mask] += float("inf")
    z = beta * torch.logsumexp(box_z / beta, dim=dim, keepdim=keepdim)
    Z = -beta * torch.logsumexp(-box_Z / beta, dim=dim, keepdim=keepdim)

    return BoxTensor.from_zZ(z, Z)
예제 #17
0
def bag_of_boxes_pooler(
    boxes: BoxTensor,
    mask: Optional[torch.BoolTensor] = None,
    weights: Optional[torch.Tensor] = None,
    dim: int = 0,
    keepdim: bool = False,
) -> BoxTensor:
    box_z = boxes.z
    box_Z = boxes.Z

    if weights is None:
        weights = torch.ones_like(box_z)

    if mask is not None:
        weights = weights * mask
    denominator = torch.sum(weights, dim=dim, keepdim=keepdim)
    z = torch.sum(box_z * weights, dim=dim,
                  keepdim=keepdim) / (denominator + 1e-14)
    Z = torch.sum(box_Z * weights, dim=dim,
                  keepdim=keepdim) / (denominator + 1e-14)

    return boxes.like_this_from_zZ(z, Z)
예제 #18
0
def test_creation_from_center():
    c = torch.tensor([[0.1, 0.2], [0.2, 0.1]])
    delta = 0.1
    box = BoxTensor.from_center_vector(c, delta=delta)
    assert torch.allclose(box.z, c - delta / 2.0)
    assert torch.allclose(box.Z, c + delta / 2.0)
예제 #19
0
from box_embeddings.modules.pooling.bag_of_boxes import BagOfBoxesBoxPooler
from box_embeddings.parameterizations.box_tensor import BoxTensor
import hypothesis
from hypothesis.strategies import sampled_from, just
import torch
import pytest


@hypothesis.given(
    others=sampled_from([
        {
            "box":
            BoxTensor(
                torch.tensor([[[1, 1], [3, 5]], [[2, 0], [6, 2]]]).float()),
            "weights":
            None,
            "mask":
            None,
            "keepdim":
            True,
            "dim":
            0,
            "expected":
            BoxTensor(
                torch.tensor([[3.0 / 2.0, 1.0 / 2.0], [9.0 / 2.0,
                                                       7.0 / 2.0]])),
        },
        {
            "box":
            BoxTensor(
                torch.tensor([[[1, 1], [3, 5]], [[2, 0], [6, 2]]]).float()),