From 49b35422ad0cf53657849e525a3f9bcab4bcf8bc Mon Sep 17 00:00:00 2001 From: yu1120 <65484599+myaokai@users.noreply.github.com> Date: Tue, 23 Jan 2024 16:38:46 +0900 Subject: [PATCH 01/27] first commit From fb203f14e291c84fb1fe6219ba30c0827e2ba190 Mon Sep 17 00:00:00 2001 From: yu1120 <65484599+myaokai@users.noreply.github.com> Date: Tue, 23 Jan 2024 16:47:23 +0900 Subject: [PATCH 02/27] create test files --- tests/dl/torch/test_dataset.py | 0 tests/recon/torch/modules/test_latent.py | 0 tests/recon/torch/task/__init__.py | 0 tests/recon/torch/task/test_inversion.py | 0 tests/task/test_core.py | 0 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/dl/torch/test_dataset.py create mode 100644 tests/recon/torch/modules/test_latent.py create mode 100644 tests/recon/torch/task/__init__.py create mode 100644 tests/recon/torch/task/test_inversion.py create mode 100644 tests/task/test_core.py diff --git a/tests/dl/torch/test_dataset.py b/tests/dl/torch/test_dataset.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/recon/torch/modules/test_latent.py b/tests/recon/torch/modules/test_latent.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/recon/torch/task/__init__.py b/tests/recon/torch/task/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/recon/torch/task/test_inversion.py b/tests/recon/torch/task/test_inversion.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/task/test_core.py b/tests/task/test_core.py new file mode 100644 index 00000000..e69de29b From 3210670cf16a9e8da463cf525ce8f264b2491187 Mon Sep 17 00:00:00 2001 From: yu1120 <65484599+myaokai@users.noreply.github.com> Date: Wed, 24 Jan 2024 10:51:58 +0900 Subject: [PATCH 03/27] add TestBaseLatent --- tests/dl/torch/test_dataset.py | 27 +++++++++++ tests/recon/torch/modules/test_latent.py | 60 ++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/tests/dl/torch/test_dataset.py b/tests/dl/torch/test_dataset.py index e69de29b..56656a4c 100644 --- a/tests/dl/torch/test_dataset.py +++ b/tests/dl/torch/test_dataset.py @@ -0,0 +1,27 @@ +import unittest + +import torch +import torch.nn as nn + +from bdpy.dl.torch import models + + +class TestFeatureDataset(unittest.TestCase): + def setUp(self): + #self.dataset = + pass + pass + +class TestDecodedFeatureDataset(unittest.TestCase): + pass + +class TestImageDataset(unittest.TestCase): + pass + +class TestRenameFeatureKeys(unittest.TestCase): + pass + + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/tests/recon/torch/modules/test_latent.py b/tests/recon/torch/modules/test_latent.py index e69de29b..a3d0525a 100644 --- a/tests/recon/torch/modules/test_latent.py +++ b/tests/recon/torch/modules/test_latent.py @@ -0,0 +1,60 @@ +import torch +import unittest +from abc import ABC, abstractmethod +from typing import Iterator +import torch.nn as nn +from bdpy.recon.torch.modules import latent as latent_module + + +class DummyLatent(latent_module.BaseLatent): + def __init__(self): + self.latent = torch.tensor([1.0]) + + def reset_states(self): + self.latent = torch.zeros_like(self.latent) + + def parameters(self, recurse): + return iter([nn.Parameter(self.latent)]) + + def generate(self): + return self.latent + +class TestBaseLatent(unittest.TestCase): + """Tests for bdpy.recon.torch.modules.latent.BaseLatent.""" + def setUp(self): + self.latent = torch.tensor([1.0]) + + def test_instantiation(self): + """Test instantiation.""" + self.assertRaises(TypeError, latent_module.BaseLatent) + + def test_call(self): + """Test __call__.""" + + latent = DummyLatent() + + self.assertEqual(latent(), self.latent) + + def test_parameters(self): + """test parameters""" + latent = DummyLatent() + params = latent.parameters(recurse=True) + + self.assertIsInstance(params, Iterator) + self.assertEqual(next(params).item(), 1.0) + + def test_reset_states(self): + """test reset_states""" + latent = DummyLatent() + latent.reset_states() + params = latent.parameters(recurse=True) + + self.assertEqual(next(params).item(), 0.0) + + + + + + +if __name__ == '__main__': + unittest.main() From 31d3ba50645b9370e6f3a18bd95433ec1e0531fd Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Wed, 24 Jan 2024 13:46:27 +0900 Subject: [PATCH 04/27] Update tests/recon/torch/modules/test_latent.py Co-authored-by: Yoshihiro Nagano --- tests/recon/torch/modules/test_latent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/recon/torch/modules/test_latent.py b/tests/recon/torch/modules/test_latent.py index a3d0525a..a99560c6 100644 --- a/tests/recon/torch/modules/test_latent.py +++ b/tests/recon/torch/modules/test_latent.py @@ -22,7 +22,7 @@ def generate(self): class TestBaseLatent(unittest.TestCase): """Tests for bdpy.recon.torch.modules.latent.BaseLatent.""" def setUp(self): - self.latent = torch.tensor([1.0]) + self.latent_value_expected = torch.tensor([1.0]) def test_instantiation(self): """Test instantiation.""" From 4f367b5b01ccd4712a5c38524b7f69bc108efbdd Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Wed, 24 Jan 2024 13:46:39 +0900 Subject: [PATCH 05/27] Update tests/recon/torch/modules/test_latent.py Co-authored-by: Yoshihiro Nagano --- tests/recon/torch/modules/test_latent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/recon/torch/modules/test_latent.py b/tests/recon/torch/modules/test_latent.py index a99560c6..af0af0d2 100644 --- a/tests/recon/torch/modules/test_latent.py +++ b/tests/recon/torch/modules/test_latent.py @@ -8,7 +8,7 @@ class DummyLatent(latent_module.BaseLatent): def __init__(self): - self.latent = torch.tensor([1.0]) + self.latent = nn.Parameter(torch.tensor([1.0])) def reset_states(self): self.latent = torch.zeros_like(self.latent) From 3660f4043092d83bbaee15340cb50fb3d7745673 Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Wed, 24 Jan 2024 13:46:48 +0900 Subject: [PATCH 06/27] Update tests/recon/torch/modules/test_latent.py Co-authored-by: Yoshihiro Nagano --- tests/recon/torch/modules/test_latent.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/recon/torch/modules/test_latent.py b/tests/recon/torch/modules/test_latent.py index af0af0d2..131589a8 100644 --- a/tests/recon/torch/modules/test_latent.py +++ b/tests/recon/torch/modules/test_latent.py @@ -11,7 +11,8 @@ def __init__(self): self.latent = nn.Parameter(torch.tensor([1.0])) def reset_states(self): - self.latent = torch.zeros_like(self.latent) + with torch.no_grad(): + self.latent.fill_(0.0) def parameters(self, recurse): return iter([nn.Parameter(self.latent)]) From 33f2c9fbb2c19373b3394716299108779aaaef5a Mon Sep 17 00:00:00 2001 From: yu1120 <65484599+myaokai@users.noreply.github.com> Date: Thu, 25 Jan 2024 15:15:51 +0900 Subject: [PATCH 07/27] update test latent --- tests/recon/torch/modules/test_latent.py | 84 +++++++++++++++++++++--- 1 file changed, 74 insertions(+), 10 deletions(-) diff --git a/tests/recon/torch/modules/test_latent.py b/tests/recon/torch/modules/test_latent.py index 131589a8..76b5ca32 100644 --- a/tests/recon/torch/modules/test_latent.py +++ b/tests/recon/torch/modules/test_latent.py @@ -3,19 +3,21 @@ from abc import ABC, abstractmethod from typing import Iterator import torch.nn as nn +from functools import partial from bdpy.recon.torch.modules import latent as latent_module +from IPython import embed class DummyLatent(latent_module.BaseLatent): def __init__(self): - self.latent = nn.Parameter(torch.tensor([1.0])) + self.latent = nn.Parameter(torch.tensor([0.0, 1.0, 2.0])) def reset_states(self): with torch.no_grad(): self.latent.fill_(0.0) def parameters(self, recurse): - return iter([nn.Parameter(self.latent)]) + return iter(self.latent) def generate(self): return self.latent @@ -23,7 +25,8 @@ def generate(self): class TestBaseLatent(unittest.TestCase): """Tests for bdpy.recon.torch.modules.latent.BaseLatent.""" def setUp(self): - self.latent_value_expected = torch.tensor([1.0]) + self.latent_value_expected = nn.Parameter(torch.tensor([0.0, 1.0, 2.0])) + self.latent_reset_value_expected = nn.Parameter(torch.tensor([0.0, 0.0, 0.0])) def test_instantiation(self): """Test instantiation.""" @@ -31,31 +34,92 @@ def test_instantiation(self): def test_call(self): """Test __call__.""" - latent = DummyLatent() - - self.assertEqual(latent(), self.latent) + self.assertTrue(torch.equal(latent(), self.latent_value_expected)) def test_parameters(self): """test parameters""" latent = DummyLatent() params = latent.parameters(recurse=True) - self.assertIsInstance(params, Iterator) - self.assertEqual(next(params).item(), 1.0) def test_reset_states(self): """test reset_states""" latent = DummyLatent() latent.reset_states() - params = latent.parameters(recurse=True) + self.assertTrue(torch.equal(latent(), self.latent_reset_value_expected)) + +class DummyNNModuleLatent(latent_module.NNModuleLatent): + def __init__(self): + super().__init__() + self.latent = nn.Parameter(torch.tensor([0.0, 1.0, 2.0])) + + def reset_states(self): + with torch.no_grad(): + self.latent.fill_(0.0) + + def generate(self): + return self.latent + +class TestNNModuleLatent(unittest.TestCase): + """Tests for bdpy.recon.torch.modules.latent.NNModuleLatent.""" + def setUp(self): + self.latent_value_expected = nn.Parameter(torch.tensor([0.0, 1.0, 2.0])) + self.latent_reset_value_expected = nn.Parameter(torch.tensor([0.0, 0.0, 0.0])) + + def test_instantiation(self): + """Test instantiation.""" + self.assertRaises(TypeError, latent_module.NNModuleLatent) + + def test_call(self): + """Test __call__.""" + latent = DummyNNModuleLatent() + self.assertTrue(torch.equal(latent(), self.latent_value_expected)) - self.assertEqual(next(params).item(), 0.0) + def test_parameters(self): + """test parameters""" + latent = DummyNNModuleLatent() + params = latent.parameters(recurse=True) + self.assertIsInstance(params, Iterator) + + def test_reset_states(self): + """test reset_states""" + latent = DummyNNModuleLatent() + latent.reset_states() + self.assertTrue(torch.equal(latent(), self.latent_reset_value_expected)) +class DummyArbitraryLatent(latent_module.ArbitraryLatent): + def parameters(self, recurse): + return iter(self._latent) +class TestArbitraryLatent(unittest.TestCase): + """Tests for bdpy.recon.torch.modules.latent.ArbitraryLatent.""" + def setUp(self): + self.latent = DummyArbitraryLatent((1, 3, 64, 64), partial(nn.init.normal_, mean=0, std=1)) + self.latent_shape_expected = (1, 3, 64, 64) + self.latent_value_expected = nn.Parameter(torch.tensor([0.0, 1.0, 2.0])) + self.latent_reset_value_expected = nn.Parameter(torch.tensor([0.0, 0.0, 0.0])) + def test_instantiation(self): + """Test instantiation.""" + self.assertRaises(TypeError, latent_module.ArbitraryLatent) + def test_call(self): + """Test __call__.""" + self.assertEqual(self.latent().size(), self.latent_shape_expected) + def test_parameters(self): + """test parameters""" + params = self.latent.parameters(recurse=True) + self.assertIsInstance(params, Iterator) + + def test_reset_states(self): + """test reset_states""" + self.latent.reset_states() + mean = self.latent().mean().item() + std = self.latent().std().item() + self.assertAlmostEqual(mean, 0, places=1) + self.assertAlmostEqual(std, 1, places=1) if __name__ == '__main__': unittest.main() From b03b68b64477ebad9d6bf8cbec559b7618c655d1 Mon Sep 17 00:00:00 2001 From: yu1120 <65484599+myaokai@users.noreply.github.com> Date: Thu, 25 Jan 2024 16:37:05 +0900 Subject: [PATCH 08/27] create test_core --- tests/dl/torch/domain/__init__.py | 0 tests/dl/torch/domain/test_core.py | 83 ++++++++++++++++++++ tests/dl/torch/domain/test_feature_domain.py | 0 tests/dl/torch/domain/test_image_domain.py | 0 4 files changed, 83 insertions(+) create mode 100644 tests/dl/torch/domain/__init__.py create mode 100644 tests/dl/torch/domain/test_core.py create mode 100644 tests/dl/torch/domain/test_feature_domain.py create mode 100644 tests/dl/torch/domain/test_image_domain.py diff --git a/tests/dl/torch/domain/__init__.py b/tests/dl/torch/domain/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/dl/torch/domain/test_core.py b/tests/dl/torch/domain/test_core.py new file mode 100644 index 00000000..e774f38c --- /dev/null +++ b/tests/dl/torch/domain/test_core.py @@ -0,0 +1,83 @@ +"""Tests for bdpy.dl.torch.domain.core.""" + +import unittest +import torch +from bdpy.dl.torch.domain import core as core_module + + +class DummyAddDomain(core_module.Domain): + def send(self, num): + return num + 1 + + def receive(self, num): + return num - 1 + +class DummyDoubleDomain(core_module.Domain): + def send(self, num): + return num * 2 + + def receive(self, num): + return num // 2 + +class TestDomain(unittest.TestCase): + """Tests for bdpy.dl.torch.domain.core.Domain.""" + def setUp(self): + self.domian = DummyAddDomain() + self.original_space_num = 0 + self.internal_space_num = 1 + + def test_send(self): + """test send""" + self.assertEqual(self.domian.send(self.original_space_num), self.internal_space_num) + + def test_receive(self): + """test receive""" + self.assertEqual(self.domian.receive(self.internal_space_num), self.original_space_num) + +class TestInternalDomain(unittest.TestCase): + """Tests for bdpy.dl.torch.domain.core.InternalDomain.""" + def setUp(self): + self.domian = core_module.InternalDomain() + self.num = 1 + + def test_send(self): + """test send""" + self.assertEqual(self.domian.send(self.num), self.num) + + def test_receive(self): + """test receive""" + self.assertEqual(self.domian.receive(self.num), self.num) + +class TestIrreversibleDomain(unittest.TestCase): + """Tests for bdpy.dl.torch.domain.core.IrreversibleDomain.""" + def setUp(self): + self.domian = core_module.IrreversibleDomain() + self.num = 1 + + def test_send(self): + """test send""" + self.assertEqual(self.domian.send(self.num), self.num) + + def test_receive(self): + """test receive""" + self.assertEqual(self.domian.receive(self.num), self.num) + +class TestComposedDomain(unittest.TestCase): + """Tests for bdpy.dl.torch.domain.core.ComposedDomain.""" + def setUp(self): + self.composed_domian = core_module.ComposedDomain([ + DummyDoubleDomain(), + DummyAddDomain(), + ]) + self.original_space_num = 0 + self.internal_space_num = 2 + + def test_send(self): + """test send""" + self.assertEqual(self.composed_domian.send(self.original_space_num), self.internal_space_num) + + def test_receive(self): + """test receive""" + self.assertEqual(self.composed_domian.receive(self.internal_space_num), self.original_space_num) +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/tests/dl/torch/domain/test_feature_domain.py b/tests/dl/torch/domain/test_feature_domain.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/dl/torch/domain/test_image_domain.py b/tests/dl/torch/domain/test_image_domain.py new file mode 100644 index 00000000..e69de29b From 6cef2f2a1dbe7331bf2c38babead84de41b2d8ec Mon Sep 17 00:00:00 2001 From: yu1120 <65484599+myaokai@users.noreply.github.com> Date: Thu, 25 Jan 2024 16:55:38 +0900 Subject: [PATCH 09/27] update test_core --- tests/dl/torch/domain/test_core.py | 28 ++++++++++++++++++++ tests/dl/torch/domain/test_feature_domain.py | 5 ++++ 2 files changed, 33 insertions(+) diff --git a/tests/dl/torch/domain/test_core.py b/tests/dl/torch/domain/test_core.py index e774f38c..f03d1ecb 100644 --- a/tests/dl/torch/domain/test_core.py +++ b/tests/dl/torch/domain/test_core.py @@ -19,6 +19,13 @@ def send(self, num): def receive(self, num): return num // 2 +class DummyUpperCaseDomain(core_module.Domain): + def send(self, text): + return text.upper() + + def receive(self, value): + return value.lower() + class TestDomain(unittest.TestCase): """Tests for bdpy.dl.torch.domain.core.Domain.""" def setUp(self): @@ -79,5 +86,26 @@ def test_send(self): def test_receive(self): """test receive""" self.assertEqual(self.composed_domian.receive(self.internal_space_num), self.original_space_num) + +class TestKeyValueDomain(unittest.TestCase): + """Tests for bdpy.dl.torch.domain.core.KeyValueDomain.""" + def setUp(self): + self.key_value_domian = core_module.KeyValueDomain({ + "name": DummyUpperCaseDomain(), + "age": DummyDoubleDomain() + }) + self.original_space_data = {"name": "alice", "age": 30} + self.internal_space_data = {"name": "ALICE", "age": 60} + + def test_send(self): + """test send""" + self.assertEqual(self.key_value_domian.send(self.original_space_data), self.internal_space_data) + + def test_receive(self): + """test receive""" + self.assertEqual(self.key_value_domian.receive(self.internal_space_data), self.original_space_data) + + + if __name__ == "__main__": unittest.main() \ No newline at end of file diff --git a/tests/dl/torch/domain/test_feature_domain.py b/tests/dl/torch/domain/test_feature_domain.py index e69de29b..3fd137a9 100644 --- a/tests/dl/torch/domain/test_feature_domain.py +++ b/tests/dl/torch/domain/test_feature_domain.py @@ -0,0 +1,5 @@ +"""Tests for bdpy.dl.torch.domain.feature_domain.""" + +import unittest +import torch +from bdpy.dl.torch.domain import feature_domain as feature_domain_module \ No newline at end of file From 547d337028a8c0a97f8e18ed98527e71a3d11b97 Mon Sep 17 00:00:00 2001 From: yu1120 <65484599+myaokai@users.noreply.github.com> Date: Thu, 25 Jan 2024 17:35:21 +0900 Subject: [PATCH 10/27] create test_feature_domain --- tests/dl/torch/domain/test_feature_domain.py | 80 +++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/tests/dl/torch/domain/test_feature_domain.py b/tests/dl/torch/domain/test_feature_domain.py index 3fd137a9..72d7ba92 100644 --- a/tests/dl/torch/domain/test_feature_domain.py +++ b/tests/dl/torch/domain/test_feature_domain.py @@ -2,4 +2,82 @@ import unittest import torch -from bdpy.dl.torch.domain import feature_domain as feature_domain_module \ No newline at end of file +from bdpy.dl.torch.domain import feature_domain as feature_domain_module + +class TestMethods(unittest.TestCase): + def setUp(self): + self.lnd_tensor = torch.empty((12, 196, 768)) + self.nld_tensor = torch.empty((196, 12, 768)) + + def test_lnd2nld(self): + """test _lnd2nld""" + self.assertEqual(feature_domain_module._lnd2nld(self.lnd_tensor).shape, self.nld_tensor.shape) + + def test_nld2lnd(self): + """test _nld2lnd""" + self.assertEqual(feature_domain_module._nld2lnd(self.nld_tensor).shape, self.lnd_tensor.shape) + +class TestArbitraryFeatureKeyDomain(unittest.TestCase): + """Tests for bdpy.dl.torch.domain.feature_domain.ArbitraryFeatureKeyDomain.""" + def setUp(self): + self.to_internal_mapping = { + "self_key1": "internal_key1", + "self_key2": "internal_key2" + } + self.to_self_mapping = { + "internal_key1": "self_key1", + "internal_key2": "self_key2" + } + self.features = { + "self_key1": 123, + "self_key2": 456 + } + self.internal_features = { + "internal_key1": 123, + "internal_key2": 456 + } + + def test_send(self): + """test send""" + # when both are specified + domain = feature_domain_module.ArbitraryFeatureKeyDomain( + to_internal=self.to_internal_mapping, + to_self=self.to_self_mapping + ) + self.assertEqual(domain.send(self.features), self.internal_features) + + # when only to_self is specified + domain = feature_domain_module.ArbitraryFeatureKeyDomain( + to_self=self.to_self_mapping + ) + self.assertEqual(domain.send(self.features), self.internal_features) + + # when only to_internal is specified + domain = feature_domain_module.ArbitraryFeatureKeyDomain( + to_internal=self.to_internal_mapping + ) + self.assertEqual(domain.send(self.features), self.internal_features) + + def test_receive(self): + """test receive""" + # when both are specified + domain = feature_domain_module.ArbitraryFeatureKeyDomain( + to_internal=self.to_internal_mapping, + to_self=self.to_self_mapping + ) + self.assertEqual(domain.receive(self.internal_features), self.features) + + # when only to_self is specified + domain = feature_domain_module.ArbitraryFeatureKeyDomain( + to_self=self.to_self_mapping + ) + self.assertEqual(domain.receive(self.internal_features), self.features) + + # when only to_internal is specified + domain = feature_domain_module.ArbitraryFeatureKeyDomain( + to_internal=self.to_internal_mapping + ) + self.assertEqual(domain.receive(self.internal_features), self.features) + +if __name__ == "__main__": + unittest.main() \ No newline at end of file From b038a757e8f049ac1e3d28a711055dc7b3e9e3d2 Mon Sep 17 00:00:00 2001 From: yu1120 <65484599+myaokai@users.noreply.github.com> Date: Sat, 27 Jan 2024 02:45:41 +0900 Subject: [PATCH 11/27] create test_image_domain --- bdpy/dl/torch/domain/image_domain.py | 2 +- tests/dl/torch/domain/test_core.py | 4 + tests/dl/torch/domain/test_image_domain.py | 120 +++++++++++++++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) diff --git a/bdpy/dl/torch/domain/image_domain.py b/bdpy/dl/torch/domain/image_domain.py index dcf9440d..74b49b49 100644 --- a/bdpy/dl/torch/domain/image_domain.py +++ b/bdpy/dl/torch/domain/image_domain.py @@ -85,7 +85,7 @@ def __init__( if isinstance(center, (float, int)) or center.ndim == 0: center = np.array([center])[np.newaxis, np.newaxis, np.newaxis] - if center.ndim == 1: # 1D vector (C,) + elif center.ndim == 1: # 1D vector (C,) center = center[np.newaxis, :, np.newaxis, np.newaxis] elif center.ndim == 3: # 3D vector (1, C, W, H) center = center[np.newaxis] diff --git a/tests/dl/torch/domain/test_core.py b/tests/dl/torch/domain/test_core.py index f03d1ecb..bb00e2ea 100644 --- a/tests/dl/torch/domain/test_core.py +++ b/tests/dl/torch/domain/test_core.py @@ -33,6 +33,10 @@ def setUp(self): self.original_space_num = 0 self.internal_space_num = 1 + def test_instantiation(self): + """Test instantiation.""" + self.assertRaises(TypeError, core_module.Domain) + def test_send(self): """test send""" self.assertEqual(self.domian.send(self.original_space_num), self.internal_space_num) diff --git a/tests/dl/torch/domain/test_image_domain.py b/tests/dl/torch/domain/test_image_domain.py index e69de29b..5c1d8635 100644 --- a/tests/dl/torch/domain/test_image_domain.py +++ b/tests/dl/torch/domain/test_image_domain.py @@ -0,0 +1,120 @@ +"""Tests for bdpy.dl.torch.domain.image_domain.""" + +import unittest +import torch +import numpy as np +import warnings +from bdpy.dl.torch.domain import image_domain as iamge_domain_module + +class TestAffineDomain(unittest.TestCase): + """Tests for bdpy.dl.torch.domain.image_domain.AffineDomain""" + def setUp(self): + self.center0d = 0.0 + self.center1d = np.random.randn(3) + self.center2d = np.random.randn(32, 32) + self.center3d = np.random.randn(3, 32, 32) + self.scale0d = 1 + self.scale1d = np.random.randn(3) + self.scale2d = np.random.randn(32, 32) + self.scale3d = np.random.randn(3, 32, 32) + self.image = torch.rand((1, 3, 32, 32)) + + def test_instantiation(self): + """Test instantiation.""" + # Succeeds when center and scale are 0-dimensional + affine_domain = iamge_domain_module.AffineDomain(self.center0d, self.scale0d) + self.assertIsInstance(affine_domain, iamge_domain_module.AffineDomain) + + # Succeeds when center and scale are 1-dimensional + affine_domain = iamge_domain_module.AffineDomain(self.center1d, self.scale1d) + self.assertIsInstance(affine_domain, iamge_domain_module.AffineDomain) + + # Succeeds when center and scale are 3-dimensional + affine_domain = iamge_domain_module.AffineDomain(self.center3d, self.scale3d) + self.assertIsInstance(affine_domain, iamge_domain_module.AffineDomain) + + # Failss when the center is neither 1-dimensional nor 3-dimensional + with self.assertRaises(ValueError): + iamge_domain_module.AffineDomain(self.center2d, self.scale0d) + + # Failss when the scale is neither 1-dimensional nor 3-dimensional + with self.assertRaises(ValueError): + iamge_domain_module.AffineDomain(self.center0d, self.scale2d) + + def test_send_and_receive(self): + """Test send and receive""" + # when 0d + affine_domain = iamge_domain_module.AffineDomain(self.center0d, self.scale0d) + transformed_image = affine_domain.send(self.image) + center0d = torch.from_numpy(np.array([self.center0d])[np.newaxis, np.newaxis, np.newaxis]) + scale0d = torch.from_numpy(np.array([self.scale0d])[np.newaxis, np.newaxis, np.newaxis]) + expected_transformed_image = (self.image + center0d) / self.scale0d + torch.testing.assert_close(transformed_image, expected_transformed_image) + received_image = affine_domain.receive(transformed_image) + expected_received_image = expected_transformed_image * scale0d - center0d + torch.testing.assert_close(received_image, expected_received_image) + + # when 1d + affine_domain = iamge_domain_module.AffineDomain(self.center1d, self.scale1d) + transformed_image = affine_domain.send(self.image) + center1d = self.center1d[np.newaxis, :, np.newaxis, np.newaxis] + scale1d = self.scale1d[np.newaxis, :, np.newaxis, np.newaxis] + expected_transformed_image = (self.image + center1d) / scale1d + torch.testing.assert_close(transformed_image, expected_transformed_image) + received_image = affine_domain.receive(transformed_image) + expected_received_image = expected_transformed_image * scale1d - center1d + torch.testing.assert_close(received_image, expected_received_image) + + # when 3d + affine_domain = iamge_domain_module.AffineDomain(self.center3d, self.scale3d) + transformed_image = affine_domain.send(self.image) + center3d = self.center3d[np.newaxis] + scale3d = self.scale3d[np.newaxis] + expected_transformed_image = (self.image + center3d) / scale3d + torch.testing.assert_close(transformed_image, expected_transformed_image) + received_image = affine_domain.receive(transformed_image) + expected_received_image = expected_transformed_image * scale3d - center3d + torch.testing.assert_close(received_image, expected_received_image) + +class TestRGBDomain(unittest.TestCase): + """Tests fot bdpy.dl.torch.domain.image_domain.BGRDomain""" + + def setUp(self): + self.bgr_image = torch.rand((1, 3, 32, 32)) + self.rgb_image = self.bgr_image[:, [2, 1, 0], ...] + + def test_send(self): + """Test send""" + bgr_domain = iamge_domain_module.BGRDomain() + transformed_image = bgr_domain.send(self.bgr_image) + torch.testing.assert_close(transformed_image, self.rgb_image) + + def test_receive(self): + """Tests receive""" + bgr_domain = iamge_domain_module.BGRDomain() + received_image = bgr_domain.receive(self.rgb_image) + torch.testing.assert_close(received_image, self.bgr_image) + +class TestPILDomainWithExplicitCrop(unittest.TestCase): + """Tests fot bdpy.dl.torch.domain.image_domain.PILDomainWithExplicitCrop""" + def setUp(self): + self.expected_transformed_image = torch.rand((1, 3, 32, 32)) + self.image = self.expected_transformed_image.permute(0, 2, 3, 1) * 255 + + def test_send(self): + """Test send""" + pdwe_domain = iamge_domain_module.PILDomainWithExplicitCrop() + transformed_image = pdwe_domain.send(self.image) + torch.testing.assert_close(transformed_image, self.expected_transformed_image) + + def test_receive(self): + """Tests receive""" + pdwe_domain = iamge_domain_module.PILDomainWithExplicitCrop() + with warnings.catch_warnings(record=True) as w: + received_image = pdwe_domain.receive(self.expected_transformed_image) + self.assertTrue(any(isinstance(warn.message, RuntimeWarning) for warn in w)) + torch.testing.assert_close(received_image, self.image) + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file From 6605f280e5ebf4cd5933e479c1c50ac5638f8612 Mon Sep 17 00:00:00 2001 From: yu1120 <65484599+myaokai@users.noreply.github.com> Date: Tue, 30 Jan 2024 15:58:51 +0900 Subject: [PATCH 12/27] Update test_image_domain.py --- tests/dl/torch/domain/test_image_domain.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/dl/torch/domain/test_image_domain.py b/tests/dl/torch/domain/test_image_domain.py index 5c1d8635..9f658fee 100644 --- a/tests/dl/torch/domain/test_image_domain.py +++ b/tests/dl/torch/domain/test_image_domain.py @@ -5,6 +5,7 @@ import numpy as np import warnings from bdpy.dl.torch.domain import image_domain as iamge_domain_module +from IPython import embed class TestAffineDomain(unittest.TestCase): """Tests for bdpy.dl.torch.domain.image_domain.AffineDomain""" @@ -114,7 +115,25 @@ def test_receive(self): received_image = pdwe_domain.receive(self.expected_transformed_image) self.assertTrue(any(isinstance(warn.message, RuntimeWarning) for warn in w)) torch.testing.assert_close(received_image, self.image) - + +class TestFixedResolutionDomain(unittest.TestCase): + """Tests fot bdpy.dl.torch.domain.image_domain.FixedResolutionDomain""" + def setUp(self): + self.expected_received_image_size = (1, 3, 16, 16) + self.image =torch.rand((1, 3, 32, 32)) + + def test_send(self): + """Test send""" + fr_domain = iamge_domain_module.FixedResolutionDomain((16, 16)) + with self.assertRaises(RuntimeError): + fr_domain.send(self.image) + + def test_receive(self): + """Tests receive""" + fr_domain = iamge_domain_module.FixedResolutionDomain((16, 16)) + + received_image = fr_domain.receive(self.image) + self.assertEqual(received_image.size(), self.expected_received_image_size) if __name__ == "__main__": unittest.main() \ No newline at end of file From 7cbfc0ecf23311bb3c9024342950f2b811e166d2 Mon Sep 17 00:00:00 2001 From: yu1120 <65484599+myaokai@users.noreply.github.com> Date: Tue, 30 Jan 2024 16:41:23 +0900 Subject: [PATCH 13/27] create task/test_core --- tests/dl/torch/domain/test_image_domain.py | 1 - tests/recon/torch/modules/test_latent.py | 1 - tests/task/test_core.py | 57 ++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/tests/dl/torch/domain/test_image_domain.py b/tests/dl/torch/domain/test_image_domain.py index 9f658fee..c52bfa4f 100644 --- a/tests/dl/torch/domain/test_image_domain.py +++ b/tests/dl/torch/domain/test_image_domain.py @@ -5,7 +5,6 @@ import numpy as np import warnings from bdpy.dl.torch.domain import image_domain as iamge_domain_module -from IPython import embed class TestAffineDomain(unittest.TestCase): """Tests for bdpy.dl.torch.domain.image_domain.AffineDomain""" diff --git a/tests/recon/torch/modules/test_latent.py b/tests/recon/torch/modules/test_latent.py index 76b5ca32..5910ad03 100644 --- a/tests/recon/torch/modules/test_latent.py +++ b/tests/recon/torch/modules/test_latent.py @@ -5,7 +5,6 @@ import torch.nn as nn from functools import partial from bdpy.recon.torch.modules import latent as latent_module -from IPython import embed class DummyLatent(latent_module.BaseLatent): diff --git a/tests/task/test_core.py b/tests/task/test_core.py index e69de29b..3fdd2a5e 100644 --- a/tests/task/test_core.py +++ b/tests/task/test_core.py @@ -0,0 +1,57 @@ +"""Tests for bdpy.task.core.""" + +from __future__ import annotations + +import unittest + +from bdpy.task import core as core_module + +class MockCallback(core_module.BaseCallback): + """Mock callback for testing.""" + def __init__(self): + self._storage = [] + + def on_some_event(self, input_): + self._storage.append(input_) + +class MockTask(core_module.BaseTask[MockCallback]): + """Mock task for testing BaseTask.""" + def __call__(self, *inputs, **parameters): + self._callback_handler.fire("on_some_event", input_=1) + return inputs, parameters + +class TestBaseTask(unittest.TestCase): + """Tests forbdpy.task.core.BaseTask """ + def setUp(self): + self.input1 = 1.0 + self.input2 = 2.0 + self.task_name = "reconstruction" + + def test_initialization_without_callbacks(self): + """Test initialization without callbacks.""" + task = MockTask() + self.assertIsInstance(task._callback_handler, core_module.CallbackHandler) + self.assertEqual(len(task._callback_handler._callbacks), 0) + + def test_initialization_with_callbacks(self): + """Test initialization with callbacks.""" + mock_callback = MockCallback() + task = MockTask(callbacks=mock_callback) + self.assertEqual(len(task._callback_handler._callbacks), 1) + self.assertIn(mock_callback, task._callback_handler._callbacks) + + def test_register_callback(self): + """Test register_callback method.""" + task = MockTask() + mock_callback = MockCallback() + task.register_callback(mock_callback) + self.assertIn(mock_callback, task._callback_handler._callbacks) + + def test_call(self): + """Test __call__""" + mock_callback = MockCallback() + task = MockTask(callbacks=mock_callback) + task_inputs, task_parameters = task(self.input1, self.input2, name=self.task_name) + self.assertEqual(task_inputs, (self.input1, self.input2)) + self.assertEqual(task_parameters["name"], self.task_name) + self.assertEqual(mock_callback._storage, [1]) From ca3b1629a033457542e3803a08f2dfb926f9bf64 Mon Sep 17 00:00:00 2001 From: yu1120 <65484599+myaokai@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:34:13 +0900 Subject: [PATCH 14/27] create inversion test --- tests/recon/torch/task/test_inversion.py | 97 ++++++++++++++++++++++++ tests/task/test_core.py | 3 + 2 files changed, 100 insertions(+) diff --git a/tests/recon/torch/task/test_inversion.py b/tests/recon/torch/task/test_inversion.py index e69de29b..81f412c8 100644 --- a/tests/recon/torch/task/test_inversion.py +++ b/tests/recon/torch/task/test_inversion.py @@ -0,0 +1,97 @@ +"""Tests for bdpy.recon.torch.task.inversion""" + +from __future__ import annotations + +import unittest +from unittest.mock import patch +import torch + +from bdpy.recon.torch.task import inversion as inversion_module +from bdpy.task import callback as callback_module + + +class TaskFeatureInversionCallback(inversion_module.FeatureInversionCallback): + def __init__(self): + super().__init__() + + def on_task_start(self): + print('task start') + +class TestFeatureInversionCallback(unittest.TestCase): + """Tests for bdpy.recon.torch.task.inversion.FeatureInversionCallback""" + def setUp(self): + self.callback = inversion_module.FeatureInversionCallback() + self.expected_method_names = { + "on_task_start", + "on_iteration_start", + "on_image_generated", + "on_layerwise_loss_calculated", + "on_loss_calculated", + "on_iteration_end", + "on_task_end", + } + + def test_instance_methods(self): + method_names = { + event_type + for event_type in dir(self.callback) + if event_type.startswith("on_") + and callable(getattr(self.callback, event_type)) + } + self.assertEqual(method_names, self.expected_method_names) + for event_type in method_names: + fn = getattr(self.callback, event_type) + self.assertRaises(RuntimeError, fn) + + + def test_validate_callback(self): + + class Unrelated(callback_module.BaseCallback): + """Valid callback object but is not a subclass of TaskFeatureInversionCallback""" + + pass + + class HasUnknownEvent(TaskFeatureInversionCallback): + """Having invalid instance method `on_unknown_event` as a subclass of TaskFeatureInversionCallback""" + + def on_unknown_event(self): + pass + + self.assertIsNone( + callback_module._validate_callback(TaskFeatureInversionCallback(), inversion_module.FeatureInversionCallback) + ) + self.assertRaises( + TypeError, callback_module._validate_callback, Unrelated(), inversion_module.FeatureInversionCallback + ) + self.assertRaises(ValueError, HasUnknownEvent) + + +class TestCUILoggingCallback(unittest.TestCase): + """Tests for bdpy.recon.torch.task.inversion.CUILoggingCallback""" + def setUp(self): + self.callback = inversion_module.CUILoggingCallback() + self.expected_loss = torch.tensor([1.0]) + + def test_on_loss_culculated(self): + self.callback.on_loss_calculated(step=0, loss=self.expected_loss) + self.assertEqual(self.callback._loss, self.expected_loss.item()) + + @patch('builtins.print') + def test_on_iteration_end(self, mock_print): + self.callback.on_iteration_end(step=0) + mock_print.assert_called_once_with("Step: [1], Loss: -1.0000") + +class TestFeatureInversionTask(unittest.TestCase): + """Tests for bdpy.recon.torch.task.inversion.FeatureInversionTask""" + def setUp(self): + pass + + + + + + + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/tests/task/test_core.py b/tests/task/test_core.py index 3fdd2a5e..98b92527 100644 --- a/tests/task/test_core.py +++ b/tests/task/test_core.py @@ -55,3 +55,6 @@ def test_call(self): self.assertEqual(task_inputs, (self.input1, self.input2)) self.assertEqual(task_parameters["name"], self.task_name) self.assertEqual(mock_callback._storage, [1]) + +if __name__ == "__main__": + unittest.main() \ No newline at end of file From 948d5a59e02ab8e3dcfe73af2d5dc6e9ae4586d2 Mon Sep 17 00:00:00 2001 From: yu1120 <65484599+myaokai@users.noreply.github.com> Date: Thu, 8 Feb 2024 16:09:33 +0900 Subject: [PATCH 15/27] Update test_inversion.py --- tests/recon/torch/task/test_inversion.py | 143 +++++++++++++++++++++-- 1 file changed, 132 insertions(+), 11 deletions(-) diff --git a/tests/recon/torch/task/test_inversion.py b/tests/recon/torch/task/test_inversion.py index 81f412c8..9a532cbc 100644 --- a/tests/recon/torch/task/test_inversion.py +++ b/tests/recon/torch/task/test_inversion.py @@ -3,19 +3,53 @@ from __future__ import annotations import unittest -from unittest.mock import patch +from unittest.mock import patch, call +import copy import torch +import torch.nn as nn +import torch.optim as optim from bdpy.recon.torch.task import inversion as inversion_module from bdpy.task import callback as callback_module +from bdpy.dl.torch.domain.image_domain import Zero2OneImageDomain +from bdpy.recon.torch.modules import encoder as encoder_module +from bdpy.recon.torch.modules import generator as generator_module +from bdpy.recon.torch.modules import latent as latent_module +from bdpy.recon.torch.modules import critic as critic_module +from IPython import embed -class TaskFeatureInversionCallback(inversion_module.FeatureInversionCallback): - def __init__(self): +class DummyFeatureInversionCallback(inversion_module.FeatureInversionCallback): + def __init__(self, total_steps = 1): super().__init__() + self._total_steps = total_steps + self._loss = 0 + + def _step_str(self, step: int) -> str: + if self._total_steps > 0: + return f"{step+1}/{self._total_steps}" + else: + return f"{step+1}" def on_task_start(self): print('task start') + + def on_iteration_start(self, step): + print(f"Step [{self._step_str(step)}] start") + + def on_image_generated(self, step, image): + print(f"Step [{self._step_str(step)}], {image.shape}") + + def on_loss_calculated(self, step, loss): + self._loss = loss.item() + + def on_iteration_end(self, step): + print(f"Step [{self._step_str(step)}] end") + + def on_task_end(self): + print('task end') + + class TestFeatureInversionCallback(unittest.TestCase): """Tests for bdpy.recon.torch.task.inversion.FeatureInversionCallback""" @@ -51,14 +85,14 @@ class Unrelated(callback_module.BaseCallback): pass - class HasUnknownEvent(TaskFeatureInversionCallback): + class HasUnknownEvent(DummyFeatureInversionCallback): """Having invalid instance method `on_unknown_event` as a subclass of TaskFeatureInversionCallback""" def on_unknown_event(self): pass self.assertIsNone( - callback_module._validate_callback(TaskFeatureInversionCallback(), inversion_module.FeatureInversionCallback) + callback_module._validate_callback(DummyFeatureInversionCallback(), inversion_module.FeatureInversionCallback) ) self.assertRaises( TypeError, callback_module._validate_callback, Unrelated(), inversion_module.FeatureInversionCallback @@ -81,17 +115,104 @@ def test_on_iteration_end(self, mock_print): self.callback.on_iteration_end(step=0) mock_print.assert_called_once_with("Step: [1], Loss: -1.0000") -class TestFeatureInversionTask(unittest.TestCase): - """Tests for bdpy.recon.torch.task.inversion.FeatureInversionTask""" - def setUp(self): - pass +class MLP(nn.Module): + """A simple MLP.""" - + def __init__(self): + super().__init__() + self.fc1 = nn.Linear(7 * 7 * 3, 32) + self.fc2 = nn.Linear(32, 10) + def forward(self, x): + x = x.view(x.size(0), -1) + x = self.fc1(x) + x = torch.relu(x) + x = self.fc2(x) + return x +class LinearGenerator(generator_module.NNModuleGenerator): + def __init__(self): + super().__init__() + self.fc = nn.Linear(10, 7 * 7 * 3) - + def generate(self, latent): + return self.fc(latent) + + def reset_states(self) -> None: + self.fc.apply(generator_module.call_reset_parameters) + +class DummyNNModuleLatent(latent_module.NNModuleLatent): + def __init__(self, base_latent): + super().__init__() + self.latent = nn.Parameter(base_latent) + def reset_states(self): + with torch.no_grad(): + self.latent.fill_(0.0) + + def generate(self): + return self.latent + +class TestFeatureInversionTask(unittest.TestCase): + """Tests for bdpy.recon.torch.task.inversion.FeatureInversionTask""" + def setUp(self): + self.init_latent = torch.randn(1, 10) + self.target_feature = { + 'fc1': torch.randn(1, 32), + 'fc2': torch.randn(1, 10) + } + self.encoder = encoder_module.SimpleEncoder( + MLP(), ["fc1", "fc2"], domain=Zero2OneImageDomain() + ) + self.generator = generator_module.DNNGenerator(LinearGenerator()) + self.latent = DummyNNModuleLatent(self.init_latent.clone()) + self.critic = critic_module.MSE() + self.optimizer = optim.SGD([self.latent.latent], lr=0.1) + self.callbacks = DummyFeatureInversionCallback() + + self.inversion_task = inversion_module.FeatureInversionTask( + encoder=self.encoder, + generator=copy.deepcopy(self.generator), + latent=copy.deepcopy(self.latent), + critic=self.critic, + optimizer=self.optimizer, + callbacks=self.callbacks + ) + + @patch('builtins.print') + def test_call(self, mock_print): + """Test __call__.""" + generated_image = self.inversion_task(self.target_feature) + self.assertTrue(len(self.inversion_task._callback_handler._callbacks) > 0) + + # test for process + self.assertEqual(generated_image.shape, (1, 7 * 7 * 3)) + self.assertIsNotNone(self.inversion_task._generator._generator_network.fc.weight.grad) + self.assertFalse(torch.equal(self.inversion_task._latent.latent, self.init_latent)) + + + # test for callbacks + self.assertTrue(self.inversion_task._callback_handler._callbacks[0]._loss > 0 ) + mock_print.assert_has_calls([ + call('task start'), + call('Step [1/1] start'), + call('Step [1/1], torch.Size([1, 147])'), + call('Step [1/1] end'), + call('task end'), + ]) + + def test_reset_state(self): + """Test reset_states.""" + generator_copy = copy.deepcopy(self.inversion_task._generator) + latent_copy = copy.deepcopy(self.inversion_task._latent) + for p1, p2 in zip(self.inversion_task._generator.parameters(), generator_copy.parameters()): + self.assertTrue(torch.equal(p1, p2)) + torch.testing.assert_close(self.inversion_task._latent.latent, latent_copy.latent) + self.inversion_task.reset_states() + + for p1, p2 in zip(self.inversion_task._generator.parameters(), generator_copy.parameters()): + self.assertFalse(torch.equal(p1, p2)) + self.assertFalse(torch.equal(self.inversion_task._latent.latent, latent_copy.latent)) if __name__ == "__main__": unittest.main() \ No newline at end of file From bd2e180816d41156517ee7df1cc6d81a462123f9 Mon Sep 17 00:00:00 2001 From: yu1120 <65484599+myaokai@users.noreply.github.com> Date: Thu, 8 Feb 2024 16:18:19 +0900 Subject: [PATCH 16/27] Update test_inversion.py --- tests/recon/torch/task/test_inversion.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/recon/torch/task/test_inversion.py b/tests/recon/torch/task/test_inversion.py index 9a532cbc..05503b0e 100644 --- a/tests/recon/torch/task/test_inversion.py +++ b/tests/recon/torch/task/test_inversion.py @@ -172,8 +172,8 @@ def setUp(self): self.inversion_task = inversion_module.FeatureInversionTask( encoder=self.encoder, - generator=copy.deepcopy(self.generator), - latent=copy.deepcopy(self.latent), + generator=self.generator, + latent=self.latent, critic=self.critic, optimizer=self.optimizer, callbacks=self.callbacks From 3f693810cae7466e6c791f666672b4c19e6fc83f Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:23:24 +0900 Subject: [PATCH 17/27] Update tests/dl/torch/domain/test_core.py Co-authored-by: Yoshihiro Nagano --- tests/dl/torch/domain/test_core.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/dl/torch/domain/test_core.py b/tests/dl/torch/domain/test_core.py index bb00e2ea..82b8d1ec 100644 --- a/tests/dl/torch/domain/test_core.py +++ b/tests/dl/torch/domain/test_core.py @@ -1,7 +1,6 @@ """Tests for bdpy.dl.torch.domain.core.""" import unittest -import torch from bdpy.dl.torch.domain import core as core_module From 291807fde6d887cdec8afd6ffc20732748b6aa43 Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:23:36 +0900 Subject: [PATCH 18/27] Update tests/dl/torch/domain/test_core.py Co-authored-by: Yoshihiro Nagano --- tests/dl/torch/domain/test_core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/dl/torch/domain/test_core.py b/tests/dl/torch/domain/test_core.py index 82b8d1ec..ca8687d4 100644 --- a/tests/dl/torch/domain/test_core.py +++ b/tests/dl/torch/domain/test_core.py @@ -11,6 +11,7 @@ def send(self, num): def receive(self, num): return num - 1 + class DummyDoubleDomain(core_module.Domain): def send(self, num): return num * 2 From c87d8bcacd9f641b87827573d71acc2fff6bcce5 Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:23:43 +0900 Subject: [PATCH 19/27] Update tests/dl/torch/domain/test_image_domain.py Co-authored-by: Yoshihiro Nagano --- tests/dl/torch/domain/test_image_domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/dl/torch/domain/test_image_domain.py b/tests/dl/torch/domain/test_image_domain.py index c52bfa4f..81682040 100644 --- a/tests/dl/torch/domain/test_image_domain.py +++ b/tests/dl/torch/domain/test_image_domain.py @@ -33,7 +33,7 @@ def test_instantiation(self): affine_domain = iamge_domain_module.AffineDomain(self.center3d, self.scale3d) self.assertIsInstance(affine_domain, iamge_domain_module.AffineDomain) - # Failss when the center is neither 1-dimensional nor 3-dimensional + # Fails when the center is neither 1-dimensional nor 3-dimensional with self.assertRaises(ValueError): iamge_domain_module.AffineDomain(self.center2d, self.scale0d) From 7f0c3235ab6fac5517cfcca29020933edac672c0 Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:23:49 +0900 Subject: [PATCH 20/27] Update tests/dl/torch/domain/test_image_domain.py Co-authored-by: Yoshihiro Nagano --- tests/dl/torch/domain/test_image_domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/dl/torch/domain/test_image_domain.py b/tests/dl/torch/domain/test_image_domain.py index 81682040..e8d79cc5 100644 --- a/tests/dl/torch/domain/test_image_domain.py +++ b/tests/dl/torch/domain/test_image_domain.py @@ -37,7 +37,7 @@ def test_instantiation(self): with self.assertRaises(ValueError): iamge_domain_module.AffineDomain(self.center2d, self.scale0d) - # Failss when the scale is neither 1-dimensional nor 3-dimensional + # Fails when the scale is neither 1-dimensional nor 3-dimensional with self.assertRaises(ValueError): iamge_domain_module.AffineDomain(self.center0d, self.scale2d) From 13da19fab63e15ddc550ef46a76daca8f0a4b5dd Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:24:21 +0900 Subject: [PATCH 21/27] Update tests/dl/torch/domain/test_core.py Co-authored-by: Yoshihiro Nagano --- tests/dl/torch/domain/test_core.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/dl/torch/domain/test_core.py b/tests/dl/torch/domain/test_core.py index ca8687d4..92442ffe 100644 --- a/tests/dl/torch/domain/test_core.py +++ b/tests/dl/torch/domain/test_core.py @@ -18,7 +18,8 @@ def send(self, num): def receive(self, num): return num // 2 - + + class DummyUpperCaseDomain(core_module.Domain): def send(self, text): return text.upper() From 46d4d10fa58aa60e1a9b31c902cefc3061c83715 Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:24:27 +0900 Subject: [PATCH 22/27] Update tests/recon/torch/modules/test_latent.py Co-authored-by: Yoshihiro Nagano --- tests/recon/torch/modules/test_latent.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/recon/torch/modules/test_latent.py b/tests/recon/torch/modules/test_latent.py index 5910ad03..a668114e 100644 --- a/tests/recon/torch/modules/test_latent.py +++ b/tests/recon/torch/modules/test_latent.py @@ -1,6 +1,5 @@ import torch import unittest -from abc import ABC, abstractmethod from typing import Iterator import torch.nn as nn from functools import partial From 75a45ab795a6e6bde9f38e0cef760cd91588d4ff Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:24:35 +0900 Subject: [PATCH 23/27] Update tests/recon/torch/task/test_inversion.py Co-authored-by: Yoshihiro Nagano --- tests/recon/torch/task/test_inversion.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/recon/torch/task/test_inversion.py b/tests/recon/torch/task/test_inversion.py index 05503b0e..cf04b56f 100644 --- a/tests/recon/torch/task/test_inversion.py +++ b/tests/recon/torch/task/test_inversion.py @@ -16,7 +16,6 @@ from bdpy.recon.torch.modules import generator as generator_module from bdpy.recon.torch.modules import latent as latent_module from bdpy.recon.torch.modules import critic as critic_module -from IPython import embed class DummyFeatureInversionCallback(inversion_module.FeatureInversionCallback): From bbae3d7b835ae12534852fb18b79977203c5325f Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:53:51 +0900 Subject: [PATCH 24/27] Update test_core.py --- tests/dl/torch/domain/test_core.py | 58 ++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/tests/dl/torch/domain/test_core.py b/tests/dl/torch/domain/test_core.py index 92442ffe..092c3487 100644 --- a/tests/dl/torch/domain/test_core.py +++ b/tests/dl/torch/domain/test_core.py @@ -26,11 +26,12 @@ def send(self, text): def receive(self, value): return value.lower() - + + class TestDomain(unittest.TestCase): """Tests for bdpy.dl.torch.domain.core.Domain.""" def setUp(self): - self.domian = DummyAddDomain() + self.domain = DummyAddDomain() self.original_space_num = 0 self.internal_space_num = 1 @@ -40,44 +41,59 @@ def test_instantiation(self): def test_send(self): """test send""" - self.assertEqual(self.domian.send(self.original_space_num), self.internal_space_num) + self.assertEqual(self.domain.send(self.original_space_num), self.internal_space_num) def test_receive(self): """test receive""" - self.assertEqual(self.domian.receive(self.internal_space_num), self.original_space_num) + self.assertEqual(self.domain.receive(self.internal_space_num), self.original_space_num) + + def test_invertibility(self): + input_candidates = [-1, 0, 1, 0.5] + for x in input_candidates: + assert x == self.domain.send(self.domain.receive(x)) + assert x == self.domain.receive(self.domain.send(x)) + class TestInternalDomain(unittest.TestCase): """Tests for bdpy.dl.torch.domain.core.InternalDomain.""" def setUp(self): - self.domian = core_module.InternalDomain() + self.domain = core_module.InternalDomain() self.num = 1 def test_send(self): """test send""" - self.assertEqual(self.domian.send(self.num), self.num) + self.assertEqual(self.domain.send(self.num), self.num) def test_receive(self): """test receive""" - self.assertEqual(self.domian.receive(self.num), self.num) + self.assertEqual(self.domain.receive(self.num), self.num) + + def test_invertibility(self): + input_candidates = [-1, 0, 1, 0.5] + for x in input_candidates: + assert x == self.domain.send(self.domain.receive(x)) + assert x == self.domain.receive(self.domain.send(x)) + class TestIrreversibleDomain(unittest.TestCase): """Tests for bdpy.dl.torch.domain.core.IrreversibleDomain.""" def setUp(self): - self.domian = core_module.IrreversibleDomain() + self.domain = core_module.IrreversibleDomain() self.num = 1 def test_send(self): """test send""" - self.assertEqual(self.domian.send(self.num), self.num) + self.assertEqual(self.domain.send(self.num), self.num) def test_receive(self): """test receive""" - self.assertEqual(self.domian.receive(self.num), self.num) + self.assertEqual(self.domain.receive(self.num), self.num) + class TestComposedDomain(unittest.TestCase): """Tests for bdpy.dl.torch.domain.core.ComposedDomain.""" def setUp(self): - self.composed_domian = core_module.ComposedDomain([ + self.composed_domain = core_module.ComposedDomain([ DummyDoubleDomain(), DummyAddDomain(), ]) @@ -86,16 +102,17 @@ def setUp(self): def test_send(self): """test send""" - self.assertEqual(self.composed_domian.send(self.original_space_num), self.internal_space_num) + self.assertEqual(self.composed_domain.send(self.original_space_num), self.internal_space_num) def test_receive(self): """test receive""" - self.assertEqual(self.composed_domian.receive(self.internal_space_num), self.original_space_num) + self.assertEqual(self.composed_domain.receive(self.internal_space_num), self.original_space_num) + class TestKeyValueDomain(unittest.TestCase): """Tests for bdpy.dl.torch.domain.core.KeyValueDomain.""" def setUp(self): - self.key_value_domian = core_module.KeyValueDomain({ + self.key_value_domain = core_module.KeyValueDomain({ "name": DummyUpperCaseDomain(), "age": DummyDoubleDomain() }) @@ -104,13 +121,18 @@ def setUp(self): def test_send(self): """test send""" - self.assertEqual(self.key_value_domian.send(self.original_space_data), self.internal_space_data) + self.assertEqual(self.key_value_domain.send(self.original_space_data), self.internal_space_data) def test_receive(self): """test receive""" - self.assertEqual(self.key_value_domian.receive(self.internal_space_data), self.original_space_data) - + self.assertEqual(self.key_value_domain.receive(self.internal_space_data), self.original_space_data) if __name__ == "__main__": - unittest.main() \ No newline at end of file + #unittest.main() + composed_domain = core_module.ComposedDomain([ + DummyDoubleDomain(), + DummyAddDomain(), + ]) + print(composed_domain.receive(-1)) + print(composed_domain.send(-2)) From 556e6f0af8c803297e7fa2d2fafc962f6dee9fec Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Thu, 21 Mar 2024 16:03:33 +0900 Subject: [PATCH 25/27] fix --- tests/dl/torch/test_dataset.py | 27 ------------------------ tests/recon/torch/modules/test_latent.py | 11 +++++----- tests/recon/torch/task/test_inversion.py | 6 +++++- 3 files changed, 11 insertions(+), 33 deletions(-) delete mode 100644 tests/dl/torch/test_dataset.py diff --git a/tests/dl/torch/test_dataset.py b/tests/dl/torch/test_dataset.py deleted file mode 100644 index 56656a4c..00000000 --- a/tests/dl/torch/test_dataset.py +++ /dev/null @@ -1,27 +0,0 @@ -import unittest - -import torch -import torch.nn as nn - -from bdpy.dl.torch import models - - -class TestFeatureDataset(unittest.TestCase): - def setUp(self): - #self.dataset = - pass - pass - -class TestDecodedFeatureDataset(unittest.TestCase): - pass - -class TestImageDataset(unittest.TestCase): - pass - -class TestRenameFeatureKeys(unittest.TestCase): - pass - - - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/tests/recon/torch/modules/test_latent.py b/tests/recon/torch/modules/test_latent.py index a668114e..6e24d50a 100644 --- a/tests/recon/torch/modules/test_latent.py +++ b/tests/recon/torch/modules/test_latent.py @@ -19,7 +19,8 @@ def parameters(self, recurse): def generate(self): return self.latent - + + class TestBaseLatent(unittest.TestCase): """Tests for bdpy.recon.torch.modules.latent.BaseLatent.""" def setUp(self): @@ -47,6 +48,7 @@ def test_reset_states(self): latent.reset_states() self.assertTrue(torch.equal(latent(), self.latent_reset_value_expected)) + class DummyNNModuleLatent(latent_module.NNModuleLatent): def __init__(self): super().__init__() @@ -59,6 +61,7 @@ def reset_states(self): def generate(self): return self.latent + class TestNNModuleLatent(unittest.TestCase): """Tests for bdpy.recon.torch.modules.latent.NNModuleLatent.""" def setUp(self): @@ -86,14 +89,11 @@ def test_reset_states(self): latent.reset_states() self.assertTrue(torch.equal(latent(), self.latent_reset_value_expected)) -class DummyArbitraryLatent(latent_module.ArbitraryLatent): - def parameters(self, recurse): - return iter(self._latent) class TestArbitraryLatent(unittest.TestCase): """Tests for bdpy.recon.torch.modules.latent.ArbitraryLatent.""" def setUp(self): - self.latent = DummyArbitraryLatent((1, 3, 64, 64), partial(nn.init.normal_, mean=0, std=1)) + self.latent = latent_module.ArbitraryLatent((1, 3, 64, 64), partial(nn.init.normal_, mean=0, std=1)) self.latent_shape_expected = (1, 3, 64, 64) self.latent_value_expected = nn.Parameter(torch.tensor([0.0, 1.0, 2.0])) self.latent_reset_value_expected = nn.Parameter(torch.tensor([0.0, 0.0, 0.0])) @@ -119,5 +119,6 @@ def test_reset_states(self): self.assertAlmostEqual(mean, 0, places=1) self.assertAlmostEqual(std, 1, places=1) + if __name__ == '__main__': unittest.main() diff --git a/tests/recon/torch/task/test_inversion.py b/tests/recon/torch/task/test_inversion.py index cf04b56f..dc548cb9 100644 --- a/tests/recon/torch/task/test_inversion.py +++ b/tests/recon/torch/task/test_inversion.py @@ -140,6 +140,7 @@ def generate(self, latent): def reset_states(self) -> None: self.fc.apply(generator_module.call_reset_parameters) + class DummyNNModuleLatent(latent_module.NNModuleLatent): def __init__(self, base_latent): super().__init__() @@ -151,7 +152,8 @@ def reset_states(self): def generate(self): return self.latent - + + class TestFeatureInversionTask(unittest.TestCase): """Tests for bdpy.recon.torch.task.inversion.FeatureInversionTask""" def setUp(self): @@ -185,6 +187,7 @@ def test_call(self, mock_print): self.assertTrue(len(self.inversion_task._callback_handler._callbacks) > 0) # test for process + assert isinstance(generated_image, torch.Tensor) self.assertEqual(generated_image.shape, (1, 7 * 7 * 3)) self.assertIsNotNone(self.inversion_task._generator._generator_network.fc.weight.grad) self.assertFalse(torch.equal(self.inversion_task._latent.latent, self.init_latent)) @@ -213,5 +216,6 @@ def test_reset_state(self): self.assertFalse(torch.equal(p1, p2)) self.assertFalse(torch.equal(self.inversion_task._latent.latent, latent_copy.latent)) + if __name__ == "__main__": unittest.main() \ No newline at end of file From 7ddd4fbcb4a37e650f3e96a8406d76ab94a67bc7 Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Thu, 21 Mar 2024 16:05:24 +0900 Subject: [PATCH 26/27] fix --- tests/dl/torch/domain/test_feature_domain.py | 3 +++ tests/dl/torch/domain/test_image_domain.py | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/tests/dl/torch/domain/test_feature_domain.py b/tests/dl/torch/domain/test_feature_domain.py index 72d7ba92..970950b3 100644 --- a/tests/dl/torch/domain/test_feature_domain.py +++ b/tests/dl/torch/domain/test_feature_domain.py @@ -4,6 +4,7 @@ import torch from bdpy.dl.torch.domain import feature_domain as feature_domain_module + class TestMethods(unittest.TestCase): def setUp(self): self.lnd_tensor = torch.empty((12, 196, 768)) @@ -17,6 +18,7 @@ def test_nld2lnd(self): """test _nld2lnd""" self.assertEqual(feature_domain_module._nld2lnd(self.nld_tensor).shape, self.lnd_tensor.shape) + class TestArbitraryFeatureKeyDomain(unittest.TestCase): """Tests for bdpy.dl.torch.domain.feature_domain.ArbitraryFeatureKeyDomain.""" def setUp(self): @@ -79,5 +81,6 @@ def test_receive(self): ) self.assertEqual(domain.receive(self.internal_features), self.features) + if __name__ == "__main__": unittest.main() \ No newline at end of file diff --git a/tests/dl/torch/domain/test_image_domain.py b/tests/dl/torch/domain/test_image_domain.py index e8d79cc5..6140ab26 100644 --- a/tests/dl/torch/domain/test_image_domain.py +++ b/tests/dl/torch/domain/test_image_domain.py @@ -6,6 +6,7 @@ import warnings from bdpy.dl.torch.domain import image_domain as iamge_domain_module + class TestAffineDomain(unittest.TestCase): """Tests for bdpy.dl.torch.domain.image_domain.AffineDomain""" def setUp(self): @@ -76,6 +77,7 @@ def test_send_and_receive(self): expected_received_image = expected_transformed_image * scale3d - center3d torch.testing.assert_close(received_image, expected_received_image) + class TestRGBDomain(unittest.TestCase): """Tests fot bdpy.dl.torch.domain.image_domain.BGRDomain""" @@ -95,6 +97,7 @@ def test_receive(self): received_image = bgr_domain.receive(self.rgb_image) torch.testing.assert_close(received_image, self.bgr_image) + class TestPILDomainWithExplicitCrop(unittest.TestCase): """Tests fot bdpy.dl.torch.domain.image_domain.PILDomainWithExplicitCrop""" def setUp(self): @@ -115,6 +118,7 @@ def test_receive(self): self.assertTrue(any(isinstance(warn.message, RuntimeWarning) for warn in w)) torch.testing.assert_close(received_image, self.image) + class TestFixedResolutionDomain(unittest.TestCase): """Tests fot bdpy.dl.torch.domain.image_domain.FixedResolutionDomain""" def setUp(self): @@ -134,5 +138,6 @@ def test_receive(self): received_image = fr_domain.receive(self.image) self.assertEqual(received_image.size(), self.expected_received_image_size) + if __name__ == "__main__": unittest.main() \ No newline at end of file From d86e526b20b11218a93daf56023cb5cc1ff04c2e Mon Sep 17 00:00:00 2001 From: myaokai <65484599+myaokai@users.noreply.github.com> Date: Thu, 21 Mar 2024 16:07:47 +0900 Subject: [PATCH 27/27] fix --- tests/recon/torch/task/test_inversion.py | 2 ++ tests/task/test_core.py | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/recon/torch/task/test_inversion.py b/tests/recon/torch/task/test_inversion.py index dc548cb9..080fe930 100644 --- a/tests/recon/torch/task/test_inversion.py +++ b/tests/recon/torch/task/test_inversion.py @@ -114,6 +114,7 @@ def test_on_iteration_end(self, mock_print): self.callback.on_iteration_end(step=0) mock_print.assert_called_once_with("Step: [1], Loss: -1.0000") + class MLP(nn.Module): """A simple MLP.""" @@ -129,6 +130,7 @@ def forward(self, x): x = self.fc2(x) return x + class LinearGenerator(generator_module.NNModuleGenerator): def __init__(self): super().__init__() diff --git a/tests/task/test_core.py b/tests/task/test_core.py index 98b92527..0ba74d4e 100644 --- a/tests/task/test_core.py +++ b/tests/task/test_core.py @@ -3,9 +3,9 @@ from __future__ import annotations import unittest - from bdpy.task import core as core_module + class MockCallback(core_module.BaseCallback): """Mock callback for testing.""" def __init__(self): @@ -14,12 +14,14 @@ def __init__(self): def on_some_event(self, input_): self._storage.append(input_) + class MockTask(core_module.BaseTask[MockCallback]): """Mock task for testing BaseTask.""" def __call__(self, *inputs, **parameters): self._callback_handler.fire("on_some_event", input_=1) return inputs, parameters + class TestBaseTask(unittest.TestCase): """Tests forbdpy.task.core.BaseTask """ def setUp(self): @@ -56,5 +58,6 @@ def test_call(self): self.assertEqual(task_parameters["name"], self.task_name) self.assertEqual(mock_callback._storage, [1]) + if __name__ == "__main__": unittest.main() \ No newline at end of file