Skip to content

unittest_util

OneLayerTorchModel

Bases: Module

Torch Model with one dense layer without activation function. * Model input shape: (3,) * Model output: (1,) * dense layer weight: [1.0, 2.0, 3.0]

How to feed_forward this model

model = OneLayerTorchModel()
x = torch.tensor([[1.0, 1.0, 1.0], [1.0, -1.0, -0.5]])
b = fe.backend.feed_forward(model, x) # [[6.0], [-2.5]]

Source code in fastestimator/fastestimator/test/unittest_util.py
class OneLayerTorchModel(torch.nn.Module):
    """Torch Model with one dense layer without activation function.
    * Model input shape: (3,)
    * Model output: (1,)
    * dense layer weight: [1.0, 2.0, 3.0]

    How to feed_forward this model
    ```python
    model = OneLayerTorchModel()
    x = torch.tensor([[1.0, 1.0, 1.0], [1.0, -1.0, -0.5]])
    b = fe.backend.feed_forward(model, x) # [[6.0], [-2.5]]
    ```

    """
    def __init__(self) -> None:
        super().__init__()
        self.fc1 = torch.nn.Linear(3, 1, bias=False)
        self.fc1.weight.data = torch.tensor([[1, 2, 3]], dtype=torch.float32)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        x = self.fc1(x)
        return x

TraceRun

Class to simulate the trace calling protocol.

This serve for testing purpose without using estimator class.

Parameters:

Name Type Description Default
trace Trace

Target trace to run.

required
batch Dict[str, Any]

Batch data from pipepline.

required
prediction Dict[str, Any]

Batch data from network.

required
Source code in fastestimator/fastestimator/test/unittest_util.py
class TraceRun:
    """Class to simulate the trace calling protocol.

    This serve for testing purpose without using estimator class.

    Args:
        trace: Target trace to run.
        batch: Batch data from pipepline.
        prediction: Batch data from network.
    """
    def __init__(self, trace: Trace, batch: Dict[str, Any], prediction: Dict[str, Any]):
        self.trace = trace
        self.batch = batch
        self.prediction = prediction
        self.data_on_begin = None
        self.data_on_end = None
        self.data_on_epoch_begin = None
        self.data_on_epoch_end = None
        self.data_on_batch_begin = None
        self.data_on_batch_end = None

    def run_trace(self) -> None:
        system = sample_system_object()
        self.trace.system = system

        self.data_on_begin = Data()
        self.trace.on_begin(self.data_on_begin)

        self.data_on_epoch_begin = Data()
        self.trace.on_epoch_begin(self.data_on_epoch_begin)

        self.data_on_batch_begin = Data(self.batch)
        self.trace.on_batch_begin(self.data_on_batch_begin)

        self.data_on_batch_end = Data(ChainMap(self.prediction, self.batch))
        self.trace.on_batch_end(self.data_on_batch_end)

        self.data_on_epoch_end = Data()
        self.trace.on_epoch_end(self.data_on_epoch_end)

        self.data_on_end = Data()
        self.trace.on_end(self.data_on_end)

check_img_similar

Check whether img1 and img2 array are similar based on pixel to pixel comparision Args: img1: Image 1 img2: Image 2 ptol: Pixel value tolerance ntol: Number of pixel difference tolerace rate

Returns:

Type Description
bool

Boolean of whether the images are similar

Source code in fastestimator/fastestimator/test/unittest_util.py
def check_img_similar(img1: np.ndarray, img2: np.ndarray, ptol: int = 3, ntol: float = 0.01) -> bool:
    """Check whether img1 and img2 array are similar based on pixel to pixel comparision
    Args:
        img1: Image 1
        img2: Image 2
        ptol: Pixel value tolerance
        ntol: Number of pixel difference tolerace rate

    Returns:
        Boolean of whether the images are similar
    """
    if img1.shape == img2.shape:
        diff = np.abs(img1.astype(np.float32) - img2.astype(np.float32))
        n_pixel_diff = diff[diff > ptol].size
        if n_pixel_diff < img1.size * ntol:
            return True
        else:
            return False
    return False

fig_to_rgb_array

Convert image in plt.Figure to numpy array

Parameters:

Name Type Description Default
fig Figure

Input figure object

required

Returns:

Type Description
ndarray

Image array

