├── .gitignore
├── README.md
├── data
├── images_test
│ ├── images
│ │ ├── Img_0.png
│ │ ├── Img_1.png
│ │ ├── Img_2.png
│ │ ├── Img_3.png
│ │ ├── Img_4.png
│ │ ├── Img_5.png
│ │ ├── Img_6.png
│ │ ├── Img_7.png
│ │ ├── Img_8.png
│ │ └── Img_9.png
│ └── masks
│ │ ├── Mask_0.png
│ │ ├── Mask_1.png
│ │ ├── Mask_2.png
│ │ ├── Mask_3.png
│ │ ├── Mask_4.png
│ │ ├── Mask_5.png
│ │ ├── Mask_6.png
│ │ ├── Mask_7.png
│ │ ├── Mask_8.png
│ │ └── Mask_9.png
└── images_train
│ ├── images
│ ├── Img_0.png
│ ├── Img_1.png
│ ├── Img_10.png
│ ├── Img_11.png
│ ├── Img_12.png
│ ├── Img_13.png
│ ├── Img_14.png
│ ├── Img_15.png
│ ├── Img_16.png
│ ├── Img_17.png
│ ├── Img_18.png
│ ├── Img_19.png
│ ├── Img_2.png
│ ├── Img_20.png
│ ├── Img_21.png
│ ├── Img_22.png
│ ├── Img_23.png
│ ├── Img_24.png
│ ├── Img_25.png
│ ├── Img_26.png
│ ├── Img_27.png
│ ├── Img_28.png
│ ├── Img_29.png
│ ├── Img_3.png
│ ├── Img_30.png
│ ├── Img_31.png
│ ├── Img_32.png
│ ├── Img_33.png
│ ├── Img_34.png
│ ├── Img_35.png
│ ├── Img_36.png
│ ├── Img_37.png
│ ├── Img_38.png
│ ├── Img_39.png
│ ├── Img_4.png
│ ├── Img_40.png
│ ├── Img_41.png
│ ├── Img_42.png
│ ├── Img_43.png
│ ├── Img_44.png
│ ├── Img_45.png
│ ├── Img_46.png
│ ├── Img_47.png
│ ├── Img_48.png
│ ├── Img_49.png
│ ├── Img_5.png
│ ├── Img_50.png
│ ├── Img_51.png
│ ├── Img_52.png
│ ├── Img_53.png
│ ├── Img_54.png
│ ├── Img_55.png
│ ├── Img_56.png
│ ├── Img_57.png
│ ├── Img_58.png
│ ├── Img_59.png
│ ├── Img_6.png
│ ├── Img_60.png
│ ├── Img_61.png
│ ├── Img_62.png
│ ├── Img_63.png
│ ├── Img_64.png
│ ├── Img_65.png
│ ├── Img_66.png
│ ├── Img_67.png
│ ├── Img_68.png
│ ├── Img_69.png
│ ├── Img_7.png
│ ├── Img_70.png
│ ├── Img_71.png
│ ├── Img_72.png
│ ├── Img_73.png
│ ├── Img_74.png
│ ├── Img_75.png
│ ├── Img_76.png
│ ├── Img_77.png
│ ├── Img_78.png
│ ├── Img_79.png
│ ├── Img_8.png
│ ├── Img_80.png
│ ├── Img_81.png
│ ├── Img_82.png
│ ├── Img_83.png
│ ├── Img_84.png
│ ├── Img_85.png
│ ├── Img_86.png
│ ├── Img_87.png
│ ├── Img_88.png
│ ├── Img_89.png
│ ├── Img_9.png
│ ├── Img_90.png
│ ├── Img_91.png
│ ├── Img_92.png
│ ├── Img_93.png
│ ├── Img_94.png
│ ├── Img_95.png
│ ├── Img_96.png
│ ├── Img_97.png
│ ├── Img_98.png
│ └── Img_99.png
│ └── masks
│ ├── Mask_0.png
│ ├── Mask_1.png
│ ├── Mask_10.png
│ ├── Mask_11.png
│ ├── Mask_12.png
│ ├── Mask_13.png
│ ├── Mask_14.png
│ ├── Mask_15.png
│ ├── Mask_16.png
│ ├── Mask_17.png
│ ├── Mask_18.png
│ ├── Mask_19.png
│ ├── Mask_2.png
│ ├── Mask_20.png
│ ├── Mask_21.png
│ ├── Mask_22.png
│ ├── Mask_23.png
│ ├── Mask_24.png
│ ├── Mask_25.png
│ ├── Mask_26.png
│ ├── Mask_27.png
│ ├── Mask_28.png
│ ├── Mask_29.png
│ ├── Mask_3.png
│ ├── Mask_30.png
│ ├── Mask_31.png
│ ├── Mask_32.png
│ ├── Mask_33.png
│ ├── Mask_34.png
│ ├── Mask_35.png
│ ├── Mask_36.png
│ ├── Mask_37.png
│ ├── Mask_38.png
│ ├── Mask_39.png
│ ├── Mask_4.png
│ ├── Mask_40.png
│ ├── Mask_41.png
│ ├── Mask_42.png
│ ├── Mask_43.png
│ ├── Mask_44.png
│ ├── Mask_45.png
│ ├── Mask_46.png
│ ├── Mask_47.png
│ ├── Mask_48.png
│ ├── Mask_49.png
│ ├── Mask_5.png
│ ├── Mask_50.png
│ ├── Mask_51.png
│ ├── Mask_52.png
│ ├── Mask_53.png
│ ├── Mask_54.png
│ ├── Mask_55.png
│ ├── Mask_56.png
│ ├── Mask_57.png
│ ├── Mask_58.png
│ ├── Mask_59.png
│ ├── Mask_6.png
│ ├── Mask_60.png
│ ├── Mask_61.png
│ ├── Mask_62.png
│ ├── Mask_63.png
│ ├── Mask_64.png
│ ├── Mask_65.png
│ ├── Mask_66.png
│ ├── Mask_67.png
│ ├── Mask_68.png
│ ├── Mask_69.png
│ ├── Mask_7.png
│ ├── Mask_70.png
│ ├── Mask_71.png
│ ├── Mask_72.png
│ ├── Mask_73.png
│ ├── Mask_74.png
│ ├── Mask_75.png
│ ├── Mask_76.png
│ ├── Mask_77.png
│ ├── Mask_78.png
│ ├── Mask_79.png
│ ├── Mask_8.png
│ ├── Mask_80.png
│ ├── Mask_81.png
│ ├── Mask_82.png
│ ├── Mask_83.png
│ ├── Mask_84.png
│ ├── Mask_85.png
│ ├── Mask_86.png
│ ├── Mask_87.png
│ ├── Mask_88.png
│ ├── Mask_89.png
│ ├── Mask_9.png
│ ├── Mask_90.png
│ ├── Mask_91.png
│ ├── Mask_92.png
│ ├── Mask_93.png
│ ├── Mask_94.png
│ ├── Mask_95.png
│ ├── Mask_96.png
│ ├── Mask_97.png
│ ├── Mask_98.png
│ └── Mask_99.png
├── dataloader
├── __init__.py
├── image_load.py
└── utils.py
├── lib
├── __init__.py
├── extract_patches.py
├── generate_images.py
├── utils.py
└── visualization.py
├── model
├── __init__.py
├── clean_checkpoints.py
├── eval.py
├── load_data.py
├── predict.py
├── unet_model.py
├── unet_parts.py
└── utils.py
├── notebooks
├── Image_generation.ipynb
├── Image_predict.ipynb
└── Image_preparation.ipynb
├── params.json
├── pictures
├── Image_patches.png
├── Input_data.png
├── Model_prediction.png
└── Model_training.png
├── requirements.txt
└── train.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Python
2 | __pycache__/
3 | *.pyc
4 |
5 | # Mac/OSX
6 | .DS_Store
7 |
8 | # Jupyter Notebook
9 | .ipynb_checkpoints
10 |
11 | # IPython
12 | profile_default/
13 | ipython_config.py
14 |
15 | # Model checkpoints
16 | checkpoints/
17 | *.pth
18 |
19 | # Tensorboard summaries
20 | runs/
21 | events.*
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # unet-multiclass-pytorch
2 |
3 | Multiclass semantic segmentation using U-Net architecture combined with strong image augmentation (i.e. patch training and inference) tested on sythetic images
4 |
5 | ## Background
6 | This project combines (i) the U-Net archicture [1], as implemented in PyTorch by Milesial [2], with (ii) the patch training and inference technique implemented by Orobix for retina blood vessel segmentation [3], and extend them to a broad class of multi-class semantic segmentation tasks with small numbers of images and labels
7 |
8 | ## Project structure
9 | ```
10 | unet-multiclass-pytorch/
11 | - checkpoints/
12 | - dataloader/
13 | - .gitignore
14 | - lib/
15 | - model/
16 | - notebooks/
17 | - parameters.json
18 | - runs/
19 | - README.md
20 | - requirements.txt
21 | - train.py
22 | ```
23 | in which:
24 | - `checkpoints/` contains PyTorch U-Net model parameters
25 | - `dataloader/` contains functions for loading raw data
26 | - `lib/` contains functions for generating and processing training data, and for model visualization
27 | - `model/` contains model parts and model related functions
28 | - `notebooks/` contains jupyter notebooks for preparing training data, and for model inference and evaluation
29 | - `parameters.json` define all the parameters of the analysis
30 | - `runs/` contains Tensorboard summary files
31 | - `train.py` is the main script for model training
32 |
33 | ## Synthetic image generation
34 | Syntethic images and masks of size 400 by 200 are generated through the [`image_generation.ipynb`](./notebooks/Image_generation.ipynb) notebook as shown below. Randomly oriented lines and ellipses with variable gray scale intensity are placed onto a Gaussian noise background. The images are stored into the `data` folder as:
35 | ```
36 | .data/
37 | - images_training # (100 images)
38 | - images_test # (10 images)
39 | ```
40 |
41 |

