From 9ca1a12e00edafc5deb2318defbfb174f9119706 Mon Sep 17 00:00:00 2001
From: Ycblue <yuchialan@gmail.com>
Date: Thu, 14 Jul 2022 14:30:21 +0200
Subject: [PATCH] changed folder hierarchy

---
 DeepGraft/AttMIL_simple_no_other.yaml         |   2 +-
 DeepGraft/AttMIL_simple_no_viral.yaml         |   6 +-
 DeepGraft/AttMIL_simple_tcmr_viral.yaml       |   7 +-
 DeepGraft/DTFDMIL_resnet50_tcmr_viral.yaml    |  51 ++
 DeepGraft/TransMIL_efficientnet_no_viral.yaml |   5 +-
 .../TransMIL_efficientnet_tcmr_viral.yaml     |  13 +-
 DeepGraft/TransMIL_resnet18_tcmr_viral.yaml   |  17 +-
 DeepGraft/TransMIL_resnet50_tcmr_viral.yaml   |  15 +-
 .../TransformerMIL_resnet50_tcmr_viral.yaml   |  52 ++
 .../__pycache__/loss_factory.cpython-39.pyc   | Bin 2545 -> 0 bytes
 README.md                                     |  23 +
 {MyBackbone => code/MyBackbone}/__init__.py   |   0
 .../MyBackbone}/backbone_factory.py           |   1 -
 {MyLoss => code/MyLoss}/ND_Crossentropy.py    |   0
 {MyLoss => code/MyLoss}/__init__.py           |   0
 .../ND_Crossentropy.cpython-39.pyc            | Bin
 .../__pycache__/__init__.cpython-39.pyc       | Bin
 .../__pycache__/boundary_loss.cpython-39.pyc  | Bin
 .../__pycache__/dice_loss.cpython-39.pyc      | Bin
 .../__pycache__/focal_loss.cpython-39.pyc     | Bin
 .../__pycache__/hausdorff.cpython-39.pyc      | Bin
 .../__pycache__/loss_factory.cpython-39.pyc   | Bin 0 -> 2623 bytes
 .../__pycache__/lovasz_loss.cpython-39.pyc    | Bin
 .../__pycache__/poly_loss.cpython-39.pyc      | Bin
 {MyLoss => code/MyLoss}/boundary_loss.py      |   0
 {MyLoss => code/MyLoss}/dice_loss.py          |   0
 {MyLoss => code/MyLoss}/focal_loss.py         |   0
 {MyLoss => code/MyLoss}/hausdorff.py          |   0
 {MyLoss => code/MyLoss}/loss_factory.py       |   6 +-
 {MyLoss => code/MyLoss}/lovasz_loss.py        |   0
 {MyLoss => code/MyLoss}/poly_loss.py          |   0
 {MyOptimizer => code/MyOptimizer}/__init__.py |   0
 .../__pycache__/__init__.cpython-39.pyc       | Bin
 .../__pycache__/adafactor.cpython-39.pyc      | Bin
 .../__pycache__/adahessian.cpython-39.pyc     | Bin
 .../__pycache__/adamp.cpython-39.pyc          | Bin
 .../__pycache__/adamw.cpython-39.pyc          | Bin
 .../__pycache__/lookahead.cpython-39.pyc      | Bin
 .../__pycache__/nadam.cpython-39.pyc          | Bin
 .../__pycache__/novograd.cpython-39.pyc       | Bin
 .../__pycache__/nvnovograd.cpython-39.pyc     | Bin
 .../__pycache__/optim_factory.cpython-39.pyc  | Bin
 .../__pycache__/radam.cpython-39.pyc          | Bin
 .../__pycache__/rmsprop_tf.cpython-39.pyc     | Bin
 .../__pycache__/sgdp.cpython-39.pyc           | Bin
 .../MyOptimizer}/adafactor.py                 |   0
 .../MyOptimizer}/adahessian.py                |   0
 {MyOptimizer => code/MyOptimizer}/adamp.py    |   0
 {MyOptimizer => code/MyOptimizer}/adamw.py    |   0
 .../MyOptimizer}/lookahead.py                 |   0
 {MyOptimizer => code/MyOptimizer}/nadam.py    |   0
 {MyOptimizer => code/MyOptimizer}/novograd.py |   0
 .../MyOptimizer}/nvnovograd.py                |   0
 .../MyOptimizer}/optim_factory.py             |   0
 {MyOptimizer => code/MyOptimizer}/radam.py    |   0
 .../MyOptimizer}/rmsprop_tf.py                |   0
 {MyOptimizer => code/MyOptimizer}/sgdp.py     |   0
 .../__pycache__/test_visualize.cpython-39.pyc | Bin 0 -> 11095 bytes
 code/__pycache__/train_loop.cpython-39.pyc    | Bin 0 -> 14557 bytes
 code/datasets/__init__.py                     |   3 +
 .../__pycache__/__init__.cpython-39.pyc       | Bin 0 -> 270 bytes
 .../__pycache__/camel_data.cpython-39.pyc     | Bin
 .../camel_dataloader.cpython-39.pyc           | Bin
 .../custom_dataloader.cpython-39.pyc          | Bin
 .../custom_jpg_dataloader.cpython-39.pyc      | Bin 0 -> 10649 bytes
 .../__pycache__/data_interface.cpython-39.pyc | Bin
 {datasets => code/datasets}/camel_data.py     |   0
 .../datasets}/camel_dataloader.py             |   0
 .../datasets}/custom_dataloader.py            |   0
 .../datasets}/custom_jpg_dataloader.py        |  93 ++-
 code/datasets/dali_dataloader.py              | 139 ++++
 {datasets => code/datasets}/data_interface.py |   0
 code/lightning_logs/version_0/cm_test.png     | Bin 0 -> 47096 bytes
 ...nts.out.tfevents.1657535217.dgx2.2080039.0 | Bin 0 -> 4702 bytes
 code/lightning_logs/version_0/hparams.yaml    | 368 +++++++++
 code/lightning_logs/version_1/cm_test.png     | Bin 0 -> 45165 bytes
 ...nts.out.tfevents.1657535625.dgx2.2086189.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_1/hparams.yaml    | 368 +++++++++
 ...vents.out.tfevents.1657546166.dgx1.47613.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_10/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657546322.dgx1.48740.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_11/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657546521.dgx1.50053.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_12/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657546918.dgx1.52290.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_13/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657546992.dgx1.53435.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_14/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657547134.dgx1.54703.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_15/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657547198.dgx1.55641.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_16/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657623153.dgx1.41577.0 | Bin 0 -> 4704 bytes
 code/lightning_logs/version_17/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657624768.dgx1.72352.0 | Bin 0 -> 4704 bytes
 code/lightning_logs/version_18/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657624869.dgx1.76706.0 | Bin 0 -> 4704 bytes
 code/lightning_logs/version_19/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657543650.dgx1.33429.0 | Bin 0 -> 4700 bytes
 code/lightning_logs/version_2/hparams.yaml    | 368 +++++++++
 ...events.out.tfevents.1657625133.dgx1.5999.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_20/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657625248.dgx1.11114.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_21/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657625470.dgx1.20071.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_22/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657625510.dgx1.22295.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_23/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657625570.dgx1.25099.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_24/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657625613.dgx1.27343.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_25/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657625763.dgx1.33397.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_26/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657625819.dgx1.36236.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_27/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657625859.dgx1.38333.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_28/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657625903.dgx1.40628.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_29/hparams.yaml   | 368 +++++++++
 code/lightning_logs/version_3/cm_test.png     | Bin 0 -> 63231 bytes
 ...vents.out.tfevents.1657543830.dgx1.34643.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_3/hparams.yaml    | 368 +++++++++
 ...vents.out.tfevents.1657625960.dgx1.43463.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_30/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657626120.dgx1.48909.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_31/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657626628.dgx1.65460.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_32/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657626794.dgx1.71384.0 | Bin 0 -> 4699 bytes
 code/lightning_logs/version_33/hparams.yaml   | 368 +++++++++
 ...vents.out.tfevents.1657545281.dgx1.41143.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_4/hparams.yaml    | 368 +++++++++
 ...vents.out.tfevents.1657545407.dgx1.42159.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_5/hparams.yaml    | 368 +++++++++
 ...vents.out.tfevents.1657545574.dgx1.43290.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_6/hparams.yaml    | 368 +++++++++
 ...vents.out.tfevents.1657545679.dgx1.44154.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_7/hparams.yaml    | 368 +++++++++
 ...vents.out.tfevents.1657545837.dgx1.45339.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_8/hparams.yaml    | 368 +++++++++
 ...vents.out.tfevents.1657545985.dgx1.46385.0 | Bin 0 -> 4705 bytes
 code/lightning_logs/version_9/hparams.yaml    | 368 +++++++++
 {models => code/models}/AttMIL.py             |   2 +-
 code/models/DTFDMIL.py                        | 109 +++
 {models => code/models}/TransMIL.py           |  53 +-
 code/models/TransformerMIL.py                 | 129 ++++
 {models => code/models}/__init__.py           |   0
 .../models}/__pycache__/AttMIL.cpython-39.pyc | Bin 1551 -> 1555 bytes
 .../models/__pycache__/DTFDMIL.cpython-39.pyc | Bin 0 -> 3969 bytes
 .../__pycache__/TransMIL.cpython-39.pyc       | Bin 0 -> 3455 bytes
 .../__pycache__/TransformerMIL.cpython-39.pyc | Bin 0 -> 3440 bytes
 .../__pycache__/__init__.cpython-39.pyc       | Bin
 .../model_interface.cpython-39.pyc            | Bin 0 -> 15830 bytes
 .../model_interface_dtfd.cpython-39.pyc       | Bin 0 -> 17058 bytes
 .../__pycache__/resnet50.cpython-39.pyc       | Bin
 .../vision_transformer.cpython-39.pyc         | Bin
 {models => code/models}/model_interface.py    | 293 +++++---
 code/models/model_interface_dtfd.py           | 707 ++++++++++++++++++
 {models => code/models}/resnet50.py           |   0
 {models => code/models}/vision_transformer.py |   0
 code/test_visualize.py                        | 437 +++++++++++
 train.py => code/train.py                     |  30 +-
 code/train_loop.py                            | 496 ++++++++++++
 {utils => code/utils}/__init__.py             |   0
 .../__pycache__/__init__.cpython-39.pyc       | Bin
 code/utils/__pycache__/utils.cpython-39.pyc   | Bin 0 -> 4080 bytes
 code/utils/extract_features.py                |  37 +
 {utils => code/utils}/utils.py                |  11 +-
 datasets/__init__.py                          |   2 -
 datasets/__pycache__/__init__.cpython-39.pyc  | Bin 193 -> 0 bytes
 .../custom_jpg_dataloader.cpython-39.pyc      | Bin 11037 -> 0 bytes
 models/__pycache__/TransMIL.cpython-39.pyc    | Bin 3233 -> 0 bytes
 .../model_interface.cpython-39.pyc            | Bin 14054 -> 0 bytes
 test_visualize.py                             | 148 ----
 train_loop.py                                 | 212 ------
 utils/__pycache__/utils.cpython-39.pyc        | Bin 4005 -> 0 bytes
 utils/extract_features.py                     |  27 -
 178 files changed, 15046 insertions(+), 592 deletions(-)
 create mode 100644 DeepGraft/DTFDMIL_resnet50_tcmr_viral.yaml
 create mode 100644 DeepGraft/TransformerMIL_resnet50_tcmr_viral.yaml
 delete mode 100644 MyLoss/__pycache__/loss_factory.cpython-39.pyc
 rename {MyBackbone => code/MyBackbone}/__init__.py (100%)
 rename {MyBackbone => code/MyBackbone}/backbone_factory.py (99%)
 rename {MyLoss => code/MyLoss}/ND_Crossentropy.py (100%)
 rename {MyLoss => code/MyLoss}/__init__.py (100%)
 rename {MyLoss => code/MyLoss}/__pycache__/ND_Crossentropy.cpython-39.pyc (100%)
 rename {MyLoss => code/MyLoss}/__pycache__/__init__.cpython-39.pyc (100%)
 rename {MyLoss => code/MyLoss}/__pycache__/boundary_loss.cpython-39.pyc (100%)
 rename {MyLoss => code/MyLoss}/__pycache__/dice_loss.cpython-39.pyc (100%)
 rename {MyLoss => code/MyLoss}/__pycache__/focal_loss.cpython-39.pyc (100%)
 rename {MyLoss => code/MyLoss}/__pycache__/hausdorff.cpython-39.pyc (100%)
 create mode 100644 code/MyLoss/__pycache__/loss_factory.cpython-39.pyc
 rename {MyLoss => code/MyLoss}/__pycache__/lovasz_loss.cpython-39.pyc (100%)
 rename {MyLoss => code/MyLoss}/__pycache__/poly_loss.cpython-39.pyc (100%)
 rename {MyLoss => code/MyLoss}/boundary_loss.py (100%)
 rename {MyLoss => code/MyLoss}/dice_loss.py (100%)
 rename {MyLoss => code/MyLoss}/focal_loss.py (100%)
 rename {MyLoss => code/MyLoss}/hausdorff.py (100%)
 rename {MyLoss => code/MyLoss}/loss_factory.py (91%)
 rename {MyLoss => code/MyLoss}/lovasz_loss.py (100%)
 rename {MyLoss => code/MyLoss}/poly_loss.py (100%)
 rename {MyOptimizer => code/MyOptimizer}/__init__.py (100%)
 rename {MyOptimizer => code/MyOptimizer}/__pycache__/__init__.cpython-39.pyc (100%)
 rename {MyOptimizer => code/MyOptimizer}/__pycache__/adafactor.cpython-39.pyc (100%)
 rename {MyOptimizer => code/MyOptimizer}/__pycache__/adahessian.cpython-39.pyc (100%)
 rename {MyOptimizer => code/MyOptimizer}/__pycache__/adamp.cpython-39.pyc (100%)
 rename {MyOptimizer => code/MyOptimizer}/__pycache__/adamw.cpython-39.pyc (100%)
 rename {MyOptimizer => code/MyOptimizer}/__pycache__/lookahead.cpython-39.pyc (100%)
 rename {MyOptimizer => code/MyOptimizer}/__pycache__/nadam.cpython-39.pyc (100%)
 rename {MyOptimizer => code/MyOptimizer}/__pycache__/novograd.cpython-39.pyc (100%)
 rename {MyOptimizer => code/MyOptimizer}/__pycache__/nvnovograd.cpython-39.pyc (100%)
 rename {MyOptimizer => code/MyOptimizer}/__pycache__/optim_factory.cpython-39.pyc (100%)
 rename {MyOptimizer => code/MyOptimizer}/__pycache__/radam.cpython-39.pyc (100%)
 rename {MyOptimizer => code/MyOptimizer}/__pycache__/rmsprop_tf.cpython-39.pyc (100%)
 rename {MyOptimizer => code/MyOptimizer}/__pycache__/sgdp.cpython-39.pyc (100%)
 rename {MyOptimizer => code/MyOptimizer}/adafactor.py (100%)
 rename {MyOptimizer => code/MyOptimizer}/adahessian.py (100%)
 rename {MyOptimizer => code/MyOptimizer}/adamp.py (100%)
 rename {MyOptimizer => code/MyOptimizer}/adamw.py (100%)
 rename {MyOptimizer => code/MyOptimizer}/lookahead.py (100%)
 rename {MyOptimizer => code/MyOptimizer}/nadam.py (100%)
 rename {MyOptimizer => code/MyOptimizer}/novograd.py (100%)
 rename {MyOptimizer => code/MyOptimizer}/nvnovograd.py (100%)
 rename {MyOptimizer => code/MyOptimizer}/optim_factory.py (100%)
 rename {MyOptimizer => code/MyOptimizer}/radam.py (100%)
 rename {MyOptimizer => code/MyOptimizer}/rmsprop_tf.py (100%)
 rename {MyOptimizer => code/MyOptimizer}/sgdp.py (100%)
 create mode 100644 code/__pycache__/test_visualize.cpython-39.pyc
 create mode 100644 code/__pycache__/train_loop.cpython-39.pyc
 create mode 100644 code/datasets/__init__.py
 create mode 100644 code/datasets/__pycache__/__init__.cpython-39.pyc
 rename {datasets => code/datasets}/__pycache__/camel_data.cpython-39.pyc (100%)
 rename {datasets => code/datasets}/__pycache__/camel_dataloader.cpython-39.pyc (100%)
 rename {datasets => code/datasets}/__pycache__/custom_dataloader.cpython-39.pyc (100%)
 create mode 100644 code/datasets/__pycache__/custom_jpg_dataloader.cpython-39.pyc
 rename {datasets => code/datasets}/__pycache__/data_interface.cpython-39.pyc (100%)
 rename {datasets => code/datasets}/camel_data.py (100%)
 rename {datasets => code/datasets}/camel_dataloader.py (100%)
 rename {datasets => code/datasets}/custom_dataloader.py (100%)
 rename {datasets => code/datasets}/custom_jpg_dataloader.py (87%)
 create mode 100644 code/datasets/dali_dataloader.py
 rename {datasets => code/datasets}/data_interface.py (100%)
 create mode 100644 code/lightning_logs/version_0/cm_test.png
 create mode 100644 code/lightning_logs/version_0/events.out.tfevents.1657535217.dgx2.2080039.0
 create mode 100644 code/lightning_logs/version_0/hparams.yaml
 create mode 100644 code/lightning_logs/version_1/cm_test.png
 create mode 100644 code/lightning_logs/version_1/events.out.tfevents.1657535625.dgx2.2086189.0
 create mode 100644 code/lightning_logs/version_1/hparams.yaml
 create mode 100644 code/lightning_logs/version_10/events.out.tfevents.1657546166.dgx1.47613.0
 create mode 100644 code/lightning_logs/version_10/hparams.yaml
 create mode 100644 code/lightning_logs/version_11/events.out.tfevents.1657546322.dgx1.48740.0
 create mode 100644 code/lightning_logs/version_11/hparams.yaml
 create mode 100644 code/lightning_logs/version_12/events.out.tfevents.1657546521.dgx1.50053.0
 create mode 100644 code/lightning_logs/version_12/hparams.yaml
 create mode 100644 code/lightning_logs/version_13/events.out.tfevents.1657546918.dgx1.52290.0
 create mode 100644 code/lightning_logs/version_13/hparams.yaml
 create mode 100644 code/lightning_logs/version_14/events.out.tfevents.1657546992.dgx1.53435.0
 create mode 100644 code/lightning_logs/version_14/hparams.yaml
 create mode 100644 code/lightning_logs/version_15/events.out.tfevents.1657547134.dgx1.54703.0
 create mode 100644 code/lightning_logs/version_15/hparams.yaml
 create mode 100644 code/lightning_logs/version_16/events.out.tfevents.1657547198.dgx1.55641.0
 create mode 100644 code/lightning_logs/version_16/hparams.yaml
 create mode 100644 code/lightning_logs/version_17/events.out.tfevents.1657623153.dgx1.41577.0
 create mode 100644 code/lightning_logs/version_17/hparams.yaml
 create mode 100644 code/lightning_logs/version_18/events.out.tfevents.1657624768.dgx1.72352.0
 create mode 100644 code/lightning_logs/version_18/hparams.yaml
 create mode 100644 code/lightning_logs/version_19/events.out.tfevents.1657624869.dgx1.76706.0
 create mode 100644 code/lightning_logs/version_19/hparams.yaml
 create mode 100644 code/lightning_logs/version_2/events.out.tfevents.1657543650.dgx1.33429.0
 create mode 100644 code/lightning_logs/version_2/hparams.yaml
 create mode 100644 code/lightning_logs/version_20/events.out.tfevents.1657625133.dgx1.5999.0
 create mode 100644 code/lightning_logs/version_20/hparams.yaml
 create mode 100644 code/lightning_logs/version_21/events.out.tfevents.1657625248.dgx1.11114.0
 create mode 100644 code/lightning_logs/version_21/hparams.yaml
 create mode 100644 code/lightning_logs/version_22/events.out.tfevents.1657625470.dgx1.20071.0
 create mode 100644 code/lightning_logs/version_22/hparams.yaml
 create mode 100644 code/lightning_logs/version_23/events.out.tfevents.1657625510.dgx1.22295.0
 create mode 100644 code/lightning_logs/version_23/hparams.yaml
 create mode 100644 code/lightning_logs/version_24/events.out.tfevents.1657625570.dgx1.25099.0
 create mode 100644 code/lightning_logs/version_24/hparams.yaml
 create mode 100644 code/lightning_logs/version_25/events.out.tfevents.1657625613.dgx1.27343.0
 create mode 100644 code/lightning_logs/version_25/hparams.yaml
 create mode 100644 code/lightning_logs/version_26/events.out.tfevents.1657625763.dgx1.33397.0
 create mode 100644 code/lightning_logs/version_26/hparams.yaml
 create mode 100644 code/lightning_logs/version_27/events.out.tfevents.1657625819.dgx1.36236.0
 create mode 100644 code/lightning_logs/version_27/hparams.yaml
 create mode 100644 code/lightning_logs/version_28/events.out.tfevents.1657625859.dgx1.38333.0
 create mode 100644 code/lightning_logs/version_28/hparams.yaml
 create mode 100644 code/lightning_logs/version_29/events.out.tfevents.1657625903.dgx1.40628.0
 create mode 100644 code/lightning_logs/version_29/hparams.yaml
 create mode 100644 code/lightning_logs/version_3/cm_test.png
 create mode 100644 code/lightning_logs/version_3/events.out.tfevents.1657543830.dgx1.34643.0
 create mode 100644 code/lightning_logs/version_3/hparams.yaml
 create mode 100644 code/lightning_logs/version_30/events.out.tfevents.1657625960.dgx1.43463.0
 create mode 100644 code/lightning_logs/version_30/hparams.yaml
 create mode 100644 code/lightning_logs/version_31/events.out.tfevents.1657626120.dgx1.48909.0
 create mode 100644 code/lightning_logs/version_31/hparams.yaml
 create mode 100644 code/lightning_logs/version_32/events.out.tfevents.1657626628.dgx1.65460.0
 create mode 100644 code/lightning_logs/version_32/hparams.yaml
 create mode 100644 code/lightning_logs/version_33/events.out.tfevents.1657626794.dgx1.71384.0
 create mode 100644 code/lightning_logs/version_33/hparams.yaml
 create mode 100644 code/lightning_logs/version_4/events.out.tfevents.1657545281.dgx1.41143.0
 create mode 100644 code/lightning_logs/version_4/hparams.yaml
 create mode 100644 code/lightning_logs/version_5/events.out.tfevents.1657545407.dgx1.42159.0
 create mode 100644 code/lightning_logs/version_5/hparams.yaml
 create mode 100644 code/lightning_logs/version_6/events.out.tfevents.1657545574.dgx1.43290.0
 create mode 100644 code/lightning_logs/version_6/hparams.yaml
 create mode 100644 code/lightning_logs/version_7/events.out.tfevents.1657545679.dgx1.44154.0
 create mode 100644 code/lightning_logs/version_7/hparams.yaml
 create mode 100644 code/lightning_logs/version_8/events.out.tfevents.1657545837.dgx1.45339.0
 create mode 100644 code/lightning_logs/version_8/hparams.yaml
 create mode 100644 code/lightning_logs/version_9/events.out.tfevents.1657545985.dgx1.46385.0
 create mode 100644 code/lightning_logs/version_9/hparams.yaml
 rename {models => code/models}/AttMIL.py (98%)
 create mode 100644 code/models/DTFDMIL.py
 rename {models => code/models}/TransMIL.py (70%)
 create mode 100644 code/models/TransformerMIL.py
 rename {models => code/models}/__init__.py (100%)
 rename {models => code/models}/__pycache__/AttMIL.cpython-39.pyc (79%)
 create mode 100644 code/models/__pycache__/DTFDMIL.cpython-39.pyc
 create mode 100644 code/models/__pycache__/TransMIL.cpython-39.pyc
 create mode 100644 code/models/__pycache__/TransformerMIL.cpython-39.pyc
 rename {models => code/models}/__pycache__/__init__.cpython-39.pyc (100%)
 create mode 100644 code/models/__pycache__/model_interface.cpython-39.pyc
 create mode 100644 code/models/__pycache__/model_interface_dtfd.cpython-39.pyc
 rename {models => code/models}/__pycache__/resnet50.cpython-39.pyc (100%)
 rename {models => code/models}/__pycache__/vision_transformer.cpython-39.pyc (100%)
 rename {models => code/models}/model_interface.py (70%)
 create mode 100644 code/models/model_interface_dtfd.py
 rename {models => code/models}/resnet50.py (100%)
 rename {models => code/models}/vision_transformer.py (100%)
 create mode 100644 code/test_visualize.py
 rename train.py => code/train.py (85%)
 create mode 100644 code/train_loop.py
 rename {utils => code/utils}/__init__.py (100%)
 rename {utils => code/utils}/__pycache__/__init__.cpython-39.pyc (100%)
 create mode 100644 code/utils/__pycache__/utils.cpython-39.pyc
 create mode 100644 code/utils/extract_features.py
 rename {utils => code/utils}/utils.py (95%)
 delete mode 100644 datasets/__init__.py
 delete mode 100644 datasets/__pycache__/__init__.cpython-39.pyc
 delete mode 100644 datasets/__pycache__/custom_jpg_dataloader.cpython-39.pyc
 delete mode 100644 models/__pycache__/TransMIL.cpython-39.pyc
 delete mode 100644 models/__pycache__/model_interface.cpython-39.pyc
 delete mode 100644 test_visualize.py
 delete mode 100644 train_loop.py
 delete mode 100644 utils/__pycache__/utils.cpython-39.pyc
 delete mode 100644 utils/extract_features.py

diff --git a/DeepGraft/AttMIL_simple_no_other.yaml b/DeepGraft/AttMIL_simple_no_other.yaml
index ae90a80..344c204 100644
--- a/DeepGraft/AttMIL_simple_no_other.yaml
+++ b/DeepGraft/AttMIL_simple_no_other.yaml
@@ -16,7 +16,7 @@ General:
 Data:
     dataset_name: custom
     data_shuffle: False
-    data_dir: '/home/ylan/DeepGraft/dataset/hdf5/256_256um_split/'
+    data_dir: '/home/ylan/data/DeepGraft/224_128um/'
     label_file: '/home/ylan/DeepGraft/training_tables/split_PAS_no_other.json'
     fold: 1
     nfold: 3
diff --git a/DeepGraft/AttMIL_simple_no_viral.yaml b/DeepGraft/AttMIL_simple_no_viral.yaml
index 37ee074..ac18f9c 100644
--- a/DeepGraft/AttMIL_simple_no_viral.yaml
+++ b/DeepGraft/AttMIL_simple_no_viral.yaml
@@ -6,7 +6,7 @@ General:
     precision: 16 
     multi_gpu_mode: dp
     gpus: [3]
-    epochs: &epoch 500 
+    epochs: &epoch 200 
     grad_acc: 2
     frozen_bn: False
     patience: 50
@@ -16,7 +16,7 @@ General:
 Data:
     dataset_name: custom
     data_shuffle: False
-    data_dir: '/home/ylan/DeepGraft/dataset/hdf5/256_256um_split/'
+    data_dir: '/home/ylan/data/DeepGraft/224_128um/'
     label_file: '/home/ylan/DeepGraft/training_tables/split_PAS_no_viral.json'
     fold: 1
     nfold: 4
@@ -41,7 +41,7 @@ Optimizer:
     opt_eps: null 
     opt_betas: null
     momentum: null 
-    weight_decay: 0.00001
+    weight_decay: 0.01
 
 Loss:
     base_loss: CrossEntropyLoss
diff --git a/DeepGraft/AttMIL_simple_tcmr_viral.yaml b/DeepGraft/AttMIL_simple_tcmr_viral.yaml
index c982d3a..2aa4ed8 100644
--- a/DeepGraft/AttMIL_simple_tcmr_viral.yaml
+++ b/DeepGraft/AttMIL_simple_tcmr_viral.yaml
@@ -6,7 +6,7 @@ General:
     precision: 16 
     multi_gpu_mode: dp
     gpus: [3]
-    epochs: &epoch 300 
+    epochs: &epoch 200 
     grad_acc: 2
     frozen_bn: False
     patience: 20
@@ -16,7 +16,7 @@ General:
 Data:
     dataset_name: custom
     data_shuffle: False
-    data_dir: '/home/ylan/DeepGraft/dataset/hdf5/256_256um_split/'
+    data_dir: '/home/ylan/data/DeepGraft/224_128um/'
     label_file: '/home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json'
     fold: 1
     nfold: 3
@@ -34,6 +34,7 @@ Model:
     name: AttMIL
     n_classes: 2
     backbone: simple
+    in_features: 512
 
 
 Optimizer:
@@ -42,7 +43,7 @@ Optimizer:
     opt_eps: null 
     opt_betas: null
     momentum: null 
-    weight_decay: 0.00001
+    weight_decay: 0.01
 
 Loss:
     base_loss: CrossEntropyLoss
diff --git a/DeepGraft/DTFDMIL_resnet50_tcmr_viral.yaml b/DeepGraft/DTFDMIL_resnet50_tcmr_viral.yaml
new file mode 100644
index 0000000..7493b37
--- /dev/null
+++ b/DeepGraft/DTFDMIL_resnet50_tcmr_viral.yaml
@@ -0,0 +1,51 @@
+General:
+    comment: 
+    seed: 2021
+    fp16: True
+    amp_level: O2
+    precision: 16 
+    multi_gpu_mode: dp
+    gpus: [0]
+    epochs: &epoch 200 
+    grad_acc: 2
+    frozen_bn: False
+    patience: 50
+    server: test #train #test
+    log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+
+Data:
+    dataset_name: custom
+    data_shuffle: False
+    data_dir: '/home/ylan/data/DeepGraft/224_128um/'
+    label_file: '/home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json'
+    fold: 1
+    nfold: 3
+    cross_val: False
+
+    train_dataloader:
+        batch_size: 1 
+        num_workers: 8
+
+    test_dataloader:
+        batch_size: 1
+        num_workers: 8
+
+Model:
+    name: DTFDMIL
+    n_classes: 2
+    backbone: resnet50
+    in_features: 512
+    out_features: 512
+
+
+Optimizer:
+    opt: lookahead_radam
+    lr: 0.0002
+    opt_eps: null 
+    opt_betas: null
+    momentum: null 
+    weight_decay: 0.01
+
+Loss:
+    base_loss: CrossEntropyLoss
+
diff --git a/DeepGraft/TransMIL_efficientnet_no_viral.yaml b/DeepGraft/TransMIL_efficientnet_no_viral.yaml
index 98fe377..cffd500 100644
--- a/DeepGraft/TransMIL_efficientnet_no_viral.yaml
+++ b/DeepGraft/TransMIL_efficientnet_no_viral.yaml
@@ -11,15 +11,16 @@ General:
     frozen_bn: False
     patience: 20
     server: test #train #test
-    log_path: logs/
+    log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
 
 Data:
     dataset_name: custom
     data_shuffle: False
-    data_dir: '/home/ylan/DeepGraft/dataset/hdf5/256_256um_split/'
+    data_dir: '/home/ylan/data/DeepGraft/256_256um/'
     label_file: '/home/ylan/DeepGraft/training_tables/split_PAS_no_viral.json'
     fold: 1
     nfold: 4
+    cross_val: False
 
     train_dataloader:
         batch_size: 1 
diff --git a/DeepGraft/TransMIL_efficientnet_tcmr_viral.yaml b/DeepGraft/TransMIL_efficientnet_tcmr_viral.yaml
index 5223032..0dc5fa1 100644
--- a/DeepGraft/TransMIL_efficientnet_tcmr_viral.yaml
+++ b/DeepGraft/TransMIL_efficientnet_tcmr_viral.yaml
@@ -6,21 +6,21 @@ General:
     precision: 16 
     multi_gpu_mode: dp
     gpus: [0]
-    epochs: &epoch 500 
+    epochs: &epoch 200 
     grad_acc: 2
     frozen_bn: False
-    patience: 200
+    patience: 20
     server: train #train #test
-    log_path: logs/
+    log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
 
 Data:
     dataset_name: custom
     data_shuffle: False
-    data_dir: '/home/ylan/data/DeepGraft/256_256um/'
+    data_dir: '/home/ylan/data/DeepGraft/224_128um/'
     label_file: '/home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json'
     fold: 1
     nfold: 3
-    cross_val: True
+    cross_val: False
 
     train_dataloader:
         batch_size: 1 
@@ -35,6 +35,7 @@ Model:
     n_classes: 2
     backbone: efficientnet
     in_features: 512
+    out_features: 512
 
 
 Optimizer:
@@ -43,7 +44,7 @@ Optimizer:
     opt_eps: null 
     opt_betas: null
     momentum: null 
-    weight_decay: 0.00001
+    weight_decay: 0.01
 
 Loss:
     base_loss: CrossEntropyLoss
diff --git a/DeepGraft/TransMIL_resnet18_tcmr_viral.yaml b/DeepGraft/TransMIL_resnet18_tcmr_viral.yaml
index c26e1e9..961f819 100644
--- a/DeepGraft/TransMIL_resnet18_tcmr_viral.yaml
+++ b/DeepGraft/TransMIL_resnet18_tcmr_viral.yaml
@@ -5,21 +5,22 @@ General:
     amp_level: O2
     precision: 16 
     multi_gpu_mode: dp
-    gpus: [3]
-    epochs: &epoch 500 
+    gpus: [0]
+    epochs: &epoch 200 
     grad_acc: 2
     frozen_bn: False
     patience: 50
     server: test #train #test
-    log_path: logs/
+    log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
 
 Data:
     dataset_name: custom
     data_shuffle: False
-    data_dir: '/home/ylan/DeepGraft/dataset/hdf5/256_256um_split/'
-    label_file: '/home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json'
+    data_dir: '/home/ylan/data/DeepGraft/224_128um/'
+    label_file: '/home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json'
     fold: 1
-    nfold: 4
+    nfold: 3
+    cross_val: False
 
     train_dataloader:
         batch_size: 1 
@@ -33,6 +34,8 @@ Model:
     name: TransMIL
     n_classes: 2
     backbone: resnet18
+    in_features: 512
+    out_features: 512
 
 
 Optimizer:
@@ -41,7 +44,7 @@ Optimizer:
     opt_eps: null 
     opt_betas: null
     momentum: null 
-    weight_decay: 0.00001
+    weight_decay: 0.01
 
 Loss:
     base_loss: CrossEntropyLoss
diff --git a/DeepGraft/TransMIL_resnet50_tcmr_viral.yaml b/DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
index f6e4697..df205a2 100644
--- a/DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+++ b/DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
@@ -6,21 +6,21 @@ General:
     precision: 16 
     multi_gpu_mode: dp
     gpus: [0]
-    epochs: &epoch 200 
+    epochs: &epoch 500 
     grad_acc: 2
     frozen_bn: False
     patience: 50
     server: test #train #test
-    log_path: logs/
+    log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
 
 Data:
     dataset_name: custom
     data_shuffle: False
-    data_dir: '/home/ylan/DeepGraft/dataset/hdf5/256_256um_split/'
-    label_file: '/home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json'
+    data_dir: '/home/ylan/data/DeepGraft/224_128um/'
+    label_file: '/home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json'
     fold: 1
     nfold: 3
-    cross_val: True
+    cross_val: False
 
     train_dataloader:
         batch_size: 1 
@@ -34,6 +34,8 @@ Model:
     name: TransMIL
     n_classes: 2
     backbone: resnet50
+    in_features: 512
+    out_features: 512
 
 
 Optimizer:
@@ -42,8 +44,9 @@ Optimizer:
     opt_eps: null 
     opt_betas: null
     momentum: null 
-    weight_decay: 0.00001
+    weight_decay: 0.01
 
 Loss:
     base_loss: CrossEntropyLoss
+    loss_weight: [1., 1.]
 
