Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Noninteractive run of notebooks and flake8 checks #107

Merged
merged 63 commits into from
Jan 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
d466995
start of automatic and update occ. sens.
rijobro Jan 12, 2021
b4a5063
current progress
rijobro Jan 12, 2021
a5d961e
current progress
rijobro Jan 12, 2021
432ff45
current progress
rijobro Jan 12, 2021
41023c2
current progress
rijobro Jan 13, 2021
eb2b957
vae
rijobro Jan 13, 2021
bec8927
models ensemble
rijobro Jan 13, 2021
64cf6cc
layer_wise_learning_rate
rijobro Jan 13, 2021
7a634bf
gan
rijobro Jan 13, 2021
536277c
Merge remote-tracking branch 'MONAI/master' into noninteractive_run
rijobro Jan 13, 2021
87ccfe5
3d_classification
rijobro Jan 13, 2021
bb4725a
add 3d_segmentation as well as flake
rijobro Jan 13, 2021
a9e9df9
transform speed
rijobro Jan 13, 2021
d46ad99
autopep8
rijobro Jan 13, 2021
be1048b
update runner
rijobro Jan 13, 2021
5fffbe6
flake8 support added
rijobro Jan 13, 2021
fd2640d
max_num_epochs->max_epochs
rijobro Jan 14, 2021
a1b35fa
check that max_epochs exists unless not expected
rijobro Jan 14, 2021
47210c6
uncomment executing notebook
rijobro Jan 14, 2021
7fb0ae9
check pip install
rijobro Jan 14, 2021
360633f
ignore temp files
rijobro Jan 14, 2021
e332c92
no noqa for indented import monai
rijobro Jan 14, 2021
4b8f80c
dont check for indented import monai
rijobro Jan 14, 2021
de2939c
flake8 changes
rijobro Jan 14, 2021
fb1d425
magic pip installs
rijobro Jan 14, 2021
32b5fa0
autofixes
rijobro Jan 14, 2021
900fcc4
use ! instead of % for pip install
rijobro Jan 14, 2021
919514d
so far
rijobro Jan 14, 2021
6152fe2
current progress. add black, isort, autoflake
rijobro Jan 14, 2021
252a269
current progress
rijobro Jan 14, 2021
fbea800
update class lung lesion notebook
rijobro Jan 14, 2021
b0d3b9f
class lung lesion
rijobro Jan 14, 2021
d12a92b
current progress
rijobro Jan 14, 2021
f01d585
current progress
rijobro Jan 14, 2021
af18daf
finished
rijobro Jan 14, 2021
33e7c60
Merge remote-tracking branch 'MONAI/master' into noninteractive_run
rijobro Jan 14, 2021
d5a3d87
finished
rijobro Jan 14, 2021
6b06a80
Merge branch 'noninteractive_run' of https://github.com/rijobro/tutor…
rijobro Jan 14, 2021
0dd96b0
remove pip install of pinned pytorch version
rijobro Jan 15, 2021
3968b3f
= list() to = []
rijobro Jan 15, 2021
c61cfd1
[DLMED] fix dyunet notebook issue
Nic-Ma Jan 19, 2021
9ea603d
correct faulty import
rijobro Jan 19, 2021
5f0ae23
pep8 for dynunet
rijobro Jan 20, 2021
51b519a
all working
rijobro Jan 20, 2021
79675df
add missing quotations
rijobro Jan 20, 2021
8803d51
remove personal file path
rijobro Jan 21, 2021
783425b
remove NiftiDataset
rijobro Jan 21, 2021
434e246
Merge branch 'noninteractive_run' of https://github.com/rijobro/tutor…
rijobro Jan 21, 2021
f7deb35
dont remove EOL whitespace from comments
rijobro Jan 21, 2021
8190097
Merge remote-tracking branch 'MONAI/master' into noninteractive_run
rijobro Jan 27, 2021
22563f2
2d_classification
rijobro Jan 27, 2021
e9a2b25
re-add spaces
rijobro Jan 27, 2021
f5e60f5
spaces
rijobro Jan 27, 2021
e8c6c39
last spaces
rijobro Jan 27, 2021
f31e4d1
merge
rijobro Jan 27, 2021
cc5df07
final changes
rijobro Jan 27, 2021
54f9d5d
notification at end
rijobro Jan 27, 2021
905500c
notification on exit
rijobro Jan 27, 2021
47cdbf2
add github action
rijobro Jan 27, 2021
9ad89af
data subfolder
rijobro Jan 27, 2021
5fadfff
make folder if necessary
rijobro Jan 27, 2021
9a37268
add flake8 to requirements
rijobro Jan 27, 2021
516bc6c
change test name
rijobro Jan 27, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/pep8.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: build

on:
# quick tests for every pull request
push:
branches:
- master
pull_request:

