Commit 3afc4acf authored by mathpluscode's avatar mathpluscode

Merge branch 'dev'

parents 5fbbe004 e21b85ff
Pipeline #3267 failed with stages
in 22 seconds
......@@ -41,43 +41,15 @@ build mac installer:
tags:
- shared-mac
build windows installer:
<<: *build-skip-template
<<: *build-install-template
tags:
- shared-win
test Linux:
stage: test
script:
- tox
tags:
- shared-linux
coverage: '/^TOTAL.*\s+(\d+\%)$/'
test macOS:
stage: test
script:
- tox
tags:
- shared-mac
test Windows:
stage: test
script:
- tox
tags:
- shared-win
deploy pip to PyPI:
stage: deploy
when: manual
when: manual
only:
- tags
environment:
name: PyPI
url: https://pypi.python.org/pypi/yunguanfu-mil3id2019
url: https://pypi.python.org/pypi/yunguanfu-mil3id2019
tags:
- pip-production
......
====================
yunguanfu-mil3id2019
===============================
====================
.. image:: https://weisslab.cs.ucl.ac.uk/WEISS/SoftwareRepositories/yunguanfu-mil3id2019/raw/master/project-icon.png
:height: 128px
......@@ -27,58 +28,101 @@ yunguanfu-mil3id2019 is part of the `SNAPPY`_ software project, developed at the
yunguanfu-mil3id2019 supports Python 3.6.
yunguanfu-mil3id2019 is currently a demo project, which will add/multiply two numbers. Example usage:
yunguanfu-mil3id2019 is currently a demo project. It implements Yunguan Fu's paper `More unlabelled data or label more data? A study on semi-supervised laparoscopic image segmentation`_.
Data Set Structure
------------------
The data should be stored in `data/` where images are stored in ``data/img/`` and videos are stored in ``data/video/``.
For images, the labelled data is stored in ``data/img/labeled/``, inside which each folder corresponds to a patient. Some foldes' name contains HLS, these folders are ignored. Inside this folder, each subfolder, e.g. ``LR01``, corresponds to a patient. In this folder, each subfolder corresponds to the images extracted from a video and its labels. For instance, if the name of an image is ``x_left.png``, the label is available only if ``x_leftMask.png`` and ``x_leftContour.png`` both exist. It is possible that the mask file exists but is all black and the contour file doesn't exist.
For videos, each folder of ``data/video/`` corresponds to a patient, inside which, each subfolder corresponds to a video. Compared to the data in the server, the folders are selected and renamed manually to match the labeled data. Often the folder name contains only number ``LS09/556/``, it corresponds to the folder of labeled image ``2016.04.28_10-08-03-556``. Videos are stored in ``.264`` format.
Example Usage
-------------
Preprocess
^^^^^^^^^^
::
python yfmil3id2019_train.py -x 5 -y 8
python yfmil3id2019_train.py -x 3 -y 6 --multiply
python preprocess_mean_std.py -p config.yaml
Please explore the project structure, and implement your own functionality.
This code calculates the mean and std on channel level for the image data of each patient. The output is stored in ``data/img/mean_std``. These files are required for training.
Developing
----------
::
Cloning
^^^^^^^
python preprocess_unlabel.py -f 4
You can clone the repository using the following command:
This code extracts the unlabelled images from videos. The output is stored in ``data/img/unlabeled``. These files are required for semi-supervised training.
::
git clone https://weisslab.cs.ucl.ac.uk/WEISS/SoftwareRepositories/yunguanfu-mil3id2019
python preprocess_cut.py -p config.yaml
This code calculates the images without black border. The output is stored in ``data/img/cut``. These files are required for evaluation.
Train
^^^^^
Running tests
^^^^^^^^^^^^^
Pytest is used for running unit tests:
::
pip install pytest
python -m pytest
python train.py -p config.yaml -g 0
This code trains models with parameters defined in config.yaml file and uses GPU number 0.
Evaluate
^^^^^^^^
::
python eval.py -p log/20190902225640-config -g 0 --eval
Linting
This code evaluates the models in the log folder. It calculates the prediction of each model of cross validation on the corresponding test set. The predictions of ``LR01`` will be saved in ``log/20190902225640-config/LR01/preds/final``.
::
python eval.py -p log/20190902225640-config -g 0 --eval --all
This code calculates the prediction of each model of cross validation on all data, including training set and test set. The predictions of ``LR01`` will be saved in ``log/20190902225640-config/LR01/preds/final_all``.
Analyse
^^^^^^^
This code conforms to the PEP8 standard. Pylint can be used to analyse the code:
::
python analyse.py -p log/ --std
This code
- summarises the statistics of metrics
- generates the performance vs foreground proportion curve only for test set.
::
pip install pylint
pylint --rcfile=tests/pylintrc yfmil3id2019
python analyse.py -p log/ --std --all
This code
Installing
----------
- summarises the statistics of metrics
- generates the performance vs foreground proportion curves, one for training and another one for test.
But it requires to evaluate with ``--all``
You can pip install directly from the repository as follows:
Test
^^^^
::
pip install git+https://weisslab.cs.ucl.ac.uk/WEISS/SoftwareRepositories/SNAPPY/yunguanfu-mil3id2019
python test.py -p log/20190902225640-config/LR01 -d demo -g 0
This code tests the model in the folder ``log/20190902225640-config/LR01`` on images inside ``demo/``.
Developing
----------
Contributing
^^^^^^^^^^^^
......@@ -115,4 +159,4 @@ Supported by `Wellcome`_ and `EPSRC`_.
.. _`EPSRC`: https://www.epsrc.ac.uk/
.. _`contributing guidelines`: https://weisslab.cs.ucl.ac.uk/WEISS/SoftwareRepositories/yunguanfu-mil3id2019/blob/master/CONTRIBUTING.rst
.. _`license file`: https://weisslab.cs.ucl.ac.uk/WEISS/SoftwareRepositories/yunguanfu-mil3id2019/blob/master/LICENSE
.. _`More unlabelled data or label more data? A study on semi-supervised laparoscopic image segmentation`: https://arxiv.org/abs/1908.08035
......@@ -11,7 +11,7 @@ data:
shape: # shape is [height, width]
orig: [540, 1920]
border: 130 # crop border manually, output has shape [540, 1660]
input: [64, 64] # input size for NN
input: [128, 384] # input size for NN
sl:
keep_ratio: 1 # proportion of labeled data, randomly sampled
ssl:
......@@ -51,7 +51,7 @@ model:
lr: 1.e-4 # learning rate
clip_norm: 5.0 # grad clip norm
weight_decay: 1.e-5 # l2 loss weight for adam or weight_decay for adamw
batch_size: 4
batch_size: 64
ssl:
mode: "mean_teacher" # pi: consistency between noised1 and noised2, mean_teacher: noise1 for student and noise2 for teacher
loss:
......@@ -66,7 +66,7 @@ model:
tf: # configuration for tensorflow
gpu: "" # GPU ID should be specified manually
num_parallel_calls: 4 # number of cpus
num_parallel_calls: 8 # number of cpus
save_best:
metric_name: "metric_bin/f1_percentile_50"
large_is_better: true
......@@ -77,7 +77,7 @@ tf: # configuration for tensorflow
log_step_count_steps: 100 # output frequency
train: # tf.estimator.TrainSpec
max_steps: 100
max_steps: 10000
eval: # tf.estimator.EvalSpec
steps: 200 # number of batches for evaluation, each folder has at maximum 260 frames
......
......@@ -14,3 +14,12 @@ sphinx_rtd_theme
pyinstaller
pytest
tox
numpy
scipy
matplotlib
pyyaml
opencv-python
tqdm
seaborn
ray
plotly
......@@ -63,7 +63,7 @@ def analyse_foreground(log_path, best, std):
metrics_total = dict()
for p in folder_paths:
name = ''.join(p.split('-')[1:])
m_total, _, _ = read_folder(p, best=best, total=False)
m_total, _, _ = read_folder(p, best=best, total=False, all=False)
names.append(name)
metrics_total[name] = m_total
......
......@@ -111,16 +111,11 @@ def calculate_metrics(fnames, dir_cut, return_hd, all):
def eval_app(config, path, best, all, eval, return_hd):
# create log folder
app_name = 'eval-' + path.split('/')[-1]
cwd = os.getcwd() + '/'
dir_log = init_log_dir(cwd + config['dir']['log'], app_name)
set_tf_logger(dir_log, app_name)
# check if the copy of cut data has been made
dir_cut = config['dir']['data'] + 'img/cut/'
# get folders for labeled and unlabeled data
cwd = os.getcwd() + '/'
fs_lbl = get_labeled_folders(cwd, config)
fs_unlbl = get_unlabeled_folders(fs_lbl, config)
verify_dirs(fs_unlbl)
......
......@@ -50,12 +50,6 @@ def test_app(config, model_path, data_path, best):
:param best:
:return:
"""
# create log folder
app_name = 'test'
cwd = os.getcwd() + '/'
dir_log = init_log_dir(cwd + config['dir']['log'], app_name)
set_tf_logger(dir_log, app_name)
# init configs
session_config = ConfigProto(device_count={'GPU': 0})
run_config = tf.estimator.RunConfig(session_config=session_config, **config['tf']['run'])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment