コード例 #1
0
 def test_iloc(self):
     torch.manual_seed(123)
     a = [torch.randn((i, j)) for i, j in [(5, 3), (5, 2)]]
     a = tuplefy(a, torch.randint(10, (5, )))
     b = tuplefy((a[0][0][:2], a[0][1][:2]), a[1][:2])
     a = a.iloc[:2]
     assert_tupletree_equal(a, b)
コード例 #2
0
ファイル: base.py プロジェクト: hleu/torchtuples
 def _to_device(self, data) -> TupleTree:
     """Move `data` to self.device.
     If `data` is a tensor, it will be returned as a `TupleTree`.
     """
     if data is None:
         return tuplefy(data)
     return tuplefy(data).to_device(self.device)
コード例 #3
0
 def test_stack_shapes(self):
     torch.manual_seed(123)
     a = [torch.randn((i, j)) for i, j in [(5, 3), (5, 2)]]
     a = tuplefy(a, torch.randint(10, (5, )))
     b = tuplefy((torch.Size([3, 5, 3]), torch.Size([3, 5, 2])),
                 torch.Size([3, 5]))
     assert_tupletree_equal(a.repeat(3).stack().shapes(), b)
コード例 #4
0
def test_make_data_loader_sorted(batch_size, num_workers):
    torch.manual_seed(123)
    a = tuplefy(torch.randn(10, 3), torch.randn(10))
    dl = make_dataloader(a, batch_size, False, num_workers)
    b = tuplefy()
    for inp, tar in dl:
        b = b + tuplefy(inp, tar).add_root()
    assert_tupletree_equal(b.cat(), a)
コード例 #5
0
def test_dataloader_input_only():
    n = 10
    input = tuplefy(torch.randn(n, 3), torch.randn(n, 2))
    target = torch.randn(n)
    dl = tuplefy(input, target).make_dataloader(4, False)
    dl_input = dataloader_input_only(dl)
    for (inp, tar), inp2 in zip(dl, dl_input):
        assert_tupletree_equal(inp, inp2)
コード例 #6
0
def test_make_data_loader_unsorted(batch_size, num_workers):
    torch.manual_seed(123)
    a = tuplefy(torch.randn(10, 3), torch.randn(10))
    dl = make_dataloader(a, batch_size, True, num_workers)
    b = tuplefy()
    for inp, tar in dl:
        b = b + tuplefy(inp, tar).add_root()
    b = b.cat()
    assert_tupletree_equal(b.shapes(), a.shapes())
    assert (tuplefy(a, b).apply(sum).zip_leaf().apply(
        lambda x: x[0] - x[1]).apply(lambda x: x.max()).pipe(max) < 1e-6)
コード例 #7
0
ファイル: base.py プロジェクト: prerna-khanna/torchtuples
 def _to_device(self, data):
     """Move data to self.device.
     
     Arguments:
         data {tensor or tuple} -- Data
     
     Returns:
         tensor or tuple -- Data moved to device.
     """
     if data is None:
         return tuplefy(data)
     return tuplefy(data).to_device(self.device)
コード例 #8
0
ファイル: base.py プロジェクト: havakv/torchtuples
    def _predict_func_dl(self,
                         func,
                         dataloader,
                         numpy=False,
                         eval_=True,
                         grads=False,
                         to_cpu=False):
        """Get predictions from `dataloader`.
        `func` can be anything and is not concatenated to `self.net` or `self.net.predict`.
        This is different from `predict` and `predict_net` which both use call `self.net`.
        """
        if hasattr(self, "fit_info") and (self.make_dataloader is
                                          self.make_dataloader_predict):
            data = _get_element_in_dataloader(dataloader)
            if data is not None:
                input = tuplefy(data)
                input_train = self.fit_info.get("input")
                if input_train is not None:
                    if input.to_levels() != input_train.get("levels"):
                        warnings.warn(
                            """The input from the dataloader is different from
                        the 'input' during trainig. Make sure to remove 'target' from dataloader.
                        Can be done with 'torchtuples.data.dataloader_input_only'."""
                        )
                    if input.shapes().apply(
                            lambda x: x[1:]) != input_train.get("shapes"):
                        warnings.warn(
                            """The input from the dataloader is different from
                        the 'input' during trainig. The shapes are different."""
                        )

        if eval_:
            self.net.eval()
        with torch.set_grad_enabled(grads):
            preds = []
            for input in dataloader:
                input = tuplefy(input).to_device(self.device)
                preds_batch = tuplefy(func(*input))
                if numpy or to_cpu:
                    preds_batch = preds_batch.to_device("cpu")
                preds.append(preds_batch)
        if eval_:
            self.net.train()
        preds = tuplefy(preds).cat()
        if numpy:
            preds = preds.to_numpy()
        if len(preds) == 1:
            preds = preds[0]
        return preds
