From 88ae1030bd71a5e7c8127e9c77be67eeaad6700e Mon Sep 17 00:00:00 2001 From: agisga <11449372+agisga@users.noreply.github.com> Date: Tue, 28 May 2024 16:55:07 -0400 Subject: [PATCH] adds missing doc files to git --- docs/build/doctrees/add_dset.doctree | Bin 0 -> 20184 bytes docs/build/doctrees/add_model.doctree | Bin 0 -> 13065 bytes docs/build/doctrees/addnew_link.doctree | Bin 0 -> 78706 bytes .../conferences_commandlines.doctree | Bin 0 -> 25964 bytes .../html/_modules/domid/algos/zoo_algos.html | 406 +++++++++++++ docs/build/html/_modules/domid/mk_exp.html | 407 +++++++++++++ .../html/_modules/domid/tests/utils.html | 376 ++++++++++++ .../_modules/domid/trainers/zoo_trainer.html | 406 +++++++++++++ docs/build/html/_sources/add_dset.md.txt | 115 ++++ docs/build/html/_sources/add_model.md.txt | 70 +++ docs/build/html/_sources/addnew_link.rst.txt | 9 + .../conferences_commandlines.md.txt | 112 ++++ docs/build/html/add_dset.html | 481 +++++++++++++++ docs/build/html/add_model.html | 430 +++++++++++++ docs/build/html/addnew_link.html | 569 ++++++++++++++++++ .../conferences_commandlines.html | 490 +++++++++++++++ 16 files changed, 3871 insertions(+) create mode 100644 docs/build/doctrees/add_dset.doctree create mode 100644 docs/build/doctrees/add_model.doctree create mode 100644 docs/build/doctrees/addnew_link.doctree create mode 100644 docs/build/doctrees/markdownfiles/conferences_commandlines.doctree create mode 100644 docs/build/html/_modules/domid/algos/zoo_algos.html create mode 100644 docs/build/html/_modules/domid/mk_exp.html create mode 100644 docs/build/html/_modules/domid/tests/utils.html create mode 100644 docs/build/html/_modules/domid/trainers/zoo_trainer.html create mode 100644 docs/build/html/_sources/add_dset.md.txt create mode 100644 docs/build/html/_sources/add_model.md.txt create mode 100644 docs/build/html/_sources/addnew_link.rst.txt create mode 100644 docs/build/html/_sources/markdownfiles/conferences_commandlines.md.txt create mode 100644 docs/build/html/add_dset.html create mode 100644 docs/build/html/add_model.html create mode 100644 docs/build/html/addnew_link.html create mode 100644 docs/build/html/markdownfiles/conferences_commandlines.html diff --git a/docs/build/doctrees/add_dset.doctree b/docs/build/doctrees/add_dset.doctree new file mode 100644 index 0000000000000000000000000000000000000000..5b498c8003c98b4732271e5ba9ccb9b19d85c180 GIT binary patch literal 20184 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 NCljW$z4WM7{|CD8DAE7` literal 0 HcmV?d00001 diff --git a/docs/build/doctrees/add_model.doctree b/docs/build/doctrees/add_model.doctree new file mode 100644 index 0000000000000000000000000000000000000000..2be1cccb277edd94689cbda6cb690810e8a684a6 GIT binary patch literal 13065 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 literal 0 HcmV?d00001 diff --git a/docs/build/doctrees/markdownfiles/conferences_commandlines.doctree b/docs/build/doctrees/markdownfiles/conferences_commandlines.doctree new file mode 100644 index 0000000000000000000000000000000000000000..c7321d0937eeab4eea70e4a3adef78cf6764e191 GIT binary patch literal 25964 zcmeHQYiu0Xb(SoV5~-JETaHmbaxKR;Wpj7AT)sqCX=#eFX<3Y5O0tkR7|!ktIkTFb zSf!dp*F;Wz0+5&aj{Akl3MgO&EfdXlRI4%P8Pf)i%3ba7c0zr!c z0s5UgbLZY2?o*OoyOCk9=XLKr=iKwU=bn4`#>h8xa}WO~J{B}B+r3fL4a4;eGib#J z4X+k8OgC)3-8%K<*6Xc_c+A(Y2VUgY%vQVyU(_tyF?`c)eF-m*()Xe51jV$21A$o! zZO_fxTO-z}bpYR5WAR96hmNVdiXS?^y1cx!%BH8LD{R?wH%;_hGuZ{bY5FZ{hi3aP znl}ibK3~7tN&p^h>gXhFS;ylsEyKs!7mucBti}5s+cjHjQB{w}^)U49Y7_!}LU*5S z1VAl5P;>Mkz(ZV*xOyYGI%q^qc~jMESABDnzKP-kp}s}0TGlb^k#l>khvUzcg3$Bz zEpz%}Y0D0+s9HMfHCBxhfC@?t-M?yh*WFFqF@sVq!#&VyUZbJA2EiB<8%E1|&^l~A zWbKQpAjTN5)3Ej#_>(wz547r zaAdB>fQw-h6EMBmbZqpG;R%)obyMWiI$_-(U-__rZl$aM!j*_{*28PoBbaTBxp%zB z%a=X`WV?W3TAv2DS&xFjAH#o-^Uz8z*M+jDzXU@w^K!S)-;>!k{d*r*K2lwiCT6dFpO`z zTWr(wNg|V()E%~JVB+mfyQcH01$(VW)h*wPz+Nw7=D|ZcJ8Of{@$m&cv^>Y#+GeW_ z2mo6*!y;RC+4DvAoNty2@nYLF^ul@FYIvSO$h}l#7xiri08gwKLGcu@Hw^#^p!w*_UZV*u1*9NWK#J~6 zpDhJ}4QvenhTCg|9(eYHH{NEdR+_l%K^n?4)6?^ltl2EGxw$!fGdDjA3a&SaR_JR@ z4dU6RmZDcRVMJt9;ni$XNGWx{K#d^ZCE9j zHFVq6yeKR-w^^YOnwr6;=)&h0Wj0MWdT{lOW%_h&Hof2s6gMt)^6<`F(+v|huNj(Q zH_lAY(wpSE!d@B2S526|Glti&jgszcc|oZf!D%*qjanwdzIbL9t>A)bp?_wY_du=K zNn&oegN-WOKLalT>`8nXz>^BuRB-{<)c`QkK#q?mQ}`$8%Z3GfPLBe7!d)#^bKUWD zHtx`ZXpwLoysCGCYIo_155jwwa_Z)Aa|VMFmPY(H#t8( za_$Iv6+9`G+W1pXtwDtaPd&BBCjx%2H7a@k4^`fW78(sg-*dMV9*#$Ndm&Tlo$TRH z)gHQ|L<-|iAU*e{(!&Q%6vm>WFxuehuP{V!0`IZ-P&INKGt?Y-RtgqEfxtA<8x6X) zvFo)Z$@U64kYd?j=#WONN+vc85|NEl%r#AeFKVhV7Dk$0APIMeaA;*tZ;#zK|{YE$-*_in;eZ8lSI>bs>OBSeA0!Q|9| zZ(CkgO~<>=uG@~oBCJ2@qvtMM!V+SWZF>=31e`lasna{T3Z=PUzHljPm9C{3EvB(( z-QvLwwoxd!2wW)M!p_GAHpzZaQHf!=H1X3;q`zL(O*U z2!?9gtdcolcZlP5AWp)I)`Rs`@Xmmane_+OyViF|W`qOw3+O=MNa;*`Kk>off-y`B zf=?9YNyDSb9Km}?~!J;#P5z zN72YaaS0WU3``o2xzdX!MYn0G#U;Dli>zPCNwD=jA&v2V z@*agYNN%L$Yq@s4Z3MZGER}pQBDWEr8HBEiSrd(g8BxsIVU_v>aL@V0@HyDM~U`QMI0RLo>@zrme zQOOKoeGYxcOM~0JZlemDms*r;pQA_Q;Y>H1$DXDgjcYbS$j&xhA_UCW1s*N2a7@LJ}vaHoyX@=#^tb+FU3t=BhrpmT#h?4fM~Y%-Dq#7@a*%gO$5D^9|X zb2D|bPQp)e{q&x3auO!f85a=n89#q2*^;
vsy5l(911*Lb=^8Cl`!R)Carcw?r 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 literal 0 HcmV?d00001 diff --git a/docs/build/html/_modules/domid/algos/zoo_algos.html b/docs/build/html/_modules/domid/algos/zoo_algos.html new file mode 100644 index 0000000..80ccdf2 --- /dev/null +++ b/docs/build/html/_modules/domid/algos/zoo_algos.html @@ -0,0 +1,406 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + domid.algos.zoo_algos — domid documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content +
+ +
+ + +
+ + + + +
+
+ +
+
+
+ +
+
+
+
+
+
+ + +
+
+
+ +
+
+ +

Source code for domid.algos.zoo_algos

+"""
+chain of responsibility pattern for algorithm selection
+"""
+from domainlab.utils.u_import import import_path
+
+from domid.algos.builder_ae import NodeAlgoBuilderAE
+from domid.algos.builder_dec import NodeAlgoBuilderDEC
+from domid.algos.builder_m2yd import NodeAlgoBuilderM2YD
+from domid.algos.builder_sdcn import NodeAlgoBuilderSDCN
+from domid.algos.builder_vade import NodeAlgoBuilderVaDE
+
+
+
[docs]class AlgoBuilderChainNodeGetter: + + """ + 1. Hardcoded chain + 3. Return selected node + """ + +
[docs] def __init__(self, model, apath): + self.model = model + self.apath = apath + # + self._list_str_model = model.split("_") + self.model = self._list_str_model.pop(0)
+ +
[docs] def register_external_node(self, chain): + """ + if the user specify an external python file to implement the algorithm + """ + if self.apath is None: + return chain + node_module = import_path(self.apath) + node_fun = node_module.get_node_na() + newchain = node_fun(chain) + return newchain
+ + def __call__(self): + """ + 1. construct the chain, filter out responsible node, create heavy-weight business object + 2. hard code seems to be the best solution + """ + + chain = NodeAlgoBuilderSDCN(None) + chain = NodeAlgoBuilderDEC(chain) + chain = NodeAlgoBuilderVaDE(chain) + chain = NodeAlgoBuilderAE(chain) + chain = NodeAlgoBuilderM2YD(chain) + chain = self.register_external_node(chain) + node = chain.handle(self.model) + head = node + while self._list_str_model: + self.model = self._list_str_model.pop(0) + node2decorate = self.__call__() + head.extend(node2decorate) + head = node2decorate + return node
+
+ +
+
+
+
+
+
+ + +
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/domid/mk_exp.html b/docs/build/html/_modules/domid/mk_exp.html new file mode 100644 index 0000000..07e087a --- /dev/null +++ b/docs/build/html/_modules/domid/mk_exp.html @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + domid.mk_exp — domid documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content +
+ +
+ + +
+ + + + +
+
+ +
+
+
+ +
+
+
+
+
+
+ + +
+
+
+ +
+
+ +

Source code for domid.mk_exp

+"""
+make an experiment
+"""
+from domid.arg_parser import mk_parser_main
+from domid.compos.exp.exp_main import Exp
+
+
+
[docs]def mk_exp( + task, + model, + trainer: str, + train_domain: str, + test_domain: str, + batchsize: int, + pre_tr=5, + epos=10, + nocu=True, + shuffling_off=False, + **kwargs, +): + """ + Creates a custom experiment. The user can specify the input parameters. + :param task: use a predefined task in DomId, or create a task to a custom dataset. For more explanation on the + input params refer to the documentation found in "domainlab.tasks.task_dset.py". + :param model: create a model [NameOfModel] by importing the appropriate "mk_[NameOfModel]". For a concrete example + and explanation of the input params refer to the documentation found in "domainlab.models.model_[NameOfModel].py" + :param string trainer: for instance, 'ae', 'cluster', 'sdcn'; see the available trainers under 'domid/trainers/' + and 'domainlab/trainers/' or define your own trainer. + :param string test_domain: enumerate which domains from the chosen 'task' to use for training (separated by spaces) + :param string test_domain: enumerate which domains from the chosen 'task' to use for testing (separated by spaces) + :param int batchsize: batch size to use for training + :param \**kwargs: any additional parameters that can be processed by the arg_parser of DomId or DomainLab + :return exp: the experiment object + """ + str_arg = ( + f"--model={model} --trainer={trainer} --bs={batchsize} --task={task} " + f"--pre_tr={pre_tr} --epos={epos} --d_dim={len(train_domain.split(' '))} " + ) + if nocu: + str_arg += " --nocu " + if shuffling_off: + str_arg += " --shuffling_off " + + str_arg += " --tr_d " + train_domain + str_arg += " --te_d " + test_domain + + # Iterating over the Python kwargs dictionary + for key, value in kwargs.items(): + if type(value) == bool: + str_arg += f" --{key}" + else: + str_arg += f" --{key}={value}" + + parser = mk_parser_main() + conf = parser.parse_args(str_arg.split()) + print(conf) + exp = Exp(conf, task, model=model) + return exp
+
+ +
+
+
+
+
+
+ + +
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/domid/tests/utils.html b/docs/build/html/_modules/domid/tests/utils.html new file mode 100644 index 0000000..7d1a30f --- /dev/null +++ b/docs/build/html/_modules/domid/tests/utils.html @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + domid.tests.utils — domid documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content +
+ +
+ + +
+ + + + +
+
+ +
+
+
+ +
+
+
+
+
+
+ + +
+
+
+ +
+
+ +

Source code for domid.tests.utils

+import os
+import shutil
+
+from domid.compos.exp.exp_main import Exp
+
+
+
[docs]def experiment_train(args, save_path=None): + + exp = Exp(args) + # exp.execute() + exp.trainer.before_tr() + exp.trainer.tr_epoch(0) + # exp.trainer.post_tr() + if not save_path is None: + # This is used to move the saved model weights and all byproducts of the test run into a temporary + # directory, so that the actual results directory will not be polluted with the byproduct files of the tests. + # This is also used as a mechanism to reuse the same saved weights between different test functions. + source_dir = exp.trainer.storage.ex_path + dest_dir = save_path + for file_name in os.listdir(source_dir): + source_file = os.path.join(source_dir, file_name) + destination_file = os.path.join(dest_dir, file_name) + shutil.move(source_file, destination_file) + if not os.listdir(source_dir): + os.rmdir(source_dir) + else: + raise OSError(f"Trying to delete {source_dir}, but it is not empty.")
+
+ +
+
+
+
+
+
+ + +
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/domid/trainers/zoo_trainer.html b/docs/build/html/_modules/domid/trainers/zoo_trainer.html new file mode 100644 index 0000000..105b8b0 --- /dev/null +++ b/docs/build/html/_modules/domid/trainers/zoo_trainer.html @@ -0,0 +1,406 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + domid.trainers.zoo_trainer — domid documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content +
+ +
+ + +
+ + + + +
+
+ +
+
+
+ +
+
+
+
+
+
+ + +
+
+
+ +
+
+ +

Source code for domid.trainers.zoo_trainer

+"""
+select trainer
+"""
+from domainlab.algos.trainers.train_basic import TrainerBasic
+from domainlab.algos.trainers.train_hyper_scheduler import TrainerHyperScheduler
+
+from domid.trainers.trainer_ae import TrainerAE
+from domid.trainers.trainer_cluster import TrainerCluster
+from domid.trainers.trainer_sdcn import TrainerSDCN
+
+
+
[docs]class TrainerChainNodeGetter(object): + """ + Chain of Responsibility: node is named in pattern Trainer[XXX] where the string + after 'Trainer' is the name to be passed to args.trainer. + """ + +
[docs] def __init__(self, str_trainer): + """__init__. + :param args: command line arguments + """ + self._list_str_trainer = None + if str_trainer is not None: + self._list_str_trainer = str_trainer.split("_") + self.request = self._list_str_trainer.pop(0) + else: + self.request = str_trainer
+ + def __call__(self, lst_candidates=None, default=None, lst_excludes=None): + """ + 1. construct the chain, filter out responsible node, + create heavy-weight business object + 2. hard code seems to be the best solution + """ + if lst_candidates is not None and self.request not in lst_candidates: + raise RuntimeError( + f"desired {self.request} is not supported \ + among {lst_candidates}" + ) + if default is not None and self.request is None: + self.request = default + if lst_excludes is not None and self.request in lst_excludes: + raise RuntimeError(f"desired {self.request} is not supported among {lst_excludes}") + + chain = TrainerBasic(None) + chain = TrainerSDCN(chain) + chain = TrainerCluster(chain) + chain = TrainerAE(chain) + + node = chain.handle(self.request) + head = node + while self._list_str_trainer: + self.request = self._list_str_trainer.pop(0) + node2decorate = self.__call__(lst_candidates, default, lst_excludes) + head.extend(node2decorate) + head = node2decorate + return node
+
+ +
+
+
+
+
+
+ + +
+ + + + \ No newline at end of file diff --git a/docs/build/html/_sources/add_dset.md.txt b/docs/build/html/_sources/add_dset.md.txt new file mode 100644 index 0000000..1020c93 --- /dev/null +++ b/docs/build/html/_sources/add_dset.md.txt @@ -0,0 +1,115 @@ +# How to Add a New Dataset + +This tutorial guides you through the steps to add a new dataset to our framework in a Python project. +Each dataset is loaded by the domain label, i.e., a separate dataset object is loaded for each domain. The corresponding domain labels are specified in the command line/experiment definition (`--tr_d`). + +Within each such dataset (one per domain), individual observations have the form (X, Y), where X would be an image (or features, etc.) and Y would be its associated label. In general, the label Y is a separate concept from the domain label. + +Follow the steps below to set up and configure your own dataset for the experiments. + +## Step 1: Create Dataset File + +1. Navigate to the `dset` folder in your project directory. +2. Create a new Python file named `dset_.py`, replacing `` with the name of your dataset. + +## Step 2: Define the Dataset Class + +Inside your new file, you will need to define a dataset class with necessary methods, along the lines of: + +```python +class DsetYourClass: + def __init__(self, domain_label): + # Initialization code here + + + def __getitem__(self, index): + # Code to load an image and its associated labels + # Returns: + # - image: the loaded image + # - image_label: the label associated with the image + # - conditional_label: a condition associated with the image + # - image_id: the identifier for the image + return image, image_label, conditional_label, image_id + ``` + +## Step 3: Implementing `__getitem__` + +The `__getitem__` method is a key part of the dataset class, which should be implemented to load and return the necessary data: + +- **image**: This should load the actual image from the dataset. +- **image_label**: Load the label (not the domain label) that is associated with the image. +- **conditional_label**: If your dataset includes conditions (for example, any additionally annotated label), this can be included using a CSV file. +- **image_id**: Useful for tracking which image is being processed, especially in debugging or complex data handling scenarios. + +## Step 4: Create a task class that would utilize your Dset class + +1. Navigate to the tasks folder in your project directory. +2. Create a task file specific to your dataset. This file will manage loading one domain at a time and will be passed to the experiment. +4. The task_.py should contain the following functions: + +```python +class NodeTaskTemplate(NodeTaskDictCluster): + """Basic template for tasks where categories are considered 'domains' + """ + + @property + def list_str_y(self): + """ + This task has no conventional labels; categories are treated as domains. + """ + return mk_dummy_label_list_str("label_prefix", number_of_domains) + + @property + def isize(self): + """ + :return: Image size object storing image channels, height, width. + """ + return ImSize(channels, height, width) + + def get_list_domains(self): + """ + Get list of domain names. + :return: List of domain names. + """ + return mk_dummy_label_list_str("domain_prefix", number_of_domains) + + def get_dset_by_domain(self, args, na_domain, split=False): + """ + Get a dataset by domain. + :param args: Command line arguments. + :param na_domain: Domain name. + :param split: Whether to perform a train/validation split. + :return: Training dataset, Validation dataset. + """ + ratio_split = float(args.split) if split else False + trans = [transforms.Resize((desired_height, desired_width)), transforms.ToTensor()] + ind_global = self.get_list_domains().index(na_domain) + dset = DsetYourClass(domain=ind_global, args=args, list_transforms=trans) + + if ratio_split > 0: + train_len = int(len(dset) * ratio_split) + val_len = len(dset) - train_len + train_set, val_set = random_split(dset, [train_len, val_len]) + else: + train_set = dset + val_set = dset + return train_set, val_set +``` + +## Step 5: Add new Task Chain in `TaskChainNodeGetter` Class + +After defining your task class, you will need to integrate it into the processing chain. +This is typically done in the `zoo_task.py` file where multiple tasks are chained together for sequential processing. + +Here's how to add your new task to the chain: + +1. Navigate to `zoo_task.py` to the `TaskChainNodeGetter` class. +2. Add your `NodeTaskTemplate` to the existing chain as shown below: + +```python +chain = NodeTaskTemplate(succ=chain) +``` + +## Conclusion + +With the dataset class set up in your `dset_.py` file that is imported to `task_.py`, your new dataset is ready to be integrated into your project. diff --git a/docs/build/html/_sources/add_model.md.txt b/docs/build/html/_sources/add_model.md.txt new file mode 100644 index 0000000..4143582 --- /dev/null +++ b/docs/build/html/_sources/add_model.md.txt @@ -0,0 +1,70 @@ +# Adding a New Model to the Domid Python Package + +This tutorial will guide you through the steps to add a new model file to the `models` submodule in the `domid` Python package. + + +## Step 1: Create the Model File and Define the Model Class + +Navigate to the `models` directory in the `domid` codebase and create a file named `model_.py`. +In this file, you will construct the new model, define loss optimization functions, and configure any necessary clustering layers. +The layers of the model are defined in the `compos` submodule. +Here, you can find already implemented fully-connected and convolutional VAEs (Variational AutoEncoders) and AEs (AutoEncoders). +These components can be used as building blocks for your model. +Create a class for your model by extending a base model class from `domid`. +Typically, models extend from a common base class such as `a_model_cluster.py`, which provides some of the default functionalities, and are wrapped within a `mk_model` method: + +```python +def mk_model(parent_class=AModelCluster): + class CustomModel(parent_class): + def __init__(self, arg1, arg2, ...): + super(CustomModel, self).__init__() + # Model initialization and layer definitions + self.model = model + + def _inference(self, x): + # ... + + def infer_d_v_2(self, x, inject_domain): + # ... + + def _cal_reconstruction_loss_helper(self, x,y): + # ... + + # Implement any additional methods necessary for your model + def _cal_loss_(self, x, y): + # ... + + return CustomModel +``` + +## Step 2: Implement a trainer function if needed + +When integrating your model into the `domid` package, +you have the option to utilize an existing trainer from the package or define a new trainer that caters +to the specific needs of your model. Below are details on both approaches. + +### Using an Existing Trainer + +`domid` includes several generic trainers that are designed to work with a variety of models. +For example, `trainer_cluster.py`, which is compatible with VaDE and DEC models. + +### Defining a New Trainer + +If the existing trainers do not meet the specific requirements of your model, +you may need to define a new trainer. This involves: + +**Creating a Trainer Class:** Define a class in Python that encapsulates all +aspects of training your model. This includes initializing the model, +running the training loops, handling validation, and potentially testing. + +```python +class CustomTrainer: + def __init__(self, model, optimizer, loss_fn, device): + self.model = model.to(device) + self.optimizer = optimizer + self.loss_fn = loss_fn + self.device = device + + def tr_epoch(self, epoch_number): + # runs one epoch of experiemnt for more details look at any other the existing trainers +``` diff --git a/docs/build/html/_sources/addnew_link.rst.txt b/docs/build/html/_sources/addnew_link.rst.txt new file mode 100644 index 0000000..e79d48c --- /dev/null +++ b/docs/build/html/_sources/addnew_link.rst.txt @@ -0,0 +1,9 @@ +---------------------------------- +Add new modalities to the package +---------------------------------- + +.. include:: add_dset.md + :parser: myst_parser.sphinx_ + +.. include:: add_model.md + :parser: myst_parser.sphinx_ diff --git a/docs/build/html/_sources/markdownfiles/conferences_commandlines.md.txt b/docs/build/html/_sources/markdownfiles/conferences_commandlines.md.txt new file mode 100644 index 0000000..55ae8b4 --- /dev/null +++ b/docs/build/html/_sources/markdownfiles/conferences_commandlines.md.txt @@ -0,0 +1,112 @@ +# MICCAI 2023 Conference Paper + +This is a summary of the steps to reproduce results presented in [Sidulova et al. 2023]. +Base Model experiments are the experiments with no condition applied to the model. + +[Sidulova et al. 2023] Sidulova, M., Sun, X., & Gossmann, A. (2023). Deep Unsupervised Clustering for Conditional Identification of Subgroups Within a Digital Pathology Image Set. In H. Greenspan, A. Madabhushi, P. Mousavi, S. Salcudean, J. Duncan, T. Syeda-Mahmood, & R. Taylor (Eds.), Medical Image Computing and Computer Assisted Intervention – MICCAI 2023 (Vol. 14227, pp. 666–675). Springer Nature Switzerland. + +The same as in the `notebooks/case-study-HER2_VaDE_CDVaDE-DEC.ipynb`. + + +## VaDE Base Model Experiments + +``` +poetry run python main_out.py --te_d 0 --tr_d 0 1 2 --task=her2 --epos=100 --aname=vade --zd_dim=250 --d_dim=3 \ +--apath=domid/algos/builder_vade.py --L=5 --pre_tr=20 --dpath "HER2/combined_train" --split 0.8 --bs 2 \ +--lr 0.00005 --prior Gaus --model cnn +``` + +**Notes**: +- Path to the dataset (`dpath`) needs to be adjusted depending on the location of the dataset. +- By default this and the other experiments below will use the GPU. If you wish to run the experiment on CPU use the command line argument `--nocu`. + + +## CVaDE: HER2 class labels + +``` +poetry run python main_out.py --te_d 0 --tr_d 0 1 2 --task=her2 --epos=100 --aname=vade --zd_dim=250 --d_dim=3 \ +--apath=domid/algos/builder_vade.py --L=5 --pre_tr=20 --dpath "HER2/combined_train" --split 0.8 --bs 2 \ +--lr 0.00005 --prior Gaus --model cnn --dim_inject_y 3 +``` + +**Note**: dimension of the injected labels (`dim_inject_y`) should be adjusted. Number of the possible class labels (e.g., for the HER2 dataset used in the paper it would be 3 - class 1, class 2, class 3) + + +## CVaDE: HER2 class labels + previously predicted domain labels + +``` +poetry run python main_out.py --te_d 0 --tr_d 0 1 2 --task=her2 --epos=100 --aname=vade --zd_dim=250 --d_dim=3 \ +--apath=domid/algos/builder_vade.py --L=5 --pre_tr=20 --dpath "HER2/combined_train" --split 0.8 --bs 2 \ +--lr 0.00005 --prior Gaus --model cnn --dim_inject_y 6 --path_to_domain notebooks/2022-11-02\ 17\:30\:13.132561/ +``` + +**Notes**: +- Dimension of the injected labels (`dim_inject_y`) in this case is the sum of the dimensions of the possible class labels and `d_dim` of previously predicted domains. (e.g. ). +- `path_to_domain` is the path to the previously obtained results directory and needs to be specified. Predicted domain labels should be stored within the directory `path_to_domain` in the file `domain_labels.txt`. + + +# CHIL 2024 Conference: + +(in press) Sidulova M., Khaki S, Hegman I., Gossmann A. "Contextual unsupervised deep clustering of digital pathology dataset", Accepted in CHIL 2024. + + +## Experiments with Colored MNIST dataset + +The following experiments are the same as in the `notebook/tutrial-MNIST-sdcn.ipynb`. + +### AE pretraining + +``` +poetry python main_out.py --te_d 0 --tr_d 0 1 2 3 4 5 6 7 8 9 --task=mnistcolor10 --epos=100 --aname ae --d_dim=10 --apath=domid/algos/builder_AE.py --bs 128 --lr 0.0001 --zd_dim=20 --pre_tr=0 --model cnn --prior Gaus +``` + +### SDCN + +``` +poetry python main_out.py --te_d 0 --tr_d 0 1 2 3 4 5 6 7 8 9 --task=mnistcolor10 --epos=100 --aname sdcn --d_dim=10 --apath=domid/algos/builder_sdcn.py --bs 600 --lr 0.0001 --zd_dim=20 --pre_tr=2 --model cnn --prior Gaus --pre_tr_weight_path path/to/pretrained/AE/' +``` + +``` +poetry python main_out.py --te_d 0 --tr_d 0 1 2 3 4 5 6 7 8 9 --task=mnistcolor10 --epos=100 --aname sdcn --d_dim=10 --apath=domid/algos/builder_sdcn.py --bs 600 --lr 0.0001 --zd_dim=20 --pre_tr=2 --model cnn --prior Gaus --pre_tr_weight_path 'path/to/pretrained/AE/’ + +``` + +Sample pretrained AE for colored MNIST could be found in `./notebooks/2023-08-03 09:06:05.234348_mnistcolor10_ae/`, `./notebooks/2023-08-01 13:53:39.168459_mnistcolor10_ae/`. + + +## Experiments with Wash U dataset + + +## WashU Dset + +The following experiments are also set in `notebooks/case-study-WashU_AS_SDCN.ipynb`. + +### AE pretraining + +``` +CUDA_VISIBLE_DEVICES=2 python main_out.py --te_d 0 --tr_d 0 1 2 3 4 5 6 7 8 9 --task=weah --epos=100 --aname ae --d_dim=10 --apath=domid/algos/builder_AE.py --dpath '../../WashU-WSI-data/patches_WashU_Aperio/data/png_files/' --bs 128 --lr 0.0001 --zd_dim=100 --pre_tr=2 --model cnn --prior Gaus --tr_d_range 0 24 +``` + +### SDCN training + +``` +CUDA_VISIBLE_DEVICES=2 python main_out.py --te_d 0 --tr_d 0 1 2 3 4 5 6 7 8 9 --task=weah --epos=100 --aname sdcn --d_dim=6 --apath=domid/algos/builder_sdcn.py --dpath '../../WashU_with_coord/combined_training_with_coords/' --bs 1200 --lr 0.0001 --zd_dim=1000 --pre_tr=2 --model cnn --pre_tr_weight_path 'path/to/pretrained/AE' --tr_d_range 0 65 --meta_data_csv 'path/to_csv_file_that_is_generated_from_the_notebook.csv' +``` + +- Sample path to generated csv file: `../../WashU_with_coord/dset_WEAH.csv`, `../../WashU_with_coord/dset_WEAH_65_subjects_3_regions.csv`. +- Sample paths to pretrained AEs: `./notebooks/2023-06-30 10:38:27.253550_weah_ae/`, `./notebooks/2023-07-05 12:18:40.078628_weah_ae/`. + + +### VADE training + +``` +CUDA_VISIBLE_DEVICES=2 python main_out.py --te_d 0 --tr_d 0 1 2 --task=weah --epos=50 --aname=vade --zd_dim=500 --d_dim=6 --apath=domid/algos/builder_vade.py --L=5 --pre_tr=17 --dpath "../../WashU_with_coord/combined_training_with_coords" --bs 4 --prior Gaus --model cnn --lr 0.0001 --tr_d_range 0 65 --meta_data_csv '../../WashU_with_coord/dset_WEAH_65_subjects_3_regions.csv' +``` + +### DEC training + +``` +CUDA_VISIBLE_DEVICES=2 python main_out.py --te_d 0 --tr_d 0 1 2 --task=weah --epos=50 --aname=dec --zd_dim=500 --d_dim=6 --apath=domid/algos/builder_dec.py --L=5 --pre_tr=2 --dpath "../../WashU_with_coord/combined_training_with_coords" --bs 4 --prior Gaus --model cnn --lr 0.0001 --tr_d_range 0 6 --meta_data_csv '../../WashU_with_coord/dset_WEAH_65_subjects_3_regions.csv' --pre_tr_weight_path './notebooks/2023-06-30 10:38:27.253550_weah_ae/' --feat_extract ae +``` + +- Note: `--feat_extract` can be either "ae" of "vae", option for loading pretrained weights also in place. diff --git a/docs/build/html/add_dset.html b/docs/build/html/add_dset.html new file mode 100644 index 0000000..21e232f --- /dev/null +++ b/docs/build/html/add_dset.html @@ -0,0 +1,481 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + How to Add a New Dataset — domid documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content +
+ +
+ + +
+ + + + +
+
+ +
+
+
+ +
+
+
+ + +
+
+ +
+

How to Add a New Dataset

+

This tutorial guides you through the steps to add a new dataset to our framework in a Python project. +Each dataset is loaded by the domain label, i.e., a separate dataset object is loaded for each domain. The corresponding domain labels are specified in the command line/experiment definition (--tr_d).

+

Within each such dataset (one per domain), individual observations have the form (X, Y), where X would be an image (or features, etc.) and Y would be its associated label. In general, the label Y is a separate concept from the domain label.

+

Follow the steps below to set up and configure your own dataset for the experiments.

+
+

Step 1: Create Dataset File

+
    +
  1. Navigate to the dset folder in your project directory.

  2. +
  3. Create a new Python file named dset_<name>.py, replacing <name> with the name of your dataset.

  4. +
+
+
+

Step 2: Define the Dataset Class

+

Inside your new file, you will need to define a dataset class with necessary methods, along the lines of:

+
class DsetYourClass:
+    def __init__(self, domain_label):
+        # Initialization code here
+
+
+    def __getitem__(self, index):
+        # Code to load an image and its associated labels
+        # Returns:
+        # - image: the loaded image
+        # - image_label: the label associated with the image
+        # - conditional_label: a condition associated with the image
+        # - image_id: the identifier for the image
+        return image, image_label, conditional_label, image_id
+
+
+
+
+

Step 3: Implementing __getitem__

+

The __getitem__ method is a key part of the dataset class, which should be implemented to load and return the necessary data:

+
    +
  • image: This should load the actual image from the dataset.

  • +
  • image_label: Load the label (not the domain label) that is associated with the image.

  • +
  • conditional_label: If your dataset includes conditions (for example, any additionally annotated label), this can be included using a CSV file.

  • +
  • image_id: Useful for tracking which image is being processed, especially in debugging or complex data handling scenarios.

  • +
+
+
+

Step 4: Create a task class that would utilize your Dset class

+
    +
  1. Navigate to the tasks folder in your project directory.

  2. +
  3. Create a task file specific to your dataset. This file will manage loading one domain at a time and will be passed to the experiment.

  4. +
  5. The task_.py should contain the following functions:

  6. +
+
class NodeTaskTemplate(NodeTaskDictCluster):
+    """Basic template for tasks where categories are considered 'domains'
+    """
+
+    @property
+    def list_str_y(self):
+        """
+        This task has no conventional labels; categories are treated as domains.
+        """
+        return mk_dummy_label_list_str("label_prefix", number_of_domains)
+
+    @property
+    def isize(self):
+        """
+        :return: Image size object storing image channels, height, width.
+        """
+        return ImSize(channels, height, width)
+
+    def get_list_domains(self):
+        """
+        Get list of domain names.
+        :return: List of domain names.
+        """
+        return mk_dummy_label_list_str("domain_prefix", number_of_domains)
+
+    def get_dset_by_domain(self, args, na_domain, split=False):
+        """
+        Get a dataset by domain.
+        :param args: Command line arguments.
+        :param na_domain: Domain name.
+        :param split: Whether to perform a train/validation split.
+        :return: Training dataset, Validation dataset.
+        """
+        ratio_split = float(args.split) if split else False
+        trans = [transforms.Resize((desired_height, desired_width)), transforms.ToTensor()]
+        ind_global = self.get_list_domains().index(na_domain)
+        dset = DsetYourClass(domain=ind_global, args=args, list_transforms=trans)
+
+        if ratio_split > 0:
+            train_len = int(len(dset) * ratio_split)
+            val_len = len(dset) - train_len
+            train_set, val_set = random_split(dset, [train_len, val_len])
+        else:
+            train_set = dset
+            val_set = dset
+        return train_set, val_set
+
+
+
+
+

Step 5: Add new Task Chain in TaskChainNodeGetter Class

+

After defining your task class, you will need to integrate it into the processing chain. +This is typically done in the zoo_task.py file where multiple tasks are chained together for sequential processing.

+

Here’s how to add your new task to the chain:

+
    +
  1. Navigate to zoo_task.py to the TaskChainNodeGetter class.

  2. +
  3. Add your NodeTaskTemplate to the existing chain as shown below:

  4. +
+
chain = NodeTaskTemplate(succ=chain)
+
+
+
+
+

Conclusion

+

With the dataset class set up in your dset_<name>.py file that is imported to task_<name>.py, your new dataset is ready to be integrated into your project.

+
+
+ + +
+
+
+
+
+
+ + +
+ + + + \ No newline at end of file diff --git a/docs/build/html/add_model.html b/docs/build/html/add_model.html new file mode 100644 index 0000000..61def52 --- /dev/null +++ b/docs/build/html/add_model.html @@ -0,0 +1,430 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Adding a New Model to the Domid Python Package — domid documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content +
+ +
+ + +
+ + + + +
+
+ +
+
+
+ +
+
+
+ + +
+
+ +
+

Adding a New Model to the Domid Python Package

+

This tutorial will guide you through the steps to add a new model file to the models submodule in the domid Python package.

+
+

Step 1: Create the Model File and Define the Model Class

+

Navigate to the models directory in the domid codebase and create a file named model_<name>.py. +In this file, you will construct the new model, define loss optimization functions, and configure any necessary clustering layers. +The layers of the model are defined in the compos submodule. +Here, you can find already implemented fully-connected and convolutional VAEs (Variational AutoEncoders) and AEs (AutoEncoders). +These components can be used as building blocks for your model. +Create a class for your model by extending a base model class from domid. +Typically, models extend from a common base class such as a_model_cluster.py, which provides some of the default functionalities, and are wrapped within a mk_model method:

+
def mk_model(parent_class=AModelCluster):
+    class CustomModel(parent_class):
+        def __init__(self, arg1, arg2, ...):
+            super(CustomModel, self).__init__()
+            # Model initialization and layer definitions
+            self.model = model
+
+        def _inference(self, x):
+            # ...
+
+        def infer_d_v_2(self, x, inject_domain):
+            # ...
+
+        def _cal_reconstruction_loss_helper(self, x,y):
+            # ...
+
+        # Implement any additional methods necessary for your model
+        def _cal_loss_(self, x, y):
+            # ...
+
+    return CustomModel
+
+
+
+
+

Step 2: Implement a trainer function if needed

+

When integrating your model into the domid package, +you have the option to utilize an existing trainer from the package or define a new trainer that caters +to the specific needs of your model. Below are details on both approaches.

+
+

Using an Existing Trainer

+

domid includes several generic trainers that are designed to work with a variety of models. +For example, trainer_cluster.py, which is compatible with VaDE and DEC models.

+
+
+

Defining a New Trainer

+

If the existing trainers do not meet the specific requirements of your model, +you may need to define a new trainer. This involves:

+

Creating a Trainer Class: Define a class in Python that encapsulates all +aspects of training your model. This includes initializing the model, +running the training loops, handling validation, and potentially testing.

+
class CustomTrainer:
+    def __init__(self, model, optimizer, loss_fn, device):
+        self.model = model.to(device)
+        self.optimizer = optimizer
+        self.loss_fn = loss_fn
+        self.device = device
+
+    def tr_epoch(self, epoch_number):
+        # runs one epoch of experiemnt for more details look at any other the existing trainers
+
+
+
+
+
+ + +
+
+
+
+
+
+ + +
+ + + + \ No newline at end of file diff --git a/docs/build/html/addnew_link.html b/docs/build/html/addnew_link.html new file mode 100644 index 0000000..bb392e8 --- /dev/null +++ b/docs/build/html/addnew_link.html @@ -0,0 +1,569 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Add new modalities to the package — domid documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content +
+ +
+ + +
+ + + + +
+
+ +
+
+
+ +
+
+
+ + +
+
+ +
+

Add new modalities to the package

+
+

How to Add a New Dataset

+

This tutorial guides you through the steps to add a new dataset to our framework in a Python project. +Each dataset is loaded by the domain label, i.e., a separate dataset object is loaded for each domain. The corresponding domain labels are specified in the command line/experiment definition (--tr_d).

+

Within each such dataset (one per domain), individual observations have the form (X, Y), where X would be an image (or features, etc.) and Y would be its associated label. In general, the label Y is a separate concept from the domain label.

+

Follow the steps below to set up and configure your own dataset for the experiments.

+
+

Step 1: Create Dataset File

+
    +
  1. Navigate to the dset folder in your project directory.

  2. +
  3. Create a new Python file named dset_<name>.py, replacing <name> with the name of your dataset.

  4. +
+
+
+

Step 2: Define the Dataset Class

+

Inside your new file, you will need to define a dataset class with necessary methods, along the lines of:

+
class DsetYourClass:
+    def __init__(self, domain_label):
+        # Initialization code here
+
+
+    def __getitem__(self, index):
+        # Code to load an image and its associated labels
+        # Returns:
+        # - image: the loaded image
+        # - image_label: the label associated with the image
+        # - conditional_label: a condition associated with the image
+        # - image_id: the identifier for the image
+        return image, image_label, conditional_label, image_id
+
+
+
+
+

Step 3: Implementing __getitem__

+

The __getitem__ method is a key part of the dataset class, which should be implemented to load and return the necessary data:

+
    +
  • image: This should load the actual image from the dataset.

  • +
  • image_label: Load the label (not the domain label) that is associated with the image.

  • +
  • conditional_label: If your dataset includes conditions (for example, any additionally annotated label), this can be included using a CSV file.

  • +
  • image_id: Useful for tracking which image is being processed, especially in debugging or complex data handling scenarios.

  • +
+
+
+

Step 4: Create a task class that would utilize your Dset class

+
    +
  1. Navigate to the tasks folder in your project directory.

  2. +
  3. Create a task file specific to your dataset. This file will manage loading one domain at a time and will be passed to the experiment.

  4. +
  5. The task_.py should contain the following functions:

  6. +
+
class NodeTaskTemplate(NodeTaskDictCluster):
+    """Basic template for tasks where categories are considered 'domains'
+    """
+
+    @property
+    def list_str_y(self):
+        """
+        This task has no conventional labels; categories are treated as domains.
+        """
+        return mk_dummy_label_list_str("label_prefix", number_of_domains)
+
+    @property
+    def isize(self):
+        """
+        :return: Image size object storing image channels, height, width.
+        """
+        return ImSize(channels, height, width)
+
+    def get_list_domains(self):
+        """
+        Get list of domain names.
+        :return: List of domain names.
+        """
+        return mk_dummy_label_list_str("domain_prefix", number_of_domains)
+
+    def get_dset_by_domain(self, args, na_domain, split=False):
+        """
+        Get a dataset by domain.
+        :param args: Command line arguments.
+        :param na_domain: Domain name.
+        :param split: Whether to perform a train/validation split.
+        :return: Training dataset, Validation dataset.
+        """
+        ratio_split = float(args.split) if split else False
+        trans = [transforms.Resize((desired_height, desired_width)), transforms.ToTensor()]
+        ind_global = self.get_list_domains().index(na_domain)
+        dset = DsetYourClass(domain=ind_global, args=args, list_transforms=trans)
+
+        if ratio_split > 0:
+            train_len = int(len(dset) * ratio_split)
+            val_len = len(dset) - train_len
+            train_set, val_set = random_split(dset, [train_len, val_len])
+        else:
+            train_set = dset
+            val_set = dset
+        return train_set, val_set
+
+
+
+
+

Step 5: Add new Task Chain in TaskChainNodeGetter Class

+

After defining your task class, you will need to integrate it into the processing chain. +This is typically done in the zoo_task.py file where multiple tasks are chained together for sequential processing.

+

Here’s how to add your new task to the chain:

+
    +
  1. Navigate to zoo_task.py to the TaskChainNodeGetter class.

  2. +
  3. Add your NodeTaskTemplate to the existing chain as shown below:

  4. +
+
chain = NodeTaskTemplate(succ=chain)
+
+
+
+
+

Conclusion

+

With the dataset class set up in your dset_<name>.py file that is imported to task_<name>.py, your new dataset is ready to be integrated into your project.

+
+
+
+

Adding a New Model to the Domid Python Package

+

This tutorial will guide you through the steps to add a new model file to the models submodule in the domid Python package.

+
+

Step 1: Create the Model File and Define the Model Class

+

Navigate to the models directory in the domid codebase and create a file named model_<name>.py. +In this file, you will construct the new model, define loss optimization functions, and configure any necessary clustering layers. +The layers of the model are defined in the compos submodule. +Here, you can find already implemented fully-connected and convolutional VAEs (Variational AutoEncoders) and AEs (AutoEncoders). +These components can be used as building blocks for your model. +Create a class for your model by extending a base model class from domid. +Typically, models extend from a common base class such as a_model_cluster.py, which provides some of the default functionalities, and are wrapped within a mk_model method:

+
def mk_model(parent_class=AModelCluster):
+    class CustomModel(parent_class):
+        def __init__(self, arg1, arg2, ...):
+            super(CustomModel, self).__init__()
+            # Model initialization and layer definitions
+            self.model = model
+
+        def _inference(self, x):
+            # ...
+
+        def infer_d_v_2(self, x, inject_domain):
+            # ...
+
+        def _cal_reconstruction_loss_helper(self, x,y):
+            # ...
+
+        # Implement any additional methods necessary for your model
+        def _cal_loss_(self, x, y):
+            # ...
+
+    return CustomModel
+
+
+
+
+

Step 2: Implement a trainer function if needed

+

When integrating your model into the domid package, +you have the option to utilize an existing trainer from the package or define a new trainer that caters +to the specific needs of your model. Below are details on both approaches.

+
+

Using an Existing Trainer

+

domid includes several generic trainers that are designed to work with a variety of models. +For example, trainer_cluster.py, which is compatible with VaDE and DEC models.

+
+
+

Defining a New Trainer

+

If the existing trainers do not meet the specific requirements of your model, +you may need to define a new trainer. This involves:

+

Creating a Trainer Class: Define a class in Python that encapsulates all +aspects of training your model. This includes initializing the model, +running the training loops, handling validation, and potentially testing.

+
class CustomTrainer:
+    def __init__(self, model, optimizer, loss_fn, device):
+        self.model = model.to(device)
+        self.optimizer = optimizer
+        self.loss_fn = loss_fn
+        self.device = device
+
+    def tr_epoch(self, epoch_number):
+        # runs one epoch of experiemnt for more details look at any other the existing trainers
+
+
+
+
+
+
+ + +
+
+
+
+
+
+ + +
+ + + + \ No newline at end of file diff --git a/docs/build/html/markdownfiles/conferences_commandlines.html b/docs/build/html/markdownfiles/conferences_commandlines.html new file mode 100644 index 0000000..9abbe04 --- /dev/null +++ b/docs/build/html/markdownfiles/conferences_commandlines.html @@ -0,0 +1,490 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MICCAI 2023 Conference Paper — domid documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content +
+ +
+ + +
+ + + + +
+
+ +
+
+
+ +
+
+
+ + +
+
+ +
+

MICCAI 2023 Conference Paper

+

This is a summary of the steps to reproduce results presented in [Sidulova et al. 2023]. +Base Model experiments are the experiments with no condition applied to the model.

+

[Sidulova et al. 2023] Sidulova, M., Sun, X., & Gossmann, A. (2023). Deep Unsupervised Clustering for Conditional Identification of Subgroups Within a Digital Pathology Image Set. In H. Greenspan, A. Madabhushi, P. Mousavi, S. Salcudean, J. Duncan, T. Syeda-Mahmood, & R. Taylor (Eds.), Medical Image Computing and Computer Assisted Intervention – MICCAI 2023 (Vol. 14227, pp. 666–675). Springer Nature Switzerland. https://doi.org/10.1007/978-3-031-43993-3_64

+

The same as in the notebooks/case-study-HER2_VaDE_CDVaDE-DEC.ipynb.

+
+

VaDE Base Model Experiments

+
poetry run python main_out.py --te_d 0 --tr_d 0 1 2 --task=her2 --epos=100 --aname=vade --zd_dim=250 --d_dim=3 \
+--apath=domid/algos/builder_vade.py --L=5 --pre_tr=20 --dpath "HER2/combined_train" --split 0.8 --bs 2 \
+--lr 0.00005 --prior Gaus --model cnn
+
+
+

Notes:

+
    +
  • Path to the dataset (dpath) needs to be adjusted depending on the location of the dataset.

  • +
  • By default this and the other experiments below will use the GPU. If you wish to run the experiment on CPU use the command line argument --nocu.

  • +
+
+
+

CVaDE: HER2 class labels

+
poetry run python main_out.py --te_d 0 --tr_d 0 1 2 --task=her2 --epos=100 --aname=vade --zd_dim=250 --d_dim=3 \
+--apath=domid/algos/builder_vade.py --L=5 --pre_tr=20 --dpath "HER2/combined_train" --split 0.8 --bs 2 \
+--lr 0.00005 --prior Gaus --model cnn --dim_inject_y 3
+
+
+

Note: dimension of the injected labels (dim_inject_y) should be adjusted. Number of the possible class labels (e.g., for the HER2 dataset used in the paper it would be 3 - class 1, class 2, class 3)

+
+
+

CVaDE: HER2 class labels + previously predicted domain labels

+
poetry run python main_out.py --te_d 0 --tr_d 0 1 2 --task=her2 --epos=100 --aname=vade --zd_dim=250 --d_dim=3 \
+--apath=domid/algos/builder_vade.py --L=5 --pre_tr=20 --dpath "HER2/combined_train" --split 0.8 --bs 2 \
+--lr 0.00005 --prior Gaus --model cnn --dim_inject_y 6 --path_to_domain notebooks/2022-11-02\ 17\:30\:13.132561/
+
+
+

Notes:

+
    +
  • Dimension of the injected labels (dim_inject_y) in this case is the sum of the dimensions of the possible class labels and d_dim of previously predicted domains. (e.g. ).

  • +
  • path_to_domain is the path to the previously obtained results directory and needs to be specified. Predicted domain labels should be stored within the directory path_to_domain in the file domain_labels.txt.

  • +
+
+
+
+

CHIL 2024 Conference:

+

(in press) Sidulova M., Khaki S, Hegman I., Gossmann A. “Contextual unsupervised deep clustering of digital pathology dataset”, Accepted in CHIL 2024.

+
+

Experiments with Colored MNIST dataset

+

The following experiments are the same as in the notebook/tutrial-MNIST-sdcn.ipynb.

+
+

AE pretraining

+
poetry python main_out.py --te_d 0 --tr_d 0 1 2 3 4 5 6 7 8 9 --task=mnistcolor10 --epos=100 --aname ae --d_dim=10 --apath=domid/algos/builder_AE.py --bs 128 --lr 0.0001 --zd_dim=20 --pre_tr=0 --model cnn --prior Gaus
+
+
+
+
+

SDCN

+
poetry python main_out.py --te_d 0 --tr_d 0 1 2 3 4 5 6 7 8 9 --task=mnistcolor10 --epos=100 --aname sdcn --d_dim=10 --apath=domid/algos/builder_sdcn.py --bs 600 --lr 0.0001 --zd_dim=20 --pre_tr=2 --model cnn --prior Gaus --pre_tr_weight_path path/to/pretrained/AE/'
+
+
+
poetry python main_out.py --te_d 0 --tr_d 0 1 2 3 4 5 6 7 8 9 --task=mnistcolor10 --epos=100 --aname sdcn --d_dim=10 --apath=domid/algos/builder_sdcn.py --bs 600 --lr 0.0001 --zd_dim=20 --pre_tr=2 --model cnn --prior Gaus --pre_tr_weight_path 'path/to/pretrained/AE/’
+
+
+
+

Sample pretrained AE for colored MNIST could be found in ./notebooks/2023-08-03 09:06:05.234348_mnistcolor10_ae/, ./notebooks/2023-08-01 13:53:39.168459_mnistcolor10_ae/.

+
+
+
+

Experiments with Wash U dataset

+
+
+

WashU Dset

+

The following experiments are also set in notebooks/case-study-WashU_AS_SDCN.ipynb.

+
+

AE pretraining

+
CUDA_VISIBLE_DEVICES=2 python main_out.py --te_d 0 --tr_d 0 1 2 3 4 5 6 7 8 9 --task=weah --epos=100 --aname ae --d_dim=10 --apath=domid/algos/builder_AE.py --dpath '../../WashU-WSI-data/patches_WashU_Aperio/data/png_files/' --bs 128 --lr 0.0001 --zd_dim=100 --pre_tr=2 --model cnn --prior Gaus --tr_d_range 0 24
+
+
+
+
+

SDCN training

+
CUDA_VISIBLE_DEVICES=2 python main_out.py --te_d 0 --tr_d 0 1 2 3 4 5 6 7 8 9 --task=weah --epos=100 --aname sdcn --d_dim=6 --apath=domid/algos/builder_sdcn.py --dpath '../../WashU_with_coord/combined_training_with_coords/' --bs 1200 --lr 0.0001 --zd_dim=1000 --pre_tr=2 --model cnn --pre_tr_weight_path 'path/to/pretrained/AE' --tr_d_range 0 65 --meta_data_csv 'path/to_csv_file_that_is_generated_from_the_notebook.csv'
+
+
+
    +
  • Sample path to generated csv file: ../../WashU_with_coord/dset_WEAH.csv, ../../WashU_with_coord/dset_WEAH_65_subjects_3_regions.csv.

  • +
  • Sample paths to pretrained AEs: ./notebooks/2023-06-30 10:38:27.253550_weah_ae/, ./notebooks/2023-07-05 12:18:40.078628_weah_ae/.

  • +
+
+
+

VADE training

+
CUDA_VISIBLE_DEVICES=2 python main_out.py --te_d 0 --tr_d 0 1 2 --task=weah --epos=50 --aname=vade --zd_dim=500 --d_dim=6 --apath=domid/algos/builder_vade.py --L=5 --pre_tr=17 --dpath "../../WashU_with_coord/combined_training_with_coords" --bs 4 --prior Gaus --model cnn --lr 0.0001 --tr_d_range 0 65 --meta_data_csv '../../WashU_with_coord/dset_WEAH_65_subjects_3_regions.csv'
+
+
+
+
+

DEC training

+
CUDA_VISIBLE_DEVICES=2 python main_out.py --te_d 0 --tr_d 0 1 2 --task=weah --epos=50 --aname=dec --zd_dim=500 --d_dim=6 --apath=domid/algos/builder_dec.py --L=5 --pre_tr=2 --dpath "../../WashU_with_coord/combined_training_with_coords" --bs 4 --prior Gaus --model cnn --lr 0.0001 --tr_d_range 0 6 --meta_data_csv '../../WashU_with_coord/dset_WEAH_65_subjects_3_regions.csv' --pre_tr_weight_path './notebooks/2023-06-30 10:38:27.253550_weah_ae/' --feat_extract ae
+
+
+
    +
  • Note: --feat_extract can be either “ae” of “vae”, option for loading pretrained weights also in place.

  • +
+
+
+
+ + +
+
+
+
+
+
+ + +
+ + + + \ No newline at end of file