Skip to content

Commit

Permalink
Merge branch 'master' into 765-gdown-does-not-seem-to-be-working
Browse files Browse the repository at this point in the history
  • Loading branch information
scap3yvt authored Jan 11, 2024
2 parents 36aa768 + 55dbf7a commit a379b87
Show file tree
Hide file tree
Showing 24 changed files with 111 additions and 89 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/onCreateCommand.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ pip install wheel
pip install openvino-dev==2023.0.1 # [OPTIONAL] to generate optimized models for inference
pip install mlcube_docker # [OPTIONAL] to deploy GaNDLF models as MLCube-compliant Docker containers
pip install medmnist==2.1.0
pip install torch==1.13.1+cpu torchvision==0.14.1+cpu torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cpu
pip install torch==2.1.0+cpu torchvision==0.16.0+cpu torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cpu
2 changes: 1 addition & 1 deletion .devcontainer/postCreateCommand.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# if runnning on a GPU machine, install the GPU version of pytorch
if command -v nvidia-smi &> /dev/null
then
pip install torch==1.13.1+cu116 torchvision==0.14.1+cu116 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu116
pip install torch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cu118
fi

pip install -e .
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/devcontainer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
# if: steps.changed-files-specific.outputs.only_modified == 'false'
- name: Detect and screen file changes
id: changed-files-specific
uses: tj-actions/changed-files@v34
uses: tj-actions/changed-files@v41
with:
files: |
docs/**
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ jobs:
fail-fast: false # So that remaining jobs don't instantly quit if one fails (e.g, CPU/ROCm don't upload if CUDA just fails to push to ghcr...)
matrix:
include: # Platform locates Dockerfile ("Dockerfile-{PLATFORM}"), docker tag has to be all lowercase alphanumeric for mysterious docker reasons
- platform: CUDA11.6
dockertag: cuda116
- platform: CUDA11.8
dockertag: cuda118
- platform: CPU
dockertag: cpu
# - platform: ROCm
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/mlcube-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
# if: steps.changed-files-specific.outputs.only_modified == 'false'
- name: Detect and screen file changes
id: changed-files-specific
uses: tj-actions/changed-files@v34
uses: tj-actions/changed-files@v41
with:
files: |
.github/*.md
Expand Down Expand Up @@ -73,7 +73,7 @@ jobs:
python -m pip install --upgrade pip
python -m pip install wheel
python -m pip install openvino-dev==2023.0.1 mlcube_docker
pip install torch==1.13.1+cpu torchvision==0.14.1+cpu torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cpu
pip install torch==2.1.0+cpu torchvision==0.16.0+cpu torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cpu
pip install -e .
- name: Run mlcube deploy tests
working-directory: ./testing
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/openfl-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
# if: steps.changed-files-specific.outputs.only_modified == 'false'
- name: Detect and screen file changes
id: changed-files-specific
uses: tj-actions/changed-files@v34
uses: tj-actions/changed-files@v41
with:
files: |
.github/*.md
Expand Down Expand Up @@ -73,7 +73,7 @@ jobs:
sudo apt-get install libvips libvips-tools -y
python -m pip install --upgrade pip
python -m pip install wheel
pip install torch==1.13.1+cpu torchvision==0.14.1+cpu torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cpu
pip install torch==2.1.0+cpu torchvision==0.16.0+cpu torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cpu
pip install -e .
- name: Run generic unit tests to download data and construct CSVs
if: steps.changed-files-specific.outputs.only_modified == 'false' # Run on any non-docs change
Expand Down
22 changes: 22 additions & 0 deletions .github/workflows/python-install-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Install across python versions

on: [push, pull_request]

jobs:
pyversion_install:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v2

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
# all good if installation finishes
python -m pip install -e .
4 changes: 2 additions & 2 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
# if: steps.changed-files-specific.outputs.only_modified == 'false'
- name: Detect and screen file changes
id: changed-files-specific
uses: tj-actions/changed-files@v34
uses: tj-actions/changed-files@v41
with:
files: |
.github/*.md
Expand Down Expand Up @@ -74,7 +74,7 @@ jobs:
python -m pip install --upgrade pip
python -m pip install wheel
python -m pip install openvino-dev==2023.0.1 mlcube_docker
pip install torch==1.13.1+cpu torchvision==0.14.1+cpu torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cpu
pip install torch==2.1.0+cpu torchvision==0.16.0+cpu torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cpu
pip install -e .
- name: Run generic unit tests
if: steps.changed-files-specific.outputs.only_modified == 'false' # Run on any non-docs change
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile-CPU
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ RUN add-apt-repository ppa:deadsnakes/ppa
RUN apt-get update && apt-get install -y python3.9 python3-pip libjpeg8-dev zlib1g-dev python3-dev libpython3.9-dev libffi-dev libgl1
RUN python3.9 -m pip install --upgrade pip
# EXPLICITLY install cpu versions of torch/torchvision (not all versions have +cpu modes on PyPI...)
RUN python3.9 -m pip install torch==1.13.1+cpu torchvision==0.14.1+cpu torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cpu
RUN python3.9 -m pip install torch==2.1.0+cpu torchvision==0.16.0+cpu torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cpu
RUN python3.9 -m pip install openvino-dev==2023.0.1 opencv-python-headless mlcube_docker

# Do some dependency installation separately here to make layer caching more efficient
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile-CUDA11.6 → Dockerfile-CUDA11.8
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM nvidia/cuda:11.6.2-devel-ubuntu20.04
FROM nvidia/cuda:11.8.0-devel-ubuntu20.04
LABEL github="https://github.com/mlcommons/GaNDLF"
LABEL docs="https://mlcommons.github.io/GaNDLF/"
LABEL version=1.0
Expand All @@ -12,7 +12,7 @@ RUN apt-get update && apt-get install -y software-properties-common
RUN add-apt-repository ppa:deadsnakes/ppa
RUN apt-get update && apt-get install -y python3.9 python3-pip libjpeg8-dev zlib1g-dev python3-dev libpython3.9-dev libffi-dev libgl1
RUN python3.9 -m pip install --upgrade pip
RUN python3.9 -m pip install torch==1.13.1+cu116 torchvision==0.14.1+cu116 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu116
RUN python3.9 -m pip install torch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cu118
RUN python3.9 -m pip install openvino-dev==2023.0.1 opencv-python-headless mlcube_docker

# Do some dependency installation separately here to make layer caching more efficient
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile-ROCm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM rocm/pytorch:rocm5.2.3_ubuntu20.04_py3.7_pytorch_1.12.1
FROM rocm/pytorch:rocm5.6_ubuntu20.04_py3.8_pytorch_1.12.1
LABEL github="https://github.com/mlcommons/GaNDLF"
LABEL docs="https://mlcommons.github.io/GaNDLF/"
LABEL version=1.0
Expand All @@ -10,7 +10,7 @@ RUN apt-get update && apt-get install -y software-properties-common
RUN add-apt-repository ppa:deadsnakes/ppa
RUN apt-get update && apt-get install -y python3.9 python3-pip libjpeg8-dev zlib1g-dev python3-dev libpython3.9-dev libffi-dev libgl1
RUN python3.9 -m pip install --upgrade pip
RUN python3.9 -m pip install torch==1.13.1+rocm5.2 torchvision==0.14.1+rocm5.2 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/rocm5.2
RUN python3.9 -m pip install torch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/rocm5.6
RUN python3.9 -m pip install --upgrade pip && python3.9 -m pip install openvino-dev==2023.0.1 opencv-python-headless mlcube_docker
RUN apt-get update && apt-get install -y libgl1

Expand Down
2 changes: 1 addition & 1 deletion GANDLF/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
"Contact: [email protected]\n\n"
+ "This program is NOT FDA/CE approved and NOT intended for clinical use.\nCopyright (c) "
+ str(date.today().year)
+ " MLCommons. All rights reserved.\n\nCitation: https://arxiv.org/abs/2103.01006"
+ " MLCommons. All rights reserved.\n\nCitation: https://doi.org/10.1038/s44172-023-00066-3"
)
6 changes: 2 additions & 4 deletions GANDLF/cli/preprocess_and_save.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,13 @@ def preprocess_and_save(
# the "squeeze" is needed because the dataloader automatically
# constructs 5D tensor considering the batch_size as first
# dimension, but the constructor needs 4D tensor.
subject_process[str(channel)] = torchio.Image(
subject_process[str(channel)] = torchio.ScalarImage(
tensor=subject[str(channel)]["data"].squeeze(0),
type=torchio.INTENSITY,
path=subject[str(channel)]["path"],
)
if parameters["headers"]["labelHeader"] is not None:
subject_process["label"] = torchio.Image(
subject_process["label"] = torchio.LabelMap(
tensor=subject["label"]["data"].squeeze(0),
type=torchio.LABEL,
path=subject["label"]["path"],
)
subject_dict_to_write = torchio.Subject(subject_process)
Expand Down
12 changes: 5 additions & 7 deletions GANDLF/compute/forward_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,12 @@ def validate_network(
subject_dict = {}
label_ground_truth = None
label_present = False
# this is when we want the dataloader to pick up properties of GaNDLF's DataLoader, such as pre-processing and augmentations, if appropriate
# this is when we want the dataloader to pick up properties of GaNDLF's
# DataLoader, such as pre-processing and augmentations, if appropriate
if "label" in subject:
if subject["label"] != ["NA"]:
subject_dict["label"] = torchio.Image(
subject_dict["label"] = torchio.LabelMap(
path=subject["label"]["path"],
type=torchio.LABEL,
tensor=subject["label"]["data"].squeeze(0),
affine=subject["label"]["affine"].squeeze(0),
)
Expand All @@ -149,9 +149,8 @@ def validate_network(
)

for key in params["channel_keys"]:
subject_dict[key] = torchio.Image(
subject_dict[key] = torchio.ScalarImage(
path=subject[key]["path"],
type=subject[key]["type"],
tensor=subject[key]["data"].squeeze(0),
affine=subject[key]["affine"].squeeze(0),
)
Expand Down Expand Up @@ -320,8 +319,7 @@ def validate_network(
output_prediction = aggregator.get_output_tensor()
output_prediction = output_prediction.unsqueeze(0)
if params["save_output"]:
img_for_metadata = torchio.Image(
type=subject["1"]["type"],
img_for_metadata = torchio.ScalarImage(
tensor=subject["1"]["data"].squeeze(0),
affine=subject["1"]["affine"].squeeze(0),
).as_sitk()
Expand Down
4 changes: 2 additions & 2 deletions GANDLF/data/augmentation/noise_enhanced.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ def get_params(
mean_range: Tuple[float, float],
std_range: Tuple[float, float],
) -> Tuple[float, float]:
mean = self.sample_uniform(*mean_range).item()
std = self.sample_uniform(*std_range).item()
mean = self.sample_uniform(*mean_range)
std = self.sample_uniform(*std_range)
seed = self._get_random_seed()
return mean, std, seed

Expand Down
42 changes: 32 additions & 10 deletions GANDLF/data/patch_miner/opm/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
from skimage.morphology import remove_small_holes
from skimage.color.colorconv import rgb2hsv
import cv2
#from skimage.exposure import rescale_intensity
#from skimage.color import rgb2hed

# from skimage.exposure import rescale_intensity
# from skimage.color import rgb2hed

# import matplotlib.pyplot as plt
import yaml
Expand Down Expand Up @@ -238,7 +239,8 @@ def alpha_rgb_2d_channel_check(img):
else:
return False

#def pen_marking_check(img, intensity_thresh=225, intensity_thresh_saturation =50, intensity_thresh_b = 128):

# def pen_marking_check(img, intensity_thresh=225, intensity_thresh_saturation =50, intensity_thresh_b = 128):
# """
# This function is used to curate patches from the input image. It is used to remove patches that have pen markings.
# Args:
Expand All @@ -259,7 +261,14 @@ def alpha_rgb_2d_channel_check(img):
# #Assume patch is valid
# return True

def patch_artifact_check(img, intensity_thresh = 250, intensity_thresh_saturation = 5, intensity_thresh_b = 128, patch_size = (256,256)):

def patch_artifact_check(
img,
intensity_thresh=250,
intensity_thresh_saturation=5,
intensity_thresh_b=128,
patch_size=(256, 256),
):
"""
This function is used to curate patches from the input image. It is used to remove patches that are mostly background.
Args:
Expand All @@ -271,23 +280,36 @@ def patch_artifact_check(img, intensity_thresh = 250, intensity_thresh_saturatio
Returns:
bool: Whether the patch is valid (True) or not (False)
"""
#patch_size = config["patch_size"]
# patch_size = config["patch_size"]
patch_hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
count_white_pixels = np.sum(np.logical_and.reduce(img > intensity_thresh, axis=2))
percent_pixels = count_white_pixels / (patch_size[0] * patch_size[1])
count_black_pixels = np.sum(np.logical_and.reduce(img < intensity_thresh_b, axis=2))
percent_pixel_b = count_black_pixels / (patch_size[0] * patch_size[1])
percent_pixel_2 = np.sum(patch_hsv[...,1] < intensity_thresh_saturation) / (patch_size[0] * patch_size[1])
percent_pixel_3 = np.sum(patch_hsv[...,2] > intensity_thresh) / (patch_size[0] * patch_size[1])
percent_pixel_2 = np.sum(patch_hsv[..., 1] < intensity_thresh_saturation) / (
patch_size[0] * patch_size[1]
)
percent_pixel_3 = np.sum(patch_hsv[..., 2] > intensity_thresh) / (
patch_size[0] * patch_size[1]
)

if percent_pixel_2 > 0.99 or np.mean(patch_hsv[...,1]) < 5 or percent_pixel_3 > 0.99:
if (
percent_pixel_2 > 0.99
or np.mean(patch_hsv[..., 1]) < 5
or percent_pixel_3 > 0.99
):
if percent_pixel_2 < 0.1:
return False
elif (percent_pixel_2 > 0.99 and percent_pixel_3 > 0.99) or percent_pixel_b > 0.99 or percent_pixels > 0.9:
elif (
(percent_pixel_2 > 0.99 and percent_pixel_3 > 0.99)
or percent_pixel_b > 0.99
or percent_pixels > 0.9
):
return False
# assume that the patch is valid
return True


def parse_config(config_file):
"""
Parse config file and return a dictionary of config values.
Expand All @@ -304,7 +326,7 @@ def parse_config(config_file):
config["value_map"] = config.get("value_map", None)
config["read_type"] = config.get("read_type", "random")
config["overlap_factor"] = config.get("overlap_factor", 0.0)
config["patch_size"] = config.get("patch_size", [256,256])
config["patch_size"] = config.get("patch_size", [256, 256])

return config

Expand Down
4 changes: 1 addition & 3 deletions GANDLF/metrics/classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ def overall_stats(predictions, ground_truth, params):
"aucroc": tm.AUROC(
task=task,
num_classes=params["model"]["num_classes"],
average=average_type_key
if average_type_key != "micro"
else "macro",
average=average_type_key if average_type_key != "micro" else "macro",
),
}
for metric_name, calculator in calculators.items():
Expand Down
24 changes: 6 additions & 18 deletions GANDLF/metrics/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
)


def generic_function_output_with_check(
predicted_classes, label, metric_function
):
def generic_function_output_with_check(predicted_classes, label, metric_function):
if torch.min(predicted_classes) < 0:
print(
"WARNING: Negative values detected in prediction, cannot compute torchmetrics calculations."
Expand All @@ -32,16 +30,12 @@ def generic_function_output_with_check(
max_clamp_val = metric_function.num_classes - 1
except AttributeError:
max_clamp_val = 1
predicted_new = torch.clamp(
predicted_classes.cpu().int(), max=max_clamp_val
)
predicted_new = torch.clamp(predicted_classes.cpu().int(), max=max_clamp_val)
predicted_new = predicted_new.reshape(label.shape)
return metric_function(predicted_new, label.cpu().int())


def generic_torchmetrics_score(
output, label, metric_class, metric_key, params
):
def generic_torchmetrics_score(output, label, metric_class, metric_key, params):
task = determine_classification_task_type(params)
num_classes = params["model"]["num_classes"]
predicted_classes = output
Expand All @@ -67,25 +61,19 @@ def recall_score(output, label, params):


def precision_score(output, label, params):
return generic_torchmetrics_score(
output, label, Precision, "precision", params
)
return generic_torchmetrics_score(output, label, Precision, "precision", params)


def f1_score(output, label, params):
return generic_torchmetrics_score(output, label, F1Score, "f1", params)


def accuracy(output, label, params):
return generic_torchmetrics_score(
output, label, Accuracy, "accuracy", params
)
return generic_torchmetrics_score(output, label, Accuracy, "accuracy", params)


def specificity_score(output, label, params):
return generic_torchmetrics_score(
output, label, Specificity, "specificity", params
)
return generic_torchmetrics_score(output, label, Specificity, "specificity", params)


def iou_score(output, label, params):
Expand Down
Loading

0 comments on commit a379b87

Please sign in to comment.