Switch to unified view

a b/docs/source/adding_models.rst
1
Model Contributions
2
=====================
3
4
We are happy that you are considering contributing your model to `medigan`.
5
This will make your model accessible to the community and our users can easily integrate your synthetic data into their training pipelines and experiments.
6
7
8
Guide: Automated Model Contribution
9
_________________________________________
10
11
Create an `__init__.py <templates/examples/__init__.py>`_ file in your model's root folder.
12
13
Next, run the following code to contribute your model to `medigan`.
14
15
- Your model will be stored on `Zenodo <https://zenodo.org/>`_.
16
17
- Also, a Github `issue <https://github.com/RichardObi/medigan/issues>`_ will be created to add your model's metadata to medigan's `global.json <https://github.com/RichardObi/medigan/blob/main/config/global.json>`_.
18
19
- To do so, please provide a github access token (`get one here <https://github.com/settings/tokens>`_) and a zenodo access token (`get one here <https://zenodo.org/account/settings/applications/tokens/new/>`_), as shown below. After creation, the zenodo access token may take a few minutes before being recognized in zenodo API calls.
20
21
.. code-block:: Python
22
23
    from medigan import Generators
24
    gen = Generators()
25
26
    # Contribute your model
27
    gen.contribute(
28
        model_id = "00100_YOUR_MODEL", # assign an ID
29
        init_py_path ="path/ending/with/__init__.py",
30
        model_weights_name = "10000",
31
        model_weights_extension = ".pt",
32
        generate_method_name = "generate", # in __init__.py
33
        dependencies = ["numpy", "torch"],
34
        creator_name = "YOUR_NAME",
35
        creator_affiliation = "YOUR_AFFILIATION",
36
        zenodo_access_token = 'ZENODO_ACCESS_TOKEN',
37
        github_access_token = 'GITHUB_ACCESS_TOKEN',
38
    )
39
40
Guide:  Manual Model Contribution
41
______________________________________
42
43
In the following, you find a step-by-step guide on how to contribute your generative model to `medigan`.
44
In case you encounter problems during this process feel free to reach out by creating an issue `here <https://github.com/RichardObi/medigan-models/issues>`_ and we will try to help.
45
Checkout the figure below that shows the main components of the model contribution workflow depicted in yellow (d).
46
47
.. figure:: _static/medigan-workflows.png
48
   :alt: Architectural overview and main workflows
49
50
   Architectural overview including main workflows consisting of (a) library import and initialisation, (b) generative model search and ranking, (c) sample generation, and (d) generative model contribution.
51
52
If you are here, you have recently developed a generative model such as a GAN, VAE, Diffusion Model, etc and you would like to boost your model's impact, reusability, dissemination by uploading it to `medigan`.
53
We are delighted and will assist you in adding your model.
54
55
#. **Firstly, let's create the needed files:**
56
57
    To add your model you will need the following files.
58
59
    #. A checkpoint file that contains your trained model weights (e.g.,  the ``state_dict`` in pytorch)
60
61
    #. An ``__init__.py`` file that contains functions that