42 |
43 |
44 | ## Patches preparation
45 | Training images and masks are prepared using the [`Image_preparation`](./notebooks/Image_preparation.ipynb) notebook. Square patches are extracted at random locations following [Orobix](https://github.com/orobix/retina-unet) approach, as demonstrated below. In this project 20 patches of size 96 by 96 are extracted per image. Additional augmentation for each pactch consists of all combinations of up/down and right/left flipping.
46 |
47 |

48 |
49 |
50 | The notebook generates folders and images into the `data` folder as
51 | ```
52 | ./data/patches_s96/:
53 | - images/:
54 | - p0.png
55 | - ...
56 | - pN.png
57 | - masks/:
58 | - p0.png
59 | - ...
60 | - pN.png
61 | ```
62 |
63 | ## Model training and evaluation
64 | The following command is an example to train the model for 100 epochs, with batch size 16, and learning rate 0.01, using `patches_s96` dataset:
65 | ```
66 | python train.py -e 100 -l 0.01 -b 16 -f patches_s96
67 | ```
68 |
69 | Multiclass cross entropy loss function is used with SGD optimizer. The learning rate is decreased towards the second half of the epochs in order to stabilize the model training. Model performance is measured using mean Intersection Over Union (mIoU) across all the classes following [Keras](https://github.com/tensorflow/tensorflow/blob/v2.3.0/tensorflow/python/keras/metrics.py) approach. During training the model is evaluated on 10% of the patches dataset. The mean IoU obtained on the patches evaluation set is 0.98, as shown below
70 |
71 |
72 |
73 |
74 | ## Model inference
75 | At inference stage patches are slided across the image to segment with a 50% overlapping as a stride, and the average probability is calculated for each class, similarly to [Orobix](https://github.com/orobix/retina-unet) approach. The mean IoU obtained on the full image evaluation set is 0.97.
76 |
77 | Below is an example of predicted segmentation mask for a full image. The final prediction is obtained as the argmax probability between {background, lines, ellipses}. The dark gray regions in the probabily maps result from patch overlap averaging.
78 |
79 |
80 |
81 |
82 | ## References
83 | [1] Ronneberger O., et al. U-Net: Convolutional Networks for Biomedical Image Segmentation, (2015)
84 | [2] https://github.com/milesial/Pytorch-UNet
85 | [3] https://github.com/orobix/retina-unet
--------------------------------------------------------------------------------
/data/images_test/images/Img_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/images/Img_0.png
--------------------------------------------------------------------------------
/data/images_test/images/Img_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/images/Img_1.png
--------------------------------------------------------------------------------
/data/images_test/images/Img_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/images/Img_2.png
--------------------------------------------------------------------------------
/data/images_test/images/Img_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/images/Img_3.png
--------------------------------------------------------------------------------
/data/images_test/images/Img_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/images/Img_4.png
--------------------------------------------------------------------------------
/data/images_test/images/Img_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/images/Img_5.png
--------------------------------------------------------------------------------
/data/images_test/images/Img_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/images/Img_6.png
--------------------------------------------------------------------------------
/data/images_test/images/Img_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/images/Img_7.png
--------------------------------------------------------------------------------
/data/images_test/images/Img_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/images/Img_8.png
--------------------------------------------------------------------------------
/data/images_test/images/Img_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/images/Img_9.png
--------------------------------------------------------------------------------
/data/images_test/masks/Mask_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/masks/Mask_0.png
--------------------------------------------------------------------------------
/data/images_test/masks/Mask_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/masks/Mask_1.png
--------------------------------------------------------------------------------
/data/images_test/masks/Mask_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/masks/Mask_2.png
--------------------------------------------------------------------------------
/data/images_test/masks/Mask_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/masks/Mask_3.png
--------------------------------------------------------------------------------
/data/images_test/masks/Mask_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/masks/Mask_4.png
--------------------------------------------------------------------------------
/data/images_test/masks/Mask_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/masks/Mask_5.png
--------------------------------------------------------------------------------
/data/images_test/masks/Mask_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/masks/Mask_6.png
--------------------------------------------------------------------------------
/data/images_test/masks/Mask_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/masks/Mask_7.png
--------------------------------------------------------------------------------
/data/images_test/masks/Mask_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/masks/Mask_8.png
--------------------------------------------------------------------------------
/data/images_test/masks/Mask_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_test/masks/Mask_9.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_0.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_1.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_10.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_11.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_12.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_13.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_14.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_15.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_16.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_17.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_18.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_19.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_2.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_20.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_21.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_22.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_23.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_24.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_25.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_25.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_26.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_26.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_27.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_27.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_28.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_28.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_29.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_3.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_30.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_31.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_31.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_32.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_33.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_33.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_34.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_34.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_35.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_35.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_36.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_37.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_38.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_38.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_39.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_39.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_4.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_40.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_41.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_41.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_42.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_42.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_43.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_43.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_44.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_44.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_45.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_45.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_46.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_46.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_47.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_47.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_48.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_49.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_49.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_5.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_50.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_51.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_51.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_52.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_52.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_53.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_53.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_54.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_54.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_55.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_55.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_56.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_56.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_57.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_58.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_59.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_59.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_6.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_60.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_61.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_61.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_62.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_62.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_63.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_63.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_64.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_65.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_65.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_66.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_66.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_67.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_67.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_68.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_68.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_69.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_69.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_7.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_70.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_71.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_71.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_72.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_73.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_73.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_74.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_74.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_75.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_75.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_76.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_77.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_77.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_78.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_78.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_79.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_79.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_8.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_80.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_81.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_81.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_82.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_82.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_83.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_83.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_84.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_84.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_85.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_85.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_86.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_86.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_87.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_88.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_88.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_89.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_89.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_9.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_90.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_90.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_91.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_91.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_92.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_92.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_93.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_93.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_94.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_94.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_95.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_95.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_96.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_97.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_97.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_98.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_98.png
--------------------------------------------------------------------------------
/data/images_train/images/Img_99.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/images/Img_99.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_0.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_1.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_10.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_11.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_12.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_13.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_14.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_15.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_16.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_17.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_18.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_19.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_2.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_20.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_21.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_22.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_23.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_24.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_25.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_25.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_26.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_26.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_27.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_27.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_28.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_28.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_29.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_3.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_30.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_31.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_31.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_32.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_33.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_33.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_34.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_34.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_35.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_35.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_36.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_37.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_38.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_38.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_39.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_39.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_4.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_40.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_41.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_41.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_42.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_42.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_43.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_43.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_44.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_44.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_45.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_45.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_46.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_46.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_47.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_47.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_48.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_49.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_49.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_5.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_50.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_51.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_51.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_52.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_52.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_53.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_53.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_54.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_54.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_55.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_55.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_56.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_56.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_57.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_58.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_59.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_59.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_6.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_60.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_61.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_61.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_62.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_62.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_63.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_63.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_64.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_65.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_65.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_66.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_66.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_67.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_67.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_68.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_68.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_69.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_69.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_7.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_70.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_71.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_71.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_72.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_73.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_73.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_74.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_74.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_75.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_75.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_76.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_77.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_77.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_78.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_78.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_79.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_79.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_8.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_80.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_81.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_81.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_82.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_82.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_83.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_83.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_84.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_84.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_85.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_85.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_86.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_86.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_87.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_88.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_88.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_89.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_89.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_9.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_90.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_90.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_91.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_91.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_92.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_92.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_93.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_93.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_94.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_94.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_95.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_95.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_96.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_97.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_97.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_98.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_98.png
--------------------------------------------------------------------------------
/data/images_train/masks/Mask_99.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/data/images_train/masks/Mask_99.png
--------------------------------------------------------------------------------
/dataloader/__init__.py:
--------------------------------------------------------------------------------
1 | from .utils import *
2 | from .image_load import *
3 |
--------------------------------------------------------------------------------
/dataloader/image_load.py:
--------------------------------------------------------------------------------
1 | import os
2 | from glob import glob
3 | import natsort
4 | import json
5 | import matplotlib.pyplot as plt
6 | import numpy as np
7 | import cv2
8 | from collections import Counter
9 | from PIL import Image
10 | import re
11 | import json
12 |
13 | from dataloader.utils import *
14 | from lib.utils import *
15 |
16 | def get_image_names(mode='train'):
17 |
18 | with open(PATH_PARAMETERS) as f:
19 | params = json.load(f)
20 | params = params['models_settings']
21 |
22 | if mode=='train':
23 | data_dir = params['train_dir']
24 | if mode=='test':
25 | data_dir = params['test_dir']
26 |
27 | file_names = []
28 | for filename in natsort.natsorted(glob(os.path.join(data_dir, params['image_folder'], '*'))):
29 | file_names.append(filename.split('/')[-1])
30 |
31 | return file_names
32 |
33 | def list_labels(file_names, mode='train'):
34 |
35 | with open(PATH_PARAMETERS) as f:
36 | params = json.load(f)
37 | params = params['models_settings']
38 |
39 | masks = load_masks(file_names,mode=mode)
40 | shape_to_label = params['label_to_value']
41 | label_to_shape = {v:k for k,v in shape_to_label.items()}
42 |
43 | labels = set()
44 | for mask in masks:
45 | mask = rgb2mask(mask)
46 | labels = labels.union(set([label_to_shape[label] for label in np.unique(mask)]))
47 |
48 | return labels
49 |
50 | def get_sizes(image_names, mode='train'):
51 |
52 | with open(PATH_PARAMETERS) as f:
53 | params = json.load(f)
54 | params = params['models_settings']
55 |
56 | if mode=='train':
57 | data_dir = params['train_dir']
58 | if mode=='test':
59 | data_dir = params['test_dir']
60 |
61 | h = []
62 | w = []
63 |
64 | for image_name in image_names:
65 |
66 | file_name = os.path.join(data_dir, params['image_folder'], image_name)
67 | image = np.array(Image.open(file_name))
68 |
69 | h.append(image.shape[0])
70 | w.append(image.shape[1])
71 |
72 | d = {'h-range': [min(h), max(h)],
73 | 'w-range': [min(w), max(w)]}
74 |
75 | return d
76 |
77 | def load_images(image_names, mode='train'):
78 |
79 | with open(PATH_PARAMETERS) as f:
80 | params = json.load(f)
81 | params = params['models_settings']
82 |
83 | if mode=='train':
84 | data_dir = params['train_dir']
85 | if mode=='test':
86 | data_dir = params['test_dir']
87 |
88 | resize_w = params['resize_width']
89 | equalize = bool(params['equalize'])
90 |
91 | images = []
92 | for image_name in image_names:
93 |
94 | file_name = os.path.join(data_dir, params['image_folder'], image_name)
95 | image = Image.open(file_name)
96 |
97 | if resize_w is not None:
98 | orig_w, orig_h = image.size[:2]
99 | resize_h = int(resize_w/orig_w*orig_h)
100 | image = np.array(image.resize((resize_w,resize_h), Image.BILINEAR))
101 |
102 | images.append(image)
103 |
104 | return images
105 |
106 | def load_masks(image_names, mode='train'):
107 |
108 | with open(PATH_PARAMETERS) as f:
109 | params = json.load(f)
110 | params = params['models_settings']
111 |
112 | if mode=='train':
113 | data_dir = params['train_dir']
114 | if mode=='test':
115 | data_dir = params['test_dir']
116 |
117 | resize_w = params['resize_width']
118 |
119 | masks = []
120 | for image_name in image_names:
121 | image_name = re.sub("Img", "Mask", image_name)
122 | file_name = os.path.join(data_dir, params['mask_folder'], image_name)
123 | mask = Image.open(file_name)
124 | if resize_w is not None:
125 | orig_w, orig_h = mask.size[:2]
126 | resize_h = int(resize_w/orig_w*orig_h)
127 | mask = mask.resize((resize_w,resize_h), Image.NEAREST)
128 |
129 | masks.append(np.array(mask))
130 |
131 | return masks
132 |
--------------------------------------------------------------------------------
/dataloader/utils.py:
--------------------------------------------------------------------------------
1 | # from https://github.com/wkentaro/labelme/blob/master/labelme/utils/shape.py
2 | import numpy as np
3 | import uuid
4 | import PIL.Image
5 | import PIL.ImageDraw
6 |
7 | PATH_PARAMETERS = '../params.json'
8 |
9 | def shapes_to_label(img_shape, shapes, label_name_to_value):
10 | cls = np.zeros(img_shape[:2], dtype=np.int32)
11 | ins = np.zeros_like(cls)
12 | instances = []
13 | for shape in shapes:
14 | points = shape['points']
15 | label = shape['label']
16 | group_id = shape.get('group_id')
17 | if group_id is None:
18 | group_id = uuid.uuid1()
19 | shape_type = shape.get('shape_type', None)
20 |
21 | cls_name = label
22 | instance = (cls_name, group_id)
23 |
24 | if instance not in instances:
25 | instances.append(instance)
26 | ins_id = instances.index(instance) + 1
27 | cls_id = label_name_to_value[cls_name]
28 |
29 | mask = shape_to_mask(img_shape[:2], points, shape_type)
30 | cls[mask] = cls_id
31 | ins[mask] = ins_id
32 |
33 | return cls, ins
34 |
35 | def shape_to_mask(img_shape, points, shape_type=None,
36 | line_width=10, point_size=5):
37 | mask = np.zeros(img_shape[:2], dtype=np.uint8)
38 | mask = PIL.Image.fromarray(mask)
39 | draw = PIL.ImageDraw.Draw(mask)
40 | xy = [tuple(point) for point in points]
41 | if shape_type == 'circle':
42 | assert len(xy) == 2, 'Shape of shape_type=circle must have 2 points'
43 | (cx, cy), (px, py) = xy
44 | d = math.sqrt((cx - px) ** 2 + (cy - py) ** 2)
45 | draw.ellipse([cx - d, cy - d, cx + d, cy + d], outline=1, fill=1)
46 | elif shape_type == 'rectangle':
47 | assert len(xy) == 2, 'Shape of shape_type=rectangle must have 2 points'
48 | draw.rectangle(xy, outline=1, fill=1)
49 | elif shape_type == 'line':
50 | assert len(xy) == 2, 'Shape of shape_type=line must have 2 points'
51 | draw.line(xy=xy, fill=1, width=line_width)
52 | elif shape_type == 'linestrip':
53 | draw.line(xy=xy, fill=1, width=line_width)
54 | elif shape_type == 'point':
55 | assert len(xy) == 1, 'Shape of shape_type=point must have 1 points'
56 | cx, cy = xy[0]
57 | r = point_size
58 | draw.ellipse([cx - r, cy - r, cx + r, cy + r], outline=1, fill=1)
59 | else:
60 | assert len(xy) > 2, 'Polygon must have points more than 2'
61 | draw.polygon(xy=xy, outline=1, fill=1)
62 | mask = np.array(mask, dtype=bool)
63 | return mask
64 |
--------------------------------------------------------------------------------
/lib/__init__.py:
--------------------------------------------------------------------------------
1 | from .extract_patches import *
2 | from .visualization import *
3 | from .generate_images import *
4 | from .utils import *
--------------------------------------------------------------------------------
/lib/extract_patches.py:
--------------------------------------------------------------------------------
1 | import os
2 | import random
3 | import cv2
4 | from pathlib import Path
5 | import numpy as np
6 | from PIL import Image
7 |
8 | from lib.utils import mask2rgb, make_image_dir
9 |
10 |
11 | def random_patches(image, mask, n=1000, patch_h=48, patch_w=48):
12 | '''
13 | Extract randomly cropped images and masks. Adapted from:
14 | https://github.com/orobix/retina-unet/blob/master/lib/extract_patches.py
15 |
16 | Inputs:
17 | image : array
18 | grayscale or RGB image
19 | mask : array
20 | RGB image
21 | n : int
22 | number of patches to extract from image
23 | patch_h : int
24 | patch height
25 | patch_w : int
26 | patch width
27 |
28 | Outputs:
29 | patches : list[array]
30 | extracted patches
31 | patch_masks : list[array]
32 | mask of extracted patches
33 | '''
34 |
35 | img_h, img_w = image.shape[:2]
36 |
37 | patches = []
38 | patch_masks = []
39 |
40 | for _ in range(n):
41 |
42 | x_center = random.randint(0+int(patch_w/2),img_w-int(patch_w/2))
43 | y_center = random.randint(0+int(patch_h/2),img_h-int(patch_h/2))
44 |
45 | patch = image[y_center-int(patch_h/2):y_center+int(patch_h/2),x_center-int(patch_w/2):x_center+int(patch_w/2)]
46 | patch_mask = mask[y_center-int(patch_h/2):y_center+int(patch_h/2),x_center-int(patch_w/2):x_center+int(patch_w/2)]
47 |
48 | patches.append(patch)
49 | patch_masks.append(patch_mask)
50 |
51 | return patches, patch_masks
52 |
53 | def input_filled_mirroring(x, e = 10):
54 | '''Fill missing data by mirroring the input image contours (see Figure 2 from Ronneberger et al.).
55 | Adapted from https://github.com/hansbu/CSE527_FinalProject/blob/master/Utils.py
56 |
57 | Inputs:
58 | x : array
59 | grayscale or RGB image patch
60 |
61 | Outputs:
62 | y : array
63 | expanded grayscale or RGB image patch
64 |
65 | '''
66 | h, w = np.shape(x)[0], np.shape(x)[1]
67 | y = np.zeros((h + e * 2, w + e * 2))
68 | y[e:h + e, e:w + e] = x
69 | y[e:e + h, 0:e] = np.flip(y[e:e + h, e:2 * e], 1) # flip vertically
70 | y[e:e + h, e + w:2 * e + w] = np.flip(y[e:e + h, w:e + w], 1) # flip vertically
71 | y[0:e, 0:2 * e + w] = np.flip(y[e:2 * e, 0:2 * e + w], 0) # flip horizontally
72 | y[e + h:2 * e + h, 0:2 * e + w] = np.flip(y[h:e + h, 0:2 * e + w], 0) # flip horizontally
73 | return y
74 |
75 | def augment_rectangular(data):
76 | '''agument annotation masks with all combinations of flipping up&down and left&right
77 |
78 | Inputs:
79 | data : tuple[list]
80 | list of patch images and masks
81 |
82 | Outputs:
83 | data_aug : tuple[list]
84 | list of augmented patch images and masks
85 |
86 | '''
87 |
88 | data_aug = []
89 | for patch,mask in data:
90 | patch_ud = np.flipud(patch)
91 | mask_ud = np.flipud(mask)
92 | patch_lr = np.fliplr(patch)
93 | mask_lr = np.fliplr(mask)
94 | patch_lr_ud = np.flipud(patch_lr)
95 | mask_lr_ud = np.flipud(mask_lr)
96 |
97 | data_aug.extend([(patch,mask), (patch_lr,mask_lr), (patch_ud,mask_ud), (patch_lr_ud,mask_lr_ud)])
98 |
99 | return data_aug
100 |
101 | def save_patches(export_dir, data):
102 | '''Export patches and masks for model training
103 |
104 | Inputs:
105 | export_dir : str
106 | path of directory in which images will be saved
107 | data : tuple[list]
108 | list of patch images and masks
109 |
110 | Outputs:
111 | None
112 | '''
113 |
114 | save_dir_images = os.path.join(export_dir, 'images')
115 | save_dir_masks = os.path.join(export_dir, 'masks')
116 |
117 | make_image_dir(save_dir_images)
118 | make_image_dir(save_dir_masks)
119 |
120 | for i, (patch, patch_mask) in enumerate(data):
121 |
122 | file_name = f'p{i}'
123 | save_image_path = os.path.join(save_dir_images, file_name + '.png')
124 | save_mask_path = os.path.join(save_dir_masks, file_name + '.png')
125 |
126 | patch = Image.fromarray(np.uint8(patch))
127 | patch_mask = Image.fromarray(mask2rgb(patch_mask))
128 |
129 | patch.save(save_image_path)
130 | patch_mask.save(save_mask_path)
--------------------------------------------------------------------------------
/lib/generate_images.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from skimage.morphology import dilation, disk
3 | from skimage.draw import line,ellipse
4 | from scipy.stats import truncnorm
5 | import os
6 | import json
7 |
8 | from .utils import mask2rgb
9 |
10 | PATH_PARAMETERS = '../params.json'
11 |
12 |
13 | def make_background(img_w, img_h, mean=0.8, std=0.05, clip_min=0.6, clip_max=1.0):
14 | '''
15 | Generate Truncated Gaussian noise image background
16 |
17 | Inputs:
18 | img_w : int
19 | image width
20 | img_wh : int
21 | image height
22 | mean : float
23 | mean of Gaussian
24 | std : float
25 | std of Gaussian
26 | clip_min : float
27 | min of Truncated Gaussian
28 | clip_max : float
29 | max of Truncated Gaussian
30 |
31 | Outputs:
32 | background : array
33 | background image
34 | '''
35 |
36 | a, b = (clip_min - mean) / std, (clip_max - mean) / std
37 | background = truncnorm.rvs(a, b, loc=mean, scale=std, size=(img_h,img_w))
38 |
39 | return background
40 |
41 | def make_ellipse(img_w, img_h, centre_r, centre_c, radius_r, radius_c, angle_deg):
42 | '''
43 | Generate row, col coordinates of an elliptic region onto an image
44 |
45 | Inputs:
46 | img_w : int
47 | image width
48 | img_h : int
49 | image height
50 | centre_r : int
51 | row center coordinate
52 | centre_c : int
53 | column center coordinate
54 | radius_c : int
55 | radius along colum coordinate
56 | radius_r : int
57 | radius along row coordinate
58 | angle_deg : int
59 | orientation of ellipse in degree wrt column coordinate
60 |
61 | Outputs:
62 | (rows, columns) : tuple[list]
63 | lists of coordinate of the ellipse region in for rows and columns
64 | '''
65 |
66 | image_ellipse = np.zeros((img_h,img_w),dtype=bool)
67 | rr, cc = ellipse(centre_r, centre_c, radius_r, radius_c, rotation=np.deg2rad(angle_deg))
68 | mask_rr = rr>=img_h
69 | mask_cc = cc>=img_w
70 | rr[mask_rr] = 0
71 | cc[mask_cc] = cc[mask_cc]-img_w
72 | image_ellipse[rr, cc] = True
73 |
74 | return np.nonzero(image_ellipse)
75 |
76 | def make_line(width,height,xc,yc,theta,l,thickness):
77 | '''
78 | Generate row, col coordinates of a line onto an image
79 |
80 | Inputs:
81 | width : int
82 | image width
83 | height : int
84 | image height
85 | xc : int
86 | center of the line in column coordinates
87 | yc : int
88 | center of the line in row coordinates
89 | theta : int
90 | orientation of the line in degree wrt column coordinates
91 | thickness : int
92 | thickness of the line
93 |
94 | Outputs:
95 | (rows, columns) : tuple[list]
96 | lists of coordinate of the line region in for rows and columns
97 | '''
98 |
99 | theta = np.deg2rad(-theta)
100 | # line end points
101 | xa = int(xc+l/2*np.cos(theta))
102 | ya = int(yc+l/2*np.sin(theta))
103 | xb = int(xc-l/2*np.cos(theta))
104 | yb = int(yc-l/2*np.sin(theta))
105 | # draw line mask
106 | img_line = np.zeros((height,width),dtype=bool)
107 | rr, cc = line(ya, xa, yb, xb)
108 | mask = (cc>=0) & (cc=0) & (rr 0:
18 | for checkpoint in checkpoints_to_remove:
19 | os.remove(checkpoint)
20 |
21 |
22 | def get_args():
23 |
24 | parser = OptionParser()
25 | parser.add_option('-d', '--dir', dest='dir', default='../checkpoints', help='checkpoints directory')
26 |
27 | (options, args) = parser.parse_args()
28 | return options
29 |
30 | if __name__ == '__main__':
31 |
32 | args = get_args()
33 | print('Removing all checkpoints but the last one in ', args.dir)
34 | remove_checkpoints(args.dir) #
--------------------------------------------------------------------------------
/model/eval.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import numpy as np
3 | from sklearn.metrics import confusion_matrix
4 |
5 | def compute_IoU(cm):
6 | '''
7 | Adapted from:
8 | https://github.com/davidtvs/PyTorch-ENet/blob/master/metric/iou.py
9 | https://github.com/tensorflow/tensorflow/blob/v2.3.0/tensorflow/python/keras/metrics.py#L2716-L2844
10 | '''
11 |
12 | sum_over_row = cm.sum(axis=0)
13 | sum_over_col = cm.sum(axis=1)
14 | true_positives = np.diag(cm)
15 |
16 | # sum_over_row + sum_over_col = 2 * true_positives + false_positives + false_negatives.
17 | denominator = sum_over_row + sum_over_col - true_positives
18 |
19 | iou = true_positives / denominator
20 |
21 | return iou, np.nanmean(iou)
22 |
23 | def eval_net_loader(net, val_loader, n_classes, device='cpu'):
24 |
25 | net.eval()
26 | labels = np.arange(n_classes)
27 | cm = np.zeros((n_classes,n_classes))
28 |
29 | for i, sample_batch in enumerate(val_loader):
30 | imgs = sample_batch['image']
31 | true_masks = sample_batch['mask']
32 |
33 | imgs = imgs.to(device)
34 | true_masks = true_masks.to(device)
35 |
36 | outputs = net(imgs)
37 | probs = torch.softmax(outputs, dim=1)
38 | preds = torch.argmax(probs, dim=1)
39 |
40 | for j in range(len(true_masks)):
41 | true = true_masks[j].cpu().detach().numpy().flatten()
42 | pred = preds[j].cpu().detach().numpy().flatten()
43 | cm += confusion_matrix(true, pred, labels=labels)
44 |
45 | class_iou, mean_iou = compute_IoU(cm)
46 |
47 | return class_iou, mean_iou
48 |
49 | def IoU(mask_true, mask_pred, n_classes=2):
50 |
51 | labels = np.arange(n_classes)
52 | cm = confusion_matrix(mask_true.flatten(), mask_pred.flatten(), labels=labels)
53 |
54 | return compute_IoU(cm)
--------------------------------------------------------------------------------
/model/load_data.py:
--------------------------------------------------------------------------------
1 | import os
2 | from glob import glob
3 | import natsort
4 | import numpy as np
5 | from PIL import Image
6 | from torch.utils.data import Dataset, DataLoader, random_split
7 | from torchvision import transforms
8 | import torch
9 |
10 | from lib.utils import rgb2mask
11 |
12 | class CoreDataset(Dataset):
13 |
14 | def __init__(self, path, transform=None):
15 | self.path_images = natsort.natsorted(glob(os.path.join(path, 'images', '*.png')))
16 | self.path_masks = natsort.natsorted(glob(os.path.join(path, 'masks', '*.png')))
17 | self.transform = transform
18 |
19 | def __len__(self):
20 | return len(self.path_images)
21 |
22 | def __getitem__(self, idx):
23 |
24 | image = Image.open(self.path_images[idx])
25 | mask = Image.open(self.path_masks[idx])
26 |
27 | sample = {'image':image, 'mask':mask}
28 |
29 | if self.transform:
30 | sample = self.transform(sample)
31 |
32 | return sample
33 |
34 | # add image normalization transform at some point
35 |
36 | class ToTensor(object):
37 | """Convert ndarrays in sample to Tensors."""
38 |
39 | def __call__(self, sample):
40 |
41 | image, mask = sample['image'], sample['mask']
42 | # standard scaling would be probably better then dividing by 255 (subtract mean and divide by std of the dataset)
43 | image = np.array(image)/255
44 | # convert colors to "flat" labels
45 | mask = rgb2mask(np.array(mask))
46 | sample = {'image': torch.from_numpy(image).permute(2,0,1).float(),
47 | 'mask': torch.from_numpy(mask).long(),
48 | }
49 |
50 | return sample
51 |
52 | def make_datasets(path, val_ratio):
53 | dataset = CoreDataset(path, transform = transforms.Compose([ToTensor()]))
54 | val_len = int(val_ratio*len(dataset))
55 | lengths = [len(dataset)-val_len, val_len]
56 | train_dataset, val_dataset = random_split(dataset, lengths)
57 |
58 | return train_dataset, val_dataset
59 |
60 |
61 | def make_dataloaders(path, val_ratio, params):
62 | train_dataset, val_dataset = make_datasets(path, val_ratio)
63 | train_loader = DataLoader(train_dataset, drop_last=True, **params)
64 | val_loader = DataLoader(val_dataset, drop_last=True, **params)
65 |
66 | return train_loader, val_loader
--------------------------------------------------------------------------------
/model/predict.py:
--------------------------------------------------------------------------------
1 | import os
2 | import numpy as np
3 | import torch
4 | import torch.nn as nn
5 | from .unet_model import UNet
6 |
7 | class UnetFracture:
8 |
9 | def __init__(self, params, model_dir='..', e=5):
10 |
11 | self.model_path = os.path.join(model_dir,params['path'])
12 | self.patch_w = params['patch_width']
13 | self.patch_h = params['patch_height']
14 | self.stride_w = params['stride_horizontal']
15 | self.stride_h = params['stride_vertical']
16 | self.n_channels = params['n_channels']
17 | self.n_classes = params['n_classes']
18 | self.e = e
19 |
20 | def initialize(self):
21 |
22 | self.device = ("cuda" if torch.cuda.is_available() else "cpu" )
23 | self.net = UNet(n_channels=self.n_channels, n_classes=self.n_classes)
24 | try:
25 | self.net.load_state_dict(torch.load(self.model_path))
26 | except RuntimeError:
27 | self.net = nn.DataParallel(self.net)
28 | self.net.load_state_dict(torch.load(self.model_path))
29 | self.net.to(self.device)
30 |
31 | self.net.eval()
32 |
33 | def expand_image(self, image, mask=None):
34 |
35 | self.img_h, self.img_w = image.shape[:2]
36 |
37 | self.n_w = (self.img_w-self.patch_w)//self.stride_w+1
38 | self.n_h = (self.img_h-self.patch_h)//self.stride_h+1
39 |
40 | leftover_w = (self.img_w-self.patch_w)%self.stride_w
41 | leftover_h = (self.img_h-self.patch_h)%self.stride_h
42 |
43 | img_expand = np.zeros((self.img_h+self.stride_h-leftover_h, self.img_w+self.stride_w-leftover_w))
44 | if len(image.shape)==3:
45 | img_expand = np.repeat(img_expand[:, :, np.newaxis], 3, axis=2)
46 |
47 | img_expand[:self.img_h,:self.img_w] = image
48 |
49 | return img_expand
50 |
51 | def predict_proba(self, image):
52 |
53 | assert image.dtype.type == np.uint8, 'image format should be uint8 (PIL Image)'
54 |
55 | image = image/255 # normalize between 0-1 - consired standard scaling instead
56 | img_expand = self.expand_image(image)
57 |
58 | img_prob = np.zeros(img_expand.shape[:2]+(self.n_classes,))
59 | # img_sum is used to count pixel oberlapping during for sliding patch prediction
60 | img_sum = np.zeros(img_expand.shape[:2])
61 |
62 |
63 | for i_h in range(self.n_h+1):
64 |
65 | start_h = i_h*self.stride_h
66 | end_h = start_h+self.patch_h
67 |
68 | for i_w in range(self.n_w+1):
69 |
70 | start_w = i_w*self.stride_w
71 | end_w = start_w+self.patch_w
72 |
73 | patch = img_expand[start_h:end_h,start_w:end_w]
74 | # mirror patch contours before prediction - U-Net overlap-tile strategy
75 | patch = input_filled_mirroring(patch, e=self.e)
76 |
77 | if len(patch.shape)==2:
78 | patch_tensor = torch.from_numpy(patch).unsqueeze(0).unsqueeze(0).float()
79 | if len(patch.shape)==3:
80 | patch_tensor = torch.from_numpy(patch).permute(2,0,1).unsqueeze(0).float()
81 |
82 | pred = self.net(patch_tensor.to(self.device))
83 |
84 | prob_predict = torch.sigmoid(pred).squeeze().detach().cpu().numpy()
85 | prob_predict = np.transpose(prob_predict, (1,2,0))
86 |
87 | # crop patch contours after prediction
88 | img_prob[start_h:end_h,start_w:end_w,:] += prob_predict[self.e:-self.e,self.e:-self.e,:]
89 | img_sum[start_h:end_h,start_w:end_w] += 1
90 |
91 | img_sum = np.dstack([img_sum]*self.n_classes)
92 | avg_prob = img_prob/img_sum
93 | avg_prob = avg_prob[:self.img_h,:self.img_w,:] # crop to original image size
94 |
95 | return avg_prob
96 |
97 | def predict_image(self, image):
98 |
99 | prob_predict = self.predict_proba(image)
100 | mask = np.argmax(prob_predict, axis=2)
101 |
102 | return mask
103 |
104 |
105 | def input_filled_mirroring(x, e = 10):
106 | '''fill missing data by mirroring the input image contours
107 | from https://github.com/hansbu/CSE527_FinalProject/blob/master/Utils.py
108 | '''
109 | h, w = np.shape(x)[0], np.shape(x)[1]
110 | y = np.zeros((h + e * 2, w + e * 2))
111 | if len(x.shape)==3:
112 | y = np.repeat(y[:, :, np.newaxis], 3, axis=2)
113 | y[e:h + e, e:w + e] = x
114 | y[e:e + h, 0:e] = np.flip(y[e:e + h, e:2 * e], 1) # flip vertically
115 | y[e:e + h, e + w:2 * e + w] = np.flip(y[e:e + h, w:e + w], 1) # flip vertically
116 | y[0:e, 0:2 * e + w] = np.flip(y[e:2 * e, 0:2 * e + w], 0) # flip horizontally
117 | y[e + h:2 * e + h, 0:2 * e + w] = np.flip(y[h:e + h, 0:2 * e + w], 0) # flip horizontally
118 | return y
--------------------------------------------------------------------------------
/model/unet_model.py:
--------------------------------------------------------------------------------
1 | # full assembly of the sub-parts to form the complete net
2 |
3 | import torch.nn.functional as F
4 |
5 | from .unet_parts import *
6 |
7 | class UNet(nn.Module):
8 | def __init__(self, n_channels, n_classes):
9 | super(UNet, self).__init__()
10 | self.inc = inconv(n_channels, 64)
11 | self.down1 = down(64, 128)
12 | self.down2 = down(128, 256)
13 | self.down3 = down(256, 512)
14 | self.down4 = down(512, 512)
15 | self.up1 = up(1024, 256)
16 | self.up2 = up(512, 128)
17 | self.up3 = up(256, 64)
18 | self.up4 = up(128, 64)
19 | self.outc = outconv(64, n_classes)
20 |
21 | def forward(self, x):
22 | x1 = self.inc(x)
23 | x2 = self.down1(x1)
24 | x3 = self.down2(x2)
25 | x4 = self.down3(x3)
26 | x5 = self.down4(x4)
27 | x = self.up1(x5, x4)
28 | x = self.up2(x, x3)
29 | x = self.up3(x, x2)
30 | x = self.up4(x, x1)
31 | x = self.outc(x)
32 | return F.sigmoid(x)
33 |
--------------------------------------------------------------------------------
/model/unet_parts.py:
--------------------------------------------------------------------------------
1 | # sub-parts of the U-Net model
2 |
3 | import torch
4 | import torch.nn as nn
5 | import torch.nn.functional as F
6 |
7 |
8 | class double_conv(nn.Module):
9 | '''(conv => BN => ReLU) * 2'''
10 | def __init__(self, in_ch, out_ch):
11 | super(double_conv, self).__init__()
12 | self.conv = nn.Sequential(
13 | nn.Conv2d(in_ch, out_ch, 3, padding=1),
14 | nn.BatchNorm2d(out_ch),
15 | nn.ReLU(inplace=True),
16 | nn.Conv2d(out_ch, out_ch, 3, padding=1),
17 | nn.BatchNorm2d(out_ch),
18 | nn.ReLU(inplace=True)
19 | )
20 |
21 | def forward(self, x):
22 | x = self.conv(x)
23 | return x
24 |
25 |
26 | class inconv(nn.Module):
27 | def __init__(self, in_ch, out_ch):
28 | super(inconv, self).__init__()
29 | self.conv = double_conv(in_ch, out_ch)
30 |
31 | def forward(self, x):
32 | x = self.conv(x)
33 | return x
34 |
35 |
36 | class down(nn.Module):
37 | def __init__(self, in_ch, out_ch):
38 | super(down, self).__init__()
39 | self.mpconv = nn.Sequential(
40 | nn.MaxPool2d(2),
41 | double_conv(in_ch, out_ch)
42 | )
43 |
44 | def forward(self, x):
45 | x = self.mpconv(x)
46 | return x
47 |
48 |
49 | class up(nn.Module):
50 | def __init__(self, in_ch, out_ch, bilinear=True):
51 | super(up, self).__init__()
52 |
53 | # would be a nice idea if the upsampling could be learned too,
54 | # but my machine do not have enough memory to handle all those weights
55 | if bilinear:
56 | self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
57 | else:
58 | self.up = nn.ConvTranspose2d(in_ch//2, in_ch//2, 2, stride=2)
59 |
60 | self.conv = double_conv(in_ch, out_ch)
61 |
62 | def forward(self, x1, x2):
63 | x1 = self.up(x1)
64 |
65 | # input is CHW
66 | diffY = x2.size()[2] - x1.size()[2]
67 | diffX = x2.size()[3] - x1.size()[3]
68 |
69 | x1 = F.pad(x1, (diffX // 2, diffX - diffX//2,
70 | diffY // 2, diffY - diffY//2))
71 |
72 | # for padding issues, see
73 | # https://github.com/HaiyongJiang/U-Net-Pytorch-Unstructured-Buggy/commit/0e854509c2cea854e247a9c615f175f76fbb2e3a
74 | # https://github.com/xiaopeng-liao/Pytorch-UNet/commit/8ebac70e633bac59fc22bb5195e513d5832fb3bd
75 |
76 | x = torch.cat([x2, x1], dim=1)
77 | x = self.conv(x)
78 | return x
79 |
80 |
81 | class outconv(nn.Module):
82 | def __init__(self, in_ch, out_ch):
83 | super(outconv, self).__init__()
84 | self.conv = nn.Conv2d(in_ch, out_ch, 1)
85 |
86 | def forward(self, x):
87 | x = self.conv(x)
88 | return x
89 |
--------------------------------------------------------------------------------
/model/utils.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | import shutil
3 |
4 | def make_checkpoint_dir(dir_checkpoint):
5 |
6 | path = Path(dir_checkpoint)
7 | # remove folder if it exists
8 | if path.exists():
9 | shutil.rmtree(path)
10 | path.mkdir(parents=True, exist_ok=False)
--------------------------------------------------------------------------------
/params.json:
--------------------------------------------------------------------------------
1 | {
2 | "models_settings":{
3 | "resize_width": 256,
4 | "equalize": "True",
5 | "patch_width": 96,
6 | "patch_height": 96,
7 | "label_to_value": {
8 | "_background_": 0,
9 | "line": 1,
10 | "ellipse": 2
11 | },
12 | "train_dir": "../data/images_train",
13 | "test_dir": "../data/images_test",
14 | "image_folder": "images",
15 | "mask_folder": "masks"
16 | },
17 | "shape_segmentation": {
18 | "patches_s96": {
19 | "path": "checkpoints/patches_s96_b8/CP76.pth",
20 | "n_channels": 3,
21 | "n_classes": 3,
22 | "patch_height": 96,
23 | "patch_width": 96,
24 | "stride_vertical": 48,
25 | "stride_horizontal": 48,
26 | "description": "unet model trained on size 96 patches"
27 | }
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/pictures/Image_patches.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/pictures/Image_patches.png
--------------------------------------------------------------------------------
/pictures/Input_data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/pictures/Input_data.png
--------------------------------------------------------------------------------
/pictures/Model_prediction.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/pictures/Model_prediction.png
--------------------------------------------------------------------------------
/pictures/Model_training.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/France1/unet-multiclass-pytorch/74b4a6d579b3d919d22dbeff92735273ff46c4c2/pictures/Model_training.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pytorch
2 | jupyterlab
3 | natsort
4 | opencv-python
5 | scikit-image
6 | tensorboardX
7 | tb-nightly
--------------------------------------------------------------------------------
/train.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import os
3 | from optparse import OptionParser
4 | import numpy as np
5 |
6 | import torch
7 | import torch.nn as nn
8 | from torch import optim
9 | from tensorboardX import SummaryWriter
10 |
11 | from model import UNet, make_dataloaders, eval_net_loader, make_checkpoint_dir
12 | from lib import plot_net_predictions
13 |
14 |
15 | def train_epoch(epoch,train_loader,criterion,optimizer,batch_size,scheduler):
16 |
17 | net.train()
18 | epoch_loss = 0
19 |
20 | for i, sample_batch in enumerate(train_loader):
21 |
22 | imgs = sample_batch['image']
23 | true_masks = sample_batch['mask']
24 |
25 | imgs = imgs.to(device)
26 | true_masks = true_masks.to(device)
27 |
28 | outputs = net(imgs)
29 | probs = torch.softmax(outputs, dim=1)
30 | masks_pred = torch.argmax(probs, dim=1)
31 |
32 | loss = criterion(outputs, true_masks)
33 | epoch_loss += loss.item()
34 |
35 | print(f'epoch = {epoch+1:d}, iteration = {i:d}/{len(train_loader):d}, loss = {loss.item():.5f}')
36 | # save to summary
37 | if i%100==0:
38 | writer.add_scalar('train_loss_iter',
39 | loss.item(),
40 | i + len(train_loader) * epoch)
41 | writer.add_figure('predictions vs. actuals',
42 | plot_net_predictions(imgs, true_masks, masks_pred, batch_size),
43 | global_step = i + len(train_loader) * epoch)
44 |
45 | optimizer.zero_grad()
46 | loss.backward()
47 | optimizer.step()
48 |
49 | print(f'Epoch finished ! Loss: {epoch_loss/i:.2f}, lr:{scheduler.get_lr()}')
50 |
51 |
52 | def validate_epoch(epoch,train_loader,val_loader,device):
53 |
54 | class_iou, mean_iou = eval_net_loader(net, val_loader, 3, device)
55 | print('Class IoU:', ' '.join(f'{x:.3f}' for x in class_iou), f' | Mean IoU: {mean_iou:.3f}')
56 | # save to summary
57 | writer.add_scalar('mean_iou', mean_iou, len(train_loader) * (epoch+1))
58 |
59 | return mean_iou
60 |
61 |
62 | def train_net(train_loader, val_loader, net, device, epochs=5, batch_size=1, lr=0.1, save_cp=True):
63 |
64 | # params = {'batch_size': batch_size, 'shuffle': True, 'num_workers': 4}
65 | # train_loader, val_loader = make_dataloaders(dir_data, val_ratio, params)
66 |
67 | print(f'''
68 | Starting training:
69 | Epochs: {epochs}
70 | Batch size: {batch_size}
71 | Learning rate: {lr}
72 | Training size: {len(train_loader.dataset)}
73 | Validation size: {len(val_loader.dataset)}
74 | Checkpoints: {str(save_cp)}
75 | Device: {str(device)}
76 | ''')
77 |
78 | optimizer = optim.SGD(net. parameters(),lr=lr, momentum=0.9, weight_decay=0.0005)
79 | # multiply learning rate by 0.1 after 30% of epochs
80 | scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=int(0.3*epochs), gamma=0.1)
81 |
82 | criterion = nn.CrossEntropyLoss()
83 | # weighted cross entropy loss
84 | # criterion = nn.CrossEntropyLoss(weight=torch.tensor([0.3, 8.2, 1.0]).cuda())
85 |
86 | best_precision = 0
87 | for epoch in range(epochs):
88 |
89 | print('Starting epoch {}/{}.'.format(epoch + 1, epochs))
90 | train_epoch(epoch,train_loader,criterion,optimizer,batch_size,scheduler)
91 | precision = validate_epoch(epoch,train_loader,val_loader,device)
92 | scheduler.step()
93 |
94 | if save_cp and (precision>best_precision):
95 | state_dict = net.state_dict()
96 | if device=="cuda":
97 | state_dict = net.module.state_dict()
98 | torch.save(state_dict, dir_checkpoint+f'CP{epoch + 1}.pth')
99 | print('Checkpoint {} saved !'.format(epoch + 1))
100 | best_precision = precision
101 |
102 | writer.close()
103 |
104 |
105 | def get_args():
106 |
107 | parser = OptionParser()
108 | parser.add_option('-e', '--epochs', dest='epochs', default=5, type='int',
109 | help='number of epochs')
110 | parser.add_option('-b', '--batch-size', dest='batchsize', default=8,
111 | type='int', help='batch size')
112 | parser.add_option('-l', '--learning-rate', dest='lr', default=0.1,
113 | type='float', help='learning rate')
114 | parser.add_option('-c', '--load', dest='load',
115 | default=False, help='load file model')
116 | parser.add_option('-f', '--folder', dest='folder',
117 | default='', help='folder name')
118 |
119 | (options, args) = parser.parse_args()
120 | return options
121 |
122 |
123 | if __name__ == '__main__':
124 |
125 | device = ("cuda" if torch.cuda.is_available() else "cpu" )
126 | args = get_args()
127 |
128 | dir_data = f'./data/{args.folder}'
129 | dir_checkpoint = f'./checkpoints/{args.folder}_b{args.batchsize}/'
130 | dir_summary = f'./runs/{args.folder}_b{args.batchsize}'
131 | params = {'batch_size': args.batchsize, 'shuffle': True, 'num_workers': 4}
132 |
133 | make_checkpoint_dir(dir_checkpoint)
134 | writer = SummaryWriter(dir_summary)
135 |
136 | val_ratio=0.1
137 | train_loader, val_loader = make_dataloaders(dir_data, val_ratio, params)
138 |
139 | net = UNet(n_channels=3, n_classes=3)
140 | net.to(device)
141 |
142 | if args.load:
143 | net.load_state_dict(torch.load(args.load))
144 | print('Model loaded from {}'.format(args.load))
145 |
146 | # train model in parallel on multiple-GPUs
147 | if torch.cuda.device_count() > 1:
148 | print("Model training on", torch.cuda.device_count(), "GPUs")
149 | net = nn.DataParallel(net)
150 |
151 | try:
152 | train_net(train_loader, val_loader, net, device, epochs=args.epochs, batch_size=args.batchsize, lr=args.lr)
153 |
154 | except KeyboardInterrupt:
155 | torch.save(net.state_dict(), 'INTERRUPTED.pth')
156 | print('Saved interrupt')
157 | try:
158 | sys.exit(0)
159 | except SystemExit:
160 | os._exit(0)
161 |
--------------------------------------------------------------------------------