コード例 #9
0
ファイル: base.py プロジェクト: prerna-khanna/torchtuples
 def predict(self,
             input,
             batch_size=8224,
             numpy=None,
             eval_=True,
             grads=False,
             to_cpu=False,
             num_workers=0):
     """Get predictions from 'input'.
     
     Arguments:
         input {tuple, np.ndarra, or torch.tensor} -- Input to net.
     
     Keyword Arguments:
         batch_size {int} -- Batch size (default: {8224})
         numpy {bool} -- 'False' gives tensor, 'True' gives numpy, and None give same as input
             (default: {None})
         eval_ {bool} -- If 'True', use 'eval' modede on net. (default: {True})
         grads {bool} -- If gradients should be computed (default: {False})
         to_cpu {bool} -- For larger data sets we need to move the results to cpu
             (default: {False})
         num_workers {int} -- Number of workes in created dataloader (default: {0})
     
     Returns:
         [TupleTree, np.ndarray or tensor] -- Predictions
     """
     if numpy is None:
         numpy = tuplefy(input).type() is not torch.Tensor
     dataloader = self.make_dataloader_predict(input,
                                               batch_size,
                                               shuffle=False,
                                               num_workers=num_workers)
     preds = self.predict_dataloader(dataloader, numpy, eval_, grads,
                                     to_cpu)
     return preds
コード例 #10
0
    def compute_metrics(self, data, metrics=None) -> Dict[str, torch.Tensor]:
        """Function for computing the loss and other metrics.

        Arguments:
            data {tensor or tuple} -- A batch of data. Typically the tuple `(input, target)`.
        Keyword Arguments:
            metrics {dict} -- A dictionary with metrics. If `None` use `self.metrics`. (default: {None})
        """
        return_metrics = {}
        if metrics is None:
            metrics = self.metrics
        if (self.loss is None) and (self.loss in metrics.values()):
            raise RuntimeError(f"Need to set `self.loss`.")

        input, target = data
        input = self._to_device(input)
        target = self._to_device(target)
        #         out1, out2 = self.net(input)
        combined = self.net(input)
        #         print(combined.shape)
        combined = tuplefy(combined)
        #         out1 = tuplefy(out1)
        #         out2 = tuplefy(out2)

        #         resnet_loss = self.loss(*out1, *target)
        #         clinical_loss = self.loss(*out2, *target)
        loss = self.loss(*combined, *target)
        #         loss = resnet_loss + clinical_loss

        return {'loss': loss}
コード例 #11
0
 def test_reorder(self):
     a = tuplefy((('a', 'b', 'c', 'd'), ('e', 'f')))
     order = (0, (
         1,
         2,
     ), (5, ))
     assert a.reorder(order) == ('a', ('b', 'c'), ('f', ))
コード例 #12
0
 def test_reduce(self):
     a = (
         (1, (2, 3), 4),
         (1, (2, 3), 4),
         (1, (2, 3), 4),
     )
     b = (3, (6, 9), 12)
     a = tuplefy(a)
     assert a.reduce(lambda x, y: x + y) == b
コード例 #13
0
 def test_np2torch2np(self):
     np.random.seed(123)
     a = [
         np.random.normal(size=(i, j)).astype('float32')
         for i, j in [(2, 3), (1, 2)]
     ]
     a = tuplefy(a, np.random.choice(10, size=(4, )))
     b = a.to_tensor().to_numpy()
     assert_tupletree_equal(a, b)
コード例 #14
0
 def test_next_iter(self, batch_size, num_workers):
     torch.manual_seed(123)
     n = 20
     a = ((torch.randn(n, 3), torch.randint(200, (n, 2))), torch.randn(n))
     a = tuplefy(a)
     ds = DatasetTuple(*a)
     dl = DataLoaderBatch(ds, batch_size, False, num_workers=num_workers)
     a = a.iloc[:batch_size]
     b = next(iter(dl))
     assert_tupletree_equal(a, b)