diff --git a/DeepGraft/TransformerMIL_resnet50_tcmr_viral.yaml b/DeepGraft/TransformerMIL_resnet50_tcmr_viral.yaml
new file mode 100644
index 0000000..896bef1
--- /dev/null
+++ b/DeepGraft/TransformerMIL_resnet50_tcmr_viral.yaml
@@ -0,0 +1,52 @@
+General:
+    comment: 
+    seed: 2021
+    fp16: True
+    amp_level: O2
+    precision: 16 
+    multi_gpu_mode: dp
+    gpus: [0]
+    epochs: &epoch 500 
+    grad_acc: 2
+    frozen_bn: False
+    patience: 50
+    server: test #train #test
+    log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+
+Data:
+    dataset_name: custom
+    data_shuffle: False
+    data_dir: '/home/ylan/data/DeepGraft/224_128um/'
+    label_file: '/home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json'
+    fold: 1
+    nfold: 3
+    cross_val: False
+
+    train_dataloader:
+        batch_size: 1 
+        num_workers: 8
+
+    test_dataloader:
+        batch_size: 1
+        num_workers: 8
+
+Model:
+    name: TransformerMIL
+    n_classes: 2
+    backbone: resnet50
+    in_features: 512
+    out_features: 512
+
+
+Optimizer:
+    opt: lookahead_radam
+    lr: 0.0002
+    opt_eps: null 
+    opt_betas: null
+    momentum: null 
+    weight_decay: 0.01
+
+Loss:
+    base_loss: CrossEntropyLoss
+    
+
diff --git a/MyLoss/__pycache__/loss_factory.cpython-39.pyc b/MyLoss/__pycache__/loss_factory.cpython-39.pyc
deleted file mode 100644
index 14452dde7b34fd11b5255f4ed07bdeb48a27e49f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2545
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

diff --git a/README.md b/README.md
index effc0fe..c8594bc 100644
--- a/README.md
+++ b/README.md
@@ -13,3 +13,26 @@ python train.py --stage='test' --config='Camelyon/TransMIL.yaml'  --gpus=0 --fol
 
 ### Changes Made: 
 
+### Baseline: 
+
+lr = 0.0002
+wd = 0.01
+
+| task        | main | backbone | train_auc | val_auc | epochs | version |  
+|---|---|---|---|---|
+| tcmr_viral | TransMIL | resnet50 |  0.997 | 0.871 | 200 | 4 |
+|            |          | resnet18 |  0.999 | 0.687 | 200 | 0 |
+|            |          | efficientnet | 0.99 | 0.76 | 200 | 107 |
+|            | DTFD     | resnet50 | 0.989 | 0.621 | 200 | 44 |
+|            | AttMIL   | simple | 0.513 | 0.518 | 200 | 50 |
+
+
+159	28639			0.9222221970558167	0.19437336921691895	0.5906432867050171	0.56540447473526	0.7159091234207153	0.8709122538566589	0.30908203125
+
+### Ablation
+
+image drop out: 
+tcmr_viral TCMR efficientnet: version 0
+
+wd incerease: 
+tcmr_viral TCMR efficientnet: version 110
\ No newline at end of file
diff --git a/MyBackbone/__init__.py b/code/MyBackbone/__init__.py
similarity index 100%
rename from MyBackbone/__init__.py
rename to code/MyBackbone/__init__.py
diff --git a/MyBackbone/backbone_factory.py b/code/MyBackbone/backbone_factory.py
similarity index 99%
rename from MyBackbone/backbone_factory.py
rename to code/MyBackbone/backbone_factory.py
index ff770e5..31bc17b 100644
--- a/MyBackbone/backbone_factory.py
+++ b/code/MyBackbone/backbone_factory.py
@@ -25,7 +25,6 @@ def init_backbone(**kargs):
         resnet18 = models.resnet18(pretrained=True)
         modules = list(resnet18.children())[:-1]
         # model_ft.fc = nn.Linear(512, out_features)
-
         res18 = nn.Sequential(
             *modules,
         )
diff --git a/MyLoss/ND_Crossentropy.py b/code/MyLoss/ND_Crossentropy.py
similarity index 100%
rename from MyLoss/ND_Crossentropy.py
rename to code/MyLoss/ND_Crossentropy.py
diff --git a/MyLoss/__init__.py b/code/MyLoss/__init__.py
similarity index 100%
rename from MyLoss/__init__.py
rename to code/MyLoss/__init__.py
diff --git a/MyLoss/__pycache__/ND_Crossentropy.cpython-39.pyc b/code/MyLoss/__pycache__/ND_Crossentropy.cpython-39.pyc
similarity index 100%
rename from MyLoss/__pycache__/ND_Crossentropy.cpython-39.pyc
rename to code/MyLoss/__pycache__/ND_Crossentropy.cpython-39.pyc
diff --git a/MyLoss/__pycache__/__init__.cpython-39.pyc b/code/MyLoss/__pycache__/__init__.cpython-39.pyc
similarity index 100%
rename from MyLoss/__pycache__/__init__.cpython-39.pyc
rename to code/MyLoss/__pycache__/__init__.cpython-39.pyc
diff --git a/MyLoss/__pycache__/boundary_loss.cpython-39.pyc b/code/MyLoss/__pycache__/boundary_loss.cpython-39.pyc
similarity index 100%
rename from MyLoss/__pycache__/boundary_loss.cpython-39.pyc
rename to code/MyLoss/__pycache__/boundary_loss.cpython-39.pyc
diff --git a/MyLoss/__pycache__/dice_loss.cpython-39.pyc b/code/MyLoss/__pycache__/dice_loss.cpython-39.pyc
similarity index 100%
rename from MyLoss/__pycache__/dice_loss.cpython-39.pyc
rename to code/MyLoss/__pycache__/dice_loss.cpython-39.pyc
diff --git a/MyLoss/__pycache__/focal_loss.cpython-39.pyc b/code/MyLoss/__pycache__/focal_loss.cpython-39.pyc
similarity index 100%
rename from MyLoss/__pycache__/focal_loss.cpython-39.pyc
rename to code/MyLoss/__pycache__/focal_loss.cpython-39.pyc
diff --git a/MyLoss/__pycache__/hausdorff.cpython-39.pyc b/code/MyLoss/__pycache__/hausdorff.cpython-39.pyc
similarity index 100%
rename from MyLoss/__pycache__/hausdorff.cpython-39.pyc
rename to code/MyLoss/__pycache__/hausdorff.cpython-39.pyc
diff --git a/code/MyLoss/__pycache__/loss_factory.cpython-39.pyc b/code/MyLoss/__pycache__/loss_factory.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4a56099c87d6626e35a3f5d5f82502c95139ee5b
GIT binary patch
literal 2623
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

literal 0
HcmV?d00001

diff --git a/MyLoss/__pycache__/lovasz_loss.cpython-39.pyc b/code/MyLoss/__pycache__/lovasz_loss.cpython-39.pyc
similarity index 100%
rename from MyLoss/__pycache__/lovasz_loss.cpython-39.pyc
rename to code/MyLoss/__pycache__/lovasz_loss.cpython-39.pyc
diff --git a/MyLoss/__pycache__/poly_loss.cpython-39.pyc b/code/MyLoss/__pycache__/poly_loss.cpython-39.pyc
similarity index 100%
rename from MyLoss/__pycache__/poly_loss.cpython-39.pyc
rename to code/MyLoss/__pycache__/poly_loss.cpython-39.pyc
diff --git a/MyLoss/boundary_loss.py b/code/MyLoss/boundary_loss.py
similarity index 100%
rename from MyLoss/boundary_loss.py
rename to code/MyLoss/boundary_loss.py
diff --git a/MyLoss/dice_loss.py b/code/MyLoss/dice_loss.py
similarity index 100%
rename from MyLoss/dice_loss.py
rename to code/MyLoss/dice_loss.py
diff --git a/MyLoss/focal_loss.py b/code/MyLoss/focal_loss.py
similarity index 100%
rename from MyLoss/focal_loss.py
rename to code/MyLoss/focal_loss.py
diff --git a/MyLoss/hausdorff.py b/code/MyLoss/hausdorff.py
similarity index 100%
rename from MyLoss/hausdorff.py
rename to code/MyLoss/hausdorff.py
diff --git a/MyLoss/loss_factory.py b/code/MyLoss/loss_factory.py
similarity index 91%
rename from MyLoss/loss_factory.py
rename to code/MyLoss/loss_factory.py
index f3bdceb..8ff6d18 100755
--- a/MyLoss/loss_factory.py
+++ b/code/MyLoss/loss_factory.py
@@ -19,11 +19,15 @@ from pytorch_toolbelt import losses as L
 
 def create_loss(args, w1=1.0, w2=0.5):
     conf_loss = args.base_loss
+    if args.loss_weight: 
+        weight = torch.tensor(args.loss_weight)
+    else: weight = None
     ### MulticlassJaccardLoss(classes=np.arange(11)
     # mode = args.base_loss #BINARY_MODE \MULTICLASS_MODE \MULTILABEL_MODE 
     loss = None
     if hasattr(nn, conf_loss): 
-        loss = getattr(nn, conf_loss)(label_smoothing=0.5) 
+        loss = getattr(nn, conf_loss)(weight=weight, label_smoothing=0.5) 
+        # loss = getattr(nn, conf_loss)(label_smoothing=0.5) 
     #binary loss
     elif conf_loss == "focal":
         loss = L.BinaryFocalLoss()
diff --git a/MyLoss/lovasz_loss.py b/code/MyLoss/lovasz_loss.py
similarity index 100%
rename from MyLoss/lovasz_loss.py
rename to code/MyLoss/lovasz_loss.py
diff --git a/MyLoss/poly_loss.py b/code/MyLoss/poly_loss.py
similarity index 100%
rename from MyLoss/poly_loss.py
rename to code/MyLoss/poly_loss.py
diff --git a/MyOptimizer/__init__.py b/code/MyOptimizer/__init__.py
similarity index 100%
rename from MyOptimizer/__init__.py
rename to code/MyOptimizer/__init__.py
diff --git a/MyOptimizer/__pycache__/__init__.cpython-39.pyc b/code/MyOptimizer/__pycache__/__init__.cpython-39.pyc
similarity index 100%
rename from MyOptimizer/__pycache__/__init__.cpython-39.pyc
rename to code/MyOptimizer/__pycache__/__init__.cpython-39.pyc
diff --git a/MyOptimizer/__pycache__/adafactor.cpython-39.pyc b/code/MyOptimizer/__pycache__/adafactor.cpython-39.pyc
similarity index 100%
rename from MyOptimizer/__pycache__/adafactor.cpython-39.pyc
rename to code/MyOptimizer/__pycache__/adafactor.cpython-39.pyc
diff --git a/MyOptimizer/__pycache__/adahessian.cpython-39.pyc b/code/MyOptimizer/__pycache__/adahessian.cpython-39.pyc
similarity index 100%
rename from MyOptimizer/__pycache__/adahessian.cpython-39.pyc
rename to code/MyOptimizer/__pycache__/adahessian.cpython-39.pyc
diff --git a/MyOptimizer/__pycache__/adamp.cpython-39.pyc b/code/MyOptimizer/__pycache__/adamp.cpython-39.pyc
similarity index 100%
rename from MyOptimizer/__pycache__/adamp.cpython-39.pyc
rename to code/MyOptimizer/__pycache__/adamp.cpython-39.pyc
diff --git a/MyOptimizer/__pycache__/adamw.cpython-39.pyc b/code/MyOptimizer/__pycache__/adamw.cpython-39.pyc
similarity index 100%
rename from MyOptimizer/__pycache__/adamw.cpython-39.pyc
rename to code/MyOptimizer/__pycache__/adamw.cpython-39.pyc
diff --git a/MyOptimizer/__pycache__/lookahead.cpython-39.pyc b/code/MyOptimizer/__pycache__/lookahead.cpython-39.pyc
similarity index 100%
rename from MyOptimizer/__pycache__/lookahead.cpython-39.pyc
rename to code/MyOptimizer/__pycache__/lookahead.cpython-39.pyc
diff --git a/MyOptimizer/__pycache__/nadam.cpython-39.pyc b/code/MyOptimizer/__pycache__/nadam.cpython-39.pyc
similarity index 100%
rename from MyOptimizer/__pycache__/nadam.cpython-39.pyc
rename to code/MyOptimizer/__pycache__/nadam.cpython-39.pyc
diff --git a/MyOptimizer/__pycache__/novograd.cpython-39.pyc b/code/MyOptimizer/__pycache__/novograd.cpython-39.pyc
similarity index 100%
rename from MyOptimizer/__pycache__/novograd.cpython-39.pyc
rename to code/MyOptimizer/__pycache__/novograd.cpython-39.pyc
diff --git a/MyOptimizer/__pycache__/nvnovograd.cpython-39.pyc b/code/MyOptimizer/__pycache__/nvnovograd.cpython-39.pyc
similarity index 100%
rename from MyOptimizer/__pycache__/nvnovograd.cpython-39.pyc
rename to code/MyOptimizer/__pycache__/nvnovograd.cpython-39.pyc
diff --git a/MyOptimizer/__pycache__/optim_factory.cpython-39.pyc b/code/MyOptimizer/__pycache__/optim_factory.cpython-39.pyc
similarity index 100%
rename from MyOptimizer/__pycache__/optim_factory.cpython-39.pyc
rename to code/MyOptimizer/__pycache__/optim_factory.cpython-39.pyc
diff --git a/MyOptimizer/__pycache__/radam.cpython-39.pyc b/code/MyOptimizer/__pycache__/radam.cpython-39.pyc
similarity index 100%
rename from MyOptimizer/__pycache__/radam.cpython-39.pyc
rename to code/MyOptimizer/__pycache__/radam.cpython-39.pyc
diff --git a/MyOptimizer/__pycache__/rmsprop_tf.cpython-39.pyc b/code/MyOptimizer/__pycache__/rmsprop_tf.cpython-39.pyc
similarity index 100%
rename from MyOptimizer/__pycache__/rmsprop_tf.cpython-39.pyc
rename to code/MyOptimizer/__pycache__/rmsprop_tf.cpython-39.pyc
diff --git a/MyOptimizer/__pycache__/sgdp.cpython-39.pyc b/code/MyOptimizer/__pycache__/sgdp.cpython-39.pyc
similarity index 100%
rename from MyOptimizer/__pycache__/sgdp.cpython-39.pyc
rename to code/MyOptimizer/__pycache__/sgdp.cpython-39.pyc
diff --git a/MyOptimizer/adafactor.py b/code/MyOptimizer/adafactor.py
similarity index 100%
rename from MyOptimizer/adafactor.py
rename to code/MyOptimizer/adafactor.py
diff --git a/MyOptimizer/adahessian.py b/code/MyOptimizer/adahessian.py
similarity index 100%
rename from MyOptimizer/adahessian.py
rename to code/MyOptimizer/adahessian.py
diff --git a/MyOptimizer/adamp.py b/code/MyOptimizer/adamp.py
similarity index 100%
rename from MyOptimizer/adamp.py
rename to code/MyOptimizer/adamp.py
diff --git a/MyOptimizer/adamw.py b/code/MyOptimizer/adamw.py
similarity index 100%
rename from MyOptimizer/adamw.py
rename to code/MyOptimizer/adamw.py
diff --git a/MyOptimizer/lookahead.py b/code/MyOptimizer/lookahead.py
similarity index 100%
rename from MyOptimizer/lookahead.py
rename to code/MyOptimizer/lookahead.py
diff --git a/MyOptimizer/nadam.py b/code/MyOptimizer/nadam.py
similarity index 100%
rename from MyOptimizer/nadam.py
rename to code/MyOptimizer/nadam.py
diff --git a/MyOptimizer/novograd.py b/code/MyOptimizer/novograd.py
similarity index 100%
rename from MyOptimizer/novograd.py
rename to code/MyOptimizer/novograd.py
diff --git a/MyOptimizer/nvnovograd.py b/code/MyOptimizer/nvnovograd.py
similarity index 100%
rename from MyOptimizer/nvnovograd.py
rename to code/MyOptimizer/nvnovograd.py
diff --git a/MyOptimizer/optim_factory.py b/code/MyOptimizer/optim_factory.py
similarity index 100%
rename from MyOptimizer/optim_factory.py
rename to code/MyOptimizer/optim_factory.py
diff --git a/MyOptimizer/radam.py b/code/MyOptimizer/radam.py
similarity index 100%
rename from MyOptimizer/radam.py
rename to code/MyOptimizer/radam.py
diff --git a/MyOptimizer/rmsprop_tf.py b/code/MyOptimizer/rmsprop_tf.py
similarity index 100%
rename from MyOptimizer/rmsprop_tf.py
rename to code/MyOptimizer/rmsprop_tf.py
diff --git a/MyOptimizer/sgdp.py b/code/MyOptimizer/sgdp.py
similarity index 100%
rename from MyOptimizer/sgdp.py
rename to code/MyOptimizer/sgdp.py
diff --git a/code/__pycache__/test_visualize.cpython-39.pyc b/code/__pycache__/test_visualize.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f22258b82070b835ec1875cf4e46622cbad9198a
GIT binary patch
literal 11095
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

literal 0
HcmV?d00001

diff --git a/code/__pycache__/train_loop.cpython-39.pyc b/code/__pycache__/train_loop.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5ee4cf9ea9af6982a3d224e17d28e5ff5d4ef98c
GIT binary patch
literal 14557
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
ZwYfPMIlygi5F0db3|b{4P|pB@i~!rC@?`)3

literal 0
HcmV?d00001

diff --git a/code/datasets/__init__.py b/code/datasets/__init__.py
new file mode 100644
index 0000000..0eb1fe7
--- /dev/null
+++ b/code/datasets/__init__.py
@@ -0,0 +1,3 @@
+
+from .custom_jpg_dataloader import JPGMILDataloader
+from .data_interface import MILDataModule
diff --git a/code/datasets/__pycache__/__init__.cpython-39.pyc b/code/datasets/__pycache__/__init__.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3735aa6b4ec5cd68471afdec6d2068bc6293a2ed
GIT binary patch
literal 270
zcmYe~<>g{vU|`tr>vU2)0|Ucj5C<7EF)%PVFfcF_%P=r7q%fo~<}l<kMlmvi*i1Q0
zxy(__j0`Ev!3>%#FBusa7&IAg33vs#`+EAgB$g!R<R_-27HKlx;)M$M=BJeAr21*H
zM2RMs7MJAb#%C3z$EU!R7J=-G;sXi9XXcfp7NsR7rxr0YFfgoSC}Lq?fDpeN^)vEw
zQ}ruz67%%S^NX^J3lfu4^+Sph^NM{veRN$?Qw!XS64Ofblk-zj^+Bc;r<N4!$H!;p
aWtPOp>lIYq;;_jDyTuM<V=;)}VFUm+YDeGz

literal 0
HcmV?d00001

diff --git a/datasets/__pycache__/camel_data.cpython-39.pyc b/code/datasets/__pycache__/camel_data.cpython-39.pyc
similarity index 100%
rename from datasets/__pycache__/camel_data.cpython-39.pyc
rename to code/datasets/__pycache__/camel_data.cpython-39.pyc
diff --git a/datasets/__pycache__/camel_dataloader.cpython-39.pyc b/code/datasets/__pycache__/camel_dataloader.cpython-39.pyc
similarity index 100%
rename from datasets/__pycache__/camel_dataloader.cpython-39.pyc
rename to code/datasets/__pycache__/camel_dataloader.cpython-39.pyc
diff --git a/datasets/__pycache__/custom_dataloader.cpython-39.pyc b/code/datasets/__pycache__/custom_dataloader.cpython-39.pyc
similarity index 100%
rename from datasets/__pycache__/custom_dataloader.cpython-39.pyc
rename to code/datasets/__pycache__/custom_dataloader.cpython-39.pyc
diff --git a/code/datasets/__pycache__/custom_jpg_dataloader.cpython-39.pyc b/code/datasets/__pycache__/custom_jpg_dataloader.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1cd6ef3a6a996cd23622c3e29f8ed89d4d0d9038
GIT binary patch
literal 10649
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

literal 0
HcmV?d00001

diff --git a/datasets/__pycache__/data_interface.cpython-39.pyc b/code/datasets/__pycache__/data_interface.cpython-39.pyc
similarity index 100%
rename from datasets/__pycache__/data_interface.cpython-39.pyc
rename to code/datasets/__pycache__/data_interface.cpython-39.pyc
diff --git a/datasets/camel_data.py b/code/datasets/camel_data.py
similarity index 100%
rename from datasets/camel_data.py
rename to code/datasets/camel_data.py
diff --git a/datasets/camel_dataloader.py b/code/datasets/camel_dataloader.py
similarity index 100%
rename from datasets/camel_dataloader.py
rename to code/datasets/camel_dataloader.py
diff --git a/datasets/custom_dataloader.py b/code/datasets/custom_dataloader.py
similarity index 100%
rename from datasets/custom_dataloader.py
rename to code/datasets/custom_dataloader.py
diff --git a/datasets/custom_jpg_dataloader.py b/code/datasets/custom_jpg_dataloader.py
similarity index 87%
rename from datasets/custom_jpg_dataloader.py
rename to code/datasets/custom_jpg_dataloader.py
index 722b275..b47fc7f 100644
--- a/datasets/custom_jpg_dataloader.py
+++ b/code/datasets/custom_jpg_dataloader.py
@@ -25,18 +25,8 @@ class RangeNormalization(object):
         return (img / 255.0 - 0.5) / 0.5
 
 class JPGMILDataloader(data.Dataset):
-    """Represents an abstract HDF5 dataset. For single H5 container! 
     
-    Input params:
-        file_path: Path to the folder containing the dataset (one or multiple HDF5 files).
-        mode: 'train' or 'test'
-        load_data: If True, loads all the data immediately into RAM. Use this if
-            the dataset is fits into memory. Otherwise, leave this at false and 
-            the data will load lazily.
-        data_cache_size: Number of HDF5 files that can be cached in the cache (default=3).
-
-    """
-    def __init__(self, file_path, label_path, mode, n_classes, load_data=False, data_cache_size=10, bag_size=1024):
+    def __init__(self, file_path, label_path, mode, n_classes, load_data=False, data_cache_size=10, max_bag_size=1296):
         super().__init__()
 
         self.data_info = []
@@ -49,7 +39,8 @@ class JPGMILDataloader(data.Dataset):
         # self.csv_path = csv_path
         self.label_path = label_path
         self.n_classes = n_classes
-        self.bag_size = bag_size
+        self.max_bag_size = max_bag_size
+        self.min_bag_size = 120
         self.empty_slides = []
         # self.label_file = label_path
         recursive = True
@@ -64,7 +55,7 @@ class JPGMILDataloader(data.Dataset):
                 for cohort in Path(self.file_path).iterdir():
                     x_complete_path = Path(self.file_path) / cohort / 'BLOCKS' / Path(x)
                     if x_complete_path.is_dir():
-                        if len(list(x_complete_path.iterdir())) > 50:
+                        if len(list(x_complete_path.iterdir())) > self.min_bag_size:
                         # print(x_complete_path)
                             self.slideLabelDict[x] = y
                             self.files.append(x_complete_path)
@@ -87,7 +78,7 @@ class JPGMILDataloader(data.Dataset):
         sometimes5 = lambda aug: iaa.Sometimes(0.9, aug, name="Random5")
 
         self.train_transforms = iaa.Sequential([
-            iaa.AddToHueAndSaturation(value=(-13, 13), name="MyHSV"),
+            iaa.AddToHueAndSaturation(value=(-30, 30), name="MyHSV"), #13
             sometimes2(iaa.GammaContrast(gamma=(0.85, 1.15), name="MyGamma")),
             iaa.Fliplr(0.5, name="MyFlipLR"),
             iaa.Flipud(0.5, name="MyFlipUD"),
@@ -139,7 +130,7 @@ class JPGMILDataloader(data.Dataset):
 
     def __getitem__(self, index):
         # get data
-        batch, label, name = self.get_data(index)
+        (batch, batch_names), label, name = self.get_data(index)
         out_batch = []
         seq_img_d = self.train_transforms.to_deterministic()
         
@@ -174,7 +165,7 @@ class JPGMILDataloader(data.Dataset):
         label = torch.as_tensor(label)
         label = torch.nn.functional.one_hot(label, num_classes=self.n_classes)
         # print(out_batch)
-        return out_batch, label, name #, name_batch
+        return out_batch, label, (name, batch_names) #, name_batch
 
     def __len__(self):
         return len(self.data_info)
@@ -194,7 +185,7 @@ class JPGMILDataloader(data.Dataset):
         data_info structure.
         """
         wsi_batch = []
-        tile_names = []
+        name_batch = []
         # print(wsi_batch)
         # for tile_path in Path(file_path).iterdir():
         #     print(tile_path)
@@ -206,7 +197,7 @@ class JPGMILDataloader(data.Dataset):
             # print(wsi_batch)
             wsi_batch.append(img)
             
-            tile_names.append(tile_path.stem)
+            name_batch.append(tile_path.stem)
                 
         # if wsi_batch:
         wsi_batch = torch.stack(wsi_batch)
@@ -220,8 +211,9 @@ class JPGMILDataloader(data.Dataset):
         # if wsi_batch.shape[1:] != torch.Size([3, 256, 256]) and wsi_batch.shape[1:] != torch.Size([256, 256, 3]):
         #     print(file_path)
         #     print(wsi_batch.shape)
-        # wsi_batch, name_batch = to_fixed_size_bag(wsi_batch, self.bag_size)
-        idx = self._add_to_cache(wsi_batch, file_path)
+        if wsi_batch.size(0) > self.max_bag_size:
+            wsi_batch, name_batch, _ = to_fixed_size_bag(wsi_batch, name_batch, self.max_bag_size)
+        idx = self._add_to_cache((wsi_batch,name_batch), file_path)
         file_idx = next(i for i,v in enumerate(self.data_info) if v['data_path'] == file_path)
         self.data_info[file_idx + idx]['cache_idx'] = idx
 
@@ -309,25 +301,26 @@ class RandomHueSaturationValue(object):
             img = cv2.cvtColor(img, cv2.COLOR_HSV2RGB)
         return img #, lbl
 
-def to_fixed_size_bag(bag, bag_size: int = 512):
+def to_fixed_size_bag(bag, names, bag_size: int = 512):
 
     #duplicate bag instances unitl 
 
     # get up to bag_size elements
     bag_idxs = torch.randperm(bag.shape[0])[:bag_size]
     bag_samples = bag[bag_idxs]
+    name_samples = [names[i] for i in bag_idxs]
     # bag_sample_names = [bag_names[i] for i in bag_idxs]
-    q, r  = divmod(bag_size, bag_samples.shape[0])
-    if q > 0:
-        bag_samples = torch.cat([bag_samples]*q, 0)
+    # q, r  = divmod(bag_size, bag_samples.shape[0])
+    # if q > 0:
+    #     bag_samples = torch.cat([bag_samples]*q, 0)
     
-    self_padded = torch.cat([bag_samples, bag_samples[:r,:, :, :]])
+    # self_padded = torch.cat([bag_samples, bag_samples[:r,:, :, :]])
 
     # zero-pad if we don't have enough samples
     # zero_padded = torch.cat((bag_samples,
                             # torch.zeros(bag_size-bag_samples.shape[0], bag_samples.shape[1], bag_samples.shape[2], bag_samples.shape[3])))
 
-    return self_padded, min(bag_size, len(bag))
+    return bag_samples, name_samples, min(bag_size, len(bag))
 
 
 class RandomHueSaturationValue(object):
@@ -365,23 +358,23 @@ if __name__ == '__main__':
 
     home = Path.cwd().parts[1]
     train_csv = f'/{home}/ylan/DeepGraft_project/code/debug_train.csv'
-    data_root = f'/{home}/ylan/data/DeepGraft/256_256um'
+    data_root = f'/{home}/ylan/data/DeepGraft/224_128um'
     # data_root = f'/{home}/ylan/DeepGraft/dataset/hdf5/256_256um_split/'
     # label_path = f'/{home}/ylan/DeepGraft_project/code/split_PAS_bin.json'
     label_path = f'/{home}/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json'
-    output_path = f'/{home}/ylan/DeepGraft/dataset/check/256_256um_split/augments'
-    os.makedirs(output_path, exist_ok=True)
+    output_dir = f'/{data_root}/debug/augments'
+    os.makedirs(output_dir, exist_ok=True)
 
     n_classes = 2
 
-    dataset = JPGMILDataloader(data_root, label_path=label_path, mode='train', load_data=False, n_classes=n_classes, bag_size=20)
+    dataset = JPGMILDataloader(data_root, label_path=label_path, mode='train', load_data=False, n_classes=n_classes)
     # print(dataset.dataset)
     # a = int(len(dataset)* 0.8)
     # b = int(len(dataset) - a)
     # train_ds, val_ds = torch.utils.data.random_split(dataset, [a, b])
-    dl = DataLoader(dataset,  None, num_workers=1)
-    print(len(dl))
-    dl = DataLoader(dataset,  None, sampler=ImbalancedDatasetSampler(dataset), num_workers=5)
+    dl = DataLoader(dataset, None, num_workers=1, shuffle=False)
+    # print(len(dl))
+    # dl = DataLoader(dataset, batch_size=1, sampler=ImbalancedDatasetSampler(dataset), num_workers=5)
 
     
     
@@ -394,18 +387,16 @@ if __name__ == '__main__':
     label_count = [0] *n_classes
     print(len(dl))
     for item in dl: 
-        # if c >=10:
-        #     break
-        bag, label, name = item
-        # print(label)
+        if c >= 5:
+            break
+        bag, label, (name, _) = item
         label_count[torch.argmax(label)] += 1
         # print(name)
         # if name == 'RU0248_PASD_jke_PASD_20200201_195900_BIG':
         
             # print(bag)
             # print(label)
-        c += 1
-    print(label_count)
+        
     #     # # print(bag.shape)
     #     # if bag.shape[1] == 1:
     #     #     print(name)
@@ -423,21 +414,23 @@ if __name__ == '__main__':
     #     # bag = item[0]
     #     bag = bag.squeeze()
     #     original = original.squeeze()
-    #     for i in range(bag.shape[0]):
-    #         img = bag[i, :, :, :]
-    #         img = img.squeeze()
+        output_path = Path(output_dir) / name
+        output_path.mkdir(exist_ok=True)
+        for i in range(bag.shape[0]):
+            img = bag[i, :, :, :]
+            img = img.squeeze()
             
-    #         img = ((img-img.min())/(img.max() - img.min())) * 255
-    #         print(img)
-    #         # print(img)
-    #         img = img.numpy().astype(np.uint8).transpose(1,2,0)
+            img = ((img-img.min())/(img.max() - img.min())) * 255
+            # print(img)
+            # print(img)
+            img = img.numpy().astype(np.uint8).transpose(1,2,0)
 
             
-    #         img = Image.fromarray(img)
-    #         img = img.convert('RGB')
-    #         img.save(f'{output_path}/{i}.png')
-
+            img = Image.fromarray(img)
+            img = img.convert('RGB')
+            img.save(f'{output_path}/{i}.png')
 
+        c += 1
             
     #         o_img = original[i,:,:,:]
     #         o_img = o_img.squeeze()
diff --git a/code/datasets/dali_dataloader.py b/code/datasets/dali_dataloader.py
new file mode 100644
index 0000000..0851613
--- /dev/null
+++ b/code/datasets/dali_dataloader.py
@@ -0,0 +1,139 @@
+from nvidia.dali import pipeline_def
+from nvidia.dali.pipeline import Pipeline
+import nvidia.dali.fn as fn
+import nvidia.dali.types as types
+
+from pathlib import Path
+import matplotlib.pyplot as plt
+import matplotlib.gridspec as gridspec
+import math
+import json
+import numpy as np
+import cupy as cp
+import torch
+import imageio
+
+batch_size = 10
+home = Path.cwd().parts[1]
+# image_filename = f"/{home}/ylan/data/DeepGraft/224_128um/Aachen_Biopsy_Slides/BLOCKS/"
+
+class ExternalInputIterator(object):
+    def __init__(self, batch_size):
+        self.file_path = f"/{home}/ylan/data/DeepGraft/224_128um/"
+        # self.label_file = f'/{home}/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json'
+        self.label_path = f'/{home}/ylan/DeepGraft/training_tables/split_Aachen_PAS_tcmr_viral.json'
+        self.batch_size = batch_size
+        
+        mode = 'test'
+        # with open(self.images_dir + "file_list.txt", 'r') as f:
+        #     self.files = [line.rstrip() for line in f if line != '']
+        self.slideLabelDict = {}
+        self.files = []
+        self.empty_slides = []
+        with open(self.label_path, 'r') as f:
+            temp_slide_label_dict = json.load(f)[mode]
+            for (x, y) in temp_slide_label_dict:
+                x = Path(x).stem 
+
+                # x_complete_path = Path(self.file_path)/Path(x)
+                for cohort in Path(self.file_path).iterdir():
+                    x_complete_path = Path(self.file_path) / cohort / 'BLOCKS' / Path(x)
+                    if x_complete_path.is_dir():
+                        if len(list(x_complete_path.iterdir())) > 50:
+                        # print(x_complete_path)
+                            # self.slideLabelDict[x] = y
+                            self.files.append((x_complete_path, y))
+                        else: self.empty_slides.append(x_complete_path)
+        
+        # shuffle(self.files)
+
+    def __iter__(self):
+        self.i = 0
+        self.n = len(self.files)
+        return self
+
+    def __next__(self):
+        batch = []
+        labels = []
+        file_names = []
+
+        for _ in range(self.batch_size):
+            wsi_batch = []
+            wsi_filename, label = self.files[self.i]
+            # jpeg_filename, label = self.files[self.i].split(' ')
+            name = Path(wsi_filename).stem
+            file_names.append(name)
+            for img_path in Path(wsi_filename).iterdir():
+                # f = open(img, 'rb')
+
+                f = imageio.imread(img_path)
+                img = cp.asarray(f)
+                wsi_batch.append(img.astype(cp.uint8))
+            wsi_batch = cp.stack(wsi_batch)
+            batch.append(wsi_batch)
+            labels.append(cp.array([label], dtype = cp.uint8))
+            
+            self.i = (self.i + 1) % self.n
+        # print(batch)
+        # print(labels)
+        return (batch, labels)
+
+
+eii = ExternalInputIterator(batch_size=10)
+
+@pipeline_def()
+def hsv_pipeline(device, hue, saturation, value):
+    # files, labels = fn.readers.file(file_root=image_filename)
+    files, labels = fn.external_source(source=eii, num_outputs=2, dtype=types.UINT8)
+    images = fn.decoders.image(files, device = 'cpu' if device == 'cpu' else 'mixed')
+    converted = fn.hsv(images, hue=hue, saturation=saturation, value=value)
+    return images, converted
+
+def display(outputs, idx, columns=2, captions=None, cpu=True):
+    rows = int(math.ceil(len(outputs) / columns))
+    fig = plt.figure()
+    fig.set_size_inches(16, 6 * rows)
+    gs = gridspec.GridSpec(rows, columns)
+    row = 0
+    col = 0
+    for i, out in enumerate(outputs):
+        plt.subplot(gs[i])
+        plt.axis("off")
+        if captions is not None:
+            plt.title(captions[i])
+        plt.imshow(out.at(idx) if cpu else out.as_cpu().at(idx))
+
+# pipe_cpu = hsv_pipeline(device='cpu', hue=120, saturation=1, value=0.4, batch_size=batch_size, num_threads=1, device_id=0)
+# pipe_cpu.build()
+# cpu_output = pipe_cpu.run()
+
+# display(cpu_output, 3, captions=["Original", "Hue=120, Saturation=1, Value=0.4"])
+
+# pipe_gpu = hsv_pipeline(device='gpu', hue=120, saturation=2, value=1, batch_size=batch_size, num_threads=1, device_id=0)
+# pipe_gpu.build()
+# gpu_output = pipe_gpu.run()
+
+# display(gpu_output, 0, cpu=False, captions=["Original", "Hue=120, Saturation=2, Value=1"])
+
+
+pipe_gpu = Pipeline(batch_size=batch_size, num_threads=2, device_id=0)
+with pipe_gpu:
+    images, labels = fn.external_source(source=eii, num_outputs=2, device="gpu", dtype=types.UINT8)
+    enhance = fn.brightness_contrast(images, contrast=2)
+    pipe_gpu.set_outputs(enhance, labels)
+
+pipe_gpu.build()
+pipe_out_gpu = pipe_gpu.run()
+batch_gpu = pipe_out_gpu[0].as_cpu()
+labels_gpu = pipe_out_gpu[1].as_cpu()
+# file_names = pipe_out_gpu[2].as_cpu()
+
+output_path = f"/{home}/ylan/data/DeepGraft/224_128um/debug/augments/"
+output_path.mkdir(exist_ok=True)
+
+
+img = batch_gpu.at(2)
+print(img.shape)
+print(labels_gpu.at(2))
+plt.axis('off')
+plt.imsave(f'{output_path}/0.jpg', img[0, :, :, :])
\ No newline at end of file
diff --git a/datasets/data_interface.py b/code/datasets/data_interface.py
similarity index 100%
rename from datasets/data_interface.py
rename to code/datasets/data_interface.py
diff --git a/code/lightning_logs/version_0/cm_test.png b/code/lightning_logs/version_0/cm_test.png
new file mode 100644
index 0000000000000000000000000000000000000000..6fb672f0640e83968af9558a7d438cbf42b51815
GIT binary patch
literal 47096
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
Wxo&Q8b)P9H2s~Z=T-G@yGywpLm4hY#

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_0/events.out.tfevents.1657535217.dgx2.2080039.0 b/code/lightning_logs/version_0/events.out.tfevents.1657535217.dgx2.2080039.0
new file mode 100644
index 0000000000000000000000000000000000000000..734f0a9372e6608b0ab5aed218222431f0044e31
GIT binary patch
literal 4702
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
a*iFq#fi!gmx%d$cT^1!K4#vV`0jB`DRGnD>

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_0/hparams.yaml b/code/lightning_logs/version_0/hparams.yaml
new file mode 100644
index 0000000..de11b28
--- /dev/null
+++ b/code/lightning_logs/version_0/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/256_256um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/256_256um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_1/cm_test.png b/code/lightning_logs/version_1/cm_test.png
new file mode 100644
index 0000000000000000000000000000000000000000..e2ba8d1036ec9fa3e57078dd47b9a747a2809fc0
GIT binary patch
literal 45165
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_1/events.out.tfevents.1657535625.dgx2.2086189.0 b/code/lightning_logs/version_1/events.out.tfevents.1657535625.dgx2.2086189.0
new file mode 100644
index 0000000000000000000000000000000000000000..b11a9e985744cff77e2d36a3e726bb4b8b9ac89c
GIT binary patch
literal 4699
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_1/hparams.yaml b/code/lightning_logs/version_1/hparams.yaml
new file mode 100644
index 0000000..3027219
--- /dev/null
+++ b/code/lightning_logs/version_1/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/256_256um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/256_256um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_10/events.out.tfevents.1657546166.dgx1.47613.0 b/code/lightning_logs/version_10/events.out.tfevents.1657546166.dgx1.47613.0
new file mode 100644
index 0000000000000000000000000000000000000000..afa287ceab85beb3b739a44d7e230d7ada1d726f
GIT binary patch
literal 4705
zcmb1OfPlsI-b$SQ5qonvH{WoS;!P?_%*@ksElbTSu`-g*sCJZvC}T*_zpu=xUkXvD
zCB!Ab#hFnMpPO1zl$k8bz|gS2&r<E=J~oKz<zZEyIh9{Q6>s9@TF=WR5}#3!Sd^Gs
z9Iu~RQIJ}cnVXtd;x&zzYcekvJ5)-jomZ%ZSBZ~{D>pwSHAg=$F*j9#QAwDKAIgtU
z&PgmTPAyhoRubakg9s)iCTAz*=YbT8atT7jGV|ioQWHx`i@-|7xP&0W`K2Yu;zC?}
zIr+uK`bmk!sqr9|0;7^37jJ$+NoH<lRceubenE)>qmlp@4?-xXNP$^NluHmHl3!2~
zpIT6?z^Ek7C5$SZlv<Jqk`Ut(LP+H1gM40^tH7uv#U+LiFHg-(&nSscNli|ygxHai
zSdyp@B8pQ>;-O(7$|VRA0Sm_$XOyO;<)kVwgPe^JPRT5Sgc?{VCow5CCq6AR2NXiQ
zT%2IRwEUbD1!ho4gSmN7z7Q85n4esfUtAntmYAc!tfa!F02V6&C5?CxGbcYWCACOD
zDX}CuBfdDZ3giG)E=7=(K8C8i(%ks+{G#mCB2cU;bIC)Lr52aqGz)Gcnj%!A1i5&@
zMkOVt!yLiR#hjC$uE40o!^MG=EX28llhe}m-Ba^YixPA6lk;;yF`&SxB*G<tEK!`A
z3JMf7(X;|XGX-WPNiI=jwTZa}@j0nwsW}Ra=u!nmsmYnenfZAN%t~@xQpmb;OLIyx
z<I@XD<3R}$(*@}TrO@<(tShx3KRE*wdJ<eB$l~cmi7D}k$;p_mODoE+O3jN;0yzOq
zQ$b=$W@=tCD9*&VgpiFZPAw`+1*IG`9Xa{w@db$`83>=cU`d$J@PSJqB~DQ;L6AKN
zDM$i^MhjRNC6Nkp@xs+35++;-mRO<A2kS>puo_${aJ3l85hc-Ta;f50iJIEfxs(w~
z(b6S~nJBiSDMU3AIarVqu@Dy@$R=Op5)c|xP%)%Z5E=#$38W+sjSYx6YH29NC5A8`
ztwe-6$ser*gysl@Ft`+i+JO*7l!Ve;;vhRvrC_BY)By-dq!JODUl4L=r6Sb7KIp|Z
z9~T$M!sPtCv`kO|z|X}E;+LfsK{FyR7bi#noRuJDI*5x%+FHC^+(L*d?T)|-o=04e
z+U%^Mh!5umSZ#Jql<Tr6mkgpdD^4v2*%4n{l2}v{pP84I@3l#kYrQC<R$DA8wLp|h
z7HcUa#3se!m!Fpkl19`8ppXOy7hGBnOSvz^DF|^P0|S>Vl02-s5aN(xOD-)g$<O6-
zM=d#E{ua`g($&w%&rQ{@%t_4C2bI&s1&PV2`XNP$dBwh-KDsWcsRiyuiD@PJIr-_u
z`do^r2EmFTgi{>26d)djq`f>?VntRVhg2ZIQa)UMf&-Tfw)zqt6jEpfKeA3)NQsU}
zKRHE0oPxT}GOr(*Y1wm`L$!h`j`)<!A|W*?6(s+Ig!K_VHZn4aH#D*+&DH0UL~R2g
zo2daQMNyNakdTysGpG`E%_}L&FQ^2`aw+4=d2k;zIB@9@tRdm5KiG4rpf_Q#TC51E
zyTBzS$d6bOhzv#>3vLaA1D7;<y8t1{z$J#%ra%@~gTyi-F7gXXgaoDdbMo`E6Ejj1
zQ{syfQxbEzBq4DItDZr1pb)DRbF^VBmmzXdj=M00+p6He6$43qV80@26(LtCXQYTm
z#4)&n$jnQRFG)<wNiEhdF38C&i4SlLjxR~hEs8J8EK1CYFG(#f(aS2%&*M^nL^dRC
z!^&GBE-8+p)Z)C<5>o>%B}iDqd;@O`z};v7O5bR0R}>S(xwt@)qz|s=;MzDGxFk>t
zHMop`1D8C+Qk0+uHA>-m2I?wssDKQI)y{B37#O(hkjqdZ11UW{J*3P4D-q&hK1B*3
zy~@Pg94>iC*uZ=aE^3S67Gyeb2_coipcpnZwdB%;wJwQ^U1eM?W+6_&YLRvB535@2
zx%7x=i^AQd;J_t|>TpOqNQhmE6`VNGV-()Df*ZlW0P;JiMVF(GT%p1hG&pdDaq)w~
zT^}h)I!if{kR+4PQzaxpszVx>h?qyNFp&cVngSpx7pX;n>_}+o35!8cdl)7?WxfNK
z9G31COrD{^flG`F-s(n4&@$*P8jvh3J)zequ=Xk3U{6p4p|sOMEpoW@2YXQ9gDP`y
z;)XW_;R+ZSxD+4-FCvg&Ee?48kV0#6BI}lgWG+~!z+3)8EK*GVMqCpaxp+X<!|T)r
zMyWcah$UR9B1$7zpy(qCAALlIL$6Tub3i@DJW%NcuAHH*op=*21EN~1a8G`)=aN9~
zbECwMG$i)Gp^H%@DdKGC!Gjj149DGvM0Si3k?nH09t8)kJaFGnC|xR*E@9851j%@?
zRDs&F10{`=0z~0PoVTqZ6(%^OL4^fLEfgiRfeUOktu&T#3s^kqEPn9W2HKoFv3+q6
m=Nnjy*N{t}OA52So0^vbY3&Mf@gv&0EJ{oqj2C;)t^)wUZJD|N

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_10/hparams.yaml b/code/lightning_logs/version_10/hparams.yaml
new file mode 100644
index 0000000..385e52b
--- /dev/null
+++ b/code/lightning_logs/version_10/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_11/events.out.tfevents.1657546322.dgx1.48740.0 b/code/lightning_logs/version_11/events.out.tfevents.1657546322.dgx1.48740.0
new file mode 100644
index 0000000000000000000000000000000000000000..328e3163a4bab058ba6a473d8d58e58f2fb51ac5
GIT binary patch
literal 4705
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_11/hparams.yaml b/code/lightning_logs/version_11/hparams.yaml
new file mode 100644
index 0000000..385e52b
--- /dev/null
+++ b/code/lightning_logs/version_11/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_12/events.out.tfevents.1657546521.dgx1.50053.0 b/code/lightning_logs/version_12/events.out.tfevents.1657546521.dgx1.50053.0
new file mode 100644
index 0000000000000000000000000000000000000000..692f51dfebf86309232688295f7c9f36fc3096a5
GIT binary patch
literal 4705
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_12/hparams.yaml b/code/lightning_logs/version_12/hparams.yaml
new file mode 100644
index 0000000..385e52b
--- /dev/null
+++ b/code/lightning_logs/version_12/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_13/events.out.tfevents.1657546918.dgx1.52290.0 b/code/lightning_logs/version_13/events.out.tfevents.1657546918.dgx1.52290.0
new file mode 100644
index 0000000000000000000000000000000000000000..db43abd93eaa392fca46ac8cac0cf6ea91076b76
GIT binary patch
literal 4705
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_13/hparams.yaml b/code/lightning_logs/version_13/hparams.yaml
new file mode 100644
index 0000000..385e52b
--- /dev/null
+++ b/code/lightning_logs/version_13/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_14/events.out.tfevents.1657546992.dgx1.53435.0 b/code/lightning_logs/version_14/events.out.tfevents.1657546992.dgx1.53435.0
new file mode 100644
index 0000000000000000000000000000000000000000..3ac295e5023bf3d8ac7d7a060eb0aa861cfe9c80
GIT binary patch
literal 4705
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_14/hparams.yaml b/code/lightning_logs/version_14/hparams.yaml
new file mode 100644
index 0000000..385e52b
--- /dev/null
+++ b/code/lightning_logs/version_14/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_15/events.out.tfevents.1657547134.dgx1.54703.0 b/code/lightning_logs/version_15/events.out.tfevents.1657547134.dgx1.54703.0
new file mode 100644
index 0000000000000000000000000000000000000000..797ee6e3689ccb965f4e97b808281e986ef758b0
GIT binary patch
literal 4705
zcmb1OfPlsI-b$R#4Kw1oHs5fR;!P?_%*@ksElbTSu`)7x`{0}`L>WVZ{(WUmj~Nhk
zT0&d`T$~vN@wurbMVZN>3=9qXnZ3U6*vAG@y*#YyGpEBZsNzk$T<dwcMB+0F5{nXZ
zi{tfED+*GJGILY&O1!4=a!uytVuwlzwet$K@G9|fapmTxq~_@7CFZ6oFe(Xi@k9CX
z$vKI|#i_*#%t}IBd=SB;#N_Ox{5+6CQ7%D<SY}>)T54iRX%Sed7?%)4IKQ+6SzL&V
zFDJjaSU)MTI5i%`QeadP<l@aQD9OyttV%7?&o3xZU{n&|;z0=I6e%z(iE;@dMDhzt
z;!_KX6&RJoxr9-LlTu3(K@wtILI{c6e2~vea}^ksq`1To;^nEC=@}*QDXGbcl@L2p
z5=#>GK}2zCNjx+xM7ab(B4FY8;*8R?w4780W{|TH!YP?WkWd2)<s>Gh=ESFE=72(o
zmx~iDn3kWDqQDFaX)rer$`|6|1M`!M@{5b(%Mx=Gn3Ytx6u@F7prjEGV&>#0rlc0>
zCnc67XT%q0R)HL#%B2XB(#KGhSDG7No?n!mS_FzUWiEM$vee=doMypoL{o%nlpq%`
z*r=q$beJR9xtMeE(-jz%c(^!_l7%>zaB^C@zI$q3YEfd2esX>;C<YW5l|;A%kR^&!
zQ$c}(CYn}YXr{odB*`U;tTr*XAU-FxEHy`g5nZaFC^b2=I5R&_fmun8OA1+6ZfQ<Q
zW_)@<X*?)FV!9x`pcI;3kaeXN<R@o<LQjHA1X(=2C^02IF*zC2b!kQURjGOLNgyYn
zX(~u8$xO{l2E~~emk_dX#i>PQsi2gDrXwdmJ-#5ZBm?177c2=A8a{9-q{J!8B?z(y
zAq7dG&}ab*qa;#6E?&5LM8bp%!4fOf`C$FX308wk1+Eq&Iie(5O)gd3Dp6CLI+rp+
zDO$QjF%!jhG=-=}A_ognA{OG}1KH$@TmnLa3Mz(F3PQsGB7v0Tp|JrGM=cGdxWo|V
zqm_tIC;6k5fY2O)5C)fmP&*K!h>}p6OB`eesuZj=ggO8riBuv&^9w=_tyF~i*9X1W
z=Huc5S(u!kmzD`C0QkAMLHx4RB4|eB<>CYhfU^>$Ob2lhNn4ATi(3d$r4>$D-SvnI
zQk$JM6!GEQ2dmAliE>>Q<&r_vX2q$+AUooVOA?Dp;xqHo^1U{Ra;+Cd)M|@Gr51>C
zDdP%vAx=SvMGX#IhRA6bcj|#_QE=dr!B)8lu}QJ`<>#ex84#6j;pTm?=h7uy-Xkkl
z##M(2aSB$8taE=@)nd;j#sx2rg}9_Ric*X7QcFw?xFk`lRv}J7U1yoskIb~}xfCJg
zEjV|B%6V8FD8wPfmRwp~lAp^Zi>>?;VwYkC=Xx$Fv|<GAY6b=_S)^(di^+0GB^E4e
z!nIETg*jRt1^FtZC^4_t*V6|z5^>j>a05TsbIGFCM4&ncSy~QD!v-$j;J_u$#RUo@
zeQ?nTm*8;VQbKFa2nkB@=j7*SCuXE3ro<N|rX=QaNut^fs)K}BrI@1)W4Yvzf(cfj
z!;NQP;F8DIvVtpUaNsf`vV?`}QE=dr#?rcir)O)Vm;re?J|(kANKHybKO;XkRlhPP
zF%R4{(sxNsEpRVNOe@hhGBSxbG_oko)#p;eR~rklNHL`paH*g-3WbEE1e`(bA=kW;
zqWpqNP}##Jf!stziF{eCjX=2j&7rLplHINVN$ijk9ahqVY=&nhMby>-tfGept)~MQ
zni5z80<MI?fh&xQALKTDM2#%uEaiw4yoitmXS2+_^!Sp*q@2`Z{o;b0%#!$|lK23}
z;P{f{+@koh%%a2`y{zK=JT4jZ_Bxu|aa9=bkW+xP;vfN#2de{-oh}avB3L^QT-F!E
z6=Z^P14<hX-b#Y2VPN2rMsETmOTx=W;)-S^NErrkGEyxJH?qNj%MQ8b5;Bm|)6+vr
zys$DQ9u~{U;aZuPo5K|Y2^MfUi4<q9QqCmA8ES;Zm!uY#Kw>Qq+@cmrmr6x44b+@3
zE=WvH)rUDx7m+A(^3#j4ct9VK9`q5O!N^x?knD}9|MLq<u$5V8<t3=)4hz&N^BuT^
zkZOBSS!QTz$)y2F9iZ%s=<(sm+{ldwn7IrB4xlOpoH?-73DC%fr9OBs0IuJ_0aRXs
znjPTCf;U;=3c&ReN(zPdGC+lszY(mOKm<=t5pta=4@qwbX=sZKo`>8~iwIcrM@U~v
zm!$aR(jnN7gZt`(Jt$AXy^T>tO=RTa0m;H0)4(WIN0Mt0i4T?@iA!zzIiMbQ9;gHZ
zr&?%hG2Vnr7Luu8aS81)!h=x^sTU3RCj$eQ48}kOLe_yx9a8%sVh6cxi`-h$Bcd-2
zH&_8)tbtP%D0yP5sTCltPlV;LMmNk;zh@VmvVpWi8BT0p9K`t>*5Wnf(&v)GZ11M#
Xr9fJ{f?WKFwl0ej69;3!$?|dlTtb^n

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_15/hparams.yaml b/code/lightning_logs/version_15/hparams.yaml
new file mode 100644
index 0000000..385e52b
--- /dev/null
+++ b/code/lightning_logs/version_15/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_16/events.out.tfevents.1657547198.dgx1.55641.0 b/code/lightning_logs/version_16/events.out.tfevents.1657547198.dgx1.55641.0
new file mode 100644
index 0000000000000000000000000000000000000000..b4cf4197bf688807ead868952cb4b66fdee7b451
GIT binary patch
literal 4705
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
L9E|^7=|2GgKDU@n

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_16/hparams.yaml b/code/lightning_logs/version_16/hparams.yaml
new file mode 100644
index 0000000..385e52b
--- /dev/null
+++ b/code/lightning_logs/version_16/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_17/events.out.tfevents.1657623153.dgx1.41577.0 b/code/lightning_logs/version_17/events.out.tfevents.1657623153.dgx1.41577.0
new file mode 100644
index 0000000000000000000000000000000000000000..8236270b84bc8d5cbd60a4f1b08f8752fb734a6a
GIT binary patch
literal 4704
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_17/hparams.yaml b/code/lightning_logs/version_17/hparams.yaml
new file mode 100644
index 0000000..399847b
--- /dev/null
+++ b/code/lightning_logs/version_17/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 7
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_18/events.out.tfevents.1657624768.dgx1.72352.0 b/code/lightning_logs/version_18/events.out.tfevents.1657624768.dgx1.72352.0
new file mode 100644
index 0000000000000000000000000000000000000000..e2c425bbcbeaabdd74a5233ee4679ec8c0b467cf
GIT binary patch
literal 4704
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_18/hparams.yaml b/code/lightning_logs/version_18/hparams.yaml
new file mode 100644
index 0000000..5d30687
--- /dev/null
+++ b/code/lightning_logs/version_18/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_19/events.out.tfevents.1657624869.dgx1.76706.0 b/code/lightning_logs/version_19/events.out.tfevents.1657624869.dgx1.76706.0
new file mode 100644
index 0000000000000000000000000000000000000000..da36871f7274cacd3a80d00f386c7f1036749c2c
GIT binary patch
literal 4704
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
Qnz}4XOdO2Mf0^zF029HO6#xJL

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_19/hparams.yaml b/code/lightning_logs/version_19/hparams.yaml
new file mode 100644
index 0000000..5d30687
--- /dev/null
+++ b/code/lightning_logs/version_19/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_2/events.out.tfevents.1657543650.dgx1.33429.0 b/code/lightning_logs/version_2/events.out.tfevents.1657543650.dgx1.33429.0
new file mode 100644
index 0000000000000000000000000000000000000000..0e8f866c6b4bb783b058864f37241e2a7966e66a
GIT binary patch
literal 4700
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_2/hparams.yaml b/code/lightning_logs/version_2/hparams.yaml
new file mode 100644
index 0000000..3978f85
--- /dev/null
+++ b/code/lightning_logs/version_2/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 0
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/256_256um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/256_256um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_20/events.out.tfevents.1657625133.dgx1.5999.0 b/code/lightning_logs/version_20/events.out.tfevents.1657625133.dgx1.5999.0
new file mode 100644
index 0000000000000000000000000000000000000000..30bdf9ae84865abecf1bbf3fe104f84a7e9f681e
GIT binary patch
literal 4699
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
ZH7^Cy&K2b1N3?QTl$baeXWnx?3jlHgmmUBB

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_20/hparams.yaml b/code/lightning_logs/version_20/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_20/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_21/events.out.tfevents.1657625248.dgx1.11114.0 b/code/lightning_logs/version_21/events.out.tfevents.1657625248.dgx1.11114.0
new file mode 100644
index 0000000000000000000000000000000000000000..580ae5449c6c891452ad6bb188dade7852059ad3
GIT binary patch
literal 4699
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
b+0sqTOM$d=1-bYUty~r*CJx4n?#rtI0=t%v

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_21/hparams.yaml b/code/lightning_logs/version_21/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_21/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_22/events.out.tfevents.1657625470.dgx1.20071.0 b/code/lightning_logs/version_22/events.out.tfevents.1657625470.dgx1.20071.0
new file mode 100644
index 0000000000000000000000000000000000000000..259e2f747c61500222f0b1faf00b2d6b3a41f41e
GIT binary patch
literal 4699
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
WK-#&2T>OYuE{hTq2ji3T3F!b}<CoI_

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_22/hparams.yaml b/code/lightning_logs/version_22/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_22/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_23/events.out.tfevents.1657625510.dgx1.22295.0 b/code/lightning_logs/version_23/events.out.tfevents.1657625510.dgx1.22295.0
new file mode 100644
index 0000000000000000000000000000000000000000..c74c353abdb31d4bab1671520ec1793298923045
GIT binary patch
literal 4699
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_23/hparams.yaml b/code/lightning_logs/version_23/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_23/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_24/events.out.tfevents.1657625570.dgx1.25099.0 b/code/lightning_logs/version_24/events.out.tfevents.1657625570.dgx1.25099.0
new file mode 100644
index 0000000000000000000000000000000000000000..d23806a37c9d31bcee1beeafa2689732bbe3ab9c
GIT binary patch
literal 4699
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
BnYI7`

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_24/hparams.yaml b/code/lightning_logs/version_24/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_24/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_25/events.out.tfevents.1657625613.dgx1.27343.0 b/code/lightning_logs/version_25/events.out.tfevents.1657625613.dgx1.27343.0
new file mode 100644
index 0000000000000000000000000000000000000000..a51495644c8c24447f5a9d0bce559fe1c0f7e857
GIT binary patch
literal 4699
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_25/hparams.yaml b/code/lightning_logs/version_25/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_25/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_26/events.out.tfevents.1657625763.dgx1.33397.0 b/code/lightning_logs/version_26/events.out.tfevents.1657625763.dgx1.33397.0
new file mode 100644
index 0000000000000000000000000000000000000000..19376c22a488f8e753dbdbff5f0e810aa1ae4057
GIT binary patch
literal 4699
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_26/hparams.yaml b/code/lightning_logs/version_26/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_26/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_27/events.out.tfevents.1657625819.dgx1.36236.0 b/code/lightning_logs/version_27/events.out.tfevents.1657625819.dgx1.36236.0
new file mode 100644
index 0000000000000000000000000000000000000000..63e1dd8a5203e7fb1ff819e29310446d3cd72067
GIT binary patch
literal 4699
zcmb1OfPlsI-b$RG%g>pGZ@%Fu#hX-=n3<>NT9%quVr8Tzr@LMjqKqLy|GqNk&RGz3
zT0&d`T$~vN@wurbMVZN>3=9qX=TDkDWgi<v_42T)&zz<T=fQ?*ZQ|ux&&wqepHYxl
zl$cu_ub)~`kXn?Po0?bRHI0{RGA|c9R7$9wSEz+oiI0mbH$NpcM?WtyH&uaANtlZt
z%8yUZNh~f-EmmMw65`^62qq;aXD8+7ffR~z2|~m&^WxJ|6H7{qz)HoqgdoECr6tJX
zLR@?~`NhThNr}a&@gSB0qmm#OZ+<~ZW^QIxYLR|^L5TvRk^mPELMW$5fmunEOAsNF
zUr-XCT2QROs3guMj4GUzT9OEo5aSX;NaW^&d|sNXz^Ej}C58|$Pt8ovD2Y!=O-`(Y
z*pZT0lBf?Nic?GCp<yA)B?uA$3&$5{l%}QSq$)6joQ)7p$t;3|8dxYNF)1}CJ}ol`
z6hgdQoM6GU{G1d8W>83jxp`2&5EmbqpInq*TpVAPn4`d~q{5{D7ApZIjd&0<CqFSI
zwMaiHu_QSozBscA<N#GJMUa#}hN`^M-1zeRqU_WnP^>9)$wQQ-7MI{O3vMHtB2=RU
zxp=`wB_*cA9Kp`ToRgofz^KH-#etM8#JPl%)6(_bQ}a@b5_9yE^K(Hlpungk!X<z#
zQJk6z3KTTav;spj1!g5lE>UE)iMa*wIjLo-ISP#EQUyh+$(hBO`FRS=N^)FM$hvY%
zb4oJf(+f)DK?xGm1?dH)(DZ_=E43g$IRg}W5?mt4;^{?+De;NP$(XK7E6T4*&5KV0
zIRQ;mL1IZ}YF;uZ&cwKckc}%&Eh<X|r5rRJIr-`F1&JjY2%oxONtn>^flDDJPEjsF
zkUa<~NCJgM3s@K>kqUD0!qp=ZCR_-XSfS1b>qkzo8eA%HwHV0}CDCefsp3|Nn%dO4
zlo3kN(j|(SD7K?1L^TpQSdbF25EmcFCST+d5E@iaF{Dxu8U_#vq$CfG4Tv~uX(+`d
zhA<zkM1(rYAFTw0<_Lr^xD<rife=NMgwkB%AUjZ{V5K3{0SHN?5)qnT5OQdxBGkV=
z=*2c47Z=FF<ovv}Oi%&9&&3Vmm!%d#Ga@e+CrALCl^|t0h>J+tTD)A`LWnBuO~A1e
zceo(6S?$6-TAUYPwb=zxuCt<CGKku&IJFpLM|^QfVo^zaW?ovp*BVi-m7<7RZLX-)
zEKx2A<XTOLONt|;C^4_t*VBhf20g~nWU=H@AvP(NlGNf7E(J*028rlASjrIM6oj~)
z!GTK|S0y9FDOfGC&i!Fki#?YVT9!i?z`$jP9JWFRQhIuN`Yx%d1@1+OX(jqFU&I%s
z7U!jwm>R^FB<B{zmt__u=IB)>=H_t8LP}XgoaPh>aSG}>%e;PMre)71gHgL9EO+2i
zf)u;pOb#mUVZ{nU4Fi`V&eR49Ccpf=R4xgW^Z?f^;J`JJk&6d8DF`(%O4aFS<maa9
zSLP(<>4WO7;)2BFRJc!d5uVS<PcOz27W#-F&_{%eGpJH^%_}L&FQ^13;2cnepO=}J
z9uGDLnpopaxP*`rs}QRcv!SUamn<Y8V3ioW{t;r4V)8fQlE>D@f%~(;flCfc!vQYO
zz`zy8#SaQ!eMCtt<SgZg6c7ksg9}xVvr7__a#D-+iwklxOX8DC;sYFmkz+rrI6sfe
z5V<tQT^_=nq5z6>)HaxqpcH>jetvdhMrvY8d{JUbVlI~odfQD%NJ;=bgt?@#G}Pc}
zLI%AB3Ceb`RLmuVt<474D-FrA;A9D|kKpd-aNsf^s;+?R_+Zba0jY_>sRG^_#p)wT
z)W#@sMlvF@HiKIX4r)B@6HwAhDc}-AYBR$1GB9wdL)tcoe2rXIBNr~pxN01@X$=ls
z;#^$d^oJ3ex`f-GaC1J`bIBs5b6C4sh(n4kxwN<>KbH$`8gWTc7E-*zavikk2u}uz
zs0}h$+Y0U;PY13%aGO*pT`CnRFVU`0;ZlP%wh*zBUr>TA14*Md_2G_YVBj)`wyi-i
z5}%S;B%~&#g5-RVFjBE+WMmR=Xk<~EtIs6~DeGb31!~WN3b1IySXfC8lY%!<k?mE4
z6msBf1+oN71VU>QxG@EWW^fZe*rVG5Z;Qj#7&ve#K++>3h+qv6c)ZF%0uk&ESknw{
z!URwW1?~($YF(t}6<ke&1E@*`c|jkWetAfK2b&LXy23RxFmUM+(Vc>;S8(8x#oG0R
z`$rxUt_UAPn`&?cIt2S=aN9oEbGf4?dsr(<NMA}9DU}dT<XmE0@O~Of;i~`%A4vGZ
znzbk@<gj%0;ZAID;6lrpu&xqZ2?Hq1FnWJ5=_&IaP%AFneP5Ush7a~!;gHe-9IZ(8
zsDqRpQm_!JN3m6+(DVXJ^x#%(G2G@%2QF)*1Pe-aq-5G7^V(Ewpv}b-+ZP9Maw<Yc
iZVb8fxuh^#x~X|7kan&h7eAtv%c8`@!Dx3<JpcfJla`zS

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_27/hparams.yaml b/code/lightning_logs/version_27/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_27/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_28/events.out.tfevents.1657625859.dgx1.38333.0 b/code/lightning_logs/version_28/events.out.tfevents.1657625859.dgx1.38333.0
new file mode 100644
index 0000000000000000000000000000000000000000..6b6c0ae6852731226a72c9746e71c67c5b96361b
GIT binary patch
literal 4699
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_28/hparams.yaml b/code/lightning_logs/version_28/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_28/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_29/events.out.tfevents.1657625903.dgx1.40628.0 b/code/lightning_logs/version_29/events.out.tfevents.1657625903.dgx1.40628.0
new file mode 100644
index 0000000000000000000000000000000000000000..8783be4dc429493cadb5cc21bca2dc1a24e98d8f
GIT binary patch
literal 4699
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
bTe_)vDUf!qAQwNPmCK^U#KHKYy4er_5EPaW

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_29/hparams.yaml b/code/lightning_logs/version_29/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_29/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_3/cm_test.png b/code/lightning_logs/version_3/cm_test.png
new file mode 100644
index 0000000000000000000000000000000000000000..4a523c98c4bd81c8e446deba57c6e24579f4911a
GIT binary patch
literal 63231
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
Y@#daKw@Ux*><78Q)78&qol`;+0D0)L4*&oF

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_3/events.out.tfevents.1657543830.dgx1.34643.0 b/code/lightning_logs/version_3/events.out.tfevents.1657543830.dgx1.34643.0
new file mode 100644
index 0000000000000000000000000000000000000000..0726f25de4e54bfa2acdf91a638a4d86787f60ac
GIT binary patch
literal 4705
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
Yc`1<At{@jbqOHrK#KgfU9RKP80Fc?2x&QzG

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_3/hparams.yaml b/code/lightning_logs/version_3/hparams.yaml
new file mode 100644
index 0000000..a662047
--- /dev/null
+++ b/code/lightning_logs/version_3/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 0
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_30/events.out.tfevents.1657625960.dgx1.43463.0 b/code/lightning_logs/version_30/events.out.tfevents.1657625960.dgx1.43463.0
new file mode 100644
index 0000000000000000000000000000000000000000..5a9ead248d726804faeead94babbb17b53639f97
GIT binary patch
literal 4699
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_30/hparams.yaml b/code/lightning_logs/version_30/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_30/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_31/events.out.tfevents.1657626120.dgx1.48909.0 b/code/lightning_logs/version_31/events.out.tfevents.1657626120.dgx1.48909.0
new file mode 100644
index 0000000000000000000000000000000000000000..125ad0c8b29dcda71447e15108aa5dc4d5d085aa
GIT binary patch
literal 4699
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_31/hparams.yaml b/code/lightning_logs/version_31/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_31/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_32/events.out.tfevents.1657626628.dgx1.65460.0 b/code/lightning_logs/version_32/events.out.tfevents.1657626628.dgx1.65460.0
new file mode 100644
index 0000000000000000000000000000000000000000..32f354dc772b3edd2b278e47b884bfb45af1ef7e
GIT binary patch
literal 4699
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_32/hparams.yaml b/code/lightning_logs/version_32/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_32/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_33/events.out.tfevents.1657626794.dgx1.71384.0 b/code/lightning_logs/version_33/events.out.tfevents.1657626794.dgx1.71384.0
new file mode 100644
index 0000000000000000000000000000000000000000..1c2bc9d73a885ec5d45e076338de61fb63e3475d
GIT binary patch
literal 4699
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_33/hparams.yaml b/code/lightning_logs/version_33/hparams.yaml
new file mode 100644
index 0000000..d8ca6a0
--- /dev/null
+++ b/code/lightning_logs/version_33/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - test
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: test
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_4/events.out.tfevents.1657545281.dgx1.41143.0 b/code/lightning_logs/version_4/events.out.tfevents.1657545281.dgx1.41143.0
new file mode 100644
index 0000000000000000000000000000000000000000..04c542e7c7c8be7ebf3a1c040e54855ccc321392
GIT binary patch
literal 4705
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_4/hparams.yaml b/code/lightning_logs/version_4/hparams.yaml
new file mode 100644
index 0000000..a662047
--- /dev/null
+++ b/code/lightning_logs/version_4/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 0
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_5/events.out.tfevents.1657545407.dgx1.42159.0 b/code/lightning_logs/version_5/events.out.tfevents.1657545407.dgx1.42159.0
new file mode 100644
index 0000000000000000000000000000000000000000..de560d26010186b57ca59ac3412d2603077d9c84
GIT binary patch
literal 4705
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_5/hparams.yaml b/code/lightning_logs/version_5/hparams.yaml
new file mode 100644
index 0000000..385e52b
--- /dev/null
+++ b/code/lightning_logs/version_5/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_6/events.out.tfevents.1657545574.dgx1.43290.0 b/code/lightning_logs/version_6/events.out.tfevents.1657545574.dgx1.43290.0
new file mode 100644
index 0000000000000000000000000000000000000000..b96b3cc792298ad93aea695082529868f03f3aa0
GIT binary patch
literal 4705
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
Rk7(<%C^2y`8opBC0sxM;my7@a

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_6/hparams.yaml b/code/lightning_logs/version_6/hparams.yaml
new file mode 100644
index 0000000..385e52b
--- /dev/null
+++ b/code/lightning_logs/version_6/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_7/events.out.tfevents.1657545679.dgx1.44154.0 b/code/lightning_logs/version_7/events.out.tfevents.1657545679.dgx1.44154.0
new file mode 100644
index 0000000000000000000000000000000000000000..7094035f824ab5b403ca76dc451d320b83f282b6
GIT binary patch
literal 4705
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_7/hparams.yaml b/code/lightning_logs/version_7/hparams.yaml
new file mode 100644
index 0000000..385e52b
--- /dev/null
+++ b/code/lightning_logs/version_7/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_8/events.out.tfevents.1657545837.dgx1.45339.0 b/code/lightning_logs/version_8/events.out.tfevents.1657545837.dgx1.45339.0
new file mode 100644
index 0000000000000000000000000000000000000000..feb362684898989fdf7cfbdf3ce96d9eeef16d25
GIT binary patch
literal 4705
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
VTDyW={D`(LixLwD<HrNy4*)=<mvsOD

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_8/hparams.yaml b/code/lightning_logs/version_8/hparams.yaml
new file mode 100644
index 0000000..385e52b
--- /dev/null
+++ b/code/lightning_logs/version_8/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/code/lightning_logs/version_9/events.out.tfevents.1657545985.dgx1.46385.0 b/code/lightning_logs/version_9/events.out.tfevents.1657545985.dgx1.46385.0
new file mode 100644
index 0000000000000000000000000000000000000000..1f6b05a4e88ebf59fe40d3af43cf85a4991a21c0
GIT binary patch
literal 4705
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

literal 0
HcmV?d00001

diff --git a/code/lightning_logs/version_9/hparams.yaml b/code/lightning_logs/version_9/hparams.yaml
new file mode 100644
index 0000000..385e52b
--- /dev/null
+++ b/code/lightning_logs/version_9/hparams.yaml
@@ -0,0 +1,368 @@
+backbone: resnet50
+cfg: &id010 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - General
+    - &id002 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - comment
+        - null
+      - !!python/tuple
+        - seed
+        - 2021
+      - !!python/tuple
+        - fp16
+        - true
+      - !!python/tuple
+        - amp_level
+        - O2
+      - !!python/tuple
+        - precision
+        - 16
+      - !!python/tuple
+        - multi_gpu_mode
+        - dp
+      - !!python/tuple
+        - gpus
+        - &id001
+          - 1
+      - !!python/tuple
+        - epochs
+        - 200
+      - !!python/tuple
+        - grad_acc
+        - 2
+      - !!python/tuple
+        - frozen_bn
+        - false
+      - !!python/tuple
+        - patience
+        - 50
+      - !!python/tuple
+        - server
+        - train
+      - !!python/tuple
+        - log_path
+        - /home/ylan/workspace/TransMIL-DeepGraft/logs/
+      dictitems:
+        amp_level: O2
+        comment: null
+        epochs: 200
+        fp16: true
+        frozen_bn: false
+        gpus: *id001
+        grad_acc: 2
+        log_path: /home/ylan/workspace/TransMIL-DeepGraft/logs/
+        multi_gpu_mode: dp
+        patience: 50
+        precision: 16
+        seed: 2021
+        server: train
+      state: *id002
+  - !!python/tuple
+    - Data
+    - &id005 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - dataset_name
+        - custom
+      - !!python/tuple
+        - data_shuffle
+        - false
+      - !!python/tuple
+        - data_dir
+        - /home/ylan/data/DeepGraft/224_128um/
+      - !!python/tuple
+        - label_file
+        - /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+      - !!python/tuple
+        - fold
+        - 0
+      - !!python/tuple
+        - nfold
+        - 3
+      - !!python/tuple
+        - cross_val
+        - false
+      - !!python/tuple
+        - train_dataloader
+        - &id003 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id003
+      - !!python/tuple
+        - test_dataloader
+        - &id004 !!python/object/new:addict.addict.Dict
+          args:
+          - !!python/tuple
+            - batch_size
+            - 1
+          - !!python/tuple
+            - num_workers
+            - 8
+          dictitems:
+            batch_size: 1
+            num_workers: 8
+          state: *id004
+      - !!python/tuple
+        - bag_size
+        - 1024
+      dictitems:
+        bag_size: 1024
+        cross_val: false
+        data_dir: /home/ylan/data/DeepGraft/224_128um/
+        data_shuffle: false
+        dataset_name: custom
+        fold: 0
+        label_file: /home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral_test.json
+        nfold: 3
+        test_dataloader: *id004
+        train_dataloader: *id003
+      state: *id005
+  - !!python/tuple
+    - Model
+    - &id006 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - name
+        - TransMIL
+      - !!python/tuple
+        - n_classes
+        - 2
+      - !!python/tuple
+        - backbone
+        - resnet50
+      - !!python/tuple
+        - in_features
+        - 512
+      - !!python/tuple
+        - out_features
+        - 512
+      dictitems:
+        backbone: resnet50
+        in_features: 512
+        n_classes: 2
+        name: TransMIL
+        out_features: 512
+      state: *id006
+  - !!python/tuple
+    - Optimizer
+    - &id007 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - opt
+        - lookahead_radam
+      - !!python/tuple
+        - lr
+        - 0.0002
+      - !!python/tuple
+        - opt_eps
+        - null
+      - !!python/tuple
+        - opt_betas
+        - null
+      - !!python/tuple
+        - momentum
+        - null
+      - !!python/tuple
+        - weight_decay
+        - 0.01
+      dictitems:
+        lr: 0.0002
+        momentum: null
+        opt: lookahead_radam
+        opt_betas: null
+        opt_eps: null
+        weight_decay: 0.01
+      state: *id007
+  - !!python/tuple
+    - Loss
+    - &id008 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - base_loss
+        - CrossEntropyLoss
+      dictitems:
+        base_loss: CrossEntropyLoss
+      state: *id008
+  - !!python/tuple
+    - config
+    - ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+  - !!python/tuple
+    - version
+    - 4
+  - !!python/tuple
+    - epoch
+    - '159'
+  - !!python/tuple
+    - log_path
+    - &id009 !!python/object/apply:pathlib.PosixPath
+      - /
+      - home
+      - ylan
+      - workspace
+      - TransMIL-DeepGraft
+      - logs
+      - DeepGraft
+      - TransMIL
+      - tcmr_viral
+      - _resnet50_CrossEntropyLoss
+      - lightning_logs
+      - version_4
+  dictitems:
+    Data: *id005
+    General: *id002
+    Loss: *id008
+    Model: *id006
+    Optimizer: *id007
+    config: ../DeepGraft/TransMIL_resnet50_tcmr_viral.yaml
+    epoch: '159'
+    log_path: *id009
+    version: 4
+  state: *id010
+data: &id013 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - dataset_name
+    - custom
+  - !!python/tuple
+    - data_shuffle
+    - false
+  - !!python/tuple
+    - data_dir
+    - /home/ylan/data/DeepGraft/224_128um/
+  - !!python/tuple
+    - label_file
+    - /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+  - !!python/tuple
+    - fold
+    - 0
+  - !!python/tuple
+    - nfold
+    - 3
+  - !!python/tuple
+    - cross_val
+    - false
+  - !!python/tuple
+    - train_dataloader
+    - &id011 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id011
+  - !!python/tuple
+    - test_dataloader
+    - &id012 !!python/object/new:addict.addict.Dict
+      args:
+      - !!python/tuple
+        - batch_size
+        - 1
+      - !!python/tuple
+        - num_workers
+        - 8
+      dictitems:
+        batch_size: 1
+        num_workers: 8
+      state: *id012
+  - !!python/tuple
+    - bag_size
+    - 1024
+  dictitems:
+    bag_size: 1024
+    cross_val: false
+    data_dir: /home/ylan/data/DeepGraft/224_128um/
+    data_shuffle: false
+    dataset_name: custom
+    fold: 0
+    label_file: /home/ylan/DeepGraft/training_tables/split_bt_PAS_tcmr_viral.json
+    nfold: 3
+    test_dataloader: *id012
+    train_dataloader: *id011
+  state: *id013
+log: !!python/object/apply:pathlib.PosixPath
+- /
+- home
+- ylan
+- workspace
+- TransMIL-DeepGraft
+- logs
+- DeepGraft
+- TransMIL
+- tcmr_viral
+- _resnet50_CrossEntropyLoss
+loss: &id014 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - base_loss
+    - CrossEntropyLoss
+  dictitems:
+    base_loss: CrossEntropyLoss
+  state: *id014
+model: &id015 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - name
+    - TransMIL
+  - !!python/tuple
+    - n_classes
+    - 2
+  - !!python/tuple
+    - backbone
+    - resnet50
+  - !!python/tuple
+    - in_features
+    - 512
+  - !!python/tuple
+    - out_features
+    - 512
+  dictitems:
+    backbone: resnet50
+    in_features: 512
+    n_classes: 2
+    name: TransMIL
+    out_features: 512
+  state: *id015
+optimizer: &id016 !!python/object/new:addict.addict.Dict
+  args:
+  - !!python/tuple
+    - opt
+    - lookahead_radam
+  - !!python/tuple
+    - lr
+    - 0.0002
+  - !!python/tuple
+    - opt_eps
+    - null
+  - !!python/tuple
+    - opt_betas
+    - null
+  - !!python/tuple
+    - momentum
+    - null
+  - !!python/tuple
+    - weight_decay
+    - 0.01
+  dictitems:
+    lr: 0.0002
+    momentum: null
+    opt: lookahead_radam
+    opt_betas: null
+    opt_eps: null
+    weight_decay: 0.01
+  state: *id016
diff --git a/models/AttMIL.py b/code/models/AttMIL.py
similarity index 98%
rename from models/AttMIL.py
rename to code/models/AttMIL.py
index d1e20eb..d4a5938 100644
--- a/models/AttMIL.py
+++ b/code/models/AttMIL.py
@@ -76,4 +76,4 @@ class AttMIL(nn.Module): #gated attention
         M = torch.mm(A, H)  # KxL
         logits = self.classifier(M)
        
-        return logits
\ No newline at end of file
+        return logits, A
\ No newline at end of file
diff --git a/code/models/DTFDMIL.py b/code/models/DTFDMIL.py
new file mode 100644
index 0000000..272c1c7
--- /dev/null
+++ b/code/models/DTFDMIL.py
@@ -0,0 +1,109 @@
+import os
+import logging
+from argparse import ArgumentParser
+from collections import OrderedDict
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+import torchvision.models as models
+
+import pytorch_lightning as pl
+from pl_bolts.optimizers.lr_scheduler import LinearWarmupCosineAnnealingLR
+
+class Attention_Gated(nn.Module):
+    def __init__(self, features=512, D=128, K=1):
+        super(Attention_Gated, self).__init__()
+
+        self.L = features
+        self.D = D
+        self.K = K
+
+        self.attention_V = nn.Sequential(
+            nn.Linear(self.L, self.D),
+            nn.Tanh()
+        )
+
+        self.attention_U = nn.Sequential(
+            nn.Linear(self.L, self.D),
+            nn.Sigmoid()
+        )
+
+        self.attention_weights = nn.Linear(self.D, self.K)
+
+    def forward(self, x, isNorm=True):
+        ## x: N x L
+        # print(x.shape)
+        A_V = self.attention_V(x)  # NxD
+        A_U = self.attention_U(x)  # NxD
+        A = self.attention_weights(A_V * A_U) # NxK
+        A = torch.transpose(A, 1, 0)  # KxN
+
+        if isNorm:
+            A = F.softmax(A, dim=1)  # softmax over N
+
+        return A  ### K x N
+
+class Attention_with_Classifier(nn.Module):
+    def __init__(self, L=512, D=128, K=1, num_cls=2, droprate=0):
+        super(Attention_with_Classifier, self).__init__()
+        self.attention = Attention_Gated(L, D, K)
+        self.classifier = Classifier_1fc(L, num_cls, droprate)
+    def forward(self, x): ## x: N x L
+        AA = self.attention(x)  ## K x N
+        afeat = torch.mm(AA, x) ## K x L
+        pred = self.classifier(afeat) ## K x num_cls
+        return pred
+
+class Classifier_1fc(nn.Module):
+    def __init__(self, n_channels, n_classes, droprate=0.0):
+        super(Classifier_1fc, self).__init__()
+        self.fc = nn.Linear(n_channels, n_classes)
+        self.droprate = droprate
+        if self.droprate != 0.0:
+            self.dropout = torch.nn.Dropout(p=self.droprate)
+
+    def forward(self, x):
+
+        if self.droprate != 0.0:
+            x = self.dropout(x)
+        x = self.fc(x)
+        return x
+
+
+class residual_block(nn.Module):
+    def __init__(self, nChn=512):
+        super(residual_block, self).__init__()
+        self.block = nn.Sequential(
+                nn.Linear(nChn, nChn, bias=False),
+                nn.ReLU(inplace=True),
+                nn.Linear(nChn, nChn, bias=False),
+                nn.ReLU(inplace=True),
+            )
+    def forward(self, x):
+        tt = self.block(x)
+        x = x + tt
+        return x
+
+
+class DimReduction(nn.Module):
+    def __init__(self, n_channels, m_dim=512, numLayer_Res=0):
+        super(DimReduction, self).__init__()
+        self.fc1 = nn.Linear(n_channels, m_dim, bias=False)
+        self.relu1 = nn.ReLU(inplace=True)
+        self.numRes = numLayer_Res
+
+        self.resBlocks = []
+        for ii in range(numLayer_Res):
+            self.resBlocks.append(residual_block(m_dim))
+        self.resBlocks = nn.Sequential(*self.resBlocks)
+
+    def forward(self, x):
+
+        x = self.fc1(x)
+        x = self.relu1(x)
+
+        if self.numRes > 0:
+            x = self.resBlocks(x)
+
+        return x
\ No newline at end of file
diff --git a/models/TransMIL.py b/code/models/TransMIL.py
similarity index 70%
rename from models/TransMIL.py
rename to code/models/TransMIL.py
index ca2a1fb..c78599d 100755
--- a/models/TransMIL.py
+++ b/code/models/TransMIL.py
@@ -17,13 +17,15 @@ class TransLayer(nn.Module):
             num_landmarks = dim//2,    # number of landmarks
             pinv_iterations = 6,    # number of moore-penrose iterations for approximating pinverse. 6 was recommended by the paper
             residual = True,         # whether to do an extra residual with the value or not. supposedly faster convergence if turned on
-            dropout=0.1
+            dropout=0.7 #0.1
         )
 
     def forward(self, x):
-        x = x + self.attn(self.norm(x))
+        out, attn = self.attn(self.norm(x), return_attn=True)
+        x = x + out
+        # x = x + self.attn(self.norm(x))
 
-        return x
+        return x, attn
 
 
 class PPEG(nn.Module):
@@ -44,8 +46,10 @@ class PPEG(nn.Module):
 
 
 class TransMIL(nn.Module):
-    def __init__(self, n_classes, in_features, out_features=384):
+    def __init__(self, n_classes):
         super(TransMIL, self).__init__()
+        in_features = 512
+        out_features=512
         self.pos_layer = PPEG(dim=out_features)
         self._fc1 = nn.Sequential(nn.Linear(in_features, out_features), nn.GELU())
         # self._fc1 = nn.Sequential(nn.Linear(1024, 512), nn.ReLU())
@@ -62,42 +66,63 @@ class TransMIL(nn.Module):
         h = x.float() #[B, n, 1024]
         h = self._fc1(h) #[B, n, 512]
         
-        #---->pad
+        # print('Feature Representation: ', h.shape)
+        #---->duplicate pad
         H = h.shape[1]
         _H, _W = int(np.ceil(np.sqrt(H))), int(np.ceil(np.sqrt(H)))
         add_length = _H * _W - H
         h = torch.cat([h, h[:,:add_length,:]],dim = 1) #[B, N, 512]
+        
 
         #---->cls_token
         B = h.shape[0]
         cls_tokens = self.cls_token.expand(B, -1, -1).cuda()
         h = torch.cat((cls_tokens, h), dim=1)
 
+
         #---->Translayer x1
-        h = self.layer1(h) #[B, N, 512]
+        h, attn1 = self.layer1(h) #[B, N, 512]
+
+        # print('After first TransLayer: ', h.shape)
 
         #---->PPEG
         h = self.pos_layer(h, _H, _W) #[B, N, 512]
+        # print('After PPEG: ', h.shape)
         
         #---->Translayer x2
-        h = self.layer2(h) #[B, N, 512]
+        h, attn2 = self.layer2(h) #[B, N, 512]
 
+        # print('After second TransLayer: ', h.shape) #[1, 1025, 512] 1025 = cls_token + 1024
         #---->cls_token
-        print(h.shape) #[1, 1025, 512] 1025 = cls_token + 1024
-
-        # tokens = h
+        
         h = self.norm(h)[:,0]
 
         #---->predict
         logits = self._fc2(h) #[B, n_classes]
-        return logits
+        return logits, attn2
 
 if __name__ == "__main__":
     data = torch.randn((1, 6000, 512)).cuda()
-    model = TransMIL(n_classes=2, in_features=512).cuda()
+    model = TransMIL(n_classes=2).cuda()
     print(model.eval())
-    results_dict = model(data)
-    print(results_dict)
+    logits, attn = model(data)
+    cls_attention = attn[:,:, 0, :6000]
+    values, indices = torch.max(cls_attention, 1)
+    mean = values.mean()
+    zeros = torch.zeros(values.shape).cuda()
+    filtered = torch.where(values > mean, values, zeros)
+    
+    # filter = values > values.mean()
+    # filtered_values = values[filter]
+    # values = np.where(values>values.mean(), values, 0)
+
+    print(filtered.shape)
+
+
+    # values = [v if v > values.mean().item() else 0 for v in values]
+    # print(values)
+    # print(len(values))
+
     # logits = results_dict['logits']
     # Y_prob = results_dict['Y_prob']
     # Y_hat = results_dict['Y_hat']
diff --git a/code/models/TransformerMIL.py b/code/models/TransformerMIL.py
new file mode 100644
index 0000000..ea249ba
--- /dev/null
+++ b/code/models/TransformerMIL.py
@@ -0,0 +1,129 @@
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+import numpy as np
+from nystrom_attention import NystromAttention
+
+
+class TransLayer(nn.Module):
+
+    def __init__(self, norm_layer=nn.LayerNorm, dim=512):
+        super().__init__()
+        self.norm = norm_layer(dim)
+        self.attn = NystromAttention(
+            dim = dim,
+            dim_head = dim//8,
+            heads = 8,
+            num_landmarks = dim//2,    # number of landmarks
+            pinv_iterations = 6,    # number of moore-penrose iterations for approximating pinverse. 6 was recommended by the paper
+            residual = True,         # whether to do an extra residual with the value or not. supposedly faster convergence if turned on
+            dropout=0.25 #0.1
+        )
+
+    def forward(self, x):
+        out, attn = self.attn(self.norm(x), return_attn=True)
+        x = x + out
+        # x = x + self.attn(self.norm(x))
+
+        return x, attn
+
+
+class PPEG(nn.Module):
+    def __init__(self, dim=512):
+        super(PPEG, self).__init__()
+        self.proj = nn.Conv2d(dim, dim, 7, 1, 7//2, groups=dim)
+        self.proj1 = nn.Conv2d(dim, dim, 5, 1, 5//2, groups=dim)
+        self.proj2 = nn.Conv2d(dim, dim, 3, 1, 3//2, groups=dim)
+
+    def forward(self, x, H, W):
+        B, _, C = x.shape
+        cls_token, feat_token = x[:, 0], x[:, 1:]
+        cnn_feat = feat_token.transpose(1, 2).view(B, C, H, W)
+        x = self.proj(cnn_feat)+cnn_feat+self.proj1(cnn_feat)+self.proj2(cnn_feat)
+        x = x.flatten(2).transpose(1, 2)
+        x = torch.cat((cls_token.unsqueeze(1), x), dim=1)
+        return x
+
+
+class TransformerMIL(nn.Module):
+    def __init__(self, n_classes):
+        super(TransformerMIL, self).__init__()
+        in_features = 512
+        out_features = 512
+        self.pos_layer = PPEG(dim=out_features)
+        self._fc1 = nn.Sequential(nn.Linear(in_features, out_features), nn.GELU())
+        # self._fc1 = nn.Sequential(nn.Linear(1024, 512), nn.ReLU())
+        self.cls_token = nn.Parameter(torch.randn(1, 1, out_features))
+        self.n_classes = n_classes
+        self.layer1 = TransLayer(dim=out_features)
+        self.layer2 = TransLayer(dim=out_features)
+        self.norm = nn.LayerNorm(out_features)
+        self._fc2 = nn.Linear(out_features, self.n_classes)
+
+
+    def forward(self, x): #, **kwargs
+
+        h = x.float() #[B, n, 1024]
+        h = self._fc1(h) #[B, n, 512]
+        
+        # print('Feature Representation: ', h.shape)
+        #---->duplicate pad
+        H = h.shape[1]
+        _H, _W = int(np.ceil(np.sqrt(H))), int(np.ceil(np.sqrt(H)))
+        add_length = _H * _W - H
+        h = torch.cat([h, h[:,:add_length,:]],dim = 1) #[B, N, 512]
+        
+
+        #---->cls_token
+        B = h.shape[0]
+        cls_tokens = self.cls_token.expand(B, -1, -1).cuda()
+        h = torch.cat((cls_tokens, h), dim=1)
+
+
+        #---->Translayer x1
+        h, attn1 = self.layer1(h) #[B, N, 512]
+
+        # print('After first TransLayer: ', h.shape)
+
+        #---->PPEG
+        # h = self.pos_layer(h, _H, _W) #[B, N, 512]
+        # # print('After PPEG: ', h.shape)
+        
+        # #---->Translayer x2
+        # h, attn2 = self.layer2(h) #[B, N, 512]
+
+        # print('After second TransLayer: ', h.shape) #[1, 1025, 512] 1025 = cls_token + 1024
+        #---->cls_token
+        
+        h = self.norm(h)[:,0]
+
+        #---->predict
+        logits = self._fc2(h) #[B, n_classes]
+        return logits, attn1
+
+if __name__ == "__main__":
+    data = torch.randn((1, 6000, 512)).cuda()
+    model = TransMIL(n_classes=2).cuda()
+    print(model.eval())
+    logits, attn = model(data)
+    cls_attention = attn[:,:, 0, :6000]
+    values, indices = torch.max(cls_attention, 1)
+    mean = values.mean()
+    zeros = torch.zeros(values.shape).cuda()
+    filtered = torch.where(values > mean, values, zeros)
+    
+    # filter = values > values.mean()
+    # filtered_values = values[filter]
+    # values = np.where(values>values.mean(), values, 0)
+
+    print(filtered.shape)
+
+
+    # values = [v if v > values.mean().item() else 0 for v in values]
+    # print(values)
+    # print(len(values))
+
+    # logits = results_dict['logits']
+    # Y_prob = results_dict['Y_prob']
+    # Y_hat = results_dict['Y_hat']
+    # print(F.sigmoid(logits))
diff --git a/models/__init__.py b/code/models/__init__.py
similarity index 100%
rename from models/__init__.py
rename to code/models/__init__.py
diff --git a/models/__pycache__/AttMIL.cpython-39.pyc b/code/models/__pycache__/AttMIL.cpython-39.pyc
similarity index 79%
rename from models/__pycache__/AttMIL.cpython-39.pyc
rename to code/models/__pycache__/AttMIL.cpython-39.pyc
index 5ee3af4e0d05559e5bc7a4d8ed62481a3254c9f1..f0f6f23506b721b78a8172b4ed1b215c65ae45b0 100644
GIT binary patch
delta 38
ucmeC@nasnR$ji&cz`(%Z{P9rIi;cWq%#3-HBbc*UYFN{lHXmm8VFCcet_qX@

delta 33
pcmbQt)6c`3$ji&cz`(%JU^Xx5=|)~JX2z_^5zN_}k2Cu)0RV~T2?78B

diff --git a/code/models/__pycache__/DTFDMIL.cpython-39.pyc b/code/models/__pycache__/DTFDMIL.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1ca3b6870a8316ae4e8ac9dc503615612cb9bde2
GIT binary patch
literal 3969
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

literal 0
HcmV?d00001

diff --git a/code/models/__pycache__/TransMIL.cpython-39.pyc b/code/models/__pycache__/TransMIL.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..38ed5a1f3fedfb29af2fc50c7909b312399d39d3
GIT binary patch
literal 3455
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
Gh1dYVr4+#c

literal 0
HcmV?d00001

diff --git a/code/models/__pycache__/TransformerMIL.cpython-39.pyc b/code/models/__pycache__/TransformerMIL.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..999c95ee4caea337f6a77e6cc0eaad0fb3a6c90c
GIT binary patch
literal 3440
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

literal 0
HcmV?d00001

diff --git a/models/__pycache__/__init__.cpython-39.pyc b/code/models/__pycache__/__init__.cpython-39.pyc
similarity index 100%
rename from models/__pycache__/__init__.cpython-39.pyc
rename to code/models/__pycache__/__init__.cpython-39.pyc
diff --git a/code/models/__pycache__/model_interface.cpython-39.pyc b/code/models/__pycache__/model_interface.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..565cfe10390ef1f7b43c48995fdfeb7ea63773a2
GIT binary patch
literal 15830
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
RVG;nB!aPhu^$ZZ`0RSyr6d?cr

literal 0
HcmV?d00001

diff --git a/code/models/__pycache__/model_interface_dtfd.cpython-39.pyc b/code/models/__pycache__/model_interface_dtfd.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..01c221509c05637cfc3eaca68d9fbe8ec26c0416
GIT binary patch
literal 17058
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
HE)G@z8YYa6

literal 0
HcmV?d00001

diff --git a/models/__pycache__/resnet50.cpython-39.pyc b/code/models/__pycache__/resnet50.cpython-39.pyc
similarity index 100%
rename from models/__pycache__/resnet50.cpython-39.pyc
rename to code/models/__pycache__/resnet50.cpython-39.pyc
diff --git a/models/__pycache__/vision_transformer.cpython-39.pyc b/code/models/__pycache__/vision_transformer.cpython-39.pyc
similarity index 100%
rename from models/__pycache__/vision_transformer.cpython-39.pyc
rename to code/models/__pycache__/vision_transformer.cpython-39.pyc
diff --git a/models/model_interface.py b/code/models/model_interface.py
similarity index 70%
rename from models/model_interface.py
rename to code/models/model_interface.py
index b3a561e..586d80c 100755
--- a/models/model_interface.py
+++ b/code/models/model_interface.py
@@ -1,5 +1,6 @@
 import sys
 import numpy as np
+import re
 import inspect
 import importlib
 import random
@@ -30,9 +31,10 @@ from torch import optim as optim
 #---->
 import pytorch_lightning as pl
 from .vision_transformer import vit_small
+import torchvision
 from torchvision import models
 from torchvision.models import resnet
-from transformers import AutoFeatureExtractor, ViTModel
+from transformers import AutoFeatureExtractor, ViTModel, SwinModel
 
 from pytorch_grad_cam import GradCAM, EigenGradCAM
 from pytorch_grad_cam.utils.image import show_cam_on_image
@@ -52,12 +54,11 @@ class ModelInterface(pl.LightningModule):
         # self.loss = LabelSmoothingCrossEntropy(smoothing=0.1)
         # self.loss = 
         # print(self.model)
-        
+        self.model_name = model.name
         
         # self.ecam = EigenGradCAM(model = self.model, target_layers = target_layers, use_cuda=True, reshape_transform=self.reshape_transform)
         self.optimizer = optimizer
         self.n_classes = model.n_classes
-        print(self.n_classes)
         self.save_path = kargs['log']
         if Path(self.save_path).parts[3] == 'tcmr':
             temp = list(Path(self.save_path).parts)
@@ -85,7 +86,7 @@ class ModelInterface(pl.LightningModule):
                                                                             num_classes = self.n_classes)])
                                                                             
         else : 
-            self.AUROC = torchmetrics.AUROC(num_classes=2, average = 'weighted')
+            self.AUROC = torchmetrics.AUROC(num_classes=self.n_classes, average = 'weighted')
 
             metrics = torchmetrics.MetricCollection([torchmetrics.Accuracy(num_classes = 2,
                                                                            average = 'micro'),
@@ -97,6 +98,7 @@ class ModelInterface(pl.LightningModule):
                                                      torchmetrics.Precision(average = 'macro',
                                                                             num_classes = 2)])
         self.PRC = torchmetrics.PrecisionRecallCurve(num_classes = self.n_classes)
+        self.ROC = torchmetrics.ROC(num_classes=self.n_classes)
         # self.pr_curve = torchmetrics.BinnedPrecisionRecallCurve(num_classes = self.n_classes, thresholds=10)
         self.confusion_matrix = torchmetrics.ConfusionMatrix(num_classes = self.n_classes)                                                                    
         self.valid_metrics = metrics.clone(prefix = 'val_')
@@ -112,39 +114,42 @@ class ModelInterface(pl.LightningModule):
             self.feature_extractor = AutoFeatureExtractor.from_pretrained('facebook/dino-vitb16')
             self.model_ft = ViTModel.from_pretrained('facebook/dino-vitb16')
         elif kargs['backbone'] == 'resnet18':
-            resnet18 = models.resnet18(pretrained=True)
-            modules = list(resnet18.children())[:-1]
-            # model_ft.fc = nn.Linear(512, out_features)
-
-            res18 = nn.Sequential(
-                *modules,
-            )
-            for param in res18.parameters():
+            self.model_ft = models.resnet18(pretrained=True)
+            # modules = list(resnet18.children())[:-1]
+            for param in self.model_ft.parameters():
                 param.requires_grad = False
-            self.model_ft = nn.Sequential(
-                res18,
-                nn.AdaptiveAvgPool2d(1),
-                View((-1, 512)),
-                nn.Linear(512, self.out_features),
-                nn.GELU(),
-            )
+            self.model_ft.fc = nn.Linear(512, self.out_features)
+
+            # res18 = nn.Sequential(
+            #     *modules,
+            # )
+            # for param in res18.parameters():
+            #     param.requires_grad = False
+            # self.model_ft = nn.Sequential(
+            #     res18,
+            #     nn.AdaptiveAvgPool2d(1),
+            #     View((-1, 512)),
+            #     nn.Linear(512, self.out_features),
+            #     nn.GELU(),
+            # )
         elif kargs['backbone'] == 'resnet50':
 
-            resnet50 = models.resnet50(pretrained=True)    
-            # model_ft.fc = nn.Linear(1024, out_features)
-            modules = list(resnet50.children())[:-3]
-            res50 = nn.Sequential(
-                *modules,     
-            )
-            for param in res50.parameters():
+            self.model_ft = models.resnet50(pretrained=True)    
+            for param in self.model_ft.parameters():
                 param.requires_grad = False
-            self.model_ft = nn.Sequential(
-                res50,
-                nn.AdaptiveAvgPool2d(1),
-                View((-1, 1024)),
-                nn.Linear(1024, self.out_features),
-                # nn.GELU()
-            )
+            self.model_ft.fc = nn.Linear(2048, self.out_features)
+            # modules = list(resnet50.children())[:-3]
+            # res50 = nn.Sequential(
+            #     *modules,     
+            # )
+            
+            # self.model_ft = nn.Sequential(
+            #     res50,
+            #     nn.AdaptiveAvgPool2d(1),
+            #     View((-1, 1024)),
+            #     nn.Linear(1024, self.out_features),
+            #     # nn.GELU()
+            # )
         elif kargs['backbone'] == 'efficientnet':
             efficientnet = torch.hub.load('NVIDIA/DeepLearningExamples:torchhub', 'nvidia_efficientnet_widese_b0', pretrained=True)
             for param in efficientnet.parameters():
@@ -164,30 +169,22 @@ class ModelInterface(pl.LightningModule):
                 nn.Conv2d(20, 50, kernel_size=5),
                 nn.ReLU(),
                 nn.MaxPool2d(2, stride=2),
-                View((-1, 1024)),
-                nn.Linear(1024, self.out_features),
+                View((-1, 53*53)),
+                nn.Linear(53*53, self.out_features),
                 nn.ReLU(),
             )
         # print(self.model_ft[0].features[-1])
         # print(self.model_ft)
-        if model.name == 'TransMIL':
-            target_layers = [self.model.layer2.norm] # 32x32
-            # target_layers = [self.model_ft[0].features[-1]] # 32x32
-            self.cam = GradCAM(model=self.model, target_layers = target_layers, use_cuda=True, reshape_transform=self.reshape_transform) #, reshape_transform=self.reshape_transform
-            # self.cam_ft = GradCAM(model=self.model, target_layers = target_layers_ft, use_cuda=True) #, reshape_transform=self.reshape_transform
-        else:
-            target_layers = [self.model.attention_weights]
-            self.cam = GradCAM(model = self.model, target_layers = target_layers, use_cuda=True)
 
     def forward(self, x):
-        
+        # print(x.shape)
         feats = self.model_ft(x).unsqueeze(0)
         return self.model(feats)
 
     def step(self, input):
 
         input = input.squeeze(0).float()
-        logits = self(input) 
+        logits, _ = self(input) 
 
         Y_hat = torch.argmax(logits, dim=1)
         Y_prob = F.softmax(logits, dim=1)
@@ -195,10 +192,14 @@ class ModelInterface(pl.LightningModule):
         return logits, Y_prob, Y_hat
 
     def training_step(self, batch, batch_idx):
-        #---->inference
-        
 
         input, label, _= batch
+
+        #random image dropout
+        # bag_size = 500
+        # bag_idxs = torch.randperm(input.squeeze(0).shape[0])[:bag_size]
+        # input = input.squeeze(0)[bag_idxs].unsqueeze(0)
+
         label = label.float()
         
         logits, Y_prob, Y_hat = self.step(input) 
@@ -217,24 +218,31 @@ class ModelInterface(pl.LightningModule):
             # Y = int(label[0])
         self.data[Y]["count"] += 1
         self.data[Y]["correct"] += (int(Y_hat) == Y)
-        self.log('loss', loss, prog_bar=True, on_epoch=True, logger=True)
+        self.log('loss', loss, prog_bar=True, on_epoch=True, logger=True, batch_size=1)
 
         if self.current_epoch % 10 == 0:
 
-            grid = torchvision.utils.make_grid(images)
+            # images = input.squeeze()[:10, :, :, :]
+            # for i in range(10):
+            img = input.squeeze(0)[:10, :, :, :]
+            img = (img - torch.min(img)/(torch.max(img)-torch.min(img)))*255.0
+            
+            # mg = img.cpu().numpy()
+            grid = torchvision.utils.make_grid(img, normalize=True, value_range=(0, 255), scale_each=True)
+            # grid = img.detach().cpu().numpy()
         # log input images 
-        # self.loggers[0].experiment.add_figure(f'{stage}/input', , self.current_epoch)
+            self.loggers[0].experiment.add_image(f'{self.current_epoch}/input', grid)
 
 
-        return {'loss': loss, 'Y_prob': Y_prob, 'Y_hat': Y_hat, 'label': label} 
+        return {'loss': loss, 'Y_prob': Y_prob, 'Y_hat': Y_hat, 'label': Y} 
 
     def training_epoch_end(self, training_step_outputs):
         # logits = torch.cat([x['logits'] for x in training_step_outputs], dim = 0)
         probs = torch.cat([x['Y_prob'] for x in training_step_outputs])
         max_probs = torch.stack([x['Y_hat'] for x in training_step_outputs])
         # target = torch.stack([x['label'] for x in training_step_outputs], dim = 0)
-        target = torch.cat([x['label'] for x in training_step_outputs])
-        target = torch.argmax(target, dim=1)
+        target = torch.stack([x['label'] for x in training_step_outputs])
+        # target = torch.argmax(target, dim=1)
         for c in range(self.n_classes):
             count = self.data[c]["count"]
             correct = self.data[c]["correct"]
@@ -248,9 +256,9 @@ class ModelInterface(pl.LightningModule):
         # print('max_probs: ', max_probs)
         # print('probs: ', probs)
         if self.current_epoch % 10 == 0:
-            self.log_confusion_matrix(probs, target, stage='train')
+            self.log_confusion_matrix(max_probs, target, stage='train')
 
-        self.log('Train/auc', self.AUROC(probs, target.squeeze()), prog_bar=True, on_epoch=True, logger=True)
+        self.log('Train/auc', self.AUROC(probs, target), prog_bar=True, on_epoch=True, logger=True)
 
     def validation_step(self, batch, batch_idx):
 
@@ -266,21 +274,24 @@ class ModelInterface(pl.LightningModule):
         self.data[Y]["count"] += 1
         self.data[Y]["correct"] += (Y_hat.item() == Y)
 
-        return {'logits' : logits, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : label}
+        return {'logits' : logits, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : Y}
 
 
     def validation_epoch_end(self, val_step_outputs):
         logits = torch.cat([x['logits'] for x in val_step_outputs], dim = 0)
         probs = torch.cat([x['Y_prob'] for x in val_step_outputs])
         max_probs = torch.stack([x['Y_hat'] for x in val_step_outputs])
-        target = torch.cat([x['label'] for x in val_step_outputs])
-        target = torch.argmax(target, dim=1)
+        target = torch.stack([x['label'] for x in val_step_outputs])
+        
+        self.log_dict(self.valid_metrics(logits, target),
+                          on_epoch = True, logger = True)
+        
         #---->
         # logits = logits.long()
         # target = target.squeeze().long()
         # logits = logits.squeeze(0)
         if len(target.unique()) != 1:
-            self.log('val_auc', self.AUROC(probs, target.squeeze()), prog_bar=True, on_epoch=True, logger=True)
+            self.log('val_auc', self.AUROC(probs, target), prog_bar=True, on_epoch=True, logger=True)
         else:    
             self.log('val_auc', 0.0, prog_bar=True, on_epoch=True, logger=True)
 
@@ -289,13 +300,16 @@ class ModelInterface(pl.LightningModule):
         self.log('val_loss', cross_entropy_torch(logits, target), prog_bar=True, on_epoch=True, logger=True)
         
 
+        precision, recall, thresholds = self.PRC(probs, target)
+
+
+
         # print(max_probs.squeeze(0).shape)
         # print(target.shape)
-        self.log_dict(self.valid_metrics(max_probs.squeeze() , target),
-                          on_epoch = True, logger = True)
+        
 
         #----> log confusion matrix
-        self.log_confusion_matrix(probs, target, stage='val')
+        self.log_confusion_matrix(max_probs, target, stage='val')
         
 
         #---->acc log
@@ -306,7 +320,7 @@ class ModelInterface(pl.LightningModule):
                 acc = None
             else:
                 acc = float(correct) / count
-            print('class {}: acc {}, correct {}/{}'.format(c, acc, correct, count))
+            print('val class {}: acc {}, correct {}/{}'.format(c, acc, correct, count))
         self.data = [{"count": 0, "correct": 0} for i in range(self.n_classes)]
         
         #---->random, if shuffle data, change seed
@@ -315,34 +329,73 @@ class ModelInterface(pl.LightningModule):
             random.seed(self.count*50)
 
     def test_step(self, batch, batch_idx):
+
         torch.set_grad_enabled(True)
-        data, label, name = batch
+        data, label, (wsi_name, batch_names) = batch
+        wsi_name = wsi_name[0]
         label = label.float()
         # logits, Y_prob, Y_hat = self.step(data) 
         # print(data.shape)
         data = data.squeeze(0).float()
-        logits = self(data).detach() 
+        logits, attn = self(data)
+        attn = attn.detach()
+        logits = logits.detach()
 
         Y = torch.argmax(label)
         Y_hat = torch.argmax(logits, dim=1)
         Y_prob = F.softmax(logits, dim = 1)
         
-        #----> Get Topk tiles 
+        #----> Get GradCam maps, map each instance to attention value, assemble, overlay on original WSI 
+        if self.model_name == 'TransMIL':
+           
+            target_layers = [self.model.layer2.norm] # 32x32
+            # target_layers = [self.model_ft[0].features[-1]] # 32x32
+            self.cam = GradCAM(model=self.model, target_layers = target_layers, use_cuda=True, reshape_transform=self.reshape_transform) #, reshape_transform=self.reshape_transform
+            # self.cam_ft = GradCAM(model=self.model, target_layers = target_layers_ft, use_cuda=True) #, reshape_transform=self.reshape_transform
+        else:
+            target_layers = [self.model.attention_weights]
+            self.cam = GradCAM(model = self.model, target_layers = target_layers, use_cuda=True)
 
-        target = [ClassifierOutputTarget(Y)]
 
         data_ft = self.model_ft(data).unsqueeze(0).float()
-        # data_ft = self.model_ft(data).unsqueeze(0).float()
-        # print(data_ft.shape)
-        # print(target)
+        instance_count = data.size(0)
+        target = [ClassifierOutputTarget(Y)]
         grayscale_cam = self.cam(input_tensor=data_ft, targets=target)
-        # grayscale_ecam = self.ecam(input_tensor=data_ft, targets=target)
+        grayscale_cam = torch.Tensor(grayscale_cam)[:instance_count, :]
+
+        # attention_map = grayscale_cam[:, :, 1].squeeze()
+        # attention_map = F.relu(attention_map)
+        # mask = torch.zeros((instance_count, 3, 256, 256)).to(self.device)
+        # for i, v in enumerate(attention_map):
+        #     mask[i, :, :, :] = v
+
+        # mask = self.assemble(mask, batch_names)
+        # mask = (mask - mask.min())/(mask.max()-mask.min())
+        # mask = mask.cpu().numpy()
+        # wsi = self.assemble(data, batch_names)
+        # wsi = wsi.cpu().numpy()
+
+        # def show_cam_on_image(img, mask):
+        #     heatmap = cv2.applyColorMap(np.uint8(255 * mask), cv2.COLORMAP_JET)
+        #     heatmap = np.float32(heatmap) / 255
+        #     cam = heatmap*0.4 + np.float32(img)
+        #     cam = cam / np.max(cam)
+        #     return cam
+
+        # wsi = show_cam_on_image(wsi, mask)
+        # wsi = ((wsi-wsi.min())/(wsi.max()-wsi.min()) * 255.0).astype(np.uint8)
+        
+        # img = Image.fromarray(wsi)
+        # img = img.convert('RGB')
+        
 
-        # print(grayscale_cam)
+        # output_path = self.save_path / str(Y.item())
+        # output_path.mkdir(parents=True, exist_ok=True)
+        # img.save(f'{output_path}/{wsi_name}.jpg')
 
-        summed = torch.mean(torch.Tensor(grayscale_cam), dim=2)
-        print(summed)
-        print(summed.shape)
+
+        #----> Get Topk Tiles and Topk Patients
+        summed = torch.mean(grayscale_cam, dim=2)
         topk_tiles, topk_indices = torch.topk(summed.squeeze(0), 5, dim=0)
         topk_data = data[topk_indices].detach()
         
@@ -368,20 +421,33 @@ class ModelInterface(pl.LightningModule):
         self.data[Y]["count"] += 1
         self.data[Y]["correct"] += (Y_hat.item() == Y)
 
-        return {'logits' : logits, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : label, 'name': name, 'topk_data': topk_data} #
+        return {'logits' : logits, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : Y, 'name': wsi_name, 'topk_data': topk_data} #
         # return {'logits' : logits, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : label, 'name': name} #, 'topk_data': topk_data
 
     def test_epoch_end(self, output_results):
+        logits = torch.cat([x['logits'] for x in output_results], dim = 0)
         probs = torch.cat([x['Y_prob'] for x in output_results])
         max_probs = torch.stack([x['Y_hat'] for x in output_results])
         # target = torch.stack([x['label'] for x in output_results], dim = 0)
-        target = torch.cat([x['label'] for x in output_results])
-        target = torch.argmax(target, dim=1)
+        target = torch.stack([x['label'] for x in output_results])
+        # target = torch.argmax(target, dim=1)
         patients = [x['name'] for x in output_results]
         topk_tiles = [x['topk_data'] for x in output_results]
         #---->
-        auc = self.AUROC(probs, target.squeeze())
-        metrics = self.test_metrics(max_probs.squeeze() , target)
+        auc = self.AUROC(probs, target)
+        fpr, tpr, thresholds = self.ROC(probs, target)
+        fpr = fpr.cpu().numpy()
+        tpr = tpr.cpu().numpy()
+
+        plt.figure(1)
+        plt.plot(fpr, tpr)
+        plt.xlabel('False positive rate')
+        plt.ylabel('True positive rate')
+        plt.title('ROC curve')
+        plt.savefig(f'{self.save_path}/roc.jpg')
+        # self.loggers[0].experiment.add_figure(f'{stage}/Confusion matrix', fig_, self.current_epoch)
+
+        metrics = self.test_metrics(logits , target)
 
 
         # metrics = self.test_metrics(max_probs.squeeze() , torch.argmax(target.squeeze(), dim=1))
@@ -390,16 +456,20 @@ class ModelInterface(pl.LightningModule):
         # self.log('auc', auc, prog_bar=True, on_epoch=True, logger=True)
 
         #---->get highest scoring patients for each class
-        test_path = Path(self.save_path) / 'most_predictive'
+        # test_path = Path(self.save_path) / 'most_predictive' 
+        
+        # Path.mkdir(output_path, exist_ok=True)
         topk, topk_indices = torch.topk(probs.squeeze(0), 5, dim=0)
         for n in range(self.n_classes):
             print('class: ', n)
+            
             topk_patients = [patients[i[n]] for i in topk_indices]
             topk_patient_tiles = [topk_tiles[i[n]] for i in topk_indices]
             for x, p, t in zip(topk, topk_patients, topk_patient_tiles):
                 print(p, x[n])
-                patient = p[0]
-                outpath = test_path / str(n) / patient 
+                patient = p
+                # outpath = test_path / str(n) / patient 
+                outpath = Path(self.save_path) / str(n) / patient
                 outpath.mkdir(parents=True, exist_ok=True)
                 for i in range(len(t)):
                     tile = t[i]
@@ -408,7 +478,7 @@ class ModelInterface(pl.LightningModule):
                     tile = tile.astype(np.uint8)
                     img = Image.fromarray(tile)
                     
-                    img.save(f'{test_path}/{n}/{patient}/{i}_gradcam.jpg')
+                    img.save(f'{outpath}/{i}.jpg')
 
             
             
@@ -448,7 +518,7 @@ class ModelInterface(pl.LightningModule):
         #[tp, fp, tn, fn, tp+fn]
 
 
-        self.log_confusion_matrix(probs, target, stage='test')
+        self.log_confusion_matrix(max_probs, target, stage='test')
         #---->
         result = pd.DataFrame([metrics])
         result.to_csv(Path(self.save_path) / f'test_result.csv', mode='a', header=not Path(self.save_path).exists())
@@ -462,8 +532,13 @@ class ModelInterface(pl.LightningModule):
         optimizer = create_optimizer(self.optimizer, self.model)
         return optimizer     
 
-    def reshape_transform(self, tensor, h=32, w=32):
-        result = tensor[:, 1:, :].reshape(tensor.size(0), h, w, tensor.size(2))
+    def reshape_transform(self, tensor):
+        # print(tensor.shape)
+        H = tensor.shape[1]
+        _H, _W = int(np.ceil(np.sqrt(H))), int(np.ceil(np.sqrt(H)))
+        add_length = _H * _W - H
+        tensor = torch.cat([tensor, tensor[:,:add_length,:]],dim = 1)
+        result = tensor[:, :, :].reshape(tensor.size(0), _H, _W, tensor.size(2))
         result = result.transpose(2,3).transpose(1,2)
         # print(result.shape)
         return result
@@ -510,24 +585,42 @@ class ModelInterface(pl.LightningModule):
 
 
     def log_confusion_matrix(self, max_probs, target, stage):
-        confmat = self.confusion_matrix(max_probs.squeeze(), target)
+        confmat = self.confusion_matrix(max_probs, target)
         print(confmat)
         df_cm = pd.DataFrame(confmat.cpu().numpy(), index=range(self.n_classes), columns=range(self.n_classes))
-        # plt.figure()
-        fig_ = sns.heatmap(df_cm, annot=True, cmap='Spectral').get_figure()
-        # plt.close(fig_)
-        # plt.savefig(f'{self.save_path}/cm_e{self.current_epoch}')
+        fig_ = sns.heatmap(df_cm, annot=True, fmt='d', cmap='Spectral').get_figure()
+        if stage == 'train':
+            self.loggers[0].experiment.add_figure(f'{stage}/Confusion matrix', fig_, self.current_epoch)
+        else:
+            fig_.savefig(f'{self.loggers[0].log_dir}/cm_test.png', dpi=400)
+
+    def log_roc_curve(self, probs, target, stage):
+
+        fpr_list, tpr_list, thresholds = self.ROC(probs, target)
+
+        plt.figure(1)
+        if self.n_classes > 2:
+            for i in range(len(fpr_list)):
+                fpr = fpr_list[i].cpu().numpy()
+                tpr = tpr_list[i].cpu().numpy()
+                plt.plot(fpr, tpr, label=f'class_{i}')
+        else: 
+            print(fpr_list)
+            fpr = fpr_list.cpu().numpy()
+            tpr = tpr_list.cpu().numpy()
+            plt.plot(fpr, tpr)
         
+        plt.xlabel('False positive rate')
+        plt.ylabel('True positive rate')
+        plt.title('ROC curve')
+        plt.savefig(f'{self.loggers[0].log_dir}/roc.jpg')
 
         if stage == 'train':
-            # print(self.save_path)
-            # plt.savefig(f'{self.save_path}/cm_test')
-
-            self.loggers[0].experiment.add_figure(f'{stage}/Confusion matrix', fig_, self.current_epoch)
+            self.loggers[0].experiment.add_figure(f'{stage}/ROC', plt, self.current_epoch)
         else:
-            fig_.savefig(f'{self.save_path}/cm_test.png', dpi=400)
-        # plt.close(fig_)
-        # self.logger[0].experiment.add_figure('Confusion matrix', fig_, self.current_epoch)
+            plt.savefig(f'{self.loggers[0].log_dir}/roc.jpg', dpi=400)
+
+    
 
 class View(nn.Module):
     def __init__(self, shape):
@@ -538,8 +631,6 @@ class View(nn.Module):
         '''
         Reshapes the input according to the shape saved in the view data structure.
         '''
-        # batch_size = input.size(0)
-        # shape = (batch_size, *self.shape)
         out = input.view(*self.shape)
         return out
 
diff --git a/code/models/model_interface_dtfd.py b/code/models/model_interface_dtfd.py
new file mode 100644
index 0000000..0b503cc
--- /dev/null
+++ b/code/models/model_interface_dtfd.py
@@ -0,0 +1,707 @@
+import sys
+import numpy as np
+import re
+import inspect
+import importlib
+import random
+import pandas as pd
+import seaborn as sns
+from pathlib import Path
+from matplotlib import pyplot as plt
+import cv2
+from PIL import Image
+
+#---->
+from MyOptimizer import create_optimizer
+from MyLoss import create_loss
+from utils.utils import cross_entropy_torch
+from timm.loss import AsymmetricLossSingleLabel
+from timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy, JsdCrossEntropy
+
+#---->
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+import torchmetrics
+from torchmetrics.functional import stat_scores
+from torch import optim as optim
+# from sklearn.metrics import roc_curve, auc, roc_curve_score
+
+
+#---->
+import pytorch_lightning as pl
+from .vision_transformer import vit_small
+import torchvision
+from torchvision import models
+from torchvision.models import resnet
+from transformers import AutoFeatureExtractor, ViTModel
+
+from pytorch_grad_cam import GradCAM, EigenGradCAM
+from pytorch_grad_cam.utils.image import show_cam_on_image
+from pytorch_grad_cam.utils.model_targets import ClassifierOutputTarget
+
+from captum.attr import LayerGradCam
+from models.DTFDMIL import Attention_Gated, Classifier_1fc, DimReduction, Attention_with_Classifier
+
+class ModelInterface_DTFD(pl.LightningModule):
+
+    #---->init
+    def __init__(self, model, loss, optimizer, **kargs):
+        super(ModelInterface_DTFD, self).__init__()
+        self.save_hyperparameters()
+        # self.load_model()
+        self.loss = create_loss(loss)
+        # self.asl = AsymmetricLossSingleLabel()
+        # self.loss = LabelSmoothingCrossEntropy(smoothing=0.1)
+        # self.loss = 
+        # print(self.model)
+        self.model_name = model.name
+        
+        self.optimizer = optimizer
+        self.n_classes = model.n_classes
+        self.save_path = kargs['log']
+        if Path(self.save_path).parts[3] == 'tcmr':
+            temp = list(Path(self.save_path).parts)
+            temp[3] = 'tcmr_viral'
+            self.save_path = '/'.join(temp)
+
+        #---->acc
+        self.data = [{"count": 0, "correct": 0} for i in range(self.n_classes)]
+        #---->Metrics
+        if self.n_classes > 2: 
+            self.AUROC = torchmetrics.AUROC(num_classes = self.n_classes, average = 'weighted')
+            
+            metrics = torchmetrics.MetricCollection([torchmetrics.Accuracy(num_classes = self.n_classes,
+                                                                           average='micro'),
+                                                     torchmetrics.CohenKappa(num_classes = self.n_classes),
+                                                     torchmetrics.F1Score(num_classes = self.n_classes,
+                                                                     average = 'macro'),
+                                                     torchmetrics.Recall(average = 'macro',
+                                                                         num_classes = self.n_classes),
+                                                     torchmetrics.Precision(average = 'macro',
+                                                                            num_classes = self.n_classes),
+                                                     torchmetrics.Specificity(average = 'macro',
+                                                                            num_classes = self.n_classes)])
+                                                                            
+        else : 
+            self.AUROC = torchmetrics.AUROC(num_classes=self.n_classes, average = 'weighted')
+
+            metrics = torchmetrics.MetricCollection([torchmetrics.Accuracy(num_classes = 2,
+                                                                           average = 'micro'),
+                                                     torchmetrics.CohenKappa(num_classes = 2),
+                                                     torchmetrics.F1Score(num_classes = 2,
+                                                                     average = 'macro'),
+                                                     torchmetrics.Recall(average = 'macro',
+                                                                         num_classes = 2),
+                                                     torchmetrics.Precision(average = 'macro',
+                                                                            num_classes = 2)])
+        self.PRC = torchmetrics.PrecisionRecallCurve(num_classes = self.n_classes)
+        self.ROC = torchmetrics.ROC(num_classes=self.n_classes)
+        # self.pr_curve = torchmetrics.BinnedPrecisionRecallCurve(num_classes = self.n_classes, thresholds=10)
+        self.confusion_matrix = torchmetrics.ConfusionMatrix(num_classes = self.n_classes)                                                                    
+        self.valid_metrics = metrics.clone(prefix = 'val_')
+        self.test_metrics = metrics.clone(prefix = 'test_')
+
+        #--->random
+        self.shuffle = kargs['data'].data_shuffle
+        self.count = 0
+        self.backbone = kargs['backbone']
+
+        self.out_features = 1024
+        if kargs['backbone'] == 'dino':
+            self.feature_extractor = AutoFeatureExtractor.from_pretrained('facebook/dino-vitb16')
+            self.model_ft = ViTModel.from_pretrained('facebook/dino-vitb16')
+        elif kargs['backbone'] == 'resnet18':
+            self.model_ft = models.resnet18(pretrained=True)
+            # modules = list(resnet18.children())[:-1]
+            for param in self.model_ft.parameters():
+                param.requires_grad = False
+            self.model_ft.fc = nn.Linear(512, self.out_features)
+
+            # res18 = nn.Sequential(
+            #     *modules,
+            # )
+            # for param in res18.parameters():
+            #     param.requires_grad = False
+            # self.model_ft = nn.Sequential(
+            #     res18,
+            #     nn.AdaptiveAvgPool2d(1),
+            #     View((-1, 512)),
+            #     nn.Linear(512, self.out_features),
+            #     nn.GELU(),
+            # )
+        elif kargs['backbone'] == 'resnet50':
+
+            self.model_ft = models.resnet50(pretrained=True)    
+            for param in self.model_ft.parameters():
+                param.requires_grad = False
+            self.model_ft.fc = nn.Linear(2048, self.out_features)
+
+            # modules = list(resnet50.children())[:-3]
+            # res50 = nn.Sequential(
+            #     *modules,     
+            # )
+            
+            # self.model_ft = nn.Sequential(
+            #     res50,
+            #     nn.AdaptiveAvgPool2d(1),
+            #     View((-1, 1024)),
+            #     nn.Linear(1024, self.out_features),
+            #     # nn.GELU()
+            # )
+        elif kargs['backbone'] == 'efficientnet':
+            efficientnet = torch.hub.load('NVIDIA/DeepLearningExamples:torchhub', 'nvidia_efficientnet_widese_b0', pretrained=True)
+            for param in efficientnet.parameters():
+                param.requires_grad = False
+            # efn = list(efficientnet.children())[:-1]
+            efficientnet.classifier.fc = nn.Linear(1280, self.out_features)
+            self.model_ft = nn.Sequential(
+                efficientnet,
+                nn.GELU(),
+            )
+        self.classifier = Classifier_1fc(n_channels=512, n_classes=self.n_classes)
+        self.attention = Attention_Gated(features=512)
+        self.dimreduction = DimReduction(n_channels=self.out_features, m_dim=512)
+        self.attCls = Attention_with_Classifier(L=512, num_cls=self.n_classes)
+        self.trainable_parameters = []
+        self.trainable_parameters += list(self.classifier.parameters())
+        self.trainable_parameters += list(self.attention.parameters())
+        self.trainable_parameters += list(self.dimreduction.parameters())
+        
+        # print(self.model_ft[0].features[-1])
+        # print(self.model_ft)
+
+    def forward(self, x, bag_size=120):
+        # print(x.shape)
+        x = x.float()
+        max_pseudo_bags = x.squeeze(0).shape[0] // bag_size
+        max_pseudo_bags = min(8, max_pseudo_bags)
+        
+        slide_pseudo_feat = []
+        sub_predictions = []
+
+        input = x.squeeze(0)
+        features = self.model_ft(input) # max_pseudo_bags, 512
+        features = self.dimreduction(features)
+        randomized_idx = torch.randperm(features.shape[0])
+
+        
+        for n in range(max_pseudo_bags):
+
+            bag_idxs = randomized_idx[bag_size*n:bag_size*(n+1)] #torch.randperm(x.squeeze(0).shape[0])
+            bag_features = features.squeeze(0)[bag_idxs]
+            
+            t1AA = self.attention(bag_features).squeeze(0)
+            # print('features: ', features.shape)
+            # print('t1AA: ', t1AA.shape)
+            t1attFeats = torch.einsum('ns, n->ns', bag_features, t1AA)
+            # print('t1attFeats: ', t1attFeats.shape)
+            t1attFeats_tensor = torch.sum(t1attFeats, dim=0).unsqueeze(0)
+            # print('t1attFeats_tensor: ', t1attFeats_tensor.shape)
+            t1Predict = self.classifier(t1attFeats_tensor)
+            sub_predictions.append(t1Predict)
+
+            patch_pred_logits = get_cam_1d(self.classifier, t1attFeats.unsqueeze(0)).squeeze(0)
+            patch_pred_logits = torch.transpose(patch_pred_logits, 0, 1)  ## n x cls
+            # patch_pred_softmax = torch.softmax(patch_pred_logits, dim=1)  ## n x cls
+
+            af_inst_feat = t1attFeats_tensor
+            slide_pseudo_feat.append(af_inst_feat)
+
+        slide_pseudo_feat = torch.cat(slide_pseudo_feat, dim=0)
+
+        ## optimization for first tier
+        sub_predictions = torch.cat(sub_predictions, dim=0)
+
+        ## optimization for second tier
+        slide_prediction = self.attCls(slide_pseudo_feat)
+
+        Y_hat = torch.argmax(slide_prediction, dim=1)
+        Y_prob = F.softmax(slide_prediction, dim=1)
+
+        
+        
+        return sub_predictions, slide_prediction, Y_prob, Y_hat
+
+
+    def training_step(self, batch, batch_idx, optimizer_idx):
+
+        input, label, _= batch
+
+
+        sub_predictions, slide_prediction, Y_prob, Y_hat = self(input)
+
+        # print(sub_predictions.size(0))
+        label = label.float()
+        sub_labels = [label] * sub_predictions.size(0)         
+        sub_labels = torch.cat(sub_labels, dim=0)
+        
+        
+        sub_loss = self.loss(sub_predictions, sub_labels)
+        slide_loss = self.loss(slide_prediction, label)
+
+        
+        Y = torch.argmax(label)
+            # Y = int(label[0])
+        self.data[Y]["count"] += 1
+        self.data[Y]["correct"] += (int(Y_hat) == Y)
+        self.log('sub_loss', sub_loss, prog_bar=True, on_epoch=True, logger=True, batch_size=1)
+        self.log('slide_loss', slide_loss, prog_bar=True, on_epoch=True, logger=True, batch_size=1)
+
+        # if self.current_epoch % 10 == 0:
+
+        #     # images = input.squeeze()[:10, :, :, :]
+        #     # for i in range(10):
+        #     img = input.squeeze(0)[:10, :, :, :]
+        #     img = (img - torch.min(img)/(torch.max(img)-torch.min(img)))*255.0
+            
+        #     # mg = img.cpu().numpy()
+        #     grid = torchvision.utils.make_grid(img, normalize=True, value_range=(0, 255), scale_each=True)
+        #     # grid = img.detach().cpu().numpy()
+        # # log input images 
+        #     self.loggers[0].experiment.add_image(f'{self.current_epoch}/input', grid)
+
+
+        # print(Y_prob)
+        # print(Y_prob.shape)
+        
+        total_loss = (sub_loss + slide_loss)/2
+        # print(sub_predictions)
+        # print(sub_labels)
+        # sub_probs = sub_predictions
+        # sub_targets = torch.argmax(sub_labels, dim=1)
+        # if len(sub_targets.unique()) != 1:
+        #     self.log('Train/sub_auc', self.AUROC(sub_predictions, sub_targets), prog_bar=True, on_epoch=True, logger=True)
+
+        # else:    
+        #     self.log('Train/sub_auc', 0.0, prog_bar=True, on_epoch=True, logger=True)
+
+        return {'loss': total_loss, 'Y_prob': Y_prob.detach(), 'Y_hat': Y_hat.detach(), 'label': Y} 
+
+    def training_epoch_end(self, training_step_outputs):
+        # print(training_step_outputs)
+        # for x in training_step_outputs:
+        #     print(x)
+            # print(x['Y_prob'])
+        # logits = torch.cat([x['logits'] for x in training_step_outputs], dim = 0)
+        probs = torch.cat([x[0]['Y_prob'] for x in training_step_outputs])
+        max_probs = torch.stack([x[0]['Y_hat'] for x in training_step_outputs])
+        # target = torch.stack([x['label'] for x in training_step_outputs], dim = 0)
+        target = torch.stack([x[0]['label'] for x in training_step_outputs])
+
+        # sub_probs = torch.cat(x[0]['sub_probs'] for x in training_step_outputs)
+        # sub_targets = torch.cat(x[0]['sub_targets'] for x in training_step_outputs)
+        # target = torch.argmax(target, dim=1)
+        for c in range(self.n_classes):
+            count = self.data[c]["count"]
+            correct = self.data[c]["correct"]
+            if count == 0: 
+                acc = None
+            else:
+                acc = float(correct) / count
+            print('class {}: acc {}, correct {}/{}'.format(c, acc, correct, count))
+        self.data = [{"count": 0, "correct": 0} for i in range(self.n_classes)]
+
+        # print('max_probs: ', max_probs)
+        # print('probs: ', probs)
+        if self.current_epoch % 10 == 0:
+            self.log_confusion_matrix(max_probs, target, stage='train')
+
+        self.log('Train/auc', self.AUROC(probs, target), prog_bar=True, on_epoch=True, logger=True)
+        # self.log('Train/sub_auc', self.AUROC(sub_probs, sub_targets), prog_bar=True, on_epoch=True, logger=True)
+
+    def validation_step(self, batch, batch_idx):
+
+        input, label, _= batch
+        label = label.float()
+
+        sub_predictions, slide_prediction, Y_prob, Y_hat = self(input)
+
+        # print(sub_predictions.size(0))
+        sub_labels = [label] * sub_predictions.size(0)         
+
+        
+        sub_labels = torch.stack(sub_labels).squeeze()
+        # print(sub_labels.shape)
+        # print(sub_predictions.shape)
+        
+        sub_loss = self.loss(sub_predictions, sub_labels)
+        slide_loss = self.loss(slide_prediction, label)
+
+        
+        Y = torch.argmax(label)
+
+        #---->acc log
+        # Y = int(label[0][1])
+        Y = torch.argmax(label)
+
+        self.data[Y]["count"] += 1
+        self.data[Y]["correct"] += (Y_hat.item() == Y)
+
+        return {'val_sub_loss': sub_loss, 'val_slide_loss': slide_loss, 'logits' : slide_prediction, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : Y}
+
+
+    def validation_epoch_end(self, val_step_outputs):
+        logits = torch.cat([x['logits'] for x in val_step_outputs], dim = 0)
+        probs = torch.cat([x['Y_prob'] for x in val_step_outputs])
+        max_probs = torch.stack([x['Y_hat'] for x in val_step_outputs])
+        target = torch.stack([x['label'] for x in val_step_outputs])
+        
+        self.log_dict(self.valid_metrics(logits, target),
+                          on_epoch = True, logger = True)
+        
+        #---->
+        # logits = logits.long()
+        # target = target.squeeze().long()
+        # logits = logits.squeeze(0)
+        if len(target.unique()) != 1:
+            self.log('val_auc', self.AUROC(probs, target), prog_bar=True, on_epoch=True, logger=True)
+        else:    
+            self.log('val_auc', 0.0, prog_bar=True, on_epoch=True, logger=True)
+
+        
+
+        self.log('val_loss', cross_entropy_torch(logits, target), prog_bar=True, on_epoch=True, logger=True)
+        
+
+        precision, recall, thresholds = self.PRC(probs, target)
+
+
+
+        # print(max_probs.squeeze(0).shape)
+        # print(target.shape)
+        
+
+        #----> log confusion matrix
+        self.log_confusion_matrix(max_probs, target, stage='val')
+        
+
+        #---->acc log
+        for c in range(self.n_classes):
+            count = self.data[c]["count"]
+            correct = self.data[c]["correct"]
+            if count == 0: 
+                acc = None
+            else:
+                acc = float(correct) / count
+            print('val class {}: acc {}, correct {}/{}'.format(c, acc, correct, count))
+        self.data = [{"count": 0, "correct": 0} for i in range(self.n_classes)]
+        
+        #---->random, if shuffle data, change seed
+        if self.shuffle == True:
+            self.count = self.count+1
+            random.seed(self.count*50)
+
+    def test_step(self, batch, batch_idx):
+
+        torch.set_grad_enabled(True)
+        data, label, (wsi_name, batch_names) = batch
+        wsi_name = wsi_name[0]
+        label = label.float()
+        # logits, Y_prob, Y_hat = self.step(data) 
+        # print(data.shape)
+        data = data.squeeze(0).float()
+        logits, attn = self(data)
+        attn = attn.detach()
+        logits = logits.detach()
+
+        Y = torch.argmax(label)
+        Y_hat = torch.argmax(logits, dim=1)
+        Y_prob = F.softmax(logits, dim = 1)
+        
+        #----> Get GradCam maps, map each instance to attention value, assemble, overlay on original WSI 
+        if self.model_name == 'TransMIL':
+           
+            target_layers = [self.model.layer2.norm] # 32x32
+            # target_layers = [self.model_ft[0].features[-1]] # 32x32
+            self.cam = GradCAM(model=self.model, target_layers = target_layers, use_cuda=True, reshape_transform=self.reshape_transform) #, reshape_transform=self.reshape_transform
+            # self.cam_ft = GradCAM(model=self.model, target_layers = target_layers_ft, use_cuda=True) #, reshape_transform=self.reshape_transform
+        else:
+            target_layers = [self.model.attention_weights]
+            self.cam = GradCAM(model = self.model, target_layers = target_layers, use_cuda=True)
+
+
+        data_ft = self.model_ft(data).unsqueeze(0).float()
+        instance_count = data.size(0)
+        target = [ClassifierOutputTarget(Y)]
+        grayscale_cam = self.cam(input_tensor=data_ft, targets=target)
+        grayscale_cam = torch.Tensor(grayscale_cam)[:instance_count, :]
+
+        # attention_map = grayscale_cam[:, :, 1].squeeze()
+        # attention_map = F.relu(attention_map)
+        # mask = torch.zeros((instance_count, 3, 256, 256)).to(self.device)
+        # for i, v in enumerate(attention_map):
+        #     mask[i, :, :, :] = v
+
+        # mask = self.assemble(mask, batch_names)
+        # mask = (mask - mask.min())/(mask.max()-mask.min())
+        # mask = mask.cpu().numpy()
+        # wsi = self.assemble(data, batch_names)
+        # wsi = wsi.cpu().numpy()
+
+        # def show_cam_on_image(img, mask):
+        #     heatmap = cv2.applyColorMap(np.uint8(255 * mask), cv2.COLORMAP_JET)
+        #     heatmap = np.float32(heatmap) / 255
+        #     cam = heatmap*0.4 + np.float32(img)
+        #     cam = cam / np.max(cam)
+        #     return cam
+
+        # wsi = show_cam_on_image(wsi, mask)
+        # wsi = ((wsi-wsi.min())/(wsi.max()-wsi.min()) * 255.0).astype(np.uint8)
+        
+        # img = Image.fromarray(wsi)
+        # img = img.convert('RGB')
+        
+
+        # output_path = self.save_path / str(Y.item())
+        # output_path.mkdir(parents=True, exist_ok=True)
+        # img.save(f'{output_path}/{wsi_name}.jpg')
+
+
+        #----> Get Topk Tiles and Topk Patients
+        summed = torch.mean(grayscale_cam, dim=2)
+        topk_tiles, topk_indices = torch.topk(summed.squeeze(0), 5, dim=0)
+        topk_data = data[topk_indices].detach()
+        
+        # target_ft = 
+        # grayscale_cam_ft = self.cam_ft(input_tensor=data, )
+        # for i in range(data.shape[0]):
+            
+            # vis_img = data[i, :, :, :].cpu().numpy()
+            # vis_img = np.transpose(vis_img, (1,2,0))
+            # print(vis_img.shape)
+            # cam_img = grayscale_cam.squeeze(0)
+        # cam_img = self.reshape_transform(grayscale_cam)
+
+        # print(cam_img.shape)
+            
+            # visualization = show_cam_on_image(vis_img, cam_img, use_rgb=True)
+            # visualization = ((visualization/visualization.max())*255.0).astype(np.uint8)
+            # print(visualization)
+        # cv2.imwrite(f'{test_path}/{Y}/{name}/gradcam.jpg', cam_img)
+
+        #---->acc log
+        Y = torch.argmax(label)
+        self.data[Y]["count"] += 1
+        self.data[Y]["correct"] += (Y_hat.item() == Y)
+
+        return {'logits' : logits, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : Y, 'name': wsi_name, 'topk_data': topk_data} #
+        # return {'logits' : logits, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : label, 'name': name} #, 'topk_data': topk_data
+
+    def test_epoch_end(self, output_results):
+        logits = torch.cat([x['logits'] for x in output_results], dim = 0)
+        probs = torch.cat([x['Y_prob'] for x in output_results])
+        max_probs = torch.stack([x['Y_hat'] for x in output_results])
+        # target = torch.stack([x['label'] for x in output_results], dim = 0)
+        target = torch.stack([x['label'] for x in output_results])
+        # target = torch.argmax(target, dim=1)
+        patients = [x['name'] for x in output_results]
+        topk_tiles = [x['topk_data'] for x in output_results]
+        #---->
+        auc = self.AUROC(probs, target)
+        fpr, tpr, thresholds = self.ROC(probs, target)
+        fpr = fpr.cpu().numpy()
+        tpr = tpr.cpu().numpy()
+
+        plt.figure(1)
+        plt.plot(fpr, tpr)
+        plt.xlabel('False positive rate')
+        plt.ylabel('True positive rate')
+        plt.title('ROC curve')
+        plt.savefig(f'{self.save_path}/roc.jpg')
+        # self.loggers[0].experiment.add_figure(f'{stage}/Confusion matrix', fig_, self.current_epoch)
+
+        metrics = self.test_metrics(logits , target)
+
+
+        # metrics = self.test_metrics(max_probs.squeeze() , torch.argmax(target.squeeze(), dim=1))
+        metrics['test_auc'] = auc
+
+        # self.log('auc', auc, prog_bar=True, on_epoch=True, logger=True)
+
+        #---->get highest scoring patients for each class
+        # test_path = Path(self.save_path) / 'most_predictive' 
+        
+        # Path.mkdir(output_path, exist_ok=True)
+        topk, topk_indices = torch.topk(probs.squeeze(0), 5, dim=0)
+        for n in range(self.n_classes):
+            print('class: ', n)
+            
+            topk_patients = [patients[i[n]] for i in topk_indices]
+            topk_patient_tiles = [topk_tiles[i[n]] for i in topk_indices]
+            for x, p, t in zip(topk, topk_patients, topk_patient_tiles):
+                print(p, x[n])
+                patient = p
+                # outpath = test_path / str(n) / patient 
+                outpath = Path(self.save_path) / str(n) / patient
+                outpath.mkdir(parents=True, exist_ok=True)
+                for i in range(len(t)):
+                    tile = t[i]
+                    tile = tile.cpu().numpy().transpose(1,2,0)
+                    tile = (tile - tile.min())/ (tile.max() - tile.min()) * 255
+                    tile = tile.astype(np.uint8)
+                    img = Image.fromarray(tile)
+                    
+                    img.save(f'{outpath}/{i}.jpg')
+
+            
+            
+        #----->visualize top predictive tiles
+        
+        
+
+        
+                # img = img.squeeze(0).cpu().numpy()
+                # img = np.transpose(img, (1,2,0))
+                # # print(img)
+                # # print(grayscale_cam.shape)
+                # visualization = show_cam_on_image(img, grayscale_cam, use_rgb=True)
+
+
+        for keys, values in metrics.items():
+            print(f'{keys} = {values}')
+            metrics[keys] = values.cpu().numpy()
+        #---->acc log
+        for c in range(self.n_classes):
+            count = self.data[c]["count"]
+            correct = self.data[c]["correct"]
+            if count == 0: 
+                acc = None
+            else:
+                acc = float(correct) / count
+            print('class {}: acc {}, correct {}/{}'.format(c, acc, correct, count))
+        self.data = [{"count": 0, "correct": 0} for i in range(self.n_classes)]
+
+        #---->plot auroc curve
+        # stats = stat_scores(probs, target, reduce='macro', num_classes=self.n_classes)
+        # fpr = {}
+        # tpr = {}
+        # for n in self.n_classes: 
+
+        # fpr, tpr, thresh = roc_curve(target.cpu().numpy(), probs.cpu().numpy())
+        #[tp, fp, tn, fn, tp+fn]
+
+
+        self.log_confusion_matrix(max_probs, target, stage='test')
+        #---->
+        result = pd.DataFrame([metrics])
+        result.to_csv(Path(self.save_path) / f'test_result.csv', mode='a', header=not Path(self.save_path).exists())
+
+        # with open(f'{self.save_path}/test_metrics.txt', 'a') as f:
+
+        #     f.write([metrics])
+
+    def configure_optimizers(self):
+        # optimizer_ft = optim.Adam(self.model_ft.parameters(), lr=self.optimizer.lr*0.1)
+        optimizer0 = torch.optim.Adam(self.trainable_parameters, lr=1e-4, weight_decay=1e-2)
+        optimizer1 = torch.optim.Adam(self.attCls.parameters(), lr=1e-4, weight_decay=1e-2)
+
+        scheduler0 = torch.optim.lr_scheduler.MultiStepLR(optimizer0, [100], gamma=0.2)
+        scheduler1 = torch.optim.lr_scheduler.MultiStepLR(optimizer1, [100], gamma=0.2)
+        return [optimizer0, optimizer1], [scheduler0, scheduler1]     
+
+    def reshape_transform(self, tensor):
+        # print(tensor.shape)
+        H = tensor.shape[1]
+        _H, _W = int(np.ceil(np.sqrt(H))), int(np.ceil(np.sqrt(H)))
+        add_length = _H * _W - H
+        tensor = torch.cat([tensor, tensor[:,:add_length,:]],dim = 1)
+        result = tensor[:, :, :].reshape(tensor.size(0), _H, _W, tensor.size(2))
+        result = result.transpose(2,3).transpose(1,2)
+        # print(result.shape)
+        return result
+
+    def load_model(self):
+        name = self.hparams.model.name
+        # Change the `trans_unet.py` file name to `TransUnet` class name.
+        # Please always name your model file name as `trans_unet.py` and
+        # class name or funciton name corresponding `TransUnet`.
+        if '_' in name:
+            camel_name = ''.join([i.capitalize() for i in name.split('_')])
+        else:
+            camel_name = name
+        try:
+                
+            Model = getattr(importlib.import_module(
+                f'models.{name}'), camel_name)
+        except:
+            raise ValueError('Invalid Module File Name or Invalid Class Name!')
+        self.model = self.instancialize(Model)
+        pass
+
+    def instancialize(self, Model, **other_args):
+        """ Instancialize a model using the corresponding parameters
+            from self.hparams dictionary. You can also input any args
+            to overwrite the corresponding value in self.hparams.
+        """
+        class_args = inspect.getargspec(Model.__init__).args[1:]
+        inkeys = self.hparams.model.keys()
+        args1 = {}
+        for arg in class_args:
+            if arg in inkeys:
+                args1[arg] = getattr(self.hparams.model, arg)
+        args1.update(other_args)
+        return Model(**args1)
+
+    def log_image(self, tensor, stage, name):
+        
+        tile = tile.cpu().numpy().transpose(1,2,0)
+        tile = (tile - tile.min())/ (tile.max() - tile.min()) * 255
+        tile = tile.astype(np.uint8)
+        img = Image.fromarray(tile)
+        self.loggers[0].experiment.add_figure(f'{stage}/{name}', img, self.current_epoch)
+
+
+    def log_confusion_matrix(self, max_probs, target, stage):
+        confmat = self.confusion_matrix(max_probs, target)
+        print(confmat)
+        df_cm = pd.DataFrame(confmat.cpu().numpy(), index=range(self.n_classes), columns=range(self.n_classes))
+        fig_ = sns.heatmap(df_cm, annot=True, fmt='d', cmap='Spectral').get_figure()
+        if stage == 'train':
+            self.loggers[0].experiment.add_figure(f'{stage}/Confusion matrix', fig_, self.current_epoch)
+        else:
+            fig_.savefig(f'{self.loggers[0].log_dir}/cm_test.png', dpi=400)
+
+    def log_roc_curve(self, probs, target, stage):
+
+        fpr_list, tpr_list, thresholds = self.ROC(probs, target)
+
+        plt.figure(1)
+        if self.n_classes > 2:
+            for i in range(len(fpr_list)):
+                fpr = fpr_list[i].cpu().numpy()
+                tpr = tpr_list[i].cpu().numpy()
+                plt.plot(fpr, tpr, label=f'class_{i}')
+        else: 
+            print(fpr_list)
+            fpr = fpr_list.cpu().numpy()
+            tpr = tpr_list.cpu().numpy()
+            plt.plot(fpr, tpr)
+        
+        plt.xlabel('False positive rate')
+        plt.ylabel('True positive rate')
+        plt.title('ROC curve')
+        plt.savefig(f'{self.loggers[0].log_dir}/roc.jpg')
+
+        if stage == 'train':
+            self.loggers[0].experiment.add_figure(f'{stage}/ROC', plt, self.current_epoch)
+        else:
+            plt.savefig(f'{self.loggers[0].log_dir}/roc.jpg', dpi=400)
+
+def get_cam_1d(classifier, features):
+    tweight = list(classifier.parameters())[-2]
+    cam_maps = torch.einsum('bgf,cf->bcg', [features, tweight])
+    return cam_maps
+
+class View(nn.Module):
+    def __init__(self, shape):
+        super().__init__()
+        self.shape = shape
+
+    def forward(self, input):
+        '''
+        Reshapes the input according to the shape saved in the view data structure.
+        '''
+        out = input.view(*self.shape)
+        return out
+
diff --git a/models/resnet50.py b/code/models/resnet50.py
similarity index 100%
rename from models/resnet50.py
rename to code/models/resnet50.py
diff --git a/models/vision_transformer.py b/code/models/vision_transformer.py
similarity index 100%
rename from models/vision_transformer.py
rename to code/models/vision_transformer.py
diff --git a/code/test_visualize.py b/code/test_visualize.py
new file mode 100644
index 0000000..82f6cb4
--- /dev/null
+++ b/code/test_visualize.py
@@ -0,0 +1,437 @@
+import argparse
+from pathlib import Path
+import numpy as np
+import glob
+import re
+
+from sklearn.model_selection import KFold
+from scipy.interpolate import griddata
+
+# from datasets.data_interface import DataInterface, MILDataModule, CrossVal_MILDataModule
+from datasets import JPGMILDataloader, MILDataModule
+from models.model_interface import ModelInterface
+import models.vision_transformer as vits
+from utils.utils import *
+
+# pytorch_lightning
+import pytorch_lightning as pl
+from pytorch_lightning import Trainer
+import torch
+
+from pytorch_grad_cam import GradCAM, EigenGradCAM
+from pytorch_grad_cam.utils.image import show_cam_on_image
+from pytorch_grad_cam.utils.model_targets import ClassifierOutputTarget
+
+import cv2
+from PIL import Image
+from matplotlib import pyplot as plt
+import pandas as pd
+
+#--->Setting parameters
+def make_parse():
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--stage', default='test', type=str)
+    parser.add_argument('--config', default='DeepGraft/TransMIL.yaml',type=str)
+    parser.add_argument('--version', default=0,type=int)
+    parser.add_argument('--epoch', default='0',type=str)
+    parser.add_argument('--gpus', default = 2, type=int)
+    parser.add_argument('--loss', default = 'CrossEntropyLoss', type=str)
+    parser.add_argument('--fold', default = 0)
+    parser.add_argument('--bag_size', default = 1024, type=int)
+
+    args = parser.parse_args()
+    return args
+
+class custom_test_module(ModelInterface):
+
+    def test_step(self, batch, batch_idx):
+
+        torch.set_grad_enabled(True)
+        input_data, label, (wsi_name, batch_names) = batch
+        wsi_name = wsi_name[0]
+        label = label.float()
+        # logits, Y_prob, Y_hat = self.step(data) 
+        # print(data.shape)
+        input_data = input_data.squeeze(0).float()
+        logits, attn = self(input_data)
+        attn = attn.detach()
+        logits = logits.detach()
+
+        Y = torch.argmax(label)
+        Y_hat = torch.argmax(logits, dim=1)
+        Y_prob = F.softmax(logits, dim=1)
+        
+        #----> Get GradCam maps, map each instance to attention value, assemble, overlay on original WSI 
+        if self.model_name == 'TransMIL':
+            target_layers = [self.model.layer2.norm] # 32x32
+            # target_layers = [self.model_ft[0].features[-1]] # 32x32
+            self.cam = GradCAM(model=self.model, target_layers = target_layers, use_cuda=True, reshape_transform=self.reshape_transform) #, reshape_transform=self.reshape_transform
+            # self.cam_ft = GradCAM(model=self.model, target_layers = target_layers_ft, use_cuda=True) #, reshape_transform=self.reshape_transform
+        else:
+            target_layers = [self.model.attention_weights]
+            self.cam = GradCAM(model = self.model, target_layers = target_layers, use_cuda=True)
+
+        data_ft = self.model_ft(input_data).unsqueeze(0).float()
+        instance_count = input_data.size(0)
+        target = [ClassifierOutputTarget(Y)]
+        grayscale_cam = self.cam(input_tensor=data_ft, targets=target)
+        grayscale_cam = torch.Tensor(grayscale_cam)[:instance_count, :] #.to(self.device)
+
+        #----------------------------------------------------
+        # Get Topk Tiles and Topk Patients
+        #----------------------------------------------------
+        summed = torch.mean(grayscale_cam, dim=2)
+        topk_tiles, topk_indices = torch.topk(summed.squeeze(0), 5, dim=0)
+        topk_data = input_data[topk_indices].detach()
+        
+        #----------------------------------------------------
+        # Log Correct/Count
+        #----------------------------------------------------
+        Y = torch.argmax(label)
+        self.data[Y]["count"] += 1
+        self.data[Y]["correct"] += (Y_hat.item() == Y)
+
+        #----------------------------------------------------
+        # Tile Level Attention Maps
+        #----------------------------------------------------
+
+        self.save_attention_map(wsi_name, input_data, batch_names, grayscale_cam, target=Y)
+
+        return {'logits' : logits, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : Y, 'name': wsi_name, 'topk_data': topk_data} #
+        # return {'logits' : logits, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : label, 'name': name} #, 'topk_data': topk_data
+
+    def test_epoch_end(self, output_results):
+
+        logits = torch.cat([x['logits'] for x in output_results], dim = 0)
+        probs = torch.cat([x['Y_prob'] for x in output_results])
+        max_probs = torch.stack([x['Y_hat'] for x in output_results])
+        # target = torch.stack([x['label'] for x in output_results], dim = 0)
+        target = torch.stack([x['label'] for x in output_results])
+        # target = torch.argmax(target, dim=1)
+        patients = [x['name'] for x in output_results]
+        topk_tiles = [x['topk_data'] for x in output_results]
+        #---->
+
+        auc = self.AUROC(probs, target)
+        metrics = self.test_metrics(logits , target)
+
+
+        # metrics = self.test_metrics(max_probs.squeeze() , torch.argmax(target.squeeze(), dim=1))
+        metrics['test_auc'] = auc
+
+        # self.log('auc', auc, prog_bar=True, on_epoch=True, logger=True)
+
+        #---->get highest scoring patients for each class
+        # test_path = Path(self.save_path) / 'most_predictive' 
+        
+        # Path.mkdir(output_path, exist_ok=True)
+        topk, topk_indices = torch.topk(probs.squeeze(0), 5, dim=0)
+        for n in range(self.n_classes):
+            print('class: ', n)
+            
+            topk_patients = [patients[i[n]] for i in topk_indices]
+            topk_patient_tiles = [topk_tiles[i[n]] for i in topk_indices]
+            for x, p, t in zip(topk, topk_patients, topk_patient_tiles):
+                print(p, x[n])
+                patient = p
+                # outpath = test_path / str(n) / patient 
+                outpath = Path(self.save_path) / str(n) / patient
+                outpath.mkdir(parents=True, exist_ok=True)
+                for i in range(len(t)):
+                    tile = t[i]
+                    tile = tile.cpu().numpy().transpose(1,2,0)
+                    tile = (tile - tile.min())/ (tile.max() - tile.min()) * 255
+                    tile = tile.astype(np.uint8)
+                    img = Image.fromarray(tile)
+                    
+                    img.save(f'{outpath}/{i}.jpg')
+
+        for keys, values in metrics.items():
+            print(f'{keys} = {values}')
+            metrics[keys] = values.cpu().numpy()
+        #---->acc log
+        for c in range(self.n_classes):
+            count = self.data[c]["count"]
+            correct = self.data[c]["correct"]
+            if count == 0: 
+                acc = None
+            else:
+                acc = float(correct) / count
+            print('class {}: acc {}, correct {}/{}'.format(c, acc, correct, count))
+        self.data = [{"count": 0, "correct": 0} for i in range(self.n_classes)]
+
+
+        # self.log_roc_curve(probs, target, 'test')
+        self.log_confusion_matrix(max_probs, target, stage='test')
+        #---->
+        result = pd.DataFrame([metrics])
+        result.to_csv(Path(self.save_path) / f'test_result.csv', mode='a', header=not Path(self.save_path).exists())
+
+    def save_attention_map(self, wsi_name, data, batch_names, grayscale_cam, target):
+
+        def get_coords(batch_names): #ToDO: Change function for precise coords
+            coords = []
+            
+            for tile_name in batch_names: 
+                pos = re.findall(r'\((.*?)\)', tile_name[0])
+                x, y = pos[0].split('_')
+                coords.append((int(x),int(y)))
+            return coords
+        
+        coords = get_coords(batch_names)
+        # temp_data = data.cpu()
+        # print(data.shape)
+        wsi = self.assemble(data, coords).cpu().numpy()
+        # wsi = (wsi-wsi.min())/(wsi.max()-wsi.min())
+        # wsi = wsi
+
+        #--> Get interpolated mask from GradCam
+        W, H = wsi.shape[0], wsi.shape[1]
+        
+        
+        attention_map = grayscale_cam[:, :, 1].squeeze()
+        attention_map = F.relu(attention_map)
+        # print(attention_map)
+        input_h = 256
+        
+        mask = torch.ones(( int(W/input_h), int(H/input_h))).to(self.device)
+
+        for i, (x,y) in enumerate(coords):
+            mask[y][x] = attention_map[i]
+        mask = mask.unsqueeze(0).unsqueeze(0)
+        # mask = torch.stack([mask, mask, mask]).unsqueeze(0)
+
+        mask = F.interpolate(mask, (W,H), mode='bilinear')
+        mask = mask.squeeze(0).permute(1,2,0)
+
+        mask = (mask - mask.min())/(mask.max()-mask.min())
+        mask = mask.cpu().numpy()
+        
+        def show_cam_on_image(img, mask):
+            heatmap = cv2.applyColorMap(np.uint8(255 * mask), cv2.COLORMAP_JET)
+            heatmap = np.float32(heatmap) / 255
+            cam = heatmap*0.4 + np.float32(img)
+            cam = cam / np.max(cam)
+            return cam
+
+        wsi_cam = show_cam_on_image(wsi, mask)
+        wsi_cam = ((wsi_cam-wsi_cam.min())/(wsi_cam.max()-wsi_cam.min()) * 255.0).astype(np.uint8)
+        
+        img = Image.fromarray(wsi_cam)
+        img = img.convert('RGB')
+        output_path = self.save_path / str(target.item())
+        output_path.mkdir(parents=True, exist_ok=True)
+        img.save(f'{output_path}/{wsi_name}_gradcam.jpg')
+
+        wsi = ((wsi-wsi.min())/(wsi.max()-wsi.min()) * 255.0).astype(np.uint8)
+        img = Image.fromarray(wsi)
+        img = img.convert('RGB')
+        output_path = self.save_path / str(target.item())
+        output_path.mkdir(parents=True, exist_ok=True)
+        img.save(f'{output_path}/{wsi_name}.jpg')
+
+
+    def assemble(self, tiles, coords): # with coordinates (x-y)
+        
+        def getPosition(img_name):
+            pos = re.findall(r'\((.*?)\)', img_name) #get strings in brackets (0-0)
+            a = int(pos[0].split('-')[0])
+            b = int(pos[0].split('-')[1])
+            return a, b
+
+        position_dict = {}
+        assembled = []
+        # for tile in self.predictions:
+        count = 0
+        # max_x = max(coords, key = lambda t: t[0])[0]
+        d = tiles[0,:,:,:].permute(1,2,0).shape
+        print(d)
+        white_value = 0
+        x_max = max([x[0] for x in coords])
+        y_max = max([x[1] for x in coords])
+
+        for i, (x,y) in enumerate(coords):
+
+            # name = n[0]
+            # image = tiles[i,:,:,:].permute(1,2,0)
+            
+            # d = image.shape
+            # print(image.min())
+            # print(image.max())
+            # if image.max() > white_value:
+            #     white_value = image.max()
+            # # print(image.shape)
+            
+            # tile_position = '-'.join(name.split('_')[-2:])
+            # x,y = getPosition(tile_position)
+            
+            # y_max = y if y > y_max else y_max
+            if x not in position_dict.keys():
+                position_dict[x] = [(y, i)]
+            else: position_dict[x].append((y, i))
+            # count += 1
+        print(position_dict.keys())
+        x_positions = sorted(position_dict.keys())
+        # print(x_max)
+        # complete_image = torch.zeros([x_max, y_max, 3])
+
+
+        for i in range(x_max+1):
+
+            # if i in position_dict.keys():
+            #     print(i)
+            column = [None]*(int(y_max+1))
+            # if len(d) == 3:
+            # empty_tile = torch.zeros(d).to(self.device)
+            # else:
+            # empty_tile = torch.ones(d)
+            empty_tile = torch.ones(d).to(self.device)
+            # print(i)
+            if i in position_dict.keys():
+                # print(i)
+                for j in position_dict[i]:
+                    print(j)
+                    sample_idx = j[1]
+                    print(sample_idx)
+                    # img = tiles[sample_idx, :, :, :].permute(1,2,0)
+                    column[int(j[0])] = tiles[sample_idx, :, :, :]
+            column = [empty_tile if i is None else i for i in column]
+            print(column)
+            # for c in column:
+            #     print(c.shape)
+            # column = torch.vstack(column)
+            # print(column)
+            column = torch.stack(column)
+            assembled.append((i, column))
+        
+        assembled = sorted(assembled, key=lambda x: x[0])
+
+        stack = [i[1] for i in assembled]
+        # print(stack)
+        img_compl = torch.hstack(stack)
+        print(img_compl)
+        return img_compl
+
+
+#---->main
+def main(cfg):
+
+    torch.set_num_threads(16)
+
+    #---->Initialize seed
+    pl.seed_everything(cfg.General.seed)
+
+    #---->load loggers
+    # cfg.load_loggers = load_loggers(cfg)
+
+    # print(cfg.load_loggers)
+    # save_path = Path(cfg.load_loggers[0].log_dir) 
+
+    #---->load callbacks
+    # cfg.callbacks = load_callbacks(cfg, save_path)
+
+    home = Path.cwd().parts[1]
+    cfg.Data.label_file = '/home/ylan/DeepGraft/training_tables/split_PAS_tcmr_viral.json'
+    cfg.Data.data_dir = '/home/ylan/data/DeepGraft/224_128um/'
+    DataInterface_dict = {
+                'data_root': cfg.Data.data_dir,
+                'label_path': cfg.Data.label_file,
+                'batch_size': cfg.Data.train_dataloader.batch_size,
+                'num_workers': cfg.Data.train_dataloader.num_workers,
+                'n_classes': cfg.Model.n_classes,
+                'backbone': cfg.Model.backbone,
+                'bag_size': cfg.Data.bag_size,
+                }
+
+    dm = MILDataModule(**DataInterface_dict)
+    
+
+    #---->Define Model
+    ModelInterface_dict = {'model': cfg.Model,
+                            'loss': cfg.Loss,
+                            'optimizer': cfg.Optimizer,
+                            'data': cfg.Data,
+                            'log': cfg.log_path,
+                            'backbone': cfg.Model.backbone,
+                            }
+    # model = ModelInterface(**ModelInterface_dict)
+    model = custom_test_module(**ModelInterface_dict)
+    # model.save_path = cfg.log_path
+    #---->Instantiate Trainer
+    
+    trainer = Trainer(
+        num_sanity_val_steps=0, 
+        # logger=cfg.load_loggers,
+        # callbacks=cfg.callbacks,
+        max_epochs= cfg.General.epochs,
+        min_epochs = 200,
+        gpus=cfg.General.gpus,
+        # gpus = [0,2],
+        # strategy='ddp',
+        amp_backend='native',
+        # amp_level=cfg.General.amp_level,  
+        precision=cfg.General.precision,  
+        accumulate_grad_batches=cfg.General.grad_acc,
+        # fast_dev_run = True,
+        
+        # deterministic=True,
+        check_val_every_n_epoch=10,
+    )
+
+    #---->train or test
+    log_path = Path(cfg.log_path) / 'checkpoints'
+    # print(log_path)
+    # log_path = Path('lightning_logs/2/checkpoints')
+    model_paths = list(log_path.glob('*.ckpt'))
+
+    if cfg.epoch == 'last':
+        model_paths = [str(model_path) for model_path in model_paths if f'last' in str(model_path)]
+    else:
+        model_paths = [str(model_path) for model_path in model_paths if f'epoch={cfg.epoch}' in str(model_path)]
+
+    # model_paths = [str(model_path) for model_path in model_paths if f'epoch={cfg.epoch}' in str(model_path)]
+    # model_paths = [f'lightning_logs/0/.ckpt']
+    # model_paths = [f'{log_path}/last.ckpt']
+    if not model_paths: 
+        print('No Checkpoints vailable!')
+    for path in model_paths:
+        # with open(f'{log_path}/test_metrics.txt', 'w') as f:
+        #     f.write(str(path) + '\n')
+        print(path)
+        new_model = model.load_from_checkpoint(checkpoint_path=path, cfg=cfg)
+        new_model.save_path = Path(cfg.log_path) / 'visualization'
+        trainer.test(model=new_model, datamodule=dm)
+    
+    # Top 5 scoring patches for patient
+    # GradCam
+
+
+if __name__ == '__main__':
+
+    args = make_parse()
+    cfg = read_yaml(args.config)
+
+    #---->update
+    cfg.config = args.config
+    cfg.General.gpus = [args.gpus]
+    cfg.General.server = args.stage
+    cfg.Data.fold = args.fold
+    cfg.Loss.base_loss = args.loss
+    cfg.Data.bag_size = args.bag_size
+    cfg.version = args.version
+    cfg.epoch = args.epoch
+
+    config_path = '/'.join(Path(cfg.config).parts[1:])
+    log_path = Path(cfg.General.log_path) / str(Path(config_path).parent)
+
+    Path(cfg.General.log_path).mkdir(exist_ok=True, parents=True)
+    log_name =  f'_{cfg.Model.backbone}' + f'_{cfg.Loss.base_loss}'
+    task = '_'.join(Path(cfg.config).name[:-5].split('_')[2:])
+    # task = Path(cfg.config).name[:-5].split('_')[2:][0]
+    cfg.log_path = log_path / f'{cfg.Model.name}' / task / log_name / 'lightning_logs' / f'version_{cfg.version}' 
+    
+    
+
+    #---->main
+    main(cfg)
+ 
\ No newline at end of file
diff --git a/train.py b/code/train.py
similarity index 85%
rename from train.py
rename to code/train.py
index 5e30394..ddd37e4 100644
--- a/train.py
+++ b/code/train.py
@@ -7,6 +7,7 @@ from sklearn.model_selection import KFold
 
 from datasets.data_interface import DataInterface, MILDataModule, CrossVal_MILDataModule
 from models.model_interface import ModelInterface
+from models.model_interface_dtfd import ModelInterface_DTFD
 import models.vision_transformer as vits
 from utils.utils import *
 
@@ -80,11 +81,14 @@ def main(cfg):
                             'log': cfg.log_path,
                             'backbone': cfg.Model.backbone,
                             }
-    model = ModelInterface(**ModelInterface_dict)
+    if cfg.Model.name == 'DTFDMIL':
+        model = ModelInterface_DTFD(**ModelInterface_dict)
+    else:
+        model = ModelInterface(**ModelInterface_dict)
     
     #---->Instantiate Trainer
     trainer = Trainer(
-        num_sanity_val_steps=0, 
+        # num_sanity_val_steps=0, 
         logger=cfg.load_loggers,
         callbacks=cfg.callbacks,
         max_epochs= cfg.General.epochs,
@@ -96,11 +100,25 @@ def main(cfg):
         # amp_level=cfg.General.amp_level,  
         precision=cfg.General.precision,  
         accumulate_grad_batches=cfg.General.grad_acc,
+        gradient_clip_val=0.0,
         # fast_dev_run = True,
+        # limit_train_batches=1,
         
         # deterministic=True,
-        check_val_every_n_epoch=10,
+        check_val_every_n_epoch=5,
     )
+    # print(cfg.log_path)
+    # print(trainer.loggers[0].log_dir)
+    # print(trainer.loggers[1].log_dir)
+    #----> Copy Code
+    copy_path = Path(trainer.loggers[0].log_dir) / 'code'
+    copy_path.mkdir(parents=True, exist_ok=True)
+    copy_origin = '/' / Path('/'.join(cfg.log_path.parts[1:5])) / 'code'
+    # print(copy_origin)
+    shutil.copytree(copy_origin, copy_path, dirs_exist_ok=True)
+
+    
+    # print(trainer.loggers[0].log_dir)
 
     #---->train or test
     if cfg.resume_training:
@@ -148,7 +166,11 @@ if __name__ == '__main__':
     cfg.Data.bag_size = args.bag_size
     cfg.version = args.version
 
-    log_path = Path(cfg.General.log_path) / str(Path(cfg.config).parent)
+    config_path = '/'.join(Path(cfg.config).parts[1:])
+    log_path = Path(cfg.General.log_path) / str(Path(config_path).parent)
+    # print(log_path)
+
+
     Path(cfg.General.log_path).mkdir(exist_ok=True, parents=True)
     log_name =  f'_{cfg.Model.backbone}' + f'_{cfg.Loss.base_loss}'
     task = '_'.join(Path(cfg.config).name[:-5].split('_')[2:])
diff --git a/code/train_loop.py b/code/train_loop.py
new file mode 100644
index 0000000..d198abd
--- /dev/null
+++ b/code/train_loop.py
@@ -0,0 +1,496 @@
+from pytorch_lightning import LightningModule
+import torch
+import torch.nn.functional as F
+from torchmetrics.classification.accuracy import Accuracy
+import os.path as osp
+from abc import ABC, abstractmethod
+from copy import deepcopy
+from pytorch_lightning import LightningModule
+from pytorch_lightning.loops.base import Loop
+from pytorch_lightning.loops.fit_loop import FitLoop
+from pytorch_lightning.trainer.states import TrainerFn
+from datasets.data_interface import BaseKFoldDataModule
+from typing import Any, Dict, List, Optional, Type
+import torchmetrics
+import numpy as np
+from PIL import Image
+import cv2
+import re
+
+import pandas as pd
+import matplotlib.pyplot as plt
+import seaborn as sns
+from test_visualize import custom_test_module
+from pytorch_grad_cam import GradCAM, EigenGradCAM
+from pytorch_grad_cam.utils.image import show_cam_on_image
+from pytorch_grad_cam.utils.model_targets import ClassifierOutputTarget
+from pathlib import Path
+
+
+
+class EnsembleVotingModel(LightningModule):
+    def __init__(self, model_cls: Type[LightningModule], checkpoint_paths: List[str], n_classes, log_path) -> None:
+        super().__init__()
+        # Create `num_folds` models with their associated fold weights
+        self.n_classes = n_classes
+        self.log_path = log_path
+        self.data = [{"count": 0, "correct": 0} for i in range(self.n_classes)]
+        self.models = torch.nn.ModuleList([model_cls.load_from_checkpoint(p) for p in checkpoint_paths])
+        self.test_acc = Accuracy()
+        if self.n_classes > 2: 
+            self.AUROC = torchmetrics.AUROC(num_classes = self.n_classes, average = 'weighted')
+            metrics = torchmetrics.MetricCollection([torchmetrics.Accuracy(num_classes = self.n_classes,
+                                                                           average='micro'),
+                                                     torchmetrics.CohenKappa(num_classes = self.n_classes),
+                                                     torchmetrics.F1Score(num_classes = self.n_classes,
+                                                                     average = 'macro'),
+                                                     torchmetrics.Recall(average = 'macro',
+                                                                         num_classes = self.n_classes),
+                                                     torchmetrics.Precision(average = 'macro',
+                                                                            num_classes = self.n_classes),
+                                                     torchmetrics.Specificity(average = 'macro',
+                                                                            num_classes = self.n_classes)])
+                                                                            
+        else : 
+            self.AUROC = torchmetrics.AUROC(num_classes=2, average = 'weighted')
+            metrics = torchmetrics.MetricCollection([torchmetrics.Accuracy(num_classes = 2,
+                                                                           average = 'micro'),
+                                                     torchmetrics.CohenKappa(num_classes = 2),
+                                                     torchmetrics.F1Score(num_classes = 2,
+                                                                     average = 'macro'),
+                                                     torchmetrics.Recall(average = 'macro',
+                                                                         num_classes = 2),
+                                                     torchmetrics.Precision(average = 'macro',
+                                                                            num_classes = 2)])
+        self.test_metrics = metrics.clone(prefix = 'test_')
+        self.confusion_matrix = torchmetrics.ConfusionMatrix(num_classes = self.n_classes)
+    def test_step(self, batch, batch_idx):
+
+        torch.set_grad_enabled(True)
+        data, label, (wsi_name, batch_names) = batch
+        wsi_name = wsi_name[0]
+        label = label.float()
+        # logits, Y_prob, Y_hat = self.step(data) 
+        # print(data.shape)
+        data = data.squeeze(0).float()
+        logits, attn = self(data)
+        attn = attn.detach()
+        logits = logits.detach()
+
+        Y = torch.argmax(label)
+        Y_hat = torch.argmax(logits, dim=1)
+        Y_prob = F.softmax(logits, dim = 1)
+        
+        #----> Get GradCam maps, map each instance to attention value, assemble, overlay on original WSI 
+        if self.model_name == 'TransMIL':
+           
+            target_layers = [self.model.layer2.norm] # 32x32
+            # target_layers = [self.model_ft[0].features[-1]] # 32x32
+            self.cam = GradCAM(model=self.model, target_layers = target_layers, use_cuda=True, reshape_transform=self.reshape_transform) #, reshape_transform=self.reshape_transform
+            # self.cam_ft = GradCAM(model=self.model, target_layers = target_layers_ft, use_cuda=True) #, reshape_transform=self.reshape_transform
+        else:
+            target_layers = [self.model.attention_weights]
+            self.cam = GradCAM(model = self.model, target_layers = target_layers, use_cuda=True)
+
+
+        data_ft = self.model_ft(data).unsqueeze(0).float()
+        instance_count = data.size(0)
+        target = [ClassifierOutputTarget(Y)]
+        grayscale_cam = self.cam(input_tensor=data_ft, targets=target)
+        grayscale_cam = torch.Tensor(grayscale_cam)[:instance_count, :] #.to(self.device)
+
+        #----------------------------------------------------
+        # Get Topk Tiles and Topk Patients
+        #----------------------------------------------------
+        summed = torch.mean(grayscale_cam, dim=2)
+        topk_tiles, topk_indices = torch.topk(summed.squeeze(0), 5, dim=0)
+        topk_data = data[topk_indices].detach()
+        
+        #----------------------------------------------------
+        # Log Correct/Count
+        #----------------------------------------------------
+        Y = torch.argmax(label)
+        self.data[Y]["count"] += 1
+        self.data[Y]["correct"] += (Y_hat.item() == Y)
+
+        #----------------------------------------------------
+        # Tile Level Attention Maps
+        #----------------------------------------------------
+
+        # self.save_attention_map(wsi_name, data, batch_names, grayscale_cam, Y)
+
+        return {'logits' : logits, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : Y, 'name': wsi_name, 'topk_data': topk_data} #
+        # return {'logits' : logits, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : label, 'name': name} #, 'topk_data': topk_data
+
+    def test_epoch_end(self, output_results):
+
+        logits = torch.cat([x['logits'] for x in output_results], dim = 0)
+        probs = torch.cat([x['Y_prob'] for x in output_results])
+        max_probs = torch.stack([x['Y_hat'] for x in output_results])
+        # target = torch.stack([x['label'] for x in output_results], dim = 0)
+        target = torch.stack([x['label'] for x in output_results])
+        # target = torch.argmax(target, dim=1)
+        patients = [x['name'] for x in output_results]
+        topk_tiles = [x['topk_data'] for x in output_results]
+        #---->
+        
+
+
+        auc = self.AUROC(probs, target)
+        metrics = self.test_metrics(logits , target)
+
+
+        # metrics = self.test_metrics(max_probs.squeeze() , torch.argmax(target.squeeze(), dim=1))
+        metrics['test_auc'] = auc
+
+        # self.log('auc', auc, prog_bar=True, on_epoch=True, logger=True)
+
+        #---->get highest scoring patients for each class
+        # test_path = Path(self.save_path) / 'most_predictive' 
+        
+        # Path.mkdir(output_path, exist_ok=True)
+        topk, topk_indices = torch.topk(probs.squeeze(0), 5, dim=0)
+        for n in range(self.n_classes):
+            print('class: ', n)
+            
+            topk_patients = [patients[i[n]] for i in topk_indices]
+            topk_patient_tiles = [topk_tiles[i[n]] for i in topk_indices]
+            for x, p, t in zip(topk, topk_patients, topk_patient_tiles):
+                print(p, x[n])
+                patient = p
+                # outpath = test_path / str(n) / patient 
+                outpath = Path(self.save_path) / str(n) / patient
+                outpath.mkdir(parents=True, exist_ok=True)
+                for i in range(len(t)):
+                    tile = t[i]
+                    tile = tile.cpu().numpy().transpose(1,2,0)
+                    tile = (tile - tile.min())/ (tile.max() - tile.min()) * 255
+                    tile = tile.astype(np.uint8)
+                    img = Image.fromarray(tile)
+                    
+                    img.save(f'{outpath}/{i}.jpg')
+
+        for keys, values in metrics.items():
+            print(f'{keys} = {values}')
+            metrics[keys] = values.cpu().numpy()
+        #---->acc log
+        for c in range(self.n_classes):
+            count = self.data[c]["count"]
+            correct = self.data[c]["correct"]
+            if count == 0: 
+                acc = None
+            else:
+                acc = float(correct) / count
+            print('class {}: acc {}, correct {}/{}'.format(c, acc, correct, count))
+        self.data = [{"count": 0, "correct": 0} for i in range(self.n_classes)]
+
+
+        # self.log_roc_curve(probs, target, 'test')
+        self.log_confusion_matrix(max_probs, target, stage='test')
+        #---->
+        result = pd.DataFrame([metrics])
+        result.to_csv(Path(self.save_path) / f'test_result.csv', mode='a', header=not Path(self.save_path).exists())
+
+    def save_attention_map(self, wsi_name, data, batch_names, grayscale_cam, target):
+
+        def get_coords(batch_names): #ToDO: Change function for precise coords
+            coords = []
+            
+            for tile_name in batch_names: 
+                pos = re.findall(r'\((.*?)\)', tile_name[0])
+                x, y = pos[0].split('_')
+
+                coords.append((int(x),int(y)))
+            return coords
+
+        
+        coords = get_coords(batch_names)
+        # temp_data = data.cpu()
+        print(data.shape)
+        wsi = self.assemble(data, coords).cpu().numpy()
+        wsi = (wsi-wsi.min())/(wsi.max()-wsi.min())
+        # wsi = wsi
+
+        #--> Get interpolated mask from GradCam
+        W, H = wsi.shape[0], wsi.shape[1]
+        
+        
+        attention_map = grayscale_cam[:, :, 1].squeeze()
+        attention_map = F.relu(attention_map)
+        # print(attention_map)
+        input_h = 256
+        
+        mask = torch.ones(( int(W/input_h), int(H/input_h))).to(self.device)
+
+        for i, (x,y) in enumerate(coords):
+            mask[y][x] = attention_map[i]
+        mask = mask.unsqueeze(0).unsqueeze(0)
+        # mask = torch.stack([mask, mask, mask]).unsqueeze(0)
+
+        mask = F.interpolate(mask, (W,H), mode='bilinear')
+        mask = mask.squeeze(0).permute(1,2,0)
+
+        mask = (mask - mask.min())/(mask.max()-mask.min())
+        mask = mask.cpu().numpy()
+        
+        def show_cam_on_image(img, mask):
+            heatmap = cv2.applyColorMap(np.uint8(255 * mask), cv2.COLORMAP_JET)
+            heatmap = np.float32(heatmap) / 255
+            cam = heatmap*0.4 + np.float32(img)
+            cam = cam / np.max(cam)
+            return cam
+
+        wsi_cam = show_cam_on_image(wsi, mask)
+        wsi_cam = ((wsi_cam-wsi_cam.min())/(wsi_cam.max()-wsi_cam.min()) * 255.0).astype(np.uint8)
+        
+        img = Image.fromarray(wsi_cam)
+        img = img.convert('RGB')
+        output_path = self.save_path / str(target)
+        output_path.mkdir(parents=True, exist_ok=True)
+        img.save(f'{output_path}/{wsi_name}_gradcam.jpg')
+
+        wsi = ((wsi-wsi.min())/(wsi.max()-wsi.min()) * 255.0).astype(np.uint8)
+        img = Image.fromarray(wsi)
+        img = img.convert('RGB')
+        output_path = self.save_path / str(target)
+        output_path.mkdir(parents=True, exist_ok=True)
+        img.save(f'{output_path}/{wsi_name}.jpg')
+
+
+    def assemble(self, tiles, coords): # with coordinates (x-y)
+        
+        def getPosition(img_name):
+            pos = re.findall(r'\((.*?)\)', img_name) #get strings in brackets (0-0)
+            a = int(pos[0].split('-')[0])
+            b = int(pos[0].split('-')[1])
+            return a, b
+
+        position_dict = {}
+        assembled = []
+        y_max = 0
+        # for tile in self.predictions:
+        count = 0
+        max_x = max(coords, key = lambda t: t[0])[0]
+        d = 0
+        white_value = 0
+
+        for i, (x,y) in enumerate(coords):
+
+            # name = n[0]
+            image = tiles[i,:,:,:].permute(1,2,0)
+            
+            d = image.shape
+            # print(image.min())
+            # print(image.max())
+            # if image.max() > white_value:
+            #     white_value = image.max()
+            # # print(image.shape)
+            
+            # tile_position = '-'.join(name.split('_')[-2:])
+            # x,y = getPosition(tile_position)
+            
+            y_max = y if y > y_max else y_max
+            if x not in position_dict.keys():
+                position_dict[x] = [(y, image)]
+            else: position_dict[x].append((y, image))
+            count += 1
+        
+
+        for i in range(max_x+1):
+            column = [None]*(int(y_max+1))
+            # if len(d) == 3:
+            #     empty_tile = torch.zeros(d).to(self.device)
+            # else:
+            empty_tile = torch.ones(d)
+            empty_tile = torch.ones(d).to(self.device)
+            if i in position_dict.keys():
+                for j in position_dict[i]:
+                    sample = j[1]
+                    column[int(j[0])] = sample
+            column = [empty_tile if i is None else i for i in column]
+            # for c in column:
+            #     print(c.shape)
+            # column = torch.vstack(column)
+            column = torch.stack(column)
+            assembled.append((i, column))
+
+
+
+        # for key in position_dict.keys():
+        #     column = [None]*(int(y_max+1))
+        #     # print(key)
+        #     for i in position_dict[key]:
+        #         sample = i[1]
+        #         d = sample.shape
+        #         # print(d) # [3,256,256]
+        #         if len(d) == 3:
+        #             empty_tile = torch.ones(d).to(self.device)
+        #         else:
+        #             empty_tile = torch.zeros(d).to(self.device)
+        #         column[int(i[0])] = sample
+        #     column = [empty_tile if i is None else i for i in column]
+        #     column = torch.vstack(column)
+        #     assembled.append((key, column))
+        # print(len(assembled))
+        
+        assembled = sorted(assembled, key=lambda x: x[0])
+
+        stack = [i[1] for i in assembled]
+        # print(stack)
+        img_compl = torch.hstack(stack)
+        return img_compl
+    # def test_step(self, batch: Any, batch_idx: int, dataloader_idx: int = 0) -> None:
+    #     # Compute the averaged predictions over the `num_folds` models.
+    #     # print(batch[0].shape)
+    #     input, label, _ = batch
+    #     label = label.float()
+    #     input = input.squeeze(0).float()
+
+            
+    #     logits = torch.stack([m(input) for m in self.models]).mean(0)
+    #     Y_hat = torch.argmax(logits, dim=1)
+    #     Y_prob = F.softmax(logits, dim = 1)
+    #     # #---->acc log
+    #     Y = torch.argmax(label)
+    #     self.data[Y]["count"] += 1
+    #     self.data[Y]["correct"] += (Y_hat.item() == Y)
+
+    #     return {'logits' : logits, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : label}
+
+    # def test_epoch_end(self, output_results):
+    #     probs = torch.cat([x['Y_prob'] for x in output_results])
+    #     max_probs = torch.stack([x['Y_hat'] for x in output_results])
+    #     # target = torch.stack([x['label'] for x in output_results], dim = 0)
+    #     target = torch.cat([x['label'] for x in output_results])
+    #     target = torch.argmax(target, dim=1)
+        
+    #     #---->
+    #     auc = self.AUROC(probs, target.squeeze())
+    #     metrics = self.test_metrics(max_probs.squeeze() , target)
+
+
+    #     # metrics = self.test_metrics(max_probs.squeeze() , torch.argmax(target.squeeze(), dim=1))
+    #     metrics['test_auc'] = auc
+
+    #     # self.log('auc', auc, prog_bar=True, on_epoch=True, logger=True)
+
+    #     # print(max_probs.squeeze(0).shape)
+    #     # print(target.shape)
+    #     # self.log_dict(metrics, logger = True)
+    #     for keys, values in metrics.items():
+    #         print(f'{keys} = {values}')
+    #         metrics[keys] = values.cpu().numpy()
+    #     #---->acc log
+    #     for c in range(self.n_classes):
+    #         count = self.data[c]["count"]
+    #         correct = self.data[c]["correct"]
+    #         if count == 0: 
+    #             acc = None
+    #         else:
+    #             acc = float(correct) / count
+    #         print('class {}: acc {}, correct {}/{}'.format(c, acc, correct, count))
+    #     self.data = [{"count": 0, "correct": 0} for i in range(self.n_classes)]
+
+    #     self.log_confusion_matrix(probs, target, stage='test')
+    #     #---->
+    #     result = pd.DataFrame([metrics])
+    #     result.to_csv(self.log_path / 'result.csv')
+
+
+    def log_confusion_matrix(self, max_probs, target, stage):
+            confmat = self.confusion_matrix(max_probs.squeeze(), target)
+            df_cm = pd.DataFrame(confmat.cpu().numpy(), index=range(self.n_classes), columns=range(self.n_classes))
+            plt.figure()
+            fig_ = sns.heatmap(df_cm, annot=True, cmap='Spectral').get_figure()
+            # plt.close(fig_)
+            # plt.savefig(f'{self.log_path}/cm_e{self.current_epoch}')
+            self.loggers[0].experiment.add_figure(f'{stage}/Confusion matrix', fig_, self.current_epoch)
+
+            if stage == 'test':
+                plt.savefig(f'{self.log_path}/cm_test')
+            plt.close(fig_)
+
+class KFoldLoop(Loop):
+    def __init__(self, num_folds: int, export_path: str, **kargs) -> None:
+        super().__init__()
+        self.num_folds = num_folds
+        self.current_fold: int = 0
+        self.export_path = export_path
+        self.n_classes = kargs["model"].n_classes
+        self.log_path = kargs["log"]
+
+    @property
+    def done(self) -> bool:
+        return self.current_fold >= self.num_folds
+
+    def connect(self, fit_loop: FitLoop) -> None:
+        self.fit_loop = fit_loop
+
+    def reset(self) -> None:
+        """Nothing to reset in this loop."""
+
+    def on_run_start(self, *args: Any, **kwargs: Any) -> None:
+        """Used to call `setup_folds` from the `BaseKFoldDataModule` instance and store the original weights of the
+        model."""
+        assert isinstance(self.trainer.datamodule, BaseKFoldDataModule)
+        self.trainer.datamodule.setup_folds(self.num_folds)
+        self.lightning_module_state_dict = deepcopy(self.trainer.lightning_module.state_dict())
+
+    def on_advance_start(self, *args: Any, **kwargs: Any) -> None:
+        """Used to call `setup_fold_index` from the `BaseKFoldDataModule` instance."""
+        print(f"STARTING FOLD {self.current_fold}")
+        assert isinstance(self.trainer.datamodule, BaseKFoldDataModule)
+        self.trainer.datamodule.setup_fold_index(self.current_fold)
+
+    def advance(self, *args: Any, **kwargs: Any) -> None:
+        """Used to the run a fitting and testing on the current hold."""
+        self._reset_fitting()  # requires to reset the tracking stage.
+        self.fit_loop.run()
+
+        self._reset_testing()  # requires to reset the tracking stage.
+        self.trainer.test_loop.run()
+        self.current_fold += 1  # increment fold tracking number.
+
+    def on_advance_end(self) -> None:
+        """Used to save the weights of the current fold and reset the LightningModule and its optimizers."""
+        self.trainer.save_checkpoint(osp.join(self.export_path, f"model.{self.current_fold}.pt"))
+        # restore the original weights + optimizers and schedulers.
+        self.trainer.lightning_module.load_state_dict(self.lightning_module_state_dict)
+        self.trainer.strategy.setup_optimizers(self.trainer)
+        self.replace(fit_loop=FitLoop)
+
+    def on_run_end(self) -> None:
+        """Used to compute the performance of the ensemble model on the test set."""
+        checkpoint_paths = [osp.join(self.export_path, f"model.{f_idx + 1}.pt") for f_idx in range(self.num_folds)]
+        voting_model = EnsembleVotingModel(type(self.trainer.lightning_module), checkpoint_paths, n_classes=self.n_classes, log_path=self.log_path)
+        voting_model.trainer = self.trainer
+        # This requires to connect the new model and move it the right device.
+        self.trainer.strategy.connect(voting_model)
+        self.trainer.strategy.model_to_device()
+        self.trainer.test_loop.run()
+
+    def on_save_checkpoint(self) -> Dict[str, int]:
+        return {"current_fold": self.current_fold}
+
+    def on_load_checkpoint(self, state_dict: Dict) -> None:
+        self.current_fold = state_dict["current_fold"]
+
+    def _reset_fitting(self) -> None:
+        self.trainer.reset_train_dataloader()
+        self.trainer.reset_val_dataloader()
+        self.trainer.state.fn = TrainerFn.FITTING
+        self.trainer.training = True
+
+    def _reset_testing(self) -> None:
+        self.trainer.reset_test_dataloader()
+        self.trainer.state.fn = TrainerFn.TESTING
+        self.trainer.testing = True
+
+    def __getattr__(self, key) -> Any:
+        # requires to be overridden as attributes of the wrapped loop are being accessed.
+        if key not in self.__dict__:
+            return getattr(self.fit_loop, key)
+        return self.__dict__[key]
+
+    def __setstate__(self, state: Dict[str, Any]) -> None:
+        self.__dict__.update(state)
\ No newline at end of file
diff --git a/utils/__init__.py b/code/utils/__init__.py
similarity index 100%
rename from utils/__init__.py
rename to code/utils/__init__.py
diff --git a/utils/__pycache__/__init__.cpython-39.pyc b/code/utils/__pycache__/__init__.cpython-39.pyc
similarity index 100%
rename from utils/__pycache__/__init__.cpython-39.pyc
rename to code/utils/__pycache__/__init__.cpython-39.pyc
diff --git a/code/utils/__pycache__/utils.cpython-39.pyc b/code/utils/__pycache__/utils.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4e86955d7bdf2df00f04cb9e61d452bc3f04da04
GIT binary patch
literal 4080
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
S7;`WRF>-JSFv8(4HckK>e@@^4

literal 0
HcmV?d00001

diff --git a/code/utils/extract_features.py b/code/utils/extract_features.py
new file mode 100644
index 0000000..9ec600e
--- /dev/null
+++ b/code/utils/extract_features.py
@@ -0,0 +1,37 @@
+## Choose Model and extract features from (augmented) image patches and save as .pt file
+
+# from datasets.custom_dataloader import HDF5MILDataloader
+from datasets import JPGMILDataloader
+from torchvision import models
+
+device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
+
+def extract_features(input_dir, output_dir, model, batch_size):
+
+    
+
+    dataset = JPGMILDataloader(data_root, label_path=label_path, mode='train', load_data=False, n_classes=n_classes)
+    model =  models.resnet50(pretrained=True)    
+    for param in self.model_ft.parameters():
+        param.requires_grad = False
+    self.model_ft.fc = nn.Linear(2048, self.out_features)
+
+    model = model.to(device)
+    model.eval()
+
+    
+
+
+
+
+if __name__ == '__main__':
+
+    # input_dir, output_dir
+    # initiate data loader
+    # use data loader to load and augment images 
+    # prediction from model
+    # choose save as bag or not (needed?)
+    
+    # features = torch.from_numpy(features)
+    # torch.save(features, output_path + '.pt') 
+
diff --git a/utils/utils.py b/code/utils/utils.py
similarity index 95%
rename from utils/utils.py
rename to code/utils/utils.py
index 814cf1d..7e992cf 100755
--- a/utils/utils.py
+++ b/code/utils/utils.py
@@ -15,6 +15,7 @@ from pytorch_lightning.loops.base import Loop
 from pytorch_lightning.loops.fit_loop import FitLoop
 from pytorch_lightning.trainer.states import TrainerFn
 from typing import Any, Dict, List, Optional, Type
+import shutil
 
 #---->read yaml
 import yaml
@@ -26,6 +27,7 @@ def read_yaml(fpath=None):
 
 #---->load Loggers
 from pytorch_lightning import loggers as pl_loggers
+
 def load_loggers(cfg):
 
     # log_path = cfg.General.log_path
@@ -40,9 +42,12 @@ def load_loggers(cfg):
         tb_logger = pl_loggers.TensorBoardLogger(cfg.log_path,
                                                   # version = f'fold{cfg.Data.fold}'
                                                 log_graph = True, default_hp_metric = False)
+        # print(tb_logger.version)
+        version = tb_logger.version
         #---->CSV
-        csv_logger = pl_loggers.CSVLogger(cfg.log_path,
+        csv_logger = pl_loggers.CSVLogger(cfg.log_path, version = version
                                         ) # version = f'fold{cfg.Data.fold}', 
+        # print(csv_logger.version)
     else:  
         cfg.log_path = Path(cfg.log_path) / f'test'
         tb_logger = pl_loggers.TensorBoardLogger(cfg.log_path,
@@ -98,7 +103,7 @@ def load_callbacks(cfg, save_path):
         # save_path = Path(cfg.log_path) / 'lightning_logs' / f'version_{cfg.resume_version}' / last.ckpt
         Mycallbacks.append(ModelCheckpoint(monitor = 'val_loss',
                                          dirpath = str(output_path),
-                                         filename = '{epoch:02d}-{val_loss:.4f}',
+                                         filename = '{epoch:02d}-{val_loss:.4f}-{val_auc: .4f}',
                                          verbose = True,
                                          save_last = True,
                                          save_top_k = 1,
@@ -106,7 +111,7 @@ def load_callbacks(cfg, save_path):
                                          save_weights_only = True))
         Mycallbacks.append(ModelCheckpoint(monitor = 'val_auc',
                                          dirpath = str(output_path),
-                                         filename = '{epoch:02d}-{val_auc:.4f}',
+                                         filename = '{epoch:02d}-{val_loss:.4f}-{val_auc:.4f}',
                                          verbose = True,
                                          save_last = True,
                                          save_top_k = 1,
diff --git a/datasets/__init__.py b/datasets/__init__.py
deleted file mode 100644
index e752eeb..0000000
--- a/datasets/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-
-from .data_interface import DataInterface
\ No newline at end of file
diff --git a/datasets/__pycache__/__init__.cpython-39.pyc b/datasets/__pycache__/__init__.cpython-39.pyc
deleted file mode 100644
index 13006df55083dc070f46953e4505bfef1ac8b198..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 193
zcmYe~<>g{vU|{gyJ10?#fq~&Mh=Yuo7#J8F7#J9e1sE6@QW#Pga~N_NqZk<(Qka4n
zG?`yAGB7Y`GT!2KNi0e9%qvMPN=r;m_0wd!#g~#;k{F)}6Dk53w34BSg@FM={4&zd
z$j?pHugpoz(=X32$}TQQOitAgDN4*M_Vx792Wc-(Eh*NIkI&4@EQycTE2zB1VUwGm
OQks)$2Quw5$ejTG`7km7

diff --git a/datasets/__pycache__/custom_jpg_dataloader.cpython-39.pyc b/datasets/__pycache__/custom_jpg_dataloader.cpython-39.pyc
deleted file mode 100644
index 20aefffd1a14afe3c499f646e9eb674810896281..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 11037
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

diff --git a/models/__pycache__/TransMIL.cpython-39.pyc b/models/__pycache__/TransMIL.cpython-39.pyc
deleted file mode 100644
index a329e23346d376b150c7ba792b8cd3593a128d95..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3233
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
XAyFYgAwv#EK1M!99!4%k4lo1&fCJ6U

diff --git a/models/__pycache__/model_interface.cpython-39.pyc b/models/__pycache__/model_interface.cpython-39.pyc
deleted file mode 100644
index e9d22d7ddccbb2a3d2ab59b98e066f9ac5d42285..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 14054
zcmYe~<>g{vU|@JOWkZs2C<DV|5C<8vFfcGUFfcF_w=ps>q%fo~<}gG-XvQceFrPV!
z8BDW8v4CmTC{{4d7R3&xIifgI7*d#WxN^CpxEVounR9q@d87EiY{ne^DE<_N6qX!;
zT)`+ouo!EOP_A&4FqqAjBa$l`B?@M<=ZNKsM~Q>k961uXl2MXiHfN4Ru2hs%u5^@i
zu1u5+Sd1}8HcA$3zg(_-lsr^SAy=M>fsr9sF-i$4q8z21!jQt1qmru{r3x0~&XLVk
zi&6u#8FSR5G*Wm{cyly!wW74ZVthH;xjIogU^ah_ZmwRG9+)kVqn~RKWsqwaWeDaA
z<{0G~M;YguM45p3LOG_nW>IEfws4Mlu0@mum@SfHnQIkg#mL~!kRqBQ*20h?ma36u
z-OL<i<Ia#Go+8o0kRp*PpJm(39A%fn7|ft4`4SXEewvK8SOOADGBg=)u@zJn<m8uV
zGTvhK%uP&B)nvRSkX)3SSdto_Ur>^nn^~1wq{(=T8!DEQUtFxocuP3BD8INkJ~gkT
zD8HaGz9hdW8DyBGV{v6}ZfZ$UX0lIyadB{FUV2WdPhwJPjwbUhDKH~AH$T55BQr1E
z8DxSh#DH63!TD(=A&EulsU;}l{9eT=$O0gj6qh8H#1|*$7o~z+!U}ffOGX9;22I9W
zoMo9M@x{4`IXNJ&<>sfP=71Ej6{QyErIu(i-4byuEy;IFO)M!bN_DL$DN0N($uGLa
z5tbR^3sS7fbc@}+C^5y^(f1aQYi4?C9+aoacuTN2BfmU8IWadrKQBHL8dhS?If=!^
znQ57+MgFBF1*K3=Xfod7@ky*qEdpy#%uNObJ2Ga5a*Ep+7#LC+q8L*cqL|tl(il@1
zQ<z#fqL@>dQ&?IUqF7Q`Q`lM<qF7VdQ#e`}qS#V6Q@C0fqS#ZoQ+Qe!qBv4`Q}|jK
zqBv9dQv_NVqPS87Q-oR=qPSCpQ$$)AqIgo|Qp8fkTNtBwQzTL(TNtAFQlwI(TNtAF
zQ)E(PTNt7Q+8J0Fq6C8(H05vcfdj!auOzi7EipMY8I*;g4rLHvU|`^7U|`?|WoZ@`
z28I%b62=;aW~K#93mF(0Y8VzULunQeUBX(!)XZ4J5YJY_T*DC0Uc;EhQNs|=QNmfn
zkj2r=$jDH`lENs-P{R<<Rl;4vkj2%^n8lOAB*~D%oXu3!RKkl8ZDy=xO<}2FO<}TO
zNMT*TSHrpxWHMI@TMBy%LkT~`L>C6IeF7j}3P(1}1jZtf62UAXFrPDptCy*UAzr9N
zaDi}%V3r72lp7>kBA6u#=JE70mI!8vf!VxJ8SxZeFrTlNsYEbK0);1u;H9%IWUOV&
z3jx`e!U2jSRNGQGQs8!_aHK$ON&&?l7uaO+6y6k$6u2!Ab~-D_)DpogDX<%OdO^OH
zE)mR<LE_8Suw}`CVjnCk59SG`2!MGCH7qGYk_=gjH4O1eDZ(`j@yazUDI(xdS4k1A
zVTf0S@KeOHnI<q6eJD{|pq?TQ4qc5BO*mU?0%P70s7i@!rU^_%c_rFeIw_JVQoW3|
z>?OQ4><e@kGBh)$Fr-MgGD$Mja+K(0>DO@dG1PL_a4s-d$l$^d%TvphB2&W^Z#aRe
z(4a(bfqo5ViQWRE6xoH0CB`Xo&5R{_3rs++%2Hj(RHC=QbRok+)*6O*knL_z+vUNw
zKPl19GK1RAUBX+#4YyqZ&32v|9xS%61KZAnWV<5NcBL8yknIauK=$TcfZD2@%`}0z
z$f3kM%OcA%MI}WQY&UZ)Zw)Vo>CA;7b4^mzASTuDW?98sgYDym`U#W{wem`!W~+nE
z-jX6y%Lh_bqL*cp!jz(sqM4%A%Uq(jz;+=+iC&gn3P%b@igqs(SY9JV2dBJo3YuRa
zW-R0c`KX35%RWUHY~zy}hAf9H$1JCG##;UoXArN3KSi>JA<HF2uNUNh*E~=<bI5W-
zRgt3K3(C>1DGb33ng)Kim~-;eUxLcBD3+4s+@dHh5E);VS(KRbi%~xrR5HWL5GDo&
z237_JhG0+`BF4bLkj_xU5X)B!N;eECjB}VKG8M7}GpuAP0_oCZy2YBDUz%5Pi#<8N
zs3<kLWF^B&rdv#U2Dcb9ixe0b7{J6YNBxZa+*JL_oWwl+^8BLg;)2BFRQ-^m#Jpl(
zPaj>E)YJm^qQtZkeMo%(q2e=PrJP<t<t;9ooXp~q<ow(MJ68q<hR+}eS81b`hI;Yw
znR%Hd@$q^#Ir+(nImLE*2wg8hUc1Fno|>7SQIeXX$#jc5uQWG48B{x@7T;n|EK4m)
zOi#VVnwyzil&{HHq{+a*aEmoJ5yWFE(gJw~EW}clm=h1Gyb6j^(=sb=v6iG3m&D&<
zNl7e81c%Bkj-<ro?4<m>)RzoQ44@h!GcUhN1XNxp<>zPXr)1{k>y~AfBpI6B;(*k9
zh87{3jJLQ7ic(985;OBsQ(pf6|Np;R5g(}1WGXTRS#AV!4^+LW!OOq@|Nqy7NWElW
zVPGh-0Lk;Drln;jXQt+r<fWEWsrZF?x_CP3g96wmHL)l!GcVn>A~ClhC$-oL+$6{-
zO^TAuE6YsDOpHg?8eg87l3JV^pJb2;N)NZ#iZemFUWza<FuVjM5Kujzom!NaniF4~
zSp{m8uoagSWu~OQ1i3Sc0~WcOEVo#}v3iTQ1l)Rv&jHoC#kV+0i&Nv1OH&eW2^OUm
zXCxM+#+QH+L|T4Pt|oI4s9jp*2=ccRC=A?hu@;vWq!txPf_%vVi|AV-#ffF9@fno`
zsYL~eMTxnoC8<Tlx43fh6I0^B))ujWG_ZhLMYlM?EfG+A=@w@mJmy&oiZb&`ZgGN5
zDo8BJC<3Px)`G;MlHyw|pk#N8B`ZHO?-pxOVqSV`kpaj=9&qqMT2jTgSRF%y{GD$J
z_<~zj&iOexsmUdo`FXcE9FvnvixQJ7Z*e*2XQbwNCl(YW-ePw%3<foiZm|WWCMV|P
z+~N!<N=?oz2I=4qE=Wzz1Vv&=<t-7oI7FdyX;E3~E#`nA=Ue>F`FUxjAT7R$B}JJP
zw*-=50`a*J5!U3K{Jhj#yk&_wnJMuwxAK6~E0h<-14_2>#Tlh(X*sF4*rALfIZ((O
zf<2mFS`wcIX^#~b34w(8(~9zQ;}MDVmLOC<J{8trD-s4N<N!xOd|F8nsBKbY3>Hhy
z$jnJ8O3k~)l$UplD>${VG&QdzGco5D7g7xJ7Nr)JW)`Iu$EO!1rrZ*AOi3&#$t+8C
zEK3i_&(ASRxy2HenOc5}%_lQ2HL>Uxi@U2&XptGn0#<O$++xlsO}fPbN(i^Oz?mG}
z1iZzRmVArNIX|xqWJFM^Pv|X9-^2=-nR$u1so<n{iw&Gijc&2z<rn1^fs%cZGstx2
z<iy-4!NighkfZbS;vwZpv8KQ+mg3Z$G_d9(4^ZfNf|RpnCl;j_-(o3A%`Lda4h?ij
zK(OcLr<CTT7Durbr4}1n+yW)I#9Xi+z(S@5MV1T<3{gU8ft#6^4$c@W8E<jMLsD^k
zJh+@KQUTcuDjxMf#rG3X8Og}U$ic|L$i=}1A{n_DMHmH`I2d`D#h7^*g_w94nf|jd
z@i20LX*Ncd|13;M<aZ8U0VXc692X-Sm_{OhvT+J92{7_8@-g!;vN3Wou`%*7@-Tu#
zco;>PSwQNUc^J7ESs0lZIT+a(c^KJ#bFuR=@i2*i#Qw9O%KqVC=VKIN<YDAu5(3FH
zvi;*=;bUZBWMSk3>xPhEbH20j@-Xr+NicIUR*B=N29iM;859U0466S?7!-@eQVa~B
z_Ao;Y<3h#-j46x@8Ectp7#1+qFf9ai!kGNP1-T}3Q7R}BIZN}33rkZ|s~~AZlewrG
zB+OWGixm_%#gM=US9hQoxW%59UsRr0l(G#J3*Z(ylK^9t7@8}giclO0Dp^4qz>c&5
zIg)V!1IT#`7#A|sGS)EEFg7#RGL<l8G1oAqFr_f}GSxDduw=2qc`P+dH7qsEY0SY4
znk*1+fNPPJjJKFmGIKTAZm~oCa*H)BCqJ>IC?Dh(w#1_J+{B7ojBdBsi}TY;auX{w
zSs~tJ&CDw(ExE;(lb@bhQhbXwGCm`*<Q7|Gd_hru61vw}ic3-pc7yy49(rKnW8`4s
zW8`D15=QeqNL?~0K0t8;!k}IYI|Bm)*z0{@ug5UgGS{-yvevLHU|7gd%TmLzfU$;o
zA!7`4En6*nEeANp*lJi7GSzaHFfU-KVOhvn%T>dW#ahE9$&kXx${@**!eq|C%wWR+
z7i9*Cmax@uG&9z4Wg}$SQ&?&^Q&_=}t(TRNp@y@Dy@sQPC53$sOE7~bhaaR+1XamJ
z@}P_c%H<&|nQw6v6y>MKCnXl$;>gd7Pc6t#&H#s2dTNm-3#2TV2vR=*6ws_W;LbKj
zQ5Q&P5{Lkq1CE8FZV(q-y)b9yl@x(esU|lx7LpQ6k~3~`f~ok-l!_uy7!^$inaLPm
z)DO}Lw*_qJEyhUn*x?1YE;94d<3YiH6ckOM0-b?{i;;s#fSHGri%E=8j!}fMN(L>u
zP&A?>SxyE91`b%f{b2z0Izc%qg{g(1h7r``1Lds}h6PM1%qU{aB@7D~Q&>>MSV|bO
zm}|g2>RzT=mJ$|FtTi*bFvR-RveqzUvDL6jGNiCeGSsrcc^r}qwd^%)DV(4_X$nIv
zM;=cJdkuRtV-1@$sF%Z$!nJ_2hP8&HhP{SuAq%KqTNskU4YC(uKDb{BGLtKXM~ne%
z){Pp5EN)O{0`=c}nHfPTh$n@=hG79ONOS?;LWYG*DFR?92ud&D*0zveGN@q;O3)w-
zDu6)w8Qh!(RU+x2<}^<&V+~^pgCqmAG0j*6jyX^PvXZGt2^5trAOa)+i9%4ZQl!ej
z!0-?xuExN?P-TiMhQJ9hJ~b}|TPv6>*MSl)#2xcN)?;zjBak@AS!9_HO2qih2UTT7
zAoIaxSy4O4I&c#OoDo4G{!1QQ$tzUXS}7zZCo5Ff>L@__Bns8F`qi}<E(4Xd;CR8^
z%_))vSp@d4BAf;0!XxAzNF3y{m!Jag7ArWTtYo~!T3nKto?68j0&36eCzd9M6io&-
zWck54{T6d_VhLDHayBH_2Y}4+0uiA64=EkIL7AHk)F4hQxy74YT2z#pR{||yL~`=e
z<I!7u;1Z)K2xLkp$TCiF*%2iQb`&hz$LE8G!HRFOf(r2BTb#Lx72vYG_!b+aiGGVQ
z8B*4PLiZMPVsbJhcHln0B?LDSp4#q%N)u3=FffTQiZF?Qngw9Y!N|tM!zjim#=^%a
zz*MD3Fx{e53!qR1#T2+&$Rny+C}CQ_46X`516eFJoLH&?h$y%!sNq<^x{#rU6J8at
zL5qDBaIw#dUhHeKpcl5F<g3XBi8643o)3xuL|M*~S(2Ko$pwy!qM0DMSs(&leizLK
zanVZfIUq4`fP)E8db`D625QJBf;tx90{lBD$oatK47dPi0T<s)RdQ%SjHV5x_y&b9
zy!h^61Qp*|kReWJ@eLa0>}9HD0vFe;pkfnVtb>YhrW7_5F&3~ob`&vIaIwys!jZz#
z%T&u+!cxNu3iD>h6pn1>qA8%FJcYA{VF7y$a}DbP4sgNBl>&m?pn^3IG!zILR^<VU
zaixGo!Mb=$IBS?{Seu#9WVmV=7I4?FfXu34T?moogB9W+TfoC{%!~{rpus~va1|2(
zu2lGI*d!TJ1i_UGLl%T51R5@@VFwL+PGBt3NMWeu%;PB$05>7nr5S2DO9WGd7YNm`
z)o_BU8E7T*BSi!h3J4p(l?-SoR5*nTJeb!}!;mGC!XXYCVihS7T>u)`6iE>kVOYor
znmq_+&=e!1I?-f=Bv5d=!Bt>$GBPlL3)Cue+=&IAx3SeE;1)8tB*rLN3D$T;^Wdo)
zmjk(B4kW|$1q4m!p}_Qo1Wo6InGUY4qS!$LM(`RS9h6@|IEn)#4jP!yWGb2pGIScK
zyk{;;%qdz5;(`iONK11O0|Ns_IDkq;%Ihx!xLfT(HHJ92dMa8DvVR4L02O1mm~&F|
zZn2f-WfqpEqSY})pf>w04p42Bl9^mm6c5t08bsi#(TY}rWD`LI$cMMsiW2iu@^f#o
z6sM-9K#R#J0Z`b08mX|_3X-PRfOM?|5$iz2dJq9J1QJXeKwNOL2NU2jQv|8-gQsT>
zMh1prP(91QC;_XjSOplBm_%5lScMo_{<E<Nu<(IvFD_W^#mvLV!&s$EL~cQ;zXTZ=
z7(hV;uD?{k<twOp49ej(ppFczgTn;w;4m*>PGMTe2%4~|Wv*eUVQywzz_O5`maT+g
z0V}vpV=n=9Z`h!vGDitp7O3&d3@%wYOE^Fc-*j*%XaOgvtF(X%ZXRd~hr5QmhAV}&
zm#LPggdvNk1k{-2S;&~e2G-A8!dJr!Y9NE?EPgPHAxof!7vicE_7tWRmR{x<rdqyQ
z{u<^Qen|$f>jV(4t6|6ztYMdANZ|l=vr?GhoiB(eCrGr0V}Z~@h8lLH8W&V<vedBF
z2&8b$VGCx^<n{}JlrNy#4P3}*GTq_<cSPe$QuB)Qi*B()+A76G>Y!K$^_3BA7ELxt
zasfB1!L3(N9bHro%3qu%`32eWpiwVPVQ^x<B~YAN0v=|HPt8kA%1KRuROOu@)odxL
zC5g!ykTzNm$fjNpAr2xyV*^FaAXXJfDNAl@V%{ybkW`TKiok6*R`9syEf$cKMWFOn
zv<Z~S1ksxUU@5p0A#MjZ0Kjes`vR2Squ4>tj!!Fz;!Q6~tSnAW%t-}Jciv(vF3rtN
zO}WJdvM9bJGbgq977v)6nU|88oLXG87vxNEt^gC@ticH$2n1y^b5MTJ02NA%T#Q_d
z9L#)-JWO1m^v}Y@B*MbSDgqunl49f$;bIhHlw+!rK+6Ykqfi<b($E=6P(Q!;5EH0z
z0ZRO!Y7yRu05vSg=o^9(Bdmwn$(X`{FtZahlEVV-qp^aT5}=;r0=61vP?G~ZR=`%n
z3hFP~FqE)^X6c$4Q@ErVYC#!`vxaE_YYO*5#uT0u?i4m~Qs=1UECG!vaDy5N6BuLp
zIvGlMQg}NUnwc0G+8Npz)0k5DKr_NMoS@!rEmu23J5w4{3O|w<Xa<a<hO36Vnc0OQ
z_EZdWEl(|PEnf*w4Q~xk2ZJQotQy`FZb^n({u=fYz7B?FMrno`erbkUff|7<erPX~
ziIJg%t3;rNubC0#n%J6J!5Y3AP-8`?MreWHLIzOAS|FUlnj)0Ky^y(9s0Ji1vXDW7
zp+;zd=t2+)=1DW82#YX)<QIsQh-XPGWULh`kz62EBeamQR=7rZfpiV~Y=#t(4h9fe
z!w)6}XEUUT&gB3VT@x4!{U$ILvJ@VuVOt;ro;%cuVX76W6)oYZ5t+@9B32_hn_(_9
zs0gVMg}JPTtwzL#VFF{}EkuaM2GxR^J+d`ok_;*0k_@%tH4Ir0o`fVrtwfD@3O9I0
z(J6(YRx*#LM6O1nnXyJ(nxR&*geOIEfqacvjbx2PjX0#)HG!#6C`AgC8W47X8(y+C
z3|R`GRFNW`A_Hm)mMAVzs$ok9jr~d0NM$L*Q-iEDLy8=Xw?Jhf0}n%rJV*z)hp#|J
zldOnvd#4aq4_6st%UbZN3tLkRqiI060Y<oq1S)^QEkrU*C)`9Tfq56)L;{!aq}!v(
zSOhB4A)QlP4aqW?O=OvmC^vDLUk)=riUV8-CYB~g@#p3jmw+ZnKuw~|vQ$u5G8BR8
zs48~wFol%@hHF60Inbm@u>@?^RiKu!gRzDYR6f9liXdJE7vZ1*2~DP3jCr>>3KB~|
zGk(x<Xi(V>9xG~xxr|D76`cT8BA`)2h%?|8b-*kN0j<s{NCXX26yM@Vt;j4ciO<gl
z*U&HjgEY&4My`0km2Glju3lC_dKI&RtpcLvE}~&mcO%T1py`<65^y8CiXR+lMXAN5
zIVF0@#bvh`6E&G`v4AG7Zn0&gCZ?noX{v(T322RC#4t-y0?2Eip}ry?5bH3AK(v0r
zEdl1L%z|6Y#U(|zSaY*eGK-3~f|?A>$pxjiSo2DA3o37Mf@ePq@{3b%G3RFH-C_m}
z$Fn6CmsA#{-eSrtxW!tUnO9;_1j^gDIMa&qa}$e-5-V@9faWc4v4X}JiXm+b@W?W_
zkqv5x-(o6Axy9*{Sd!=lnjgKzR+1kN@+TWOdWtori$IeZQGAe5p?FA06c?ekv~Mvd
zmL?a~f!qvfHGt<y!5%#Znxo<cH#T7DFiHrS3u%uOfkrfMF&5lnEQw-=DvV+WSqhqQ
zRR)>N0&2M2V$RG>zr~WBT3LLHtt>I8G_|-0OEdo#Xu()%P6;?AYBEET=1EY%gVQG{
zY2M-kM=iYMEC4lfKx1PJj7S4iOahDoEF7$Sj8cpO;Mp+|MltZ58E6(ufRTeyj8OqR
zBc&rCz$nBh0-DWW<YR<%3nUoDcm$Yu7^`IQmf0Bj57Zt4cL+eE?<Js-WyTtYET(2A
z(7<po!%9X!P39s{flvgRL<G+%YBGW22_gV40Kf#;qavVjz|8d0BBT|8#m7M21tk^+
zCO*u53pO1uK_;TCC<8eGJ~#v#oCFP9r!cfKr7(g?1`wIXEXlBdp$0UM#<Y;JhN*@b
z%w}H5xR9lmrG^DO^3Sr6X#q$V^Fk(&STKVos~@E3X9PtWxD782Y8x}(VuvmVxWxim
zSWt8gBnq91VuQB*88dD%mKVJS=>)kMoCqM3pP*1Z4e~i?+Mj{Zh*5;8N&zi$pynf%
z8=%AwD9AvXK_(R!fd(8IvKX=$vzTfbQy6O)%NUCEQkWJ%SO3*8E?@yo&w*Ngpm~lw
zmKw%drYflt))KY_>?y1@jI$Z$f<vX5sg^mMAy0&n0R&4pQrMaqn;0V*@|X-jGm+rV
zS`9-yBe;#h?gt(dyoK562e}U1=|`PR0L_m<CKJG60a{CvoLG=ql9&Tp?EtDOz~T@B
zlxDyc#C2GKSfz^=M4)MN$odIv?TsqX)OBi3v0jzFXCAnJ4GQAYoKyw3%$!sOzr@^B
zh5RA~n4B|ci49m(QIqQydj@!#zZjgVA@#REDEG4#7vyA?++t5pElDgXDZ0g(nOl%w
zRFadKbc+|l1UaZQC-oLr7^qlqEh@?{y2YEBS6q^qmz)XqsU`~~lYm+Ux44oMb5nET
zK~ws-Si$~-cpsc%z+vFdz`$@3lvqI35(6U_3kRbN6AL2~6B{GPe<ntz{~XX6?J7yI
ze)zIWJw*7R^mjlVeNYU6iu~dv=v-J0V;0jw#w=#gx>4}jH|83KES4<R1#F-$e<njM
zYYnJZAXm#)!&bvm#!#dMZhL|zb=jJkKz$V(hC(gSz$j>TnvtP~F^wUUp@ww{V;^X)
znz`zff+unyC?qO?YOfrH(&Eg#bcK?PRLDd~aY24w3P=PT{@{f&Tnb14RHZ0@)-dQn
zV@LtqddbgAEUMH~h|DilNKVXCNX#kDR{(d!6%z9*6+o*SP)sSwSI93*Eh;a{EJ?*;
zH@HMs$jn2rNDpoTxJdBR<h;e6nO9tpnp|>=3zQy;(m|Xe(8`8eEFde3Kttb<6a-o?
zUGx)_g4jw6QW8s2HQ6DF0My{P#g$)@ky;cF(gR%v0%5ad=7FmiR*;P0E#}0cboA8m
zmw|!dF(`F_)~+zHiZSvqvVhl8h%j<tPLQIcLzF@klqf(2DY!rZb?9rL#pObV8YWP2
zSi)2To|Y_O&H@#etP2@HNdue+IGPz@bP8iHb1iELXBHP|nJswyhj{__LeNwwa|&xV
zQ&CwBLl#d8n<PUP?*hIW=GhD>>~ooFK$DvM3qjMDY+0a%x1dfO$6O}J0$AuMGq)dT
zAzx-*N@@jYAzw~uZeDRn6h|;90*VrIK$3}hdHE%`Sdw!S3yPM2%3V;gT_vawUxcIp
zS#wmyqo14`52|?e3i8r3CoqB+eKV&NWNHc(#ey_;f(TFsDFV$H6+HlPuYicFAOhZO
zy2V_aSA2^-BQ>!kH?bfJlnmn2z;)a$_MH6m^i<F?uhfcy)S}GX)Vz{gT!|?uPz6P+
zK&gQp)GkWPOb55gU}*v|bhr$x22>5^CYD68rliFu=SH!lWu`-y(jZC+P$TLiC>?;t
zq8J!KZ2}c05mpWsIVOzZK+rHK$V~9MEa);UO{SvvAg_T4O`%&H@!%pUKK>S0JhViM
zkH5teA75CSm;)-T;^V;yy$H1Kya+s>G#8|OBZ$}xB6fj@;~?S<hyc$(f)ZB|s5~nI
zCEFs9n{V+#R|h4h=H$Ru2!XxT2+{^F0YR(jv_Z2-pg~j)W}bQmP7YQME)FRU2@XLH
zeGW^GFb-BOHVz>UKJdyr+^gh4#^GBf4_?F03aa;uazLZmpyo1YzzKvwY!C)Di;6)N
zTM0um18BtysIaSHh-U&-ibZch4FTpN7m(vYB|*_4kN~t<1Y#F~{RQ?R$Ti?lWMg7r
zC<YbD44_QQ3tBS<UnPoCbc5^$xd9ZA#h@Ht!<YqbnDsH#GSx5zGiWka#lp*}Ajpcv
zVsHruEe(^C^NYacYe_y>7(Di;07``^paKt64wq%7mMeh9@Dz$mib|6~TO1H&pC;2S
z7LWpnzaVRjz>7R?G3S>;8oH1o3hX&h>fnNVj*W-0iU;gD=&B-3wjxnb?Jfo)#6bi&
z$UwS^BtTqnFo6khsDaG{MGPy<Ob$jK7I0K)+TUU>t}HGB=g(W9&}RS{@C(G+0m?;e
z1&MhniN)aj9K~LonwXSdlvf0r1i1xj>1X6*CP9`|a^)tLfVQ%L1VG_^i@6}D<Q8*s
znb9rg08gJHP&`F(`&RnHwzYuUz)@_zm7u*Ukd>U=r6rj;#d=^8JogaAS(2HXs|T7#
zDFU@si#S0J15IldftD13yKc8Qz-t2a^74v6(=SoNFs@!&X&!i?CTRH~f?Wh2=?w(+
zY{bDzp$qqrlo#=UtO0GexFuLn304%J16o=PT4Q^QsUYW;P#JhZC!(2|T2#aj3NLQ3
zYKUwRD5-(^OGU{U5D`6a<y~9^nmD+{1MU=pRsf_HK^9+v7gk0Iz^nwVjsy(>Lslq?
zf?O<vE(ZxLJ@AH@BG6)oC>0z^z*fh@2G&7?+)>=gi3KI4xq6^BSrKSx;ugOT%$vU8
z1&rW=;T9W|14=`XWC~7PU;>o5ZgJS;f|c8WYK~$z(5fMDZ3<eQ2*RN070|jw5Dmg2
h%p8n7j6#ecl7|&cg4Px?2{3}z{qZmf)iZ!#EC3nAaHaqN

diff --git a/test_visualize.py b/test_visualize.py
deleted file mode 100644
index 7ef56d3..0000000
--- a/test_visualize.py
+++ /dev/null
@@ -1,148 +0,0 @@
-import argparse
-from pathlib import Path
-import numpy as np
-import glob
-
-from sklearn.model_selection import KFold
-
-from datasets.data_interface import DataInterface, MILDataModule, CrossVal_MILDataModule
-from models.model_interface import ModelInterface
-import models.vision_transformer as vits
-from utils.utils import *
-
-# pytorch_lightning
-import pytorch_lightning as pl
-from pytorch_lightning import Trainer
-import torch
-from train_loop import KFoldLoop
-
-#--->Setting parameters
-def make_parse():
-    parser = argparse.ArgumentParser()
-    parser.add_argument('--stage', default='train', type=str)
-    parser.add_argument('--config', default='DeepGraft/TransMIL.yaml',type=str)
-    parser.add_argument('--version', default=0,type=int)
-    parser.add_argument('--epoch', default='0',type=str)
-    parser.add_argument('--gpus', default = 2, type=int)
-    parser.add_argument('--loss', default = 'CrossEntropyLoss', type=str)
-    parser.add_argument('--fold', default = 0)
-    parser.add_argument('--bag_size', default = 1024, type=int)
-
-    args = parser.parse_args()
-    return args
-
-#---->main
-def main(cfg):
-
-    torch.set_num_threads(16)
-
-    #---->Initialize seed
-    pl.seed_everything(cfg.General.seed)
-
-    #---->load loggers
-    # cfg.load_loggers = load_loggers(cfg)
-
-    # print(cfg.load_loggers)
-    # save_path = Path(cfg.load_loggers[0].log_dir) 
-
-    #---->load callbacks
-    # cfg.callbacks = load_callbacks(cfg, save_path)
-
-    home = Path.cwd().parts[1]
-    DataInterface_dict = {
-                'data_root': cfg.Data.data_dir,
-                'label_path': cfg.Data.label_file,
-                'batch_size': cfg.Data.train_dataloader.batch_size,
-                'num_workers': cfg.Data.train_dataloader.num_workers,
-                'n_classes': cfg.Model.n_classes,
-                'backbone': cfg.Model.backbone,
-                'bag_size': cfg.Data.bag_size,
-                }
-
-    dm = MILDataModule(**DataInterface_dict)
-    
-
-    #---->Define Model
-    ModelInterface_dict = {'model': cfg.Model,
-                            'loss': cfg.Loss,
-                            'optimizer': cfg.Optimizer,
-                            'data': cfg.Data,
-                            'log': cfg.log_path,
-                            'backbone': cfg.Model.backbone,
-                            }
-    model = ModelInterface(**ModelInterface_dict)
-    
-    #---->Instantiate Trainer
-    trainer = Trainer(
-        num_sanity_val_steps=0, 
-        # logger=cfg.load_loggers,
-        # callbacks=cfg.callbacks,
-        max_epochs= cfg.General.epochs,
-        min_epochs = 200,
-        gpus=cfg.General.gpus,
-        # gpus = [0,2],
-        # strategy='ddp',
-        amp_backend='native',
-        # amp_level=cfg.General.amp_level,  
-        precision=cfg.General.precision,  
-        accumulate_grad_batches=cfg.General.grad_acc,
-        # fast_dev_run = True,
-        
-        # deterministic=True,
-        check_val_every_n_epoch=10,
-    )
-
-    #---->train or test
-    log_path = cfg.log_path
-    # print(log_path)
-    # log_path = Path('lightning_logs/2/checkpoints')
-    model_paths = list(log_path.glob('*.ckpt'))
-
-    if cfg.epoch == 'last':
-        model_paths = [str(model_path) for model_path in model_paths if f'last' in str(model_path)]
-    else:
-        model_paths = [str(model_path) for model_path in model_paths if f'epoch={cfg.epoch}' in str(model_path)]
-
-    # model_paths = [str(model_path) for model_path in model_paths if f'epoch={cfg.epoch}' in str(model_path)]
-    # model_paths = [f'lightning_logs/0/.ckpt']
-    # model_paths = [f'{log_path}/last.ckpt']
-    if not model_paths: 
-        print('No Checkpoints vailable!')
-    for path in model_paths:
-        # with open(f'{log_path}/test_metrics.txt', 'w') as f:
-        #     f.write(str(path) + '\n')
-        print(path)
-        new_model = model.load_from_checkpoint(checkpoint_path=path, cfg=cfg)
-        trainer.test(model=new_model, datamodule=dm)
-    
-    # Top 5 scoring patches for patient
-    # GradCam
-
-
-if __name__ == '__main__':
-
-    args = make_parse()
-    cfg = read_yaml(args.config)
-
-    #---->update
-    cfg.config = args.config
-    cfg.General.gpus = [args.gpus]
-    cfg.General.server = args.stage
-    cfg.Data.fold = args.fold
-    cfg.Loss.base_loss = args.loss
-    cfg.Data.bag_size = args.bag_size
-    cfg.version = args.version
-    cfg.epoch = args.epoch
-
-    log_path = Path(cfg.General.log_path) / str(Path(cfg.config).parent)
-    Path(cfg.General.log_path).mkdir(exist_ok=True, parents=True)
-    log_name =  f'_{cfg.Model.backbone}' + f'_{cfg.Loss.base_loss}'
-    task = '_'.join(Path(cfg.config).name[:-5].split('_')[2:])
-    # task = Path(cfg.config).name[:-5].split('_')[2:][0]
-    cfg.log_path = log_path / f'{cfg.Model.name}' / task / log_name / 'lightning_logs' / f'version_{cfg.version}' / 'checkpoints'
-    
-    
-
-    #---->main
-    main(cfg)
- 
\ No newline at end of file
diff --git a/train_loop.py b/train_loop.py
deleted file mode 100644
index f923681..0000000
--- a/train_loop.py
+++ /dev/null
@@ -1,212 +0,0 @@
-from pytorch_lightning import LightningModule
-import torch
-import torch.nn.functional as F
-from torchmetrics.classification.accuracy import Accuracy
-import os.path as osp
-from abc import ABC, abstractmethod
-from copy import deepcopy
-from pytorch_lightning import LightningModule
-from pytorch_lightning.loops.base import Loop
-from pytorch_lightning.loops.fit_loop import FitLoop
-from pytorch_lightning.trainer.states import TrainerFn
-from datasets.data_interface import BaseKFoldDataModule
-from typing import Any, Dict, List, Optional, Type
-import torchmetrics
-import pandas as pd
-import matplotlib.pyplot as plt
-import seaborn as sns
-
-
-
-class EnsembleVotingModel(LightningModule):
-    def __init__(self, model_cls: Type[LightningModule], checkpoint_paths: List[str], n_classes, log_path) -> None:
-        super().__init__()
-        # Create `num_folds` models with their associated fold weights
-        self.n_classes = n_classes
-        self.log_path = log_path
-        self.data = [{"count": 0, "correct": 0} for i in range(self.n_classes)]
-        self.models = torch.nn.ModuleList([model_cls.load_from_checkpoint(p) for p in checkpoint_paths])
-        self.test_acc = Accuracy()
-        if self.n_classes > 2: 
-            self.AUROC = torchmetrics.AUROC(num_classes = self.n_classes, average = 'weighted')
-            metrics = torchmetrics.MetricCollection([torchmetrics.Accuracy(num_classes = self.n_classes,
-                                                                           average='micro'),
-                                                     torchmetrics.CohenKappa(num_classes = self.n_classes),
-                                                     torchmetrics.F1Score(num_classes = self.n_classes,
-                                                                     average = 'macro'),
-                                                     torchmetrics.Recall(average = 'macro',
-                                                                         num_classes = self.n_classes),
-                                                     torchmetrics.Precision(average = 'macro',
-                                                                            num_classes = self.n_classes),
-                                                     torchmetrics.Specificity(average = 'macro',
-                                                                            num_classes = self.n_classes)])
-                                                                            
-        else : 
-            self.AUROC = torchmetrics.AUROC(num_classes=2, average = 'weighted')
-            metrics = torchmetrics.MetricCollection([torchmetrics.Accuracy(num_classes = 2,
-                                                                           average = 'micro'),
-                                                     torchmetrics.CohenKappa(num_classes = 2),
-                                                     torchmetrics.F1Score(num_classes = 2,
-                                                                     average = 'macro'),
-                                                     torchmetrics.Recall(average = 'macro',
-                                                                         num_classes = 2),
-                                                     torchmetrics.Precision(average = 'macro',
-                                                                            num_classes = 2)])
-        self.test_metrics = metrics.clone(prefix = 'test_')
-        self.confusion_matrix = torchmetrics.ConfusionMatrix(num_classes = self.n_classes)
-
-    def test_step(self, batch: Any, batch_idx: int, dataloader_idx: int = 0) -> None:
-        # Compute the averaged predictions over the `num_folds` models.
-        # print(batch[0].shape)
-        input, label, _ = batch
-        label = label.float()
-        input = input.squeeze(0).float()
-
-            
-        logits = torch.stack([m(input) for m in self.models]).mean(0)
-        Y_hat = torch.argmax(logits, dim=1)
-        Y_prob = F.softmax(logits, dim = 1)
-        # #---->acc log
-        Y = torch.argmax(label)
-        self.data[Y]["count"] += 1
-        self.data[Y]["correct"] += (Y_hat.item() == Y)
-
-        return {'logits' : logits, 'Y_prob' : Y_prob, 'Y_hat' : Y_hat, 'label' : label}
-
-    def test_epoch_end(self, output_results):
-        probs = torch.cat([x['Y_prob'] for x in output_results])
-        max_probs = torch.stack([x['Y_hat'] for x in output_results])
-        # target = torch.stack([x['label'] for x in output_results], dim = 0)
-        target = torch.cat([x['label'] for x in output_results])
-        target = torch.argmax(target, dim=1)
-        
-        #---->
-        auc = self.AUROC(probs, target.squeeze())
-        metrics = self.test_metrics(max_probs.squeeze() , target)
-
-
-        # metrics = self.test_metrics(max_probs.squeeze() , torch.argmax(target.squeeze(), dim=1))
-        metrics['test_auc'] = auc
-
-        # self.log('auc', auc, prog_bar=True, on_epoch=True, logger=True)
-
-        # print(max_probs.squeeze(0).shape)
-        # print(target.shape)
-        # self.log_dict(metrics, logger = True)
-        for keys, values in metrics.items():
-            print(f'{keys} = {values}')
-            metrics[keys] = values.cpu().numpy()
-        #---->acc log
-        for c in range(self.n_classes):
-            count = self.data[c]["count"]
-            correct = self.data[c]["correct"]
-            if count == 0: 
-                acc = None
-            else:
-                acc = float(correct) / count
-            print('class {}: acc {}, correct {}/{}'.format(c, acc, correct, count))
-        self.data = [{"count": 0, "correct": 0} for i in range(self.n_classes)]
-
-        self.log_confusion_matrix(probs, target, stage='test')
-        #---->
-        result = pd.DataFrame([metrics])
-        result.to_csv(self.log_path / 'result.csv')
-
-
-    def log_confusion_matrix(self, max_probs, target, stage):
-            confmat = self.confusion_matrix(max_probs.squeeze(), target)
-            df_cm = pd.DataFrame(confmat.cpu().numpy(), index=range(self.n_classes), columns=range(self.n_classes))
-            plt.figure()
-            fig_ = sns.heatmap(df_cm, annot=True, cmap='Spectral').get_figure()
-            # plt.close(fig_)
-            # plt.savefig(f'{self.log_path}/cm_e{self.current_epoch}')
-            self.loggers[0].experiment.add_figure(f'{stage}/Confusion matrix', fig_, self.current_epoch)
-
-            if stage == 'test':
-                plt.savefig(f'{self.log_path}/cm_test')
-            plt.close(fig_)
-
-class KFoldLoop(Loop):
-    def __init__(self, num_folds: int, export_path: str, **kargs) -> None:
-        super().__init__()
-        self.num_folds = num_folds
-        self.current_fold: int = 0
-        self.export_path = export_path
-        self.n_classes = kargs["model"].n_classes
-        self.log_path = kargs["log"]
-
-    @property
-    def done(self) -> bool:
-        return self.current_fold >= self.num_folds
-
-    def connect(self, fit_loop: FitLoop) -> None:
-        self.fit_loop = fit_loop
-
-    def reset(self) -> None:
-        """Nothing to reset in this loop."""
-
-    def on_run_start(self, *args: Any, **kwargs: Any) -> None:
-        """Used to call `setup_folds` from the `BaseKFoldDataModule` instance and store the original weights of the
-        model."""
-        assert isinstance(self.trainer.datamodule, BaseKFoldDataModule)
-        self.trainer.datamodule.setup_folds(self.num_folds)
-        self.lightning_module_state_dict = deepcopy(self.trainer.lightning_module.state_dict())
-
-    def on_advance_start(self, *args: Any, **kwargs: Any) -> None:
-        """Used to call `setup_fold_index` from the `BaseKFoldDataModule` instance."""
-        print(f"STARTING FOLD {self.current_fold}")
-        assert isinstance(self.trainer.datamodule, BaseKFoldDataModule)
-        self.trainer.datamodule.setup_fold_index(self.current_fold)
-
-    def advance(self, *args: Any, **kwargs: Any) -> None:
-        """Used to the run a fitting and testing on the current hold."""
-        self._reset_fitting()  # requires to reset the tracking stage.
-        self.fit_loop.run()
-
-        self._reset_testing()  # requires to reset the tracking stage.
-        self.trainer.test_loop.run()
-        self.current_fold += 1  # increment fold tracking number.
-
-    def on_advance_end(self) -> None:
-        """Used to save the weights of the current fold and reset the LightningModule and its optimizers."""
-        self.trainer.save_checkpoint(osp.join(self.export_path, f"model.{self.current_fold}.pt"))
-        # restore the original weights + optimizers and schedulers.
-        self.trainer.lightning_module.load_state_dict(self.lightning_module_state_dict)
-        self.trainer.strategy.setup_optimizers(self.trainer)
-        self.replace(fit_loop=FitLoop)
-
-    def on_run_end(self) -> None:
-        """Used to compute the performance of the ensemble model on the test set."""
-        checkpoint_paths = [osp.join(self.export_path, f"model.{f_idx + 1}.pt") for f_idx in range(self.num_folds)]
-        voting_model = EnsembleVotingModel(type(self.trainer.lightning_module), checkpoint_paths, n_classes=self.n_classes, log_path=self.log_path)
-        voting_model.trainer = self.trainer
-        # This requires to connect the new model and move it the right device.
-        self.trainer.strategy.connect(voting_model)
-        self.trainer.strategy.model_to_device()
-        self.trainer.test_loop.run()
-
-    def on_save_checkpoint(self) -> Dict[str, int]:
-        return {"current_fold": self.current_fold}
-
-    def on_load_checkpoint(self, state_dict: Dict) -> None:
-        self.current_fold = state_dict["current_fold"]
-
-    def _reset_fitting(self) -> None:
-        self.trainer.reset_train_dataloader()
-        self.trainer.reset_val_dataloader()
-        self.trainer.state.fn = TrainerFn.FITTING
-        self.trainer.training = True
-
-    def _reset_testing(self) -> None:
-        self.trainer.reset_test_dataloader()
-        self.trainer.state.fn = TrainerFn.TESTING
-        self.trainer.testing = True
-
-    def __getattr__(self, key) -> Any:
-        # requires to be overridden as attributes of the wrapped loop are being accessed.
-        if key not in self.__dict__:
-            return getattr(self.fit_loop, key)
-        return self.__dict__[key]
-
-    def __setstate__(self, state: Dict[str, Any]) -> None:
-        self.__dict__.update(state)
\ No newline at end of file
diff --git a/utils/__pycache__/utils.cpython-39.pyc b/utils/__pycache__/utils.cpython-39.pyc
deleted file mode 100644
index 33d3d005a578948dd3d5b58938a815f86c4e92f5..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4005
zcmYe~<>g{vU|^`fF+1t42m`}o5C<9aFfcGUFfcF_Ut(lnNMT4}%wfo7jACR2v6*t1
za+#x;b6KKTz<lN$)+p8#h7{%;wp{io4zL(Y4reY`6c?Dyn!}yT6U7T=v*qyR@<;K5
z+3Yz2xq?xGU^YjNP_A&4aIQ#{2$;{ABbqA~B?e}5<%s7>L`mdIMoH#MMM;6hxO2pF
zrK6<5Y@QsMT-hjDFq=0=E>}KE9?a&;QOH${QUtU4bChzGqm*-1qEvEKqf~R%qSSKL
zqtwB2%sCoS8Yv7Z0y&x>c}9j5wG_b=p%%s{trUh7;T-W??I;~ah7^$$(H4d%-4uot
zu^hcz{V4rhgD3;A3F0}1xkgb&V75e#ajr>}2_r*_WQtS^LzF2vWMCm=mTS($z{mg%
z59t({7KSK`6owR8C}d8No5PmE4APUroFbb7;e+JmQxsB|(fEo`K1d~Yc_pxU%5&JF
zEK^icR9hILtWubR88p>jf?`{f@fJ%!Vo8Q3(=BF4C+AzjiAlvJMTyBJ$vKI|#kr{^
z8Tl!GnvAztz1{M2QZyNFaix{!C6{F8=OyN7GT!1TO3X{i&y6oG$jK}L$+{$#B>Lnh
zrlb~WGTmYa@rqMRZm|WICKacG6mU2uCzlo_CRb`Q-xBu8OwTCE%gjp$sq@WGDa}c}
z#b2D7ni8K{mReL<l98F0ev3V%C^0iHwMdik7C&4AL@~(mKKc0tnvA#D-7-s{Oiri<
zw>(YOTg;AmmA6=2GLuVgvG`;bm)zp;FMzoI7E4HFL8>NWkq83=Loy>MFrb*3fq{X8
zfq}spl=?jw7#K<zY8X-&Q<!?0`Za19OBl15YCt4&3Ue=0EmH|g4O25?I0F+y3IhuR
z3qvzABSSEQAw#j10Rtl#MlyiXMKFUVi{C9qkVjZ@^HWka8E>&cgNpSQOMXFW-Yu5O
z#N3=)EIIj!DMeBY3=CkmX)@npO)E$&$+*RmmYI`!i@7p4XC*_CA_D`%FEjm&{M=Oi
z%ACYJ{qp>x?BasN<W&8TqQtynUr!%hm(<h(_oBqK68+MW%$#BfsaH^Wi?b*-F(n>k
zn;6KGY#^UA@-Yf97AZ3@Fo41{CqF$swWt^)U_eU20aM1nz)-`G#gM|7&0M4f4ittg
z<`kwB<`kA*W>7FKV5woqVqVBt%amtQ!U|$HGo~;~Gt@A|GsD$0f_1R=vVe4Cfpw%X
zrm%qnmMw)Hq-!?AT&8A5Mur;38m4rnU<OSNzgsLNsl_EBZkkNDICJvT<I{^03o>pA
zrlh7NmgbbiXB5Qerj`_CCTlX^VlPWAD$dN$D^ddms5;ntMH&nY3{`x(y1Ke{KKbbi
zDVar93YzS<Sc^*%(^GG8739Q2{eMd^BsH%%zsM;+u_(m{945CoKsJISgwr`V3?f*>
z#K6FCi?yIAGp|IG`4)3>T6z>`NfOkUD6Zt<GAJ7yaS%cYq=yF-+fcb;Sx{`qfntM`
zi;07Y<sTahAF}`>2O|?Bh|R&s^q-AIfVs#3<PD}<{J!}qsX5LWsma*|`I&hoxA=oH
zlQRN}^3#h_i;JBSL1|3{O(-NIH5ZijcwG~Vaw>yM@(T(w^U{++?g!Zm!k{<?760IP
z-on7Zkj_xcR0EE?TIL$&EQS;&P^|SbF*1}erm&=d;+6><_iQQby{xq?HB1XwYFHLB
zGBT8~mawI8q;RHirf{TifgyJ<dkRl4V=XIK6)Q+p4MP@F7JCYBHdE0CkZ1`<3QGxR
z4RbSN3Ln@m{uH(prWAo*4zOyb1uP{TDS}WHLQoaL$SQ&vG)4SwaVNurrZ_~C=@v(7
zMP_kHe17&V_JYKs)Vz}7TO4JHpvW#RP6zoMgl{qDW`c?i_T2ou%#!?~Tb#L>dGRT!
zIVFj=I0_O=GE?)CQ^Cn9DZe<iND>^0=|!ojdGVF0IXU^|x7ffuLoi)wVWi1^i#sK?
zIJqbjT=d-HDS$>$d{Sc3Em34%d|GB+W^qPp$}PU6#FFHUc$nlZmXgfe)LQ}tMfu68
z#l@L<>G8z{si`Tq*dYnM7*s}=fTH#mYYC{ptdgouEyz#Kure@8snxB9`O-?yB(3%(
zsI=4MD6#@MojoP92%MNXK&4AwVs2`YEl8ZRII%1>J}0rb<Q5m0S(0B6pAGS@AXuP0
z6;yr~$LHteRNi6-*^pS8TqTKNZ(?aO*xFmnxrr5;T(?+rvr{sQicCPZu)C+`r4}XT
z6xo1yY>5R0sd*_yMxd-}3>GO)Eh<YbDl!Cdn2Sq_G}(&uL2QWgKn{=M_N`1#%*jbg
zOwKO8#hqVTQczkF50(*51*P%$Vvy5eN{XC7hJ#8^q)f;M&V(=}#o&Y=21*P}EKD4X
zd`wJ?Ajk$Hf3tCLfoN3xljT1f4;K>;69*$$6-@Rg2M4A|Q6#9!LC$e33=9mQTnDOp
ziX#{p7}^=q7(rD|3r7h<31bICGh;KO3qvzwCu0fI0_JwccBV8?Ny`M1?_kPeNnw#>
zfT#eKw<SyqSZkOTGIBF?K;@(vKsh&<L6g-FrAP-k0%Wl;tl&v!s9}f|t7R-<$YShZ
zs9}@@wf7i%nI<w7vIH||G8KW-4&yE6l+0XBrdy0|x7dsG(@Js^D^@byV$w6X#h9td
zc#E+DDR8-Lax#lclJj#5>?#=;7(Ro-wMsp?D8INkJ~gkTD8HaGz9hdWIYZATCqFqc
zr`S#pp##IU><kPHVAq05Pq1sHK(1W?b!`VD$jy=r3mG9U2D?L(=@u*4hFi=z`RPTm
zkkXU0A|C4WTa1-pbwwaEixNSV11OOsfe5gF*>15GCFZ54-eS&4%_~X<B|x?kaK&(o
zwKyZOAoUh=acQn5OHl$yOBw?MLlkQTs89!0=EcQe!!?;9vZ*j7VB2m9V+n`~P;7vj
zAPkIBj4F&`j77O1O<o{(v)y7exW#CAi_z#7qwy_9lUt0YFF~>R5|nmcf)dh8R){+0
zq|Cf1u9D>3qWH4RqQsmij=X#%R(?rFYEcwtUVeOWNn#SHVUd`VgHjKGj0ItEb^uif
zB@8tTlHf!U%%I5#Y8P_mBqpWi#OEd!XfoYmDM>8OzQqa_0(%)kfCBZFcyfMTS!z*9
zJXp3kJ}ti}9;Cbj<W-O*3`|9}Aa^tRX<CDd=aP(^%p^#)%AA;#Tm<r75y*Ss;Exgm
z$7fk4sA|_M0X2Bi@{4kdZ*d{98AEP~7iZ_BCKl!Cfm&QS@x`e*so>UY5h#pqaexic
z%gZYQ<$<DTP`nC2#J~+Ey_Cd~#3E3NyCsb-43+~G8>vM_ps2bffmKCuYDp0%DDptP
zty?N!HP9kk58TGiOv_A81T{(Z5}{4wB5sg71Pdy`isN%Yr7WnGTm*`OB3_VTd?11!
zq)Y}wnO;tQenGKbQetsxkpM`E0xl(KnI-Wc#YKWRl!0rK)FQp&lEjkK;vylCGPaUR
zP=lceln24>(;`ujV?gc5B5@E)29)~Q5>rw#lS{zO$s!eyuoj2_wOejUW4Z@k@`4L`
zaQT1B2#+#7SiPuMl!;VJ7J=&wEqodgH3HZdph^f_9N!WKhqhi`o*trybBif250dq&
zK&}U+Pe_tRt3Ehva>2b9J5XU!?8d;rz{3b?wec{*pa3HelL(wA!_2|R!^p+P!^oi|
W01{>5Fy>$sV&vcuV1&b8Y@7h-4LMZ+

diff --git a/utils/extract_features.py b/utils/extract_features.py
deleted file mode 100644
index fb040a1..0000000
--- a/utils/extract_features.py
+++ /dev/null
@@ -1,27 +0,0 @@
-## Choose Model and extract features from (augmented) image patches and save as .pt file
-
-from datasets.custom_dataloader import HDF5MILDataloader
-
-
-def extract_features(input_dir, output_dir, model, batch_size):
-
-
-    dataset = HDF5MILDataloader(data_root, label_path=label_path, mode='train', load_data=False, n_classes=n_classes)
-    if model == 'resnet50':
-        model = Resnet50_baseline(pretrained = True)       
-        model = model.to(device)
-        model.eval()
-
-
-
-if __name__ == '__main__':
-
-    # input_dir, output_dir
-    # initiate data loader
-    # use data loader to load and augment images 
-    # prediction from model
-    # choose save as bag or not (needed?)
-    
-    # features = torch.from_numpy(features)
-    # torch.save(features, output_path + '.pt') 
-
-- 
GitLab