jobs:
# caching of these jobs:
# - docker-20-03-py3-pip- (shared)
# - ubuntu py37 pip-
# - os-latest-pip- (shared)
pep8:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: cache weekly timestamp
id: pip-cache
run: |
echo "::set-output name=datew::$(date '+%Y-%V')"
- name: cache for pip
uses: actions/cache@v2
id: cache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ steps.pip-cache.outputs.datew }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip wheel
python -m pip install -r requirements.txt
- name: PEP8 check
run: |
$(pwd)/runner.sh --no-run
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ temp/
.idea/

*~
._*

# Remove .pyre temporary config files
.pyre
Expand All @@ -133,3 +134,7 @@ tests/testing_data/*Hippocampus*

# saved networks
*.pth

# Ignore torch saves
*/torch/runs
logs
102 changes: 50 additions & 52 deletions 2d_classification/mednist_tutorial.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,8 @@
"metadata": {},
"outputs": [],
"source": [
"try:\n",
" import monai\n",
"except ImportError:\n",
" %pip install -q \"monai[pillow, tqdm]\""
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"scrolled": true,
"tags": []
},
"outputs": [],
"source": [
"!python -c \"import monai\" || pip install -q \"monai[pillow, tqdm]\"\n",
"!python -c \"import matplotlib\" || pip install -q matplotlib\n",
"%matplotlib inline"
]
},
Expand Down Expand Up @@ -107,12 +94,12 @@
"import os\n",
"import shutil\n",
"import tempfile\n",
"\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import PIL\n",
"import torch\n",
"import numpy as np\n",
"from sklearn.metrics import classification_report\n",
"\n",
"from monai.apps import download_and_extract\n",
"from monai.config import print_config\n",
"from monai.metrics import compute_roc_auc\n",
Expand Down Expand Up @@ -154,7 +141,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"/home/rbrown/data/MONAI\n"
"/workspace/data/medical\n"
]
}
],
Expand Down Expand Up @@ -243,7 +230,8 @@
}
],
"source": [
"class_names = sorted(x for x in os.listdir(data_dir) if os.path.isdir(os.path.join(data_dir, x)))\n",
"class_names = sorted(x for x in os.listdir(data_dir)\n",
" if os.path.isdir(os.path.join(data_dir, x)))\n",
"num_class = len(class_names)\n",
"image_files = [\n",
" [\n",
Expand Down Expand Up @@ -331,12 +319,12 @@
"source": [
"val_frac = 0.1\n",
"test_frac = 0.1\n",
"train_x = list()\n",
"train_y = list()\n",
"val_x = list()\n",
"val_y = list()\n",
"test_x = list()\n",
"test_y = list()\n",
"train_x = []\n",
"train_y = []\n",
"val_x = []\n",
"val_y = []\n",
"test_x = []\n",
"test_y = []\n",
"\n",
"for i in range(num_total):\n",
" rann = np.random.random()\n",
Expand All @@ -350,7 +338,9 @@
" train_x.append(image_files_list[i])\n",
" train_y.append(image_class[i])\n",
"\n",
"print(f\"Training count: {len(train_x)}, Validation count: {len(val_x)}, Test count: {len(test_x)}\")"
"print(\n",
" f\"Training count: {len(train_x)}, Validation count: \"\n",
" f\"{len(val_x)}, Test count: {len(test_x)}\")"
]
},
{
Expand Down Expand Up @@ -378,7 +368,8 @@
" ]\n",
")\n",
"\n",
"val_transforms = Compose([LoadImage(image_only=True), AddChannel(), ScaleIntensity(), ToTensor()])"
"val_transforms = Compose(\n",
" [LoadImage(image_only=True), AddChannel(), ScaleIntensity(), ToTensor()])"
]
},
{
Expand All @@ -401,13 +392,16 @@
"\n",
"\n",
"train_ds = MedNISTDataset(train_x, train_y, train_transforms)\n",
"train_loader = torch.utils.data.DataLoader(train_ds, batch_size=300, shuffle=True, num_workers=10)\n",
"train_loader = torch.utils.data.DataLoader(\n",
" train_ds, batch_size=300, shuffle=True, num_workers=10)\n",
"\n",
"val_ds = MedNISTDataset(val_x, val_y, val_transforms)\n",
"val_loader = torch.utils.data.DataLoader(val_ds, batch_size=300, num_workers=10)\n",
"val_loader = torch.utils.data.DataLoader(\n",
" val_ds, batch_size=300, num_workers=10)\n",
"\n",
"test_ds = MedNISTDataset(test_x, test_y, val_transforms)\n",
"test_loader = torch.utils.data.DataLoader(test_ds, batch_size=300, num_workers=10)"
"test_loader = torch.utils.data.DataLoader(\n",
" test_ds, batch_size=300, num_workers=10)"
]
},
{
Expand All @@ -419,7 +413,7 @@
"1. Set learning rate for how much the model is updated per batch.\n",
"1. Set total epoch number, as we have shuffle and random transforms, so the training data of every epoch is different. \n",
"And as this is just a get start tutorial, let's just train 4 epochs. \n",
"If train 10 epochs, the model can achieve 100% accuracy on test dataset.\n",
"If train 10 epochs, the model can achieve 100% accuracy on test dataset. \n",
"1. Use DenseNet from MONAI and move to GPU devide, this DenseNet can support both 2D and 3D classification tasks.\n",
"1. Use Adam optimizer."
]
Expand All @@ -431,10 +425,11 @@
"outputs": [],
"source": [
"device = torch.device(\"cuda:0\")\n",
"model = densenet121(spatial_dims=2, in_channels=1, out_channels=num_class).to(device)\n",
"model = densenet121(spatial_dims=2, in_channels=1,\n",
" out_channels=num_class).to(device)\n",
"loss_function = torch.nn.CrossEntropyLoss()\n",
"optimizer = torch.optim.Adam(model.parameters(), 1e-5)\n",
"max_num_epochs = 4\n",
"max_epochs = 4\n",
"val_interval = 1"
]
},
Expand Down Expand Up @@ -1130,12 +1125,12 @@
"source": [
"best_metric = -1\n",
"best_metric_epoch = -1\n",
"epoch_loss_values = list()\n",
"metric_values = list()\n",
"epoch_loss_values = []\n",
"metric_values = []\n",
"\n",
"for epoch in range(max_num_epochs):\n",
"for epoch in range(max_epochs):\n",
" print(\"-\" * 10)\n",
" print(f\"epoch {epoch + 1}/{max_num_epochs}\")\n",
" print(f\"epoch {epoch + 1}/{max_epochs}\")\n",
" model.train()\n",
" epoch_loss = 0\n",
" step = 0\n",
Expand All @@ -1148,7 +1143,9 @@
" loss.backward()\n",
" optimizer.step()\n",
" epoch_loss += loss.item()\n",
" print(f\"{step}/{len(train_ds) // train_loader.batch_size}, train_loss: {loss.item():.4f}\")\n",
" print(\n",
" f\"{step}/{len(train_ds) // train_loader.batch_size}, \"\n",
" f\"train_loss: {loss.item():.4f}\")\n",
" epoch_len = len(train_ds) // train_loader.batch_size\n",
" epoch_loss /= step\n",
" epoch_loss_values.append(epoch_loss)\n",
Expand All @@ -1166,22 +1163,27 @@
" )\n",
" y_pred = torch.cat([y_pred, model(val_images)], dim=0)\n",
" y = torch.cat([y, val_labels], dim=0)\n",
" auc_metric = compute_roc_auc(y_pred, y, to_onehot_y=True, softmax=True)\n",
" auc_metric = compute_roc_auc(\n",
" y_pred, y, to_onehot_y=True, softmax=True)\n",
" metric_values.append(auc_metric)\n",
" acc_value = torch.eq(y_pred.argmax(dim=1), y)\n",
" acc_metric = acc_value.sum().item() / len(acc_value)\n",
" if auc_metric > best_metric:\n",
" best_metric = auc_metric\n",
" best_metric_epoch = epoch + 1\n",
" torch.save(model.state_dict(), os.path.join(root_dir, \"best_metric_model.pth\"))\n",
" torch.save(model.state_dict(), os.path.join(\n",
" root_dir, \"best_metric_model.pth\"))\n",
" print(\"saved new best metric model\")\n",
" print(\n",
" f\"current epoch: {epoch + 1} current AUC: {auc_metric:.4f}\"\n",
" f\" current accuracy: {acc_metric:.4f} best AUC: {best_metric:.4f}\"\n",
" f\" current accuracy: {acc_metric:.4f}\"\n",
" f\" best AUC: {best_metric:.4f}\"\n",
" f\" at epoch: {best_metric_epoch}\"\n",
" )\n",
"\n",
"print(f\"train completed, best_metric: {best_metric:.4f} at epoch: {best_metric_epoch}\")"
"print(\n",
" f\"train completed, best_metric: {best_metric:.4f} \"\n",
" f\"at epoch: {best_metric_epoch}\")"
]
},
{
Expand Down Expand Up @@ -1243,10 +1245,11 @@
"metadata": {},
"outputs": [],
"source": [
"model.load_state_dict(torch.load(os.path.join(root_dir, \"best_metric_model.pth\")))\n",
"model.load_state_dict(torch.load(\n",
" os.path.join(root_dir, \"best_metric_model.pth\")))\n",
"model.eval()\n",
"y_true = list()\n",
"y_pred = list()\n",
"y_true = []\n",
"y_pred = []\n",
"with torch.no_grad():\n",
" for test_data in test_loader:\n",
" test_images, test_labels = (\n",
Expand Down Expand Up @@ -1288,13 +1291,8 @@
}
],
"source": [
"try:\n",
" import sklean\n",
"except ImportError:\n",
" %pip install -qU sklearn\n",
"from sklearn.metrics import classification_report\n",
"\n",
"print(classification_report(y_true, y_pred, target_names=class_names, digits=4))"
"print(classification_report(\n",
" y_true, y_pred, target_names=class_names, digits=4))"
]
},
{
Expand Down
Loading