|
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>`_. |