62
63
        - load the weights file (let's call that one ``weights.pt``)
64
65
        - initialize your model with these weights
66
67
        - generate samples with the initialized model.
68
69
    #. Now that you have the ``weights.pt`` and the ``__init__.py``, let's check if we can make them work together.
70
71
        #. Run your ``__init__.py``'s generate function using e.g. ``python -m __init__.py generate``
72
73
        #. Check whether your model did load the weights effectively and whether synthetic samples were generated as expected.
74
75
    #. Apply some necessary adjustments to your model package, particularly to your ``__init__.py``:
76
77
        #. We have some templates that you can use to guide the adjustments described below
78
79
            - If you are using a model that generates samples **without** image input (e.g., noise-to-image): Download Model `00002 <https://doi.org/10.5281/zenodo.5188557>`_ from `here <https://zenodo.org/record/5548158/files/MALIGN_DCGAN.zip?download=1>`_. Unzip it and open the ``__init__.py`` that contains an example ``generate()`` method.
80
81
            - If you are using a model that generates samples **with** image input (e.g., image-to-image): Download Model `00003 <https://doi.org/10.5281/zenodo.5547263>`_ from `here <https://zenodo.org/record/5555010/files/CycleGAN_high_density.zip?download=1>`_. Unzip it and open the ``__init__.py`` that contains an example ``generate()`` method.
82
83
        #. Please note that user's of `medigan` models may add your model to their preprocessing or AI training pipelines. Please make sure that your model, hence, runs efficiently. For instance, your model should load the weights only once even though the generate() function is called multiple times.
84
85
        #. Please make sure your model is able to run both on gpu and on cpu and your code automatically detects on which one to run.
86
87
        #. Please replace all ``print()`` functions from your code with ``logging.debug()`` (for this you need to ``import logging``).
88
89
        #. Please add appropriate error handling using ``try, except`` blocks on each possible source of error in your code. ``raise`` the error in your ``generate()`` function to allow `medigan` to handle it and pass it to the user.
90
91
        #. If your generative model needs some input images, provide a few example images in a folder called ``/images``. Users may test your model with these example images before feeding their own input images to your model.
92
93
        #. There are a few parameters of the ``generate()`` that are mandatory in `medigan` and others that you can set optionally.
94
95
            - Mandatory:
96
                - ``model_file``: string, the path where your ``generate()`` method will find its weight file
97
                - ``output_path``: string, the path where our ``generate()`` method should store the generated images
98
                - ``save_images``: boolean, whether your ``generate()`` method should store generated samples in ``output_path`` or return them as numpy arrays.
99
                - ``num_samples``: int, the number of samples that should be generated.
100
101
            - Optional:
102
                - ``input_path``: string, the path where our ``generate()`` method finds images that should be used as input into the generative model (i.e. in image-to-image translation).
103
                - ``image_size``: array, that contains image height, width, and, optionally, also depth.
104
                - ``translate_all_images``: boolean, in image-to-image translation, if ``True``, this overwrites the ``num_samples`` and instead translates all images found in ``input_path``.
105
                - ``gpu_id``: int, if a user has various GPUs available, the user can specify which one of them to use to run your generative model.
106
107
#. **Secondly, test your model locally:**
108
    Okay, now that we know which files we need, let's test them using a local version of `medigan`.
109
110
    #. Let's start by cloning `medigan` e.g. using the command line: ``git clone https://github.com/RichardObi/medigan.git``
111
    #. Next, cd into `medigan`, install the dependencies of `medigan`, and create a virtual environment.
112
113
        You can do so running these commands:
114
115
        - ``cd medigan``
116
        - ``pip install pipenv``
117
        - ``pipenv install``
118
        - ``pipenv shell``
119
120
    #. Now that you have your environment up and running, please run the following command to download the config file.
121
122
        - ``python -m tests.tests TestMediganMethods.test_init_generators``
123
124
    #. In the folder ``/config``, you should now see a file called `global.json <https://raw.githubusercontent.com/RichardObi/medigan-models/main/global.json>`_. In this file each model's metadata is stored.
125
126
        * Please add the metadata for your model at the bottom of the `global.json` file.
127
        * To add the metadata, you can use the metadata of model `00001 <https://doi.org/10.5281/zenodo.5187714>`_ in `global.json <https://raw.githubusercontent.com/RichardObi/medigan-models/main/global.json>`_ as example.
128
        * Copy the metadata of model 00001 and add it to the bottom of ``global.json``. Then adjust each entry in that part of the json so that it represents your own model.
129
            - The ``model_id`` should follow the convention ``NNNNN_TTTTTT_MMMM_AAAAA_GGGG`` (N = Number of model, T = Type of model, M = Modality, A = Anatomic/Ailment Information, G = Generated Sample Type information i.e. full for full image or roi for region of interest)
130
            - The field ``package_link`` (under ``execution``) should point to a local zip file ``NAME_OF_YOUR_MODEL_PACKAGE.zip`` of your model package.
131
            - json entries below ``execution`` are important and needed to run the model in `medigan`, e.g. the name and parameters of a ``generate()`` function in the ``__init__.py``
132
            - json entries below ``selection`` are important to enable users to search and rank the model compared to other models in `medigan`, e.g. the performance indicators such as SSIM, MSE, PSNR, etc.
133
            - json entries below ``description`` are to allow tracing back the origin and metadata of the model and allow users to get further information about the model, e.g. license, related publications, etc.
134
135
    #. You are almost done! It's Testing Time!
136
137
        - Run a local test using the following code:
138
139
        .. code-block:: Python
140
141
            from medigan import Generators
142
            gen = Generators()
143
            gen.generate(model_id="YOUR_MODEL_ID")
144
145
            # Test a few variations.
146
            test_dict = {"translate_all_images": True, "SOME_OTHER_OPTIONAL_PARAMS": True}
147
            gen.generate(model_id="YOUR_MODEL_ID", num_samples=100, output_path="here", save_images=True, **test_dict)
148
149
        - If you are code runs well with different settings/params, congratulations, you have made it! You integrated your model as a package into `medigan` and are now ready for the final steps.
150
151
#. **Thirdly, upload your model:**
152
153
    #. Package and upload your model to Zenodo - home to your model's code and documentation.
154
155
        #. First, check if your model package folder contains an ``__init__.py``, a ``weights`` file, a ``license`` file, and optionally other files.
156
157
        #. The next step is to zip this folder. To do so (e.g., on MACOS) you may ``cd`` into the folder and use the following commands (while removing hidden OS system files):
158
159
            .. code-block:: Python
160
161
                find . -name ".DS_Store" -delete
162
                zip -r NAME_OF_YOUR_MODEL_PACKAGE.zip . -x ".*" -x "__MACOSX"
163
164
        Now that you have your model package zipped and ready, note that `medigan` model's are commonly stored in Zenodo, as in Zenodo
165
            * they get a DOI
166
            * the content of their package is non editable i.e. no file modifications/updates without new DOI.
167
            * This helps to avoid security issues as package content remains static after the model is tested, verified, and added to `medigan`.
168
            * Zenodo has a close to unlimited storage capacity for research data/software.
169
            * Also, the authorship/ownership of the model are clear
170
            * There is transparent licensing.
171
            * Each model is versioned in Zenodo with different DOIs.
172
            * A model documentation and contact information can be added.
173
174
        #. Checkout this example of our model `00001 <https://doi.org/10.5281/zenodo.5187714>`_ on Zenodo. You can use the Zenodo documentation of this model as template for your own model upload.
175
176
        #. Now, let's go to the `Zenodo <https://zenodo.org/>`_ website.
177
178
        #. Click on ``New Upload`` (if you don't have an account, you can quickly create one e.g., using your `ORCID <https://orcid.org/>`_)
179
180
        #. Fill in the metadata fields for your model and upload the model package zip file (i.e. drag and drop).
181
182
        #. Click on ``Save`` and ``Submit``. Congratulations your model is now on Zenodo! Good job!
183
184
#. **Finally, add your model to `medigan's` model metadata:**
185
186
        Last step!!! Your model is on Zenodo and tested locally. Now we can officially add it to `medigan`. Remember the ``global.json`` that you created locally to test your model? It is time for glory for this file.
187
188
        #. Now, clone the `medigan-models` repository (the home of `medigan's global.json <https://github.com/RichardObi/medigan-models/blob/main/global.json>`_) e.g. by using ``git clone https://github.com/RichardObi/medigan-models.git``
189
190
        #. Create and checkout a new local branch ``git checkout -b mynewbranch``
191
192
        #. Open the ``global.json`` in your cloned local `medigan-models`
193
194
        #. Edit the ``global.json`` file and add your model's entry at the bottom, and save.
195
196
        #. Note that this is the time to replace the value of ``package_link`` from your local model file path to your new Zenodo model URL. To get this URL, go to the Zenodo page of your model, and scroll down to ``Files``, where you see a download button. Copy the url link that this button points to, which is your ``package_link``.
197
198
        #. Commit the new file (``git add .``, ``git commit -m "added model YOUR_MODEL_ID."``) and push your branch (``git push``).
199
200
        #. Lastly, go to the repository `medigan-models <https://github.com/RichardObi/medigan-models/>`_ and create a pull request that merges your recently pushed branch into ``main``.
201
202
        #. That's it!!! Your pull request will be evaluated asap. Once approved your model is officially part of `medigan`!
203
204
If you have suggestions on improvements for our model contribution process, please take a minute and let us know `here <https://github.com/RichardObi/medigan-models/issues>`_.
205
206
207
Conventions that your model should follow
208
______________________________________________
209
210
* Your model should have a ``generate`` method with the params model_file:str, num_samples:int, save_images:bool, and output_path:str (see `template (templates/examples/__init__.py>`_)
211
* Also, the model should do simple error handling, run flexibly on either gpu or cpu, use ``logging`` instead of ``prints``, and create some sort of synthetic data.
212
213
We hope to welcome you model soon to `medigan`! If you need support, please let us now `here <https://github.com/RichardObi/medigan/issues>`_.