Source code in fastestimator/fastestimator/test/unittest_util.py
def fig_to_rgb_array(fig: Figure) -> np.ndarray:
    """Convert image in plt.Figure to numpy array

    Args:
        fig: Input figure object

    Returns:
        Image array
    """
    p = fig.to_image(format='png')
    decoded = cv2.imdecode(np.frombuffer(p, np.uint8), cv2.IMREAD_COLOR)
    decoded = cv2.cvtColor(decoded, cv2.COLOR_BGR2RGB)
    return decoded

img_to_rgb_array

Read png file to numpy array (RGB)

Parameters:

Name Type Description Default
path str

Image path

required

Returns:

Type Description
ndarray

Image numpy array

Source code in fastestimator/fastestimator/test/unittest_util.py
def img_to_rgb_array(path: str) -> np.ndarray:
    """Read png file to numpy array (RGB)

    Args:
        path: Image path

    Returns:
        Image numpy array
    """
    return np.asarray(Image.open(path).convert('RGB'))

is_equal

Check whether input objects are equal. The object type can be nested iterable (list, tuple, set, dict) and with elements such as int, float, np.ndarray, tf.Tensor, tf.Varaible, torch.Tensor

Parameters:

Name Type Description Default
obj1 Any

Input object 1

required
obj2 Any

Input object 2

required
assert_type bool

Whether to assert the same data type

True
assert_dtype bool

Whether to assert the same dtype in case of nd.array, tf.Tensor, torch.Tensor

False

Returns:

Type Description
bool

Boolean of whether those two object are equal

Source code in fastestimator/fastestimator/test/unittest_util.py
def is_equal(obj1: Any, obj2: Any, assert_type: bool = True, assert_dtype: bool = False) -> bool:
    """Check whether input objects are equal. The object type can be nested iterable (list, tuple, set, dict) and
    with elements such as int, float, np.ndarray, tf.Tensor, tf.Varaible, torch.Tensor

    Args:
        obj1: Input object 1
        obj2: Input object 2
        assert_type: Whether to assert the same data type
        assert_dtype: Whether to assert the same dtype in case of nd.array, tf.Tensor, torch.Tensor

    Returns:
        Boolean of whether those two object are equal
    """
    if assert_type and type(obj1) != type(obj2):
        return False

    if type(obj1) in [list, set, tuple]:
        if len(obj1) != len(obj2):
            return False

        for iter1, iter2 in zip(obj1, obj2):
            if not is_equal(iter1, iter2):
                return False

        return True

    elif type(obj1) == dict:
        if len(obj1) != len(obj2):
            return False

        if obj1.keys() != obj2.keys():
            return False

        for value1, value2 in zip(obj1.values(), obj2.values()):
            if not is_equal(value1, value2):
                return False

        return True

    elif type(obj1) == np.ndarray:
        if assert_dtype and obj1.dtype != obj2.dtype:
            return False
        return np.array_equal(obj1, obj2)

    elif tf.is_tensor(obj1):
        if assert_dtype and obj1.dtype != obj2.dtype:
            return False
        obj1 = obj1.numpy()
        obj2 = obj2.numpy()
        return np.array_equal(obj1, obj2)

    elif isinstance(obj1, torch.Tensor):
        if assert_dtype and obj1.dtype != obj2.dtype:
            return False
        return torch.equal(obj1, obj2)

    else:
        return obj1 == obj2

one_layer_tf_model

Tensorflow Model with one dense layer without activation function. * Model input shape: (3,) * Model output: (1,) * dense layer weight: [1.0, 2.0, 3.0]

How to feed_forward this model

model = one_layer_tf_model()
x = tf.constant([[1.0, 1.0, 1.0], [1.0, -1.0, -0.5]])
b = fe.backend.feed_forward(model, x) # [[6.0], [-2.5]]

Returns:

Type Description
Model

tf.keras.Model: The model

Source code in fastestimator/fastestimator/test/unittest_util.py
def one_layer_tf_model() -> tf.keras.Model:
    """Tensorflow Model with one dense layer without activation function.
    * Model input shape: (3,)
    * Model output: (1,)
    * dense layer weight: [1.0, 2.0, 3.0]

    How to feed_forward this model
    ```python
    model = one_layer_tf_model()
    x = tf.constant([[1.0, 1.0, 1.0], [1.0, -1.0, -0.5]])
    b = fe.backend.feed_forward(model, x) # [[6.0], [-2.5]]
    ```

    Returns:
        tf.keras.Model: The model
    """
    inp = tf.keras.layers.Input([3])
    x = tf.keras.layers.Dense(units=1, use_bias=False)(inp)
    model = tf.keras.models.Model(inputs=inp, outputs=x)
    model.layers[1].set_weights([np.array([[1.0], [2.0], [3.0]])])
    return model