コード例 #15
0
ファイル: testing.py プロジェクト: prerna-khanna/torchtuples
def assert_tupletree_equal(a, b, check_dtypes=True):
    assert type(a) == type(b) == TupleTree, 'Not TupleTree'
    assert a.numerate() == b.numerate(), 'Not same structure'
    assert a.types() == b.types(), 'Not same types'
    if check_dtypes:
        ad, bd = (tuplefy(a, b).apply(
            lambda x: x.dtype if hasattr(x, 'dtype') else 'not_tensor'))
        assert ad == bd, 'Not same dtype'

    for aa, bb in zip(a.flatten(), b.flatten()):
        if hasattr(aa, 'dtype'):
            assert (aa == bb).all(), 'Not equal values'
        else:
            assert aa == bb, 'Not equal values'
コード例 #16
0
ファイル: base.py プロジェクト: prerna-khanna/torchtuples
    def compute_metrics(self, input, target, metrics):
        """Function for computing loss.
        Is rather general, but can be reimpliemented by sub classes.
        
        Arguments:
            input {tensor or tuple} -- This should be passed to self.net.
            target {tensor or tuple} -- This is the targets that should be used in self.loss.
            metrics (dictionary with funcs) -- Metrics that should be computed.

        Returns:
            tensor -- Results of self.loss()
        """
        if (self.loss is None) and (self.loss in metrics.values()):
            raise RuntimeError(
                f"Need to specify a loss (self.loss). It's currently None")
        input = self._to_device(input)
        target = self._to_device(target)
        out = self.net(*input)
        out = tuplefy(out)
        res = {name: metric(*out, *target) for name, metric in metrics.items()}
        return res
コード例 #17
0
ファイル: base.py プロジェクト: hleu/torchtuples
    def compute_metrics(self, data, metrics=None) -> Dict[str, torch.Tensor]:
        """Function for computing the loss and other metrics.
        
        Arguments:
            data {tensor or tuple} -- A batch of data. Typically the tuple `(input, target)`.

        Keyword Arguments:
            metrics {dict} -- A dictionary with metrics. If `None` use `self.metrics`. (default: {None})
        """
        if metrics is None:
            metrics = self.metrics
        if (self.loss is None) and (self.loss in metrics.values()):
            raise RuntimeError(f"Need to set `self.loss`.")

        input, target = data
        input = self._to_device(input)
        target = self._to_device(target)
        out = self.net(*input)
        out = tuplefy(out)
        return {
            name: metric(*out, *target)
            for name, metric in metrics.items()
        }
コード例 #18
0
import pytest
import numpy as np
import torch
from torchtuples.tupletree import tuplefy
from torchtuples.testing import assert_tupletree_equal


@pytest.mark.parametrize('a, b, ex_string', [
    ((1, 2), (1, ), 'Not TupleTree'),
    (tuplefy(1, 2), tuplefy(1, (2, )), 'Not same structure'),
    (tuplefy(np.arange(5)), tuplefy(torch.arange(5)), 'Not same types'),
    (tuplefy(np.arange(5)), tuplefy(
        np.arange(5).astype('float')), 'Not same dtype'),
    (tuplefy(torch.arange(5)), tuplefy(
        torch.arange(5).float()), 'Not same dtype'),
    (tuplefy(np.arange(5)), tuplefy(np.arange(1, 6)), 'Not equal values'),
    (tuplefy(torch.arange(5)), tuplefy(torch.arange(1,
                                                    6)), 'Not equal values'),
])
def test_assert_tupletree_equal_fails(a, b, ex_string):
    with pytest.raises(AssertionError) as ex:
        assert_tupletree_equal(a, b)
    assert str(ex.value) == ex_string


@pytest.mark.parametrize('a, b, check_dtypes', [
    (tuplefy(1, 2), tuplefy(1, 2), True),
    (tuplefy(np.arange(5),
             (1, 2)), tuplefy(np.arange(5).astype('float'), (1, 2)), False),
])
def test_assert_tupletree_equal_pass(a, b, check_dtypes):
コード例 #19
0
ファイル: base.py プロジェクト: hleu/torchtuples
 def _tuple_info(tuple_):
     tuple_ = tuplefy(tuple_)
     return {
         'levels': tuple_.to_levels(),
         'shapes': tuple_.shapes().apply(lambda x: x[1:])
     }
コード例 #20
0
ファイル: base.py プロジェクト: prerna-khanna/torchtuples
    def predict_dataloader(self,
                           dataloader,
                           numpy=True,
                           eval_=True,
                           grads=False,
                           to_cpu=False):
        """Get predictions from dataloader.
        
        Arguments:
            dataloader {DataLoader} -- Dataloader with inputs to net.
        
        Keyword Arguments:
            numpy {bool} -- If 'False', tensor is returned (default: {True})
            eval_ {bool} -- If 'True', use 'eval' modede on net. (default: {True})
            grads {bool} -- If gradients should be computed (default: {False})
            to_cpu {bool} -- For larger data sets we need to move the results to cpu
                (default: {False})
        
        Returns:
            [TupleTree, np.ndarray or tensor] -- Predictions
        """
        if hasattr(self, 'fit_info') and (self.make_dataloader is
                                          self.make_dataloader_predict):
            # input = tuplefy(dataloader.dataset[0])
            data = _get_element_in_dataloader(dataloader)
            if data is not None:
                input = tuplefy(data)
                input_train = self.fit_info['input']
                if input.to_levels() != input_train['levels']:
                    raise RuntimeError(
                        """The input from the dataloader is different from
                    the 'input' during trainig. Make sure to remove 'target' from dataloader.
                    Can be done with 'torchtuples.data.dataloader_input_only'."""
                    )
                if input.shapes().apply(
                        lambda x: x[1:]) != input_train['shapes']:
                    raise RuntimeError(
                        """The input from the dataloader is different from
                    the 'input' during trainig. The shapes are different.""")

        if not eval_:
            warnings.warn(
                "We still don't shuffle the data here... event though 'eval_' is True."
            )
        if eval_:
            self.net.eval()
        with torch.set_grad_enabled(grads):
            preds = []
            for input in dataloader:
                input = tuplefy(input).to_device(self.device)
                preds_batch = tuplefy(self.net(*input))
                if numpy or to_cpu:
                    preds_batch = preds_batch.to_device('cpu')
                preds.append(preds_batch)
        if eval_:
            self.net.eval()
        preds = tuplefy(preds).cat()
        if numpy:
            preds = preds.to_numpy()
        if len(preds) == 1:
            preds = preds[0]
        return preds
コード例 #21
0
 def test_apply(self):
     a = (1, (2, 3), (4, (5, )))
     a = tuplefy(a)
     b = (2, (4, 6), (8, (10, )))
     assert a.apply(lambda x: x * 2) == b
コード例 #22
0
 def test_levels(self):
     a = (1, (2, 3), (4, (5, )))
     a = tuplefy(a)
     assert a.levels == (0, (1, 1), (1, (2, )))
コード例 #23
0
 def test_types(self):
     a = ('a', (1, 4.5), {})
     b = (str, (int, float), dict)
     a = tuplefy(a)
     assert a.types() == b
コード例 #24
0
 def test_cat_lens(self):
     torch.manual_seed(123)
     a = [torch.randn((i, j)) for i, j in [(5, 3), (5, 2)]]
     a = tuplefy(a, torch.randint(10, (5, )))
     assert a.repeat(3).cat().lens() == ((15, 15), 15)
コード例 #25
0
 def test_numerate(self):
     a = (1, (2, 3), (4, (5, )))
     order = (0, (1, 2), (3, (4, )))
     a = tuplefy(a)
     assert a.numerate() == order
コード例 #26
0
 def test_enumerate(self):
     a = tuplefy(list('abcd'), list('ef'))
     a = tuplefy((('a', 'b', 'c', 'd'), ('e', 'f')))
     assert a.enumerate() == (([0, 'a'], [1, 'b'], [2, 'c'], [3, 'd']),
                              ([4, 'e'], [5, 'f']))
コード例 #27
0
 def test_repeat(self):
     a = (1, (2, 3))
     b = ((1, (2, 3)), (1, (2, 3)), (1, (2, 3)))
     assert tuplefy(a).repeat(3) == b
コード例 #28
0
 def test_add_root(self):
     a = tuplefy(1, 2, 3)
     assert a == a.add_root()[0]
コード例 #29
0
def test_tuplefy_type(inp):
    t = tuplefy(inp)
    assert type(t) is TupleTree
コード例 #30
0
 def test_cat_split(self):
     torch.manual_seed(123)
     a = [torch.randn((i, j)) for i, j in [(5, 3), (5, 2)]]
     a = tuplefy(a, torch.randint(10, (5, )))
     for sub in a.repeat(3).cat().split(5):
         assert_tupletree_equal(a, sub)