├── .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 | drawing 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 | drawing 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 | drawing 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 | drawing 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 | --------------------------------------------------------------------------------