{ "info": { "author": "Petrochenko Pavel", "author_email": "petrochenko.pavel.a@gmail.com", "bugtrack_url": null, "classifiers": [], "description": "\n# Segmentation Training Pipeline\n![Build status](https://travis-ci.com/musket-ml/segmentation_training_pipeline.svg?branch=master)\n\nThis package is a part of [Musket ML](https://musket-ml.com/) framework.\n\n## Reasons to use Segmentation Pipeline\nSegmentation Pipeline was developed with a focus of enabling to make fast and \nsimply-declared experiments, which can be easily stored, \nreproduced and compared to each other.\n\nSegmentation Pipeline has a lot of common parts with [Generic pipeline](https://musket-ml.github.io/webdocs/generic/), but it is easier to define an architecture of the network.\nAlso there are a number of segmentation-specific features.\n\nThe pipeline provides the following features:\n\n* Allows to describe experiments in a compact and expressive way\n* Provides a way to store and compare experiments in order to methodically find the best deap learning solution\n* Easy to share experiments and their results to work in a team\n* Experiment configurations are separated from model definitions\n* It is easy to configure network architecture\n* Provides great flexibility and extensibility via support of custom substances\n* Common blocks like an architecture, callbacks, model metrics, predictions vizualizers and others should be written once and be a part of a common library\n\n## Installation\n\n```\npip install segmentation_pipeline\n```\n*Note: this package requires python 3.6*\n\nThis package is a part of [Musket ML](https://musket-ml.com/) framework,\n it is recommended to install the whole collection of the framework\n packages at once using instructions [here](https://musket-ml.github.io/webdocs/generic/#installation).\n\n## Launching\n\n### Launching experiments\n\n`fit.py` script is designed to launch experiment training.\n\nIn order to run the experiment or a number of experiments, \n\nA typical command line may look like this:\n\n`musket fit --project \"path/to/project\" --name \"experiment_name\" --num_gpus=1 --gpus_per_net=1 --num_workers=1 --cache \"path/to/cache/folder\"`\n\n[--project](https://musket-ml.github.io/webdocs/segmentation/reference/#fitpy-project) points to the root of the [project](#project-structure)\n\n[--name](https://musket-ml.github.io/webdocs/segmentation/reference/#fitpy-name) is the name of the project sub-folder containing experiment yaml file.\n\n[--num_gpus](https://musket-ml.github.io/webdocs/segmentation/reference/#fitpy-num_gpus) sets number of GPUs to use during experiment launch.\n\n[--gpus_per_net](https://musket-ml.github.io/webdocs/segmentation/reference/#fitpy-gpus_per_net) is a maximum number of GPUs to use per single experiment.\n\n[--num_workers](https://musket-ml.github.io/webdocs/segmentation/reference/#fitpy-num_workers) sets number of workers to use.\n\n[--cache](https://musket-ml.github.io/webdocs/segmentation/reference/#fitpy-cache) points to a cache folder to store the temporary data.\n\nOther parameters can be found in the [fit script reference](https://musket-ml.github.io/webdocs/segmentation/reference/#fit-script-arguments)\n\n### Launching tasks\n\n`task.py` script is designed to launch experiment training.\n\nTasks must be defined in the project python scope and marked by an \nannotation like this:\n\n```python\nfrom musket_core import tasks, model\n@tasks.task\ndef measure2(m: model.ConnectedModel):\n return result\n```\n\nWorking directory *must* point to the `musket_core` root folder.\n\nIn order to run the experiment or a number of experiments, \n\nA typical command line may look like this:\n\n`python -m musket_core.task --project \"path/to/project\" --name \"experiment_name\" --task \"task_name\" --num_gpus=1 --gpus_per_net=1 --num_workers=1 --cache \"path/to/cache/folder\"`\n\n[--project](https://musket-ml.github.io/webdocs/segmentation/reference/#taskpy-project) points to the root of the [project](#project-structure)\n\n[--name](https://musket-ml.github.io/webdocs/segmentation/reference/#taskpy-name) is the name of the project sub-folder containing experiment yaml file.\n\n[--task](https://musket-ml.github.io/webdocs/segmentation/reference/#taskpy-name) is the name of the task function.\n\n[--num_gpus](https://musket-ml.github.io/webdocs/segmentation/reference/#taskpy-num_gpus) sets number of GPUs to use during experiment launch.\n\n[--gpus_per_net](https://musket-ml.github.io/webdocs/segmentation/reference/#taskpy-gpus_per_net) is a maximum number of GPUs to use per single experiment.\n\n[--num_workers](https://musket-ml.github.io/webdocs/segmentation/reference/#taskpy-num_workers) sets number of workers to use.\n\n[--cache](https://musket-ml.github.io/webdocs/segmentation/reference/#taskpy-cache) points to a cache folder to store the temporary data.\n\nOther parameters can be found in the [task script reference](https://musket-ml.github.io/webdocs/segmentation/reference/#task-script-arguments)\n\n### Launching project analysis\n\n`analize.py` script is designed to launch project-scope analysis.\n\nNote that only experiments, which training is already finished will be covered.\n\n`musket analize --inputFolder \"path/to/project\"`\n\n[--inputFolder](https://musket-ml.github.io/webdocs/segmentation/reference/#analyzepy-inputfolder) points to a folder to search for finished experiments in. Typically, project root.\n\nOther parameters can be found in the [analyze script reference](https://musket-ml.github.io/webdocs/segmentation/reference/#analyze-script-arguments)\n\n\n## Usage guide\n\n### Training a model\n\nLet's start from the absolutely minimalistic example. Let's say that you have two folders, one of them contains\njpeg images, and another one - png files with segmentation masks for these images. And you need to train a neural network\nthat will do segmentation for you. In this extremely simple setup all that you need is to type following 5\nlines of python code:\n```python\nfrom segmentation_pipeline.impl.datasets import SimplePNGMaskDataSet\nfrom segmentation_pipeline import segmentation\nds=SimplePNGMaskDataSet(\"./pics/train\",\"./pics/train_mask\")\ncfg = segmentation.parse(\"config.yaml\")\ncfg.fit(ds)\n```\n\nLooks simple, but there is a `config.yaml` file in the code, and probably it is the place where everything actually happens.\n\n```yaml\nbackbone: mobilenetv2 #let's select classifier backbone for our network \narchitecture: DeepLabV3 #let's select segmentation architecture that we would like to use\naugmentation:\n Fliplr: 0.5 #let's define some minimal augmentations on images\n Flipud: 0.5 \nclasses: 1 #we have just one class (mask or no mask)\nactivation: sigmoid #one class means that our last layer should use sigmoid activation\nencoder_weights: pascal_voc #we would like to start from network pretrained on pascal_voc dataset\nshape: [320, 320, 3] #This is our desired input image and mask size, everything will be resized to fit.\ntestSplit: 0.4\noptimizer: Adam #Adam optimizer is a good default choice\nbatch: 16 #Our batch size will be 16\nmetrics: #We would like to track some metrics\n - binary_accuracy \n - iou\nprimary_metric: val_binary_accuracy #and the most interesting metric is val_binary_accuracy\ncallbacks: #Let's configure some minimal callbacks\n EarlyStopping:\n patience: 15\n monitor: val_binary_accuracy\n verbose: 1\n ReduceLROnPlateau:\n patience: 4\n factor: 0.5\n monitor: val_binary_accuracy\n mode: auto\n cooldown: 5\n verbose: 1\nloss: binary_crossentropy #We use simple binary_crossentropy loss\nstages:\n - epochs: 100 #Let's go for 100 epochs\n```\n\nSo as you see, we have decomposed our task in two parts, *code that actually trains the model* and *experiment configuration*,\nwhich determines the model and how it should be trained from the set of predefined building blocks.\n\nMoreover, the whole fitting and prediction process can be launched with built-in script, \nthe only really required python code is dataset definition to let the system know, which data to load.\n\nWhat does this code actually do behind the scenes?\n\n- it splits your data into 5 folds, and trains one model per fold;\n- it takes care of model checkpointing, generates example image/mask/segmentation triples, collects training metrics. All this data will\n be stored in the folders just near your `config.yaml`;\n- All your folds are initialized from fixed default seed, so different experiments will use exactly the same train/validation splits\n\nAlso, datasets can be specified directly in your config file in more generic way, see examples ds_1, ds_2, ds_3 in \"segmentation_training_pipeline/examples/people\" folder. In this case you can just call cfg.fit() without providing dataset programmatically.\n\nLets discover what's going on in more details:\n\n#### General train properties\n\nLets take our standard example and check the following set of instructions:\n\n```yaml\ntestSplit: 0.4\noptimizer: Adam #Adam optimizer is a good default choice\nbatch: 16 #Our batch size will be 16\nmetrics: #We would like to track some metrics\n - binary_accuracy \n - iou\nprimary_metric: val_binary_accuracy #and the most interesting metric is val_binary_accuracy\nloss: binary_crossentropy #We use simple binary_crossentropy loss\n```\n\n[testSplit](https://musket-ml.github.io/webdocs/segmentation/reference/#testsplit) Splits the train set into two parts, using one part for train and leaving the other untouched for a later testing.\nThe split is shuffled. \n\n[optimizer](https://musket-ml.github.io/webdocs/segmentation/reference/#optimizer) sets the optimizer.\n\n[batch](https://musket-ml.github.io/webdocs/segmentation/reference/#batch) sets the training batch size.\n\n[metrics](https://musket-ml.github.io/webdocs/segmentation/reference/#metrics) sets the metrics to track during the training process. Metric calculation results will be printed in the console and to `metrics` folder of the experiment.\n\n[primary_metric](https://musket-ml.github.io/webdocs/segmentation/reference/#primary_metric) Metric to track during the training process. Metric calculation results will be printed in the console and to `metrics` folder of the experiment.\nBesides tracking, this metric will be also used by default for metric-related activity, in example, for decision regarding which epoch results are better.\n\n[loss](https://musket-ml.github.io/webdocs/segmentation/reference/#loss) sets the loss function. if your network has multiple outputs, you also may pass a list of loss functions (one per output) \n\nFramework supports composing loss as a weighted sum of predefined loss functions. For example, following construction\n```yaml\nloss: binary_crossentropy+0.1*dice_loss\n```\nwill result in loss function which is composed from `binary_crossentropy` and `dice_loss` functions.\n\nThere are many more properties to check in [Reference of root properties](https://musket-ml.github.io/webdocs/segmentation/reference/#pipeline-root-properties)\n\n#### Defining architecture\n\nLets take a look at the following part of our example:\n\n```yaml\nbackbone: mobilenetv2 #let's select classifier backbone for our network \narchitecture: DeepLabV3 #let's select segmentation architecture that we would like to use\nclasses: 1 #we have just one class (mask or no mask)\nactivation: sigmoid #one class means that our last layer should use sigmoid activation\nencoder_weights: pascal_voc #we would like to start from network pretrained on pascal_voc dataset\nshape: [320, 320, 3] #This is our desired input image and mask size, everything will be resized to fit.\n```\n\nThe following three properties are required to set:\n\n[backbone](https://musket-ml.github.io/webdocs/segmentation/reference/#backbone) This property configures encoder that should be used. Different kinds of `FPN`, `PSP`, `Linkenet`, `UNet` and more are supported.\n\n[architecture](https://musket-ml.github.io/webdocs/segmentation/reference/#architecture) This property configures decoder architecture that should be used. `net`, `Linknet`, `PSP`, `FPN` and more are supported.\n\n[classes](https://musket-ml.github.io/webdocs/segmentation/reference/#classes) sets the number of classes that should be used. \n\nThe following ones are optional, but commonly used:\n\n[activation](https://musket-ml.github.io/webdocs/segmentation/reference/#activation) sets activation function that should be used in last layer.\n\n[shape](https://musket-ml.github.io/webdocs/segmentation/reference/#shape) set the desired shape of the input picture and mask, in the form heigth, width, number of channels. Input will be resized to fit.\n\n[encoder_weights](https://musket-ml.github.io/webdocs/segmentation/reference/#encoder_weights) configures initial weights of the encoder.\n\n#### Image and Mask Augmentations\n\nFramework uses awesome [imgaug](https://github.com/aleju/imgaug) library for augmentation, so you only need to configure your augmentation process in declarative way like in the following example:\n\n```yaml\naugmentation: \n Fliplr: 0.5\n Flipud: 0.5\n Affine:\n scale: [0.8, 1.5] #random scalings\n translate_percent:\n x: [-0.2,0.2] #random shifts\n y: [-0.2,0.2]\n rotate: [-16, 16] #random rotations on -16,16 degrees\n shear: [-16, 16] #random shears on -16,16 degrees\n```\n[augmentation](https://musket-ml.github.io/webdocs/segmentation/reference/#augmentation) property defines [IMGAUG](https://imgaug.readthedocs.io) transformations sequence.\nEach object is mapped on [IMGAUG](https://imgaug.readthedocs.io) transformer by name, parameters are mapped too.\n\nIn this example, `Fliplr` and `Flipud` keys are automatically mapped on [Flip agugmenters](https://imgaug.readthedocs.io/en/latest/source/api_augmenters_flip.html),\ntheir `0.5` parameter is mapped on the first `p` parameter of the augmenter.\nNamed parameters are also mapped, in example `scale` key of `Affine` is mapped on `scale` parameter of [Affine augmenter](https://imgaug.readthedocs.io/en/latest/source/augmenters.html?highlight=affine#affine).\n\nOne interesting augementation option when doing background removal task is replacing backgrounds with random \nimages. We support this with `BackgroundReplacer` augmenter:\n\n```yaml\naugmentation:\n BackgroundReplacer:\n path: ./bg #path to folder with backgrounds\n rate: 0.5 #fraction of original backgrounds to preserve\n\n```\n\n#### Freezing and Unfreezing encoder\n\nFreezing encoder is often used with transfer learning. If you want to start with frozen encoder just add\n\n```yaml\nfreeze_encoder: true\nstages:\n - epochs: 10 #Let's go for 10 epochs with frozen encoder\n\n - epochs: 100 #Now let's go for 100 epochs with trainable encoder\n unfreeze_encoder: true \n```\n\nin your experiments configuration, then on some stage configuration just add\n\n```yaml\nunfreeze_encoder: true\n```\nto stage settings.\n\nBoth [freeze_encoder](https://musket-ml.github.io/webdocs/segmentation/reference/#freeze_encoder) and [unfreeze_encoder](https://musket-ml.github.io/webdocs/segmentation/reference/#unfreeze_encoder)\ncan be put into the root section and inside the stage.\n\n*Note: This option is not supported for DeeplabV3 architecture.*\n\n#### Custom datasets\n\nTraining data and masks are not necessarily stored in files, so sometimes you need to declare your own dataset class,\nfor example, the following code was used to support [Airbus ship detection challenge](https://www.kaggle.com/c/airbus-ship-detection/overview)\nto decode segmentation masks from rle encoded strings stored in csv file \n\n```python\nfrom segmentation_pipeline.impl.datasets import PredictionItem\nimport os\nfrom segmentation_pipeline.impl import rle\nimport imageio\nimport pandas as pd\n\nclass SegmentationRLE(datasets.DataSet):\n\n def __init__(self,path,imgPath):\n self.data=pd.read_csv(path);\n self.values=self.data.values;\n self.imgPath=imgPath;\n self.ship_groups=self.data.groupby('ImageId');\n self.masks=self.ship_groups['ImageId'];\n self.ids=list(self.ship_groups.groups.keys())\n pass\n\n def __len__(self):\n return len(self.masks)\n\n\n def __getitem__(self, item):\n pixels=self.ship_groups.get_group(self.ids[item])[\"EncodedPixels\"]\n return PredictionItem(self.ids[item] + str(), imageio.imread(os.path.join(self.imgPath,self.ids[item])),\n rle.masks_as_image(pixels) > 0.5)\n\ndef getTrain()->datasets.DataSet:\n return SegmentationRLE(\"train.csv\",\"images/\")\n``` \n\nNow, if this python code sits somewhere in python files located in `modules` folder of the project, and that file is referred by [imports](https://musket-ml.github.io/webdocs/segmentation/reference/#imports) instruction, following YAML can refer it:\n```yaml\ndataset:\n getTrain: []\n```\n\n[dataset](https://musket-ml.github.io/webdocs/segmentation/reference/#dataset) sets the main training dataset.\n\n[datasets](https://musket-ml.github.io/webdocs/segmentation/reference/#datasets) sets up a list of available data sets to be referred by other entities.\n\n#### Multistage training\n\nSometimes you need to split your training into several stages. You can easily do it by adding several stage entries\nin your experiment configuration file.\n\n[stages](https://musket-ml.github.io/webdocs/segmentation/reference/#stages) instruction allows to set up stages of the train process, where for each stage it is possible to set some specific training options like the number of epochs, learning rate, loss, callbacks, etc.\nFull list of stage properties can be found [here](https://musket-ml.github.io/webdocs/segmentation/reference/#stage-properties).\n\n```yaml\nstages:\n - epochs: 100 #Let's go for 100 epochs\n - epochs: 100 #Let's go for 100 epochs\n - epochs: 100 #Let's go for 100 epochs\n```\n\n```yaml\nstages:\n - epochs: 6 #Train for 6 epochs\n negatives: none #do not include negative examples in your training set \n validation_negatives: real #validation should contain all negative examples \n\n - lr: 0.0001 #let's use different starting learning rate\n epochs: 6\n negatives: real\n validation_negatives: real\n\n - loss: lovasz_loss #let's override loss function\n lr: 0.00001\n epochs: 6\n initial_weights: ./fpn-resnext2/weights/best-0.1.weights #let's load weights from this file \n``` \n\n#### Balancing your data\n\nOne common case is the situation when part of your images does not contain any objects of interest, like in \n[Airbus ship detection challenge](https://www.kaggle.com/c/airbus-ship-detection/overview). More over your data may\nbe to heavily inbalanced, so you may want to rebalance it. Alternatively you may want to inject some additional\nimages that do not contain objects of interest to decrease amount of false positives that will be produced by the framework.\n\nThese scenarios are supported by [negatives](https://musket-ml.github.io/webdocs/segmentation/reference/#negatives) and \n[validation_negatives](https://musket-ml.github.io/webdocs/segmentation/reference/#validation_negatives) settings of training stage configuration,\nthese settings accept following values:\n\n- none - exclude negative examples from the data\n- real - include all negative examples \n- integer number(1 or 2 or anything), how many negative examples should be included per one positive example \n\n```yaml\nstages:\n - epochs: 6 #Train for 6 epochs\n negatives: none #do not include negative examples in your training set \n validation_negatives: real #validation should contain all negative examples \n\n - lr: 0.0001 #let's use different starting learning rate\n epochs: 6\n negatives: real\n validation_negatives: real\n\n - loss: lovasz_loss #let's override loss function\n lr: 0.00001\n epochs: 6\n initial_weights: ./fpn-resnext2/weights/best-0.1.weights #let's load weights from this file \n```\n\nif you are using this setting your dataset class must support `isPositive` method which returns true for indexes\nwhich contain positive examples: \n\n```python \n def isPositive(self, item):\n pixels=self.ddd.get_group(self.ids[item])[\"EncodedPixels\"]\n for mask in pixels:\n if isinstance(mask, str):\n return True;\n return False\n``` \n#### Advanced learning rates\n##### Dynamic learning rates\n\n![Example](https://github.com/bckenstler/CLR/blob/master/images/triangularDiag.png?raw=true)\n\nAs told in [Cyclical learning rates for training neural networks](https://arxiv.org/abs/1506.01186) CLR policies can provide quicker converge for some neural network tasks and architectures. \n\n![Example2](https://github.com/bckenstler/CLR/raw/master/images/cifar.png)\n\nWe support them by adopting Brad Kenstler [CLR callback](https://github.com/bckenstler/CLR) for Keras.\n\nIf you want to use them, just add [CyclicLR](https://musket-ml.github.io/webdocs/segmentation/reference/#cycliclr) in your experiment configuration file as shown below: \n\n```yaml\ncallbacks:\n EarlyStopping:\n patience: 40\n monitor: val_binary_accuracy\n verbose: 1\n CyclicLR:\n base_lr: 0.0001\n max_lr: 0.01\n mode: triangular2\n step_size: 300\n```\n\nThere are also [ReduceLROnPlateau](https://musket-ml.github.io/webdocs/segmentation/reference/#reducelronplateau) and [LRVariator](https://musket-ml.github.io/webdocs/segmentation/reference/#lrvariator) options to modify learning rate on the fly.\n\n##### LR Finder\n\n[Estimating optimal learning rate for your model](https://arxiv.org/abs/1506.01186) is an important thing, we support this by using slightly changed \nversion of [Pavel Surmenok - Keras LR Finder](https://github.com/surmenok/keras_lr_finder)\n\n```python\ncfg= segmentation.parse(people-1.yaml)\nds=SimplePNGMaskDataSet(\"./train\",\"./train_mask\")\nfinder=cfg.lr_find(ds,start_lr=0.00001,end_lr=1,epochs=5)\nfinder.plot_loss(n_skip_beginning=20, n_skip_end=5)\nplt.show()\nfinder.plot_loss_change(sma=20, n_skip_beginning=20, n_skip_end=5, y_lim=(-0.01, 0.01))\nplt.show()\n```\nwill result in this couple of helpful images: \n\n![image](https://camo.githubusercontent.com/b41aeaff00fb7b214b5eb2e5c151e7e353a7263e/68747470733a2f2f63646e2d696d616765732d312e6d656469756d2e636f6d2f6d61782f313630302f312a48566a5f344c57656d6a764f57762d63514f397939672e706e67)\n\n![image](https://camo.githubusercontent.com/834996d32bbd2edf7435c5e105b53a6b447ef083/68747470733a2f2f63646e2d696d616765732d312e6d656469756d2e636f6d2f6d61782f313630302f312a38376d4b715f586f6d59794a4532396c39314b3064772e706e67)\n\n#### Training on crops\n\nYour images can be too large to train model on them. In this case you probably want to train model on crops. All\nthat you need to do is to specify number of splits per axis. For example, following lines in config \n\n```yaml\nshape: [768, 768, 3]\ncrops: 3\n``` \nwill lead to splitting each image/mask into 9 cells (3 horizontal splits and 3 vertical splits) and training model on these splits.\nAugmentations will be run separately on each cell. \n[crops](https://musket-ml.github.io/webdocs/segmentation/reference/#crops) property sets the number of single dimension cells.\n\n\nDuring prediction time, your images will be split into these cells, prediction will be executed on each cell, and then results\nwill be assembled in single final mask. Thus the whole process of cropping will be invisible from a consumer perspective. \n\n### Using trained model\n\nOkey, our model is trained, now we need to actually do image segmentation. Let's say, we need to run image segmentation on\nimages in the directory and store results in csv file:\n\n```python\nfrom segmentation_pipeline import segmentation\nfrom segmentation_pipeline.impl.rle import rle_encode\nfrom skimage.morphology import remove_small_objects, remove_small_holes\nimport pandas as pd\n\n#this is our callback which is called for every image\ndef onPredict(file_name, img, data):\n threshold = 0.25\n predictions = data[\"pred\"]\n imgs = data[\"images\"]\n post_img = remove_small_holes(remove_small_objects(img.arr > threshold))\n rle = rle_encode(post_img)\n predictions.append(rle)\n imgs.append(file_name[:file_name.index(\".\")])\n pass\n\ncfg= segmentation.parse(\"config.yaml\")\n\npredictions = []\nimages = []\n#Now let's use best model from fold 0 to do image segmentation on images from images_to_segment\ncfg.predict_in_directory(\"./images_to_segment\", 0, 0, onPredict, {\"pred\": predictions, \"images\": images})\n\n#Let's store results in csv\ndf = pd.DataFrame.from_dict({'image': images, 'rle_mask': predictions})\ndf.to_csv('baseline_submission.csv', index=False)\n``` \n#### Ensembling predictions\n\nAnd what if you want to ensemble models from several folds? Just pass a list of fold numbers to\n`predict_in_directory` like in the following example:\n\n```python\ncfg.predict_in_directory(\"./images_to_segment\", [0,1,2,3,4], onPredict, {\"pred\": predictions, \"images\": images})\n```\nAnother supported option is to ensemble results from extra test time augmentation (flips) by adding keyword arg `ttflips=True`.\n\n### Custom evaluation code\n\nSometimes you need to run custom evaluation code. In such case you may use: `evaluateAll` method, which provides an iterator\non the batches containing original images, training masks and predicted masks\n\n```python\nfor batch in cfg.evaluateAll(ds,2):\n for i in range(len(batch.predicted_maps_aug)):\n masks = ds.get_masks(batch.data[i])\n for d in range(1,20):\n cur_seg = binary_opening(batch.predicted_maps_aug[i].arr > d/20, np.expand_dims(disk(2), -1))\n cm = rle.masks_as_images(rle.multi_rle_encode(cur_seg))\n pr = f2(masks, cm);\n total[d]=total[d]+pr\n```\n\n### Accessing model\nYou may get trained keras model by calling: ```cfg.load_model(fold, stage)```.\n\n## Analyzing experiments results\n\nOkey, we have done a lot of experiments and now we need to compare the results and understand what works better. This repository\ncontains [script](segmentation_pipeline/analize.py) which may be used to analyze folder containing sub folders\nwith experiment configurations and results. This script gathers all configurations, diffs them by doing structural diff, then \nfor each configuration it averages metrics for all folds and generates csv file containing metrics and parameters that\nwas actually changed in your experiment like in the following [example](report.csv)\n\nThis script accepts following arguments:\n\n - inputFolder - root folder to search for experiments configurations and results\n - output - file to store aggregated metrics\n - onlyMetric - if you specify this option all other metrics will not be written in the report file\n - sortBy - metric that should be used to sort results \n\nExample: \n```commandline\npython analize.py --inputFolder ./experiments --output ./result.py\n``` \n\n## What is supported?\n\nAt this moment segmentation pipeline supports following architectures:\n\n- [Unet](https://lmb.informatik.uni-freiburg.de/people/ronneber/u-net/)\n- [Linknet](https://codeac29.github.io/projects/linknet/)\n- [PSP](https://arxiv.org/abs/1612.01105)\n- [FPN](https://arxiv.org/abs/1612.03144)\n- [DeeplabV3](https://arxiv.org/abs/1706.05587)\n\n`FPN`, `PSP`, `Linkenet`, `UNet` architectures support following backbones: \n\n - [VGGNet](https://arxiv.org/abs/1409.1556)\n - vgg16\n - vgg19\n - [ResNet](https://arxiv.org/abs/1512.03385)\n - resnet18\n - resnet34\n - resnet50 \n - resnet101\n - resnet152\n - [ResNext](https://arxiv.org/abs/1611.05431)\n - resnext50\n - resnext101\n - [DenseNet](https://arxiv.org/abs/1608.06993)\n - densenet121\n - densenet169\n - densenet201\n - [Inception-v3](https://arxiv.org/abs/1512.00567)\n - [Inception-ResNet-v2](https://arxiv.org/abs/1602.07261)\n\nAll them support the weights pretrained on [ImageNet](http://www.image-net.org/):\n```yaml\nencoder_weights: imagenet\n```\n\nAt this moment `DeeplabV3` architecture supports following backbones:\n - [MobileNetV2](https://arxiv.org/abs/1801.04381)\n - [Xception](https://arxiv.org/abs/1610.02357)\n\nDeeplab supports weights pretrained on [PASCAL VOC](http://host.robots.ox.ac.uk/pascal/VOC/):\n\n```yaml\nencoder_weights: pascal_voc\n``` \n\nEach architecture also supports some specific options, list of options is documented in [segmentation RAML library](segmentation_pipeline/schemas/segmentation.raml#L166).\n\nSupported augmentations are documented in [augmentation RAML library](segmentation_pipeline/schemas/augmenters.raml).\n\nCallbacks are documented in [callbacks RAML library](segmentation_pipeline/schemas/callbacks.raml). \n\n## Custom architectures, callbacks, metrics\n\nSegmentation pipeline uses keras custom objects registry to find entities, so if you need to use\ncustom loss function, activation or metric all that you need to do is to register it in Keras as: \n\n```python\nkeras.utils.get_custom_objects()[\"my_loss\"]= my_loss\n```\n\nIf you want to inject new architecture, you should register it in `segmentation.custom_models` dictionary.\n\nFor example:\n```python\nsegmentation.custom.models['MyUnet']=MyUnet \n```\nwhere `MyUnet` is a function that accepts architecture parameters as arguments and returns an instance\nof keras model.\n\n## Examples\n\n[Training background removal task(Pics Art Hackaton) in google collab](https://colab.research.google.com/drive/1HtJLwoI_93m8pnRkK4u8JiFwv33L9Pil)\n\n# FAQ\n\n#### How to continue training after crash?\n\nIf you would like to continue training after crash, call `setAllowResume` method before calling `fit`\n\n```python\ncfg= segmentation.parse(\"./people-1.yaml\")\ncfg.setAllowResume(True)\nds=SimplePNGMaskDataSet(\"./pics/train\",\"./pics/train_mask\")\ncfg.fit(ds)\n```\n\n\n#### My notebooks constantly run out of memory, what can I do to reduce memory usage?\n\nOne way to reduce memory usage is to limit augmentation queue limit which is 50 by default, \nlike in the following example: \n\n```python\nsegmentation_pipeline.impl.datasets.AUGMENTER_QUEUE_LIMIT = 3\n```\n\n#### How can I run sepate set of augmenters on initial image/mask when replacing backgrounds with Background Augmenter?\n```yaml\n BackgroundReplacer:\n rate: 0.5\n path: ./bg\n augmenters: #this augmenters will run on original image before replacing background\n Affine:\n scale: [0.8, 1.5]\n translate_percent:\n x: [-0.2,0.2]\n y: [-0.2,0.2]\n rotate: [-16, 16]\n shear: [-16, 16]\n erosion: [0,5] \n```\n\n\n#### How can I visualize images that are used for training (after augmentations)?\n\nYou should set `showDataExamples` to True like in the following sample\n```python\ncfg= segmentation.parse(\"./no_erosion_aug_on_masks/people-1.yaml\")\ncfg.showDataExamples=True\n```\nif will lead to generation of training images samples and storing them in examples folder at the end of each epoch\n\n#### What I can do if i have some extra training data, that should not be included into validation, but should be used during the training?\n\n```python\nextra_data=NotzeroSimplePNGMaskDataSet(\"./phaces/all\",\"./phaces/masks\") #My dataset that should be added to training\nsegmentation.extra_train[\"people\"] = extra_data\n``` \n\nand in the config file:\n\n```yaml\nextra_train_data: people\n```\n\n#### How to get basic statistics across my folds/stages\n\n\nThis code sample will return primary metric stats over folds/stages\n```\ncfg= segmentation.parse(\"./no_erosion_aug_on_masks/people-1.yaml\")\nmetrics = cfg.info()\n```\n\n\n#### I have some callbacks that are configured globally, but I need some extra callbacks for my last training stage?\n\nThere are two possible ways how you may configure callbacks on stage level:\n\n- override all global callbacks with `callbacks` setting.\n- add your own custom callbacks with `extra_callbacks` setting.\n\nIn the following sample CyclingRL callback is only appended to the sexond stage of training:\n\n```yaml\nloss: binary_crossentropy\nstages:\n - epochs: 20\n negatives: real\n - epochs: 200\n extra_callbacks:\n CyclicLR:\n base_lr: 0.000001\n max_lr: 0.0001\n mode: triangular\n step_size: 800\n negatives: real\n```\n\n#### What if I would like to build a really large ansemble of models?\n\nOne option to do this, is to store predictions for each file and model in numpy array, and then sum these predictions\nlike in the following sample:\n\n```python\ncfg.predict_to_directory(\"./pics/test\",\"./pics/arr1\", [0, 1, 4, 2], 1, ttflips=True,binaryArray=True)\ncfg.predict_to_directory(\"./pics/test\", \"./pics/arr\", [0, 1, 4, 2], 2, ttflips=True, binaryArray=True)\nsegmentation.ansemblePredictions(\"./pics/test\",[\"./pics/arr/\",\"./pics/arr1/\"],onPredict,d)\n``` \n\n#### How to train on multiple gpus?\n\n```python\ncfg.gpus=4 #or another number matching to the count of gpus that you have\n``` \n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/musket-ml/segmentation_training_pipeline", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "segmentation-pipeline", "package_url": "https://pypi.org/project/segmentation-pipeline/", "platform": "", "project_url": "https://pypi.org/project/segmentation-pipeline/", "project_urls": { "Homepage": "https://github.com/musket-ml/segmentation_training_pipeline" }, "release_url": "https://pypi.org/project/segmentation-pipeline/0.432/", "requires_dist": [ "musket-core" ], "requires_python": "", "summary": "Segmentation support piepeline for Musket ML", "version": "0.432", "yanked": false, "yanked_reason": null }, "last_serial": 6172746, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "5bfd5bf93b87948899c008d9d6074694", "sha256": "e11f46329fd3608facc68b25465b87848e7db20c3287fc108a4ebd0070ce63cd" }, "downloads": -1, "filename": "segmentation_pipeline-0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "5bfd5bf93b87948899c008d9d6074694", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 23293, "upload_time": "2018-11-02T12:11:12", "upload_time_iso_8601": "2018-11-02T12:11:12.714759Z", "url": "https://files.pythonhosted.org/packages/e0/43/ff7c3120579f065aa87c22f53499859632d0203ae3b39acbe982b49d29e3/segmentation_pipeline-0.1-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "b257326a8d805254746e430c90f36efc", "sha256": "e4db446b98ab454b3c1b22eac282fecaa655d89161ca781a5f9c19552e841bdf" }, "downloads": -1, "filename": "segmentation_pipeline-0.1.tar.gz", "has_sig": false, "md5_digest": "b257326a8d805254746e430c90f36efc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18727, "upload_time": "2018-11-02T12:11:15", "upload_time_iso_8601": "2018-11-02T12:11:15.239479Z", "url": "https://files.pythonhosted.org/packages/ec/79/39f76ba9157e86089fadb5013fb297295ac02ce18c911732281b2e90dba5/segmentation_pipeline-0.1.tar.gz", "yanked": false, "yanked_reason": null } ], "0.11": [ { "comment_text": "", "digests": { "md5": "6402478e85ba0e1fbc3322f9ce974645", "sha256": "de5c91ef9db269a6c51e66584daaa6a665778bb0f89ba340e6362729c2fa73b8" }, "downloads": -1, "filename": "segmentation_pipeline-0.11-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "6402478e85ba0e1fbc3322f9ce974645", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 26595, "upload_time": "2018-11-02T13:01:56", "upload_time_iso_8601": "2018-11-02T13:01:56.605558Z", "url": "https://files.pythonhosted.org/packages/e7/3a/6433008ee3b09c4ee42b273ad3e889e18fd7f2930a91f51b81003543135f/segmentation_pipeline-0.11-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "97e9a4f918fd283b31f31a7bfc6c0ad4", "sha256": "6079eec5a8a60d677cc64026fce6cf23e773a1b80bdef94f1bbd62bb29c39228" }, "downloads": -1, "filename": "segmentation_pipeline-0.11.tar.gz", "has_sig": false, "md5_digest": "97e9a4f918fd283b31f31a7bfc6c0ad4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22357, "upload_time": "2018-11-02T13:01:58", "upload_time_iso_8601": "2018-11-02T13:01:58.102008Z", "url": "https://files.pythonhosted.org/packages/35/32/44b548f998583055db65316562f25ff3e1e63a9e9ad08d7f2e2afc174096/segmentation_pipeline-0.11.tar.gz", "yanked": false, "yanked_reason": null } ], "0.12": [ { "comment_text": "", "digests": { "md5": "66a5f9cce01845ed8d2cd517e608e693", "sha256": "6dda31f735991a30ab7d3d96d0e1c045c086d91b0ee19caca72814d32cc2c061" }, "downloads": -1, "filename": "segmentation_pipeline-0.12-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "66a5f9cce01845ed8d2cd517e608e693", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 26638, "upload_time": "2018-11-02T13:37:28", "upload_time_iso_8601": "2018-11-02T13:37:28.910276Z", "url": "https://files.pythonhosted.org/packages/0d/e0/55cfc05894b0904fadb3d828c78aeb3b0b8469350e4f9bac9fe89c0245e4/segmentation_pipeline-0.12-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "b90fca2ea21c1365aceb440ec9654fdf", "sha256": "20292239d3372f563dc0cb3ff0614d07937804f54e31b6bb95f7292d566c7a33" }, "downloads": -1, "filename": "segmentation_pipeline-0.12.tar.gz", "has_sig": false, "md5_digest": "b90fca2ea21c1365aceb440ec9654fdf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22469, "upload_time": "2018-11-02T13:37:30", "upload_time_iso_8601": "2018-11-02T13:37:30.482397Z", "url": "https://files.pythonhosted.org/packages/0e/de/8ae1303c5b18512f3ac28a04fb7ff02ac9a88a903ec948c3651dcf84b8ca/segmentation_pipeline-0.12.tar.gz", "yanked": false, "yanked_reason": null } ], "0.14": [ { "comment_text": "", "digests": { "md5": "6e5447cc776b6f94803b745e0c0bf826", "sha256": "543045ec69643dddbe75a304e775444ea05c321cd99253de2f68df54da0365cd" }, "downloads": -1, "filename": "segmentation_pipeline-0.14-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "6e5447cc776b6f94803b745e0c0bf826", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 27158, "upload_time": "2018-11-05T15:13:06", "upload_time_iso_8601": "2018-11-05T15:13:06.808726Z", "url": "https://files.pythonhosted.org/packages/65/ac/0658c6c102ca418c94cd01ca94c06529f33d038ea69db3c5b6a6a2f6a64c/segmentation_pipeline-0.14-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "b51b56aff67938004a3b04d5fd13a2eb", "sha256": "0adaf0076447670f741f976b9945af8101cd1660a83f023ed0935c152a450051" }, "downloads": -1, "filename": "segmentation_pipeline-0.14.tar.gz", "has_sig": false, "md5_digest": "b51b56aff67938004a3b04d5fd13a2eb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23211, "upload_time": "2018-11-05T15:13:17", "upload_time_iso_8601": "2018-11-05T15:13:17.452908Z", "url": "https://files.pythonhosted.org/packages/b4/87/8efe1ae65f6971b31b3b5e911cf84c6d5ef5d4a6987440f670abbf7567d0/segmentation_pipeline-0.14.tar.gz", "yanked": false, "yanked_reason": null } ], "0.15": [ { "comment_text": "", "digests": { "md5": "ff6f684c276ba646917092d6a16ec5e5", "sha256": "f0c60a4feaf0523eea392bb82ba944d7f25e514ab82fd503139f5ac7a58e0a8d" }, "downloads": -1, "filename": "segmentation_pipeline-0.15-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "ff6f684c276ba646917092d6a16ec5e5", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 27339, "upload_time": "2018-11-06T04:16:28", "upload_time_iso_8601": "2018-11-06T04:16:28.729977Z", "url": "https://files.pythonhosted.org/packages/5d/bc/97135a518ed5a26a33825112e9e8d3c485c10047e0479a10400b419ab482/segmentation_pipeline-0.15-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "1882954da1b8bb3c4befe87fb6e28c6d", "sha256": "f5febcb9743515ed281e7025fa818cf395f2def4ae0423c8dfc385b966b1acaf" }, "downloads": -1, "filename": "segmentation_pipeline-0.15.tar.gz", "has_sig": false, "md5_digest": "1882954da1b8bb3c4befe87fb6e28c6d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23578, "upload_time": "2018-11-06T04:16:30", "upload_time_iso_8601": "2018-11-06T04:16:30.369030Z", "url": "https://files.pythonhosted.org/packages/26/5a/44e2f6544abebdfa9366d3213a1bc7e5cb0875433361cf20c52a70e0aaeb/segmentation_pipeline-0.15.tar.gz", "yanked": false, "yanked_reason": null } ], "0.16": [ { "comment_text": "", "digests": { "md5": "8ca62f7440e8a48252b19c46cc4f224d", "sha256": "0edb1a3059a1607b61ea53f0bd56a1cfb50939443e9d10a78e2f120781eb5e68" }, "downloads": -1, "filename": "segmentation_pipeline-0.16-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "8ca62f7440e8a48252b19c46cc4f224d", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 27340, "upload_time": "2018-11-06T04:28:33", "upload_time_iso_8601": "2018-11-06T04:28:33.124553Z", "url": "https://files.pythonhosted.org/packages/a8/39/0d41473bd658d3cefedaf78b247953983112431e57d0dc1ceb6b9859a470/segmentation_pipeline-0.16-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "7123a5439cf3394d4252400afb08e456", "sha256": "3e57f7db898ecc1d2918b5dc46c33651b12f81ff6d06c59ff9d4fa7899eebb98" }, "downloads": -1, "filename": "segmentation_pipeline-0.16.tar.gz", "has_sig": false, "md5_digest": "7123a5439cf3394d4252400afb08e456", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23559, "upload_time": "2018-11-06T04:28:34", "upload_time_iso_8601": "2018-11-06T04:28:34.599060Z", "url": "https://files.pythonhosted.org/packages/7f/0c/524655ac77ec5dcbb1abd2117274b3a8f2805771436cf33c4d7e4afb7ec1/segmentation_pipeline-0.16.tar.gz", "yanked": false, "yanked_reason": null } ], "0.17": [ { "comment_text": "", "digests": { "md5": "f21bddf50805f3b2e8b148dccd45caea", "sha256": "888202da0d9afc99da494addb82c5dc938dfcde7d9239eb42979d2914cc27cc1" }, "downloads": -1, "filename": "segmentation_pipeline-0.17-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "f21bddf50805f3b2e8b148dccd45caea", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 27342, "upload_time": "2018-11-06T04:56:15", "upload_time_iso_8601": "2018-11-06T04:56:15.829531Z", "url": "https://files.pythonhosted.org/packages/ab/59/42c73fa2bb679e61dd4dc2dcd696a7e6852849e7eb9dd8c486dccba8cdbb/segmentation_pipeline-0.17-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "96a14d216e433b546002fc1b52155246", "sha256": "eb4711d11174056e5c23d26e4990e973c3fb6e8bec423b5c1586b45a4b5d0f95" }, "downloads": -1, "filename": "segmentation_pipeline-0.17.tar.gz", "has_sig": false, "md5_digest": "96a14d216e433b546002fc1b52155246", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23565, "upload_time": "2018-11-06T04:56:17", "upload_time_iso_8601": "2018-11-06T04:56:17.380963Z", "url": "https://files.pythonhosted.org/packages/c9/58/5e5bc6cc2ff7252111b8038010ef19243e32e65b1b6318bc6d674571003c/segmentation_pipeline-0.17.tar.gz", "yanked": false, "yanked_reason": null } ], "0.18": [ { "comment_text": "", "digests": { "md5": "6a2748e2b6b973350d811b170ed7e8fc", "sha256": "f050fd76d84a0bbe1c82039baeb66774409a97fda38b4eccae5c06bdb20f100e" }, "downloads": -1, "filename": "segmentation_pipeline-0.18-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "6a2748e2b6b973350d811b170ed7e8fc", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 34951, "upload_time": "2018-11-11T13:36:53", "upload_time_iso_8601": "2018-11-11T13:36:53.062878Z", "url": "https://files.pythonhosted.org/packages/70/16/83fe19c1453a8df8f735ffc6dcba0765b37ccc78219d8de196db9dea7c91/segmentation_pipeline-0.18-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "7af380e5c2b0ee5f0548261e13a18bf1", "sha256": "bc4bd07eb896dd9b13038cbef864de9bd3a3de3e1032efcb6410396ec8f0759d" }, "downloads": -1, "filename": "segmentation_pipeline-0.18.tar.gz", "has_sig": false, "md5_digest": "7af380e5c2b0ee5f0548261e13a18bf1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 34573, "upload_time": "2018-11-11T13:36:54", "upload_time_iso_8601": "2018-11-11T13:36:54.998946Z", "url": "https://files.pythonhosted.org/packages/11/1a/58ca0d4de9333108c4e4814ad5bf8e4c37a7975c045c57badc455019e4c9/segmentation_pipeline-0.18.tar.gz", "yanked": false, "yanked_reason": null } ], "0.21": [ { "comment_text": "", "digests": { "md5": "888cb1b0636a99b813002d891bc6fdb8", "sha256": "6dbcd24aca5dd6cc25646f6ecdc15e7c687d5bc126e12e318ac612ec52e702bc" }, "downloads": -1, "filename": "segmentation_pipeline-0.21-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "888cb1b0636a99b813002d891bc6fdb8", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 39445, "upload_time": "2018-11-21T13:16:46", "upload_time_iso_8601": "2018-11-21T13:16:46.581238Z", "url": "https://files.pythonhosted.org/packages/6f/82/44ab88711471442029672c6f993f15607b9856ea53f8773141c7b7a22dc7/segmentation_pipeline-0.21-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "0ad1296f13af1bc4d2bbc7bc60871472", "sha256": "571d3d49a172bfc25f24de5440a60c7c1c9e9693b89558171ae6d6cb465e934a" }, "downloads": -1, "filename": "segmentation_pipeline-0.21.tar.gz", "has_sig": false, "md5_digest": "0ad1296f13af1bc4d2bbc7bc60871472", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 39598, "upload_time": "2018-11-21T13:16:48", "upload_time_iso_8601": "2018-11-21T13:16:48.573227Z", "url": "https://files.pythonhosted.org/packages/a7/89/34e9c08c867e774eca6db510ee1d66bed95590b1e76963408b45a6984e28/segmentation_pipeline-0.21.tar.gz", "yanked": false, "yanked_reason": null } ], "0.22": [ { "comment_text": "", "digests": { "md5": "8c620a0b62bd09c89615d5a05d4f8163", "sha256": "a5652175210bff7a64c4beedfe50a386569ca4c720c6b7628c524bea65315fbc" }, "downloads": -1, "filename": "segmentation_pipeline-0.22-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "8c620a0b62bd09c89615d5a05d4f8163", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 40869, "upload_time": "2018-11-27T04:27:26", "upload_time_iso_8601": "2018-11-27T04:27:26.835646Z", "url": "https://files.pythonhosted.org/packages/52/ff/557aecffda1872884987b2ea65a14a5889a4c1c9bcaedbd037587c927076/segmentation_pipeline-0.22-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "734fb3f6966daa2d1ce535bc0be1fec7", "sha256": "1a2e396cee7e0632acbf5aa2a9b72320f46e1e9ee90fcb5b67c89128e0f82aa4" }, "downloads": -1, "filename": "segmentation_pipeline-0.22.tar.gz", "has_sig": false, "md5_digest": "734fb3f6966daa2d1ce535bc0be1fec7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 42257, "upload_time": "2018-11-27T04:27:29", "upload_time_iso_8601": "2018-11-27T04:27:29.081781Z", "url": "https://files.pythonhosted.org/packages/3c/b3/0c30ea86807cbc580c5d10ede5eaafa78327de61a89346a4b2c59035762c/segmentation_pipeline-0.22.tar.gz", "yanked": false, "yanked_reason": null } ], "0.24": [ { "comment_text": "", "digests": { "md5": "cacc0944d7bc494ae53f87b42c8bd6d7", "sha256": "47f67a8d03f0a08a2e28c76e4a6e14d70b86412600fe26406716c6d5b898f734" }, "downloads": -1, "filename": "segmentation_pipeline-0.24-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "cacc0944d7bc494ae53f87b42c8bd6d7", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 19725, "upload_time": "2018-12-04T21:51:46", "upload_time_iso_8601": "2018-12-04T21:51:46.907336Z", "url": "https://files.pythonhosted.org/packages/5f/e7/494bd08714ec2e108e82a52a5244f54d9530f2c63ac70142d4caec74a417/segmentation_pipeline-0.24-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "9f1772af015ff58b27e392133ceac3b5", "sha256": "9b319f2996d28c054dbc52672f817006a30a4c2e8423e36550c0eab0368c0bcc" }, "downloads": -1, "filename": "segmentation_pipeline-0.24.tar.gz", "has_sig": false, "md5_digest": "9f1772af015ff58b27e392133ceac3b5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22708, "upload_time": "2018-12-04T21:51:48", "upload_time_iso_8601": "2018-12-04T21:51:48.400602Z", "url": "https://files.pythonhosted.org/packages/3f/d1/53cba6fc232c004465ef3786f0ea939e34246982a0f9260a84b7ad815527/segmentation_pipeline-0.24.tar.gz", "yanked": false, "yanked_reason": null } ], "0.26": [ { "comment_text": "", "digests": { "md5": "52206c2e4cd4fea5de70a4383eeff8d1", "sha256": "705b70f3f19ababa7a7bf56e9b1248f84c61f330311ff222a1690e052798f5e6" }, "downloads": -1, "filename": "segmentation_pipeline-0.26-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "52206c2e4cd4fea5de70a4383eeff8d1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 19959, "upload_time": "2018-12-04T23:05:36", "upload_time_iso_8601": "2018-12-04T23:05:36.912766Z", "url": "https://files.pythonhosted.org/packages/03/09/e7564cefcef7cb81e4299ea2ed42c5ad094e05124226323ecc43034cebc1/segmentation_pipeline-0.26-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "1dba46c31c7d383745711dab2a5c513e", "sha256": "e962f4a680a19a8847d61a4d35de8e13444545aed4204f6bac14549bca82ff04" }, "downloads": -1, "filename": "segmentation_pipeline-0.26.tar.gz", "has_sig": false, "md5_digest": "1dba46c31c7d383745711dab2a5c513e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22758, "upload_time": "2018-12-04T23:05:38", "upload_time_iso_8601": "2018-12-04T23:05:38.679683Z", "url": "https://files.pythonhosted.org/packages/91/c6/66d9a9a07ac23220a9c76375a228c734972645eb33ba2b7a475deb26b130/segmentation_pipeline-0.26.tar.gz", "yanked": false, "yanked_reason": null } ], "0.27": [ { "comment_text": "", "digests": { "md5": "7c37da13a70e394b7328b1a72d3adfc1", "sha256": "698f2e3beb3688451dd7d933b05910d2cac12ee9dd762071c7b03752d4f536f4" }, "downloads": -1, "filename": "segmentation_pipeline-0.27-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "7c37da13a70e394b7328b1a72d3adfc1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 19958, "upload_time": "2018-12-05T12:49:34", "upload_time_iso_8601": "2018-12-05T12:49:34.035072Z", "url": "https://files.pythonhosted.org/packages/d3/45/5899f88f956b70095494c0fb4794af6f985c28c0288ac3148f3315816e6d/segmentation_pipeline-0.27-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "a36957e7394c8f18dc40f38840d68eab", "sha256": "16b75025f160b6ca4947e260b26b704b6d33e27e585667d9195499dd35e2318e" }, "downloads": -1, "filename": "segmentation_pipeline-0.27.tar.gz", "has_sig": false, "md5_digest": "a36957e7394c8f18dc40f38840d68eab", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22740, "upload_time": "2018-12-05T12:49:37", "upload_time_iso_8601": "2018-12-05T12:49:37.303600Z", "url": "https://files.pythonhosted.org/packages/25/a1/f09841fe226fb572e23fbe81a2bcb8e663037cc85a16acb1ce7737d6b193/segmentation_pipeline-0.27.tar.gz", "yanked": false, "yanked_reason": null } ], "0.28": [ { "comment_text": "", "digests": { "md5": "ba58746a5d7d7fd7d9b152c15169236d", "sha256": "72685075cfbe6bc2dd916794a5e72d7324cf431c9eeaff84dde407a7224eb547" }, "downloads": -1, "filename": "segmentation_pipeline-0.28-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "ba58746a5d7d7fd7d9b152c15169236d", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 19957, "upload_time": "2018-12-05T19:09:43", "upload_time_iso_8601": "2018-12-05T19:09:43.512478Z", "url": "https://files.pythonhosted.org/packages/76/ab/d6c5dd1748f63503a5bec415cd06bb07500613de28fb030e815bd18537cd/segmentation_pipeline-0.28-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "3e404c361b7568da16f8249514ae9e23", "sha256": "9afadc7a2f15f4574c5ab943f587029937fa5f108527025251d3c66527d66609" }, "downloads": -1, "filename": "segmentation_pipeline-0.28.tar.gz", "has_sig": false, "md5_digest": "3e404c361b7568da16f8249514ae9e23", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22749, "upload_time": "2018-12-05T19:09:45", "upload_time_iso_8601": "2018-12-05T19:09:45.101052Z", "url": "https://files.pythonhosted.org/packages/c6/b7/a559094d791602adfca7ee13dc49497890a27b1e03cc95bcb8f092887f43/segmentation_pipeline-0.28.tar.gz", "yanked": false, "yanked_reason": null } ], "0.29": [ { "comment_text": "", "digests": { "md5": "4ef00e8df2889aae9518f96b85d6af46", "sha256": "ef5a7949d3d30ab86d96482c40bb8731da477ecceb01a6b090acfc336eb899a6" }, "downloads": -1, "filename": "segmentation_pipeline-0.29-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "4ef00e8df2889aae9518f96b85d6af46", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 19959, "upload_time": "2018-12-06T01:44:29", "upload_time_iso_8601": "2018-12-06T01:44:29.969226Z", "url": "https://files.pythonhosted.org/packages/25/b0/56caf2c6aff39c6a6e39d37536da61fb88345c7acdb8bef114ae76ad96dc/segmentation_pipeline-0.29-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "eae08ebefdc0a097eafacdc5d4d2816f", "sha256": "e0646814dd0bdcadae53c7dc6f166e21a64ec600cc3c781dadefbbc7c0e8bbaf" }, "downloads": -1, "filename": "segmentation_pipeline-0.29.tar.gz", "has_sig": false, "md5_digest": "eae08ebefdc0a097eafacdc5d4d2816f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22747, "upload_time": "2018-12-06T01:44:31", "upload_time_iso_8601": "2018-12-06T01:44:31.888228Z", "url": "https://files.pythonhosted.org/packages/fd/55/801265bdc236c92fd7aada1d7bdb6bcd73e79b7ca50127065e21f773898e/segmentation_pipeline-0.29.tar.gz", "yanked": false, "yanked_reason": null } ], "0.30": [ { "comment_text": "", "digests": { "md5": "5ec20502f4ab0c008f511b9cb57cbff7", "sha256": "530023c3c8895cf05444e5cef77935e837333a6cdc6063d35e5549c76735b271" }, "downloads": -1, "filename": "segmentation_pipeline-0.30-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "5ec20502f4ab0c008f511b9cb57cbff7", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 19956, "upload_time": "2018-12-10T08:09:47", "upload_time_iso_8601": "2018-12-10T08:09:47.433412Z", "url": "https://files.pythonhosted.org/packages/ae/ea/377dfa9ff3a70e51b82c6e91f84d201d55b39dba067d99e59157928064b3/segmentation_pipeline-0.30-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "ae9e370259f89825e28cc03f825f56f9", "sha256": "b8179c5c8edce8a56b220e4af1790ac6e688375bf2741bf634bf8f9c769b13fa" }, "downloads": -1, "filename": "segmentation_pipeline-0.30.tar.gz", "has_sig": false, "md5_digest": "ae9e370259f89825e28cc03f825f56f9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22750, "upload_time": "2018-12-10T08:09:50", "upload_time_iso_8601": "2018-12-10T08:09:50.100492Z", "url": "https://files.pythonhosted.org/packages/6e/86/551a144097a734d55b1bd56377eff101cd5bf5bd28798091701412590c86/segmentation_pipeline-0.30.tar.gz", "yanked": false, "yanked_reason": null } ], "0.31": [ { "comment_text": "", "digests": { "md5": "c10ad46f464c9e339661c6f67570c2cf", "sha256": "e04d8f75d13230c7e10a43fb048f349986b62506efdeb53d5c5e3d7c4e477241" }, "downloads": -1, "filename": "segmentation_pipeline-0.31-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "c10ad46f464c9e339661c6f67570c2cf", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 19991, "upload_time": "2018-12-15T10:49:42", "upload_time_iso_8601": "2018-12-15T10:49:42.332312Z", "url": "https://files.pythonhosted.org/packages/73/ff/640bca62e6b6936e4b7b9e103e46b8d7902867ad6bd40d6299b213302dae/segmentation_pipeline-0.31-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "d63d278db9aef77349a397f768136070", "sha256": "e9c4970e5c0291098b9501c58f45160069ddad7ecc19517894a7f3677a70464d" }, "downloads": -1, "filename": "segmentation_pipeline-0.31.tar.gz", "has_sig": false, "md5_digest": "d63d278db9aef77349a397f768136070", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22791, "upload_time": "2018-12-15T10:49:43", "upload_time_iso_8601": "2018-12-15T10:49:43.621966Z", "url": "https://files.pythonhosted.org/packages/6d/0a/63ba6b161647b81dc9bb536566fb9b22d60e8ec11454315e012bb419560d/segmentation_pipeline-0.31.tar.gz", "yanked": false, "yanked_reason": null } ], "0.41": [ { "comment_text": "", "digests": { "md5": "92d74a8c9cd10de87ec3d5f5892b677d", "sha256": "cf6740d3ba14d9bafcfcc9bace027b7d4c5c5e68468cd692c62478e6acd18230" }, "downloads": -1, "filename": "segmentation_pipeline-0.41-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "92d74a8c9cd10de87ec3d5f5892b677d", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 20631, "upload_time": "2019-09-26T17:31:50", "upload_time_iso_8601": "2019-09-26T17:31:50.583512Z", "url": "https://files.pythonhosted.org/packages/09/c9/1cf9023624c8e74c35ad4fdd737cb2893bf55f4e8f3b0f1d55ffa1d4d706/segmentation_pipeline-0.41-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "128449f801746e1373d280af57a49a06", "sha256": "9bd089bc4242d6559ebe285c73cea8064e753b26ac5878209c7acf83a9f079c2" }, "downloads": -1, "filename": "segmentation_pipeline-0.41.tar.gz", "has_sig": false, "md5_digest": "128449f801746e1373d280af57a49a06", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23547, "upload_time": "2019-10-23T12:53:20", "upload_time_iso_8601": "2019-10-23T12:53:20.972971Z", "url": "https://files.pythonhosted.org/packages/8b/04/8520a1c69385ce7424cd17e1e41aded0cc16337f95eba25067c003b4d15a/segmentation_pipeline-0.41.tar.gz", "yanked": false, "yanked_reason": null } ], "0.42": [ { "comment_text": "", "digests": { "md5": "02b68c90520be6d9d503e71ca993c942", "sha256": "07522e9a57ae682e6577898d51c9e97d3bece7cba47af48be0a185cc4a6d5523" }, "downloads": -1, "filename": "segmentation_pipeline-0.42-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "02b68c90520be6d9d503e71ca993c942", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 20362, "upload_time": "2019-10-23T12:53:17", "upload_time_iso_8601": "2019-10-23T12:53:17.950951Z", "url": "https://files.pythonhosted.org/packages/66/9d/669464ccab7d019d90dfa6d65ed1f80568788139ef1870d1d15a5ad7eda6/segmentation_pipeline-0.42-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "4c3b98472229abede629a5aca32bb17c", "sha256": "d1890bc4c7796525d78dcecc42cbeb9408ffb8ab371013d7beef14e85276ff4a" }, "downloads": -1, "filename": "segmentation_pipeline-0.42.tar.gz", "has_sig": false, "md5_digest": "4c3b98472229abede629a5aca32bb17c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23477, "upload_time": "2019-10-23T12:53:22", "upload_time_iso_8601": "2019-10-23T12:53:22.615715Z", "url": "https://files.pythonhosted.org/packages/35/47/44062f2651befa5923038269246fd28752e417f26b9b961f0d8001f15d3f/segmentation_pipeline-0.42.tar.gz", "yanked": false, "yanked_reason": null } ], "0.43": [ { "comment_text": "", "digests": { "md5": "9b6f4d4568663e7fc4da4d335797c025", "sha256": "b0b55b6e5eee19f8df9a0f2c5581d9168ac09eefbc121edf76fb26116dddcf11" }, "downloads": -1, "filename": "segmentation_pipeline-0.43-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9b6f4d4568663e7fc4da4d335797c025", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 26233, "upload_time": "2019-10-24T09:59:44", "upload_time_iso_8601": "2019-10-24T09:59:44.787829Z", "url": "https://files.pythonhosted.org/packages/e3/9b/3ae624c5a9d81a3334a51e668c0982a92fd3480e1267d20e4aed293ca8d8/segmentation_pipeline-0.43-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "3388fe32ef3b91668c183111759403b9", "sha256": "0345991d53bf9bfbd3c70e63745fc9769d732dfcc7b6bc53790020d3f730f007" }, "downloads": -1, "filename": "segmentation_pipeline-0.43.tar.gz", "has_sig": false, "md5_digest": "3388fe32ef3b91668c183111759403b9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23468, "upload_time": "2019-10-24T09:59:48", "upload_time_iso_8601": "2019-10-24T09:59:48.490460Z", "url": "https://files.pythonhosted.org/packages/7c/a8/931aeae3372db1c5eb8f76a23c76213e0d754ee62372be16c2387da76d6d/segmentation_pipeline-0.43.tar.gz", "yanked": false, "yanked_reason": null } ], "0.431": [ { "comment_text": "", "digests": { "md5": "0dd013898e199ac8d300f00c49cb9f3c", "sha256": "867ecaa28cee8d2789f448446bc05ec394af1e5da7a1899c4d1cad4fe0723aa0" }, "downloads": -1, "filename": "segmentation_pipeline-0.431-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "0dd013898e199ac8d300f00c49cb9f3c", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 26243, "upload_time": "2019-11-10T09:25:40", "upload_time_iso_8601": "2019-11-10T09:25:40.037801Z", "url": "https://files.pythonhosted.org/packages/a6/59/0ad8bd0dcbbe1e7351f61fff07fbe375f4a2ea1e0a26a49aca21a45408c0/segmentation_pipeline-0.431-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "4d97a6b8dbbf46b7c32a1b0e6ef85068", "sha256": "5942fc6e5a4b69d8fd27e08ed6259ccf9f64769a1ec8fefe87a4ec5564a16484" }, "downloads": -1, "filename": "segmentation_pipeline-0.431.tar.gz", "has_sig": false, "md5_digest": "4d97a6b8dbbf46b7c32a1b0e6ef85068", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23647, "upload_time": "2019-11-10T09:25:41", "upload_time_iso_8601": "2019-11-10T09:25:41.356692Z", "url": "https://files.pythonhosted.org/packages/b9/2b/2f49b9ef7ae55e590627e536399f3eb72f79de93781ca85d9c3370dd81e5/segmentation_pipeline-0.431.tar.gz", "yanked": false, "yanked_reason": null } ], "0.432": [ { "comment_text": "", "digests": { "md5": "df67eb0030c2a164002186f909cb1f83", "sha256": "c03afb8e3c76c5875901c79c3718bb96c3799a7a3464d065d5677df630dd09f1" }, "downloads": -1, "filename": "segmentation_pipeline-0.432-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "df67eb0030c2a164002186f909cb1f83", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 36361, "upload_time": "2019-11-21T03:03:30", "upload_time_iso_8601": "2019-11-21T03:03:30.295551Z", "url": "https://files.pythonhosted.org/packages/30/ef/3984917957d1fca1224915cf785604d896be26fd04bb3f0b6c7731c04224/segmentation_pipeline-0.432-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "5a754814d2b1d42cb4425474bee1019f", "sha256": "acf8a05bb7d0f128544cea7718fc55c5aa9ea554c8631ad64f8b039f1f5c098f" }, "downloads": -1, "filename": "segmentation_pipeline-0.432.tar.gz", "has_sig": false, "md5_digest": "5a754814d2b1d42cb4425474bee1019f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45528, "upload_time": "2019-11-21T03:03:33", "upload_time_iso_8601": "2019-11-21T03:03:33.397642Z", "url": "https://files.pythonhosted.org/packages/4d/0a/0dee09f1f66c04a294fe1f6844ea01d80181d232d9dfcc92d0009eeeb9ce/segmentation_pipeline-0.432.tar.gz", "yanked": false, "yanked_reason": null } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "df67eb0030c2a164002186f909cb1f83", "sha256": "c03afb8e3c76c5875901c79c3718bb96c3799a7a3464d065d5677df630dd09f1" }, "downloads": -1, "filename": "segmentation_pipeline-0.432-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "df67eb0030c2a164002186f909cb1f83", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 36361, "upload_time": "2019-11-21T03:03:30", "upload_time_iso_8601": "2019-11-21T03:03:30.295551Z", "url": "https://files.pythonhosted.org/packages/30/ef/3984917957d1fca1224915cf785604d896be26fd04bb3f0b6c7731c04224/segmentation_pipeline-0.432-py2.py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "5a754814d2b1d42cb4425474bee1019f", "sha256": "acf8a05bb7d0f128544cea7718fc55c5aa9ea554c8631ad64f8b039f1f5c098f" }, "downloads": -1, "filename": "segmentation_pipeline-0.432.tar.gz", "has_sig": false, "md5_digest": "5a754814d2b1d42cb4425474bee1019f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45528, "upload_time": "2019-11-21T03:03:33", "upload_time_iso_8601": "2019-11-21T03:03:33.397642Z", "url": "https://files.pythonhosted.org/packages/4d/0a/0dee09f1f66c04a294fe1f6844ea01d80181d232d9dfcc92d0009eeeb9ce/segmentation_pipeline-0.432.tar.gz", "yanked": false, "yanked_reason": null } ], "vulnerabilities": [] }