From 6a887e927a587f6a639ca7336063a354b1a2be61 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Wed, 7 Jul 2021 21:04:07 +0300 Subject: [PATCH 01/53] Adding label studio integration --- flash/core/data/data_module.py | 98 ++++++++++++++++++- flash/core/data/data_source.py | 71 ++++++++++++++ .../labelstudio/image_classification.py | 36 +++++++ .../integrations/labelstudio/project.json | 1 + 4 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 flash_examples/integrations/labelstudio/image_classification.py create mode 100644 flash_examples/integrations/labelstudio/project.json diff --git a/flash/core/data/data_module.py b/flash/core/data/data_module.py index bd95cfd6f1..f9d47ce32f 100644 --- a/flash/core/data/data_module.py +++ b/flash/core/data/data_module.py @@ -11,6 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import json import os import platform from typing import Any, Callable, Collection, Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union @@ -21,14 +22,15 @@ from pytorch_lightning.trainer.states import RunningStage from pytorch_lightning.utilities.exceptions import MisconfigurationException from torch.utils.data import DataLoader, Dataset -from torch.utils.data.dataset import IterableDataset, Subset +from torch.utils.data.dataset import IterableDataset, Subset, random_split from torch.utils.data.sampler import Sampler from flash.core.data.auto_dataset import BaseAutoDataset, IterableAutoDataset from flash.core.data.base_viz import BaseVisualization from flash.core.data.callback import BaseDataFetcher from flash.core.data.data_pipeline import DataPipeline, DefaultPreprocess, Postprocess, Preprocess -from flash.core.data.data_source import DataSource, DefaultDataSources +from flash.core.data.data_source import DataSource, DefaultDataSources, LabelStudioDataset, LabelStudioDataSource, \ + PathsDataSource from flash.core.data.splits import SplitDataset from flash.core.data.utils import _STAGES_PREFIX from flash.core.utilities.imports import _FIFTYONE_AVAILABLE @@ -1152,3 +1154,95 @@ def from_fiftyone( num_workers=num_workers, **preprocess_kwargs, ) + + @classmethod + def from_labelstudio( + cls, + export_json: str = None, + img_folder: str = None, + train_transform: Optional[Dict[str, Callable]] = None, + val_transform: Optional[Dict[str, Callable]] = None, + test_transform: Optional[Dict[str, Callable]] = None, + predict_transform: Optional[Dict[str, Callable]] = None, + data_fetcher: Optional[BaseDataFetcher] = None, + preprocess: Optional[Preprocess] = None, + val_split: Optional[float] = None, + batch_size: int = 4, + num_workers: Optional[int] = None, + sampler: Optional[Sampler] = None, + **preprocess_kwargs: Any, + ) -> 'DataModule': + """Creates a :class:`~flash.core.data.data_module.DataModule` object + from the given export file and data directory using the + :class:`~flash.core.data.data_source.DataSource` of name + :attr:`~flash.core.data.data_source.DefaultDataSources.FOLDERS` + from the passed or constructed :class:`~flash.core.data.process.Preprocess`. + + Args: + export_json: path to label studio export file + img_folder: path to label studio data folder + train_transform: The dictionary of transforms to use during training which maps + :class:`~flash.core.data.process.Preprocess` hook names to callable transforms. + val_transform: The dictionary of transforms to use during validation which maps + :class:`~flash.core.data.process.Preprocess` hook names to callable transforms. + test_transform: The dictionary of transforms to use during testing which maps + :class:`~flash.core.data.process.Preprocess` hook names to callable transforms. + predict_transform: The dictionary of transforms to use during predicting which maps + :class:`~flash.core.data.process.Preprocess` hook names to callable transforms. + data_fetcher: The :class:`~flash.core.data.callback.BaseDataFetcher` to pass to the + :class:`~flash.core.data.data_module.DataModule`. + preprocess: The :class:`~flash.core.data.data.Preprocess` to pass to the + :class:`~flash.core.data.data_module.DataModule`. If ``None``, ``cls.preprocess_cls`` + will be constructed and used. + val_split: The ``val_split`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`. + batch_size: The ``batch_size`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`. + num_workers: The ``num_workers`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`. + sampler: The ``sampler`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`. + preprocess_kwargs: Additional keyword arguments to use when constructing the preprocess. Will only be used + if ``preprocess = None``. + + Returns: + The constructed data module. + + Examples:: + + data_module = DataModule.from_labelstudio( + export_json='project.json', + img_folder='label-studio/media/upload', + val_split=0.8, + ) + """ + # loading export data + with open(export_json) as f: + js = json.load(f) + # loading data sets + full_dataset = LabelStudioDataset(js, img_folder) + val_dataset = LabelStudioDataset(js, img_folder, val=True) + # creating splitting params + l = len(full_dataset) + prop = int(l * val_split) + # splitting full data set + train_dataset, test_dataset = random_split(full_dataset, [prop, l - prop]) + + preprocess = preprocess or cls.preprocess_cls( + train_transform, + val_transform, + test_transform, + predict_transform, + **preprocess_kwargs, + ) + data_source = preprocess.data_source_of_name(DefaultDataSources.FOLDERS) + data = cls( + train_dataset, + val_dataset, + test_dataset, + None, + data_source=data_source, + preprocess=preprocess, + data_fetcher=data_fetcher, + val_split=val_split, + batch_size=batch_size, + num_workers=num_workers, + sampler=sampler, + ) + return data diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index f2d07b4b0d..083ed8614a 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -38,6 +38,7 @@ from pytorch_lightning.utilities.enums import LightningEnum from torch.nn import Module from torch.utils.data.dataset import Dataset +from torchvision.datasets.folder import default_loader from flash.core.data.auto_dataset import AutoDataset, BaseAutoDataset, IterableAutoDataset from flash.core.data.properties import ProcessState, Properties @@ -156,6 +157,7 @@ class DefaultDataSources(LightningEnum): JSON = "json" DATASET = "dataset" FIFTYONE = "fiftyone" + LABELSTUDIO = "labelstudio" # TODO: Create a FlashEnum class??? def __hash__(self) -> int: @@ -543,3 +545,72 @@ def _get_classes(self, data): classes = data.distinct(label_path) return classes + + +class LabelStudioDataset(Dataset): + r"""Dataset wrapping label studio annotations. + + Each sample will be retrieved by checking result field of the annotation. + + Args: + *js: json of export file + *img_folder: path to image folder of label studio + """ + def __init__(self, js, img_folder, val=False): + self._raw_data = js + self._img_folder = img_folder + self.results = list() + self.classes = set() + # iterate through all tasks in exported data + for task in self._raw_data: + for annotation in task['annotations']: + # Adding ground_truth annotation to separate dataset + result = annotation['result'] + for res in result: + t = res['type'] + for label in res['value'][t]: + # check if labeling result is a list of labels + if isinstance(label, list): + for sublabel in label: + self.classes.add(sublabel) + temp = dict() + temp['file_upload'] = task['file_upload'] + temp['label'] = sublabel + if annotation['ground_truth'] & val: + self.results.append(temp) + elif not annotation['ground_truth'] or not val: + self.results.append(temp) + else: + self.classes.add(label) + temp = dict() + temp['file_upload'] = task['file_upload'] + temp['label'] = label + if annotation['ground_truth'] & val: + self.results.append(temp) + elif not annotation['ground_truth'] or not val: + self.results.append(temp) + self.num_classes = len(self.classes) + + def __getitem__(self, idx): + r = self.results[idx] + # extracting path to file + p = os.path.join(self._img_folder, r['file_upload']) + # loading image + sample = default_loader(p) + # casting to list and sorting classes + sorted_labels = sorted(list(self.classes)) + # checking index of class + label = sorted_labels.index(r['label']) + result = {DefaultDataKeys.INPUT: sample, + DefaultDataKeys.TARGET: label} + return result + + def __len__(self): + return len(self.results) + + def items(self): + item = [] + for anno in self.results: + for label in anno['result']: + item.append((anno['file_upload'], label)) + return item diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py new file mode 100644 index 0000000000..e5f416afe4 --- /dev/null +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -0,0 +1,36 @@ +from itertools import chain + +import flash +from flash.core.classification import Labels +from flash.core.finetuning import FreezeUnfreeze +from flash.image import ImageClassificationData, ImageClassifier + +# 1. Load export data +datamodule = ImageClassificationData.from_labelstudio( + export_json='project.json', + img_folder=r'C:\Users\MI\AppData\Local\label-studio\label-studio\media\upload', + val_split=0.8, +) + +# 2. Fine tune a model +model = ImageClassifier( + backbone="resnet18", + num_classes=datamodule.num_classes, +) +trainer = flash.Trainer(max_epochs=3) + +trainer.finetune( + model, + datamodule=datamodule, + strategy=FreezeUnfreeze(unfreeze_epoch=1), +) +trainer.save_checkpoint("image_classification_model.pt") + +# 3. Predict from checkpoint +model = ImageClassifier.load_from_checkpoint("../../image_classification_model.pt") +model.serializer = Labels() + +predictions = trainer.predict(model, datamodule=datamodule) +predictions = list(chain.from_iterable(predictions)) + +# 5 Visualize predictions in FiftyOne App diff --git a/flash_examples/integrations/labelstudio/project.json b/flash_examples/integrations/labelstudio/project.json new file mode 100644 index 0000000000..3af0dab4e7 --- /dev/null +++ b/flash_examples/integrations/labelstudio/project.json @@ -0,0 +1 @@ +[{"id": 187, "annotations": [{"id": 126, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 36.25, "y": 61.666666666666664, "width": 8.125, "height": 9.583333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 45.625, "y": 24.166666666666668, "width": 7.5, "height": 9.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 17.1875, "y": 76.66666666666667, "width": 8.4375, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 15.625, "y": 62.5, "width": 9.0625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 36.666666666666664, "width": 99.375, "height": 63.333333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 55.3125, "y": 33.33333333333334, "width": 43.4375, "height": 20.416666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:45:40.563712Z", "updated_at": "2021-05-12T19:42:28.202961Z", "lead_time": 10986.086, "prediction": {}, "result_count": 0, "task": 187}, {"id": 148, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 20.9375, "y": 63.75, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 39.375, "y": 65.83333333333331, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 23.75, "y": 50.833333333333336, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 3.125, "y": 55.416666666666664, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0.625, "y": 31.24999999999999, "width": 99.375, "height": 64.16666666666669, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 38.12499827146513, "y": 13.333330869674537, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:27.482555Z", "updated_at": "2021-06-11T14:07:10.013057Z", "lead_time": 1508.967, "prediction": {}, "result_count": 0, "task": 187}, {"id": 143, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 38.75, "y": 45.416666666666664, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 17.8125, "y": 64.58333333333331, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 19.375, "y": 49.583333333333336, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 0.3125, "y": 21.666666666666668, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 45.416666666666664, "width": 99.375, "height": 54.583333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 49.6875, "y": 41.666666666666664, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jbP06Unl4Y", "type": "rectanglelabels", "value": {"x": 66.875, "y": 13.75, "width": 25.625, "height": 10, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:37.449558Z", "updated_at": "2021-05-24T13:23:37.449558Z", "lead_time": 8.586, "prediction": {}, "result_count": 0, "task": 187}], "predictions": [{"id": 32, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 31.875, "y": 20, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 45, "y": 21.666666666666668, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 17.5, "y": 20.833333333333332, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 0.3125, "y": 21.666666666666668, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 45.416666666666664, "width": 99.375, "height": 54.583333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.916666666666668, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 187}], "file_upload": "Highway20030201_1002591.jpg", "data": {"image": "/data/upload/Highway20030201_1002591.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T14:07:09.933059Z", "project": 7}, {"id": 187, "annotations": [{"id": 126, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 36.25, "y": 61.666666666666664, "width": 8.125, "height": 9.583333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 45.625, "y": 24.166666666666668, "width": 7.5, "height": 9.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 17.1875, "y": 76.66666666666667, "width": 8.4375, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 15.625, "y": 62.5, "width": 9.0625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 36.666666666666664, "width": 99.375, "height": 63.333333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 55.3125, "y": 33.33333333333334, "width": 43.4375, "height": 20.416666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:45:40.563712Z", "updated_at": "2021-05-12T19:42:28.202961Z", "lead_time": 10986.086, "prediction": {}, "result_count": 0, "task": 187}, {"id": 148, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 20.9375, "y": 63.75, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 39.375, "y": 65.83333333333331, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 23.75, "y": 50.833333333333336, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 3.125, "y": 55.416666666666664, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0.625, "y": 31.24999999999999, "width": 99.375, "height": 64.16666666666669, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 38.12499827146513, "y": 13.333330869674537, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:27.482555Z", "updated_at": "2021-06-11T14:07:10.013057Z", "lead_time": 1508.967, "prediction": {}, "result_count": 0, "task": 187}, {"id": 143, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 38.75, "y": 45.416666666666664, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 17.8125, "y": 64.58333333333331, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 19.375, "y": 49.583333333333336, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 0.3125, "y": 21.666666666666668, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 45.416666666666664, "width": 99.375, "height": 54.583333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 49.6875, "y": 41.666666666666664, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jbP06Unl4Y", "type": "rectanglelabels", "value": {"x": 66.875, "y": 13.75, "width": 25.625, "height": 10, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:37.449558Z", "updated_at": "2021-05-24T13:23:37.449558Z", "lead_time": 8.586, "prediction": {}, "result_count": 0, "task": 187}], "predictions": [{"id": 32, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 31.875, "y": 20, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 45, "y": 21.666666666666668, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 17.5, "y": 20.833333333333332, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 0.3125, "y": 21.666666666666668, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 45.416666666666664, "width": 99.375, "height": 54.583333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.916666666666668, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 187}], "file_upload": "Highway20030201_1002591.jpg", "data": {"image": "/data/upload/Highway20030201_1002591.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T14:07:09.933059Z", "project": 7}, {"id": 187, "annotations": [{"id": 126, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 36.25, "y": 61.666666666666664, "width": 8.125, "height": 9.583333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 45.625, "y": 24.166666666666668, "width": 7.5, "height": 9.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 17.1875, "y": 76.66666666666667, "width": 8.4375, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 15.625, "y": 62.5, "width": 9.0625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 36.666666666666664, "width": 99.375, "height": 63.333333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 55.3125, "y": 33.33333333333334, "width": 43.4375, "height": 20.416666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:45:40.563712Z", "updated_at": "2021-05-12T19:42:28.202961Z", "lead_time": 10986.086, "prediction": {}, "result_count": 0, "task": 187}, {"id": 148, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 20.9375, "y": 63.75, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 39.375, "y": 65.83333333333331, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 23.75, "y": 50.833333333333336, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 3.125, "y": 55.416666666666664, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0.625, "y": 31.24999999999999, "width": 99.375, "height": 64.16666666666669, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 38.12499827146513, "y": 13.333330869674537, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:27.482555Z", "updated_at": "2021-06-11T14:07:10.013057Z", "lead_time": 1508.967, "prediction": {}, "result_count": 0, "task": 187}, {"id": 143, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 38.75, "y": 45.416666666666664, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 17.8125, "y": 64.58333333333331, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 19.375, "y": 49.583333333333336, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 0.3125, "y": 21.666666666666668, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 45.416666666666664, "width": 99.375, "height": 54.583333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 49.6875, "y": 41.666666666666664, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jbP06Unl4Y", "type": "rectanglelabels", "value": {"x": 66.875, "y": 13.75, "width": 25.625, "height": 10, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:37.449558Z", "updated_at": "2021-05-24T13:23:37.449558Z", "lead_time": 8.586, "prediction": {}, "result_count": 0, "task": 187}], "predictions": [{"id": 32, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 31.875, "y": 20, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 45, "y": 21.666666666666668, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 17.5, "y": 20.833333333333332, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 0.3125, "y": 21.666666666666668, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 45.416666666666664, "width": 99.375, "height": 54.583333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.916666666666668, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 187}], "file_upload": "Highway20030201_1002591.jpg", "data": {"image": "/data/upload/Highway20030201_1002591.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T14:07:09.933059Z", "project": 7}, {"id": 190, "annotations": [{"id": 129, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 42.5, "y": 20.833333333333332, "width": 7.5, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 24.166666666666668, "width": 7.1875, "height": 9.583333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 51.875, "y": 23.333333333333332, "width": 7.5, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 39.166666666666664, "width": 72.5, "height": 60.83333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 0, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.875, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:47:03.921658Z", "updated_at": "2021-05-12T19:43:30.961382Z", "lead_time": 11048.845, "prediction": {}, "result_count": 0, "task": 190}, {"id": 146, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 41.25, "y": 20.833333333333332, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 22.5, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 52.5, "y": 23.333333333333332, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 32.91666666666666, "width": 72.5, "height": 67.08333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:44.241688Z", "updated_at": "2021-05-24T13:23:44.241688Z", "lead_time": 0.707, "prediction": {}, "result_count": 0, "task": 190}, {"id": 151, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 38.125, "y": 17.5, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 57.50000020861628, "y": 37.08333455191726, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 46.875, "y": 21.25, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 16.249998927116287, "y": 3.3333314524755346, "width": 72.5, "height": 67.08333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 58.75, "y": 72.08333333333333, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:25:01.543103Z", "updated_at": "2021-06-11T14:01:50.540876Z", "lead_time": 1189.484, "prediction": {}, "result_count": 0, "task": 190}], "predictions": [{"id": 35, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 41.25, "y": 20.833333333333332, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 22.5, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 52.5, "y": 23.333333333333332, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 32.916666666666664, "width": 72.5, "height": 67.08333333333333, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 190}], "file_upload": "Highway20030201_7960376.jpg", "data": {"image": "/data/upload/Highway20030201_7960376.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T14:01:50.462875Z", "project": 7}, {"id": 190, "annotations": [{"id": 129, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 42.5, "y": 20.833333333333332, "width": 7.5, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 24.166666666666668, "width": 7.1875, "height": 9.583333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 51.875, "y": 23.333333333333332, "width": 7.5, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 39.166666666666664, "width": 72.5, "height": 60.83333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 0, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.875, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:47:03.921658Z", "updated_at": "2021-05-12T19:43:30.961382Z", "lead_time": 11048.845, "prediction": {}, "result_count": 0, "task": 190}, {"id": 146, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 41.25, "y": 20.833333333333332, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 22.5, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 52.5, "y": 23.333333333333332, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 32.91666666666666, "width": 72.5, "height": 67.08333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:44.241688Z", "updated_at": "2021-05-24T13:23:44.241688Z", "lead_time": 0.707, "prediction": {}, "result_count": 0, "task": 190}, {"id": 151, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 38.125, "y": 17.5, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 57.50000020861628, "y": 37.08333455191726, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 46.875, "y": 21.25, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 16.249998927116287, "y": 3.3333314524755346, "width": 72.5, "height": 67.08333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 58.75, "y": 72.08333333333333, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:25:01.543103Z", "updated_at": "2021-06-11T14:01:50.540876Z", "lead_time": 1189.484, "prediction": {}, "result_count": 0, "task": 190}], "predictions": [{"id": 35, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 41.25, "y": 20.833333333333332, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 22.5, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 52.5, "y": 23.333333333333332, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 32.916666666666664, "width": 72.5, "height": 67.08333333333333, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 190}], "file_upload": "Highway20030201_7960376.jpg", "data": {"image": "/data/upload/Highway20030201_7960376.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T14:01:50.462875Z", "project": 7}, {"id": 190, "annotations": [{"id": 129, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 42.5, "y": 20.833333333333332, "width": 7.5, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 24.166666666666668, "width": 7.1875, "height": 9.583333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 51.875, "y": 23.333333333333332, "width": 7.5, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 39.166666666666664, "width": 72.5, "height": 60.83333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 0, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.875, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:47:03.921658Z", "updated_at": "2021-05-12T19:43:30.961382Z", "lead_time": 11048.845, "prediction": {}, "result_count": 0, "task": 190}, {"id": 146, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 41.25, "y": 20.833333333333332, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 22.5, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 52.5, "y": 23.333333333333332, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 32.91666666666666, "width": 72.5, "height": 67.08333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:44.241688Z", "updated_at": "2021-05-24T13:23:44.241688Z", "lead_time": 0.707, "prediction": {}, "result_count": 0, "task": 190}, {"id": 151, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 38.125, "y": 17.5, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 57.50000020861628, "y": 37.08333455191726, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 46.875, "y": 21.25, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 16.249998927116287, "y": 3.3333314524755346, "width": 72.5, "height": 67.08333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 58.75, "y": 72.08333333333333, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:25:01.543103Z", "updated_at": "2021-06-11T14:01:50.540876Z", "lead_time": 1189.484, "prediction": {}, "result_count": 0, "task": 190}], "predictions": [{"id": 35, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 41.25, "y": 20.833333333333332, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 22.5, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 52.5, "y": 23.333333333333332, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 32.916666666666664, "width": 72.5, "height": 67.08333333333333, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 190}], "file_upload": "Highway20030201_7960376.jpg", "data": {"image": "/data/upload/Highway20030201_7960376.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T14:01:50.462875Z", "project": 7}, {"id": 191, "annotations": [{"id": 130, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 8.75, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 22.5, "width": 14.0625, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 93.4375, "y": 22.916666666666668, "width": 6.5625, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 0, "y": 39.583333333333336, "width": 100, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 0, "y": 17.5, "width": 48.125, "height": 41.66666666666666, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:47:38.867146Z", "updated_at": "2021-05-12T19:43:46.700787Z", "lead_time": 11064.568, "prediction": {}, "result_count": 0, "task": 191}, {"id": 147, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 21.25, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 92.5, "y": 22.916666666666668, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 39.583333333333336, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 1.875, "y": 17.5, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:46.987697Z", "updated_at": "2021-05-24T13:23:46.987697Z", "lead_time": 0.631, "prediction": {}, "result_count": 0, "task": 191}, {"id": 152, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 30.9375, "y": 0, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.25, "y": 10, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 88.125, "y": 0, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 0, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 4.99999994039535, "y": 48.333332379658955, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:25:12.150626Z", "updated_at": "2021-06-11T13:46:56.386332Z", "lead_time": 295.349, "prediction": {}, "result_count": 0, "task": 191}], "predictions": [{"id": 36, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 21.25, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 92.5, "y": 22.916666666666668, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 39.583333333333336, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 1.875, "y": 17.5, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 191}], "file_upload": "Highway20030201_8002476.jpg", "data": {"image": "/data/upload/Highway20030201_8002476.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T13:46:56.314731Z", "project": 7}, {"id": 191, "annotations": [{"id": 130, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 8.75, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 22.5, "width": 14.0625, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 93.4375, "y": 22.916666666666668, "width": 6.5625, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 0, "y": 39.583333333333336, "width": 100, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 0, "y": 17.5, "width": 48.125, "height": 41.66666666666666, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:47:38.867146Z", "updated_at": "2021-05-12T19:43:46.700787Z", "lead_time": 11064.568, "prediction": {}, "result_count": 0, "task": 191}, {"id": 147, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 21.25, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 92.5, "y": 22.916666666666668, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 39.583333333333336, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 1.875, "y": 17.5, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:46.987697Z", "updated_at": "2021-05-24T13:23:46.987697Z", "lead_time": 0.631, "prediction": {}, "result_count": 0, "task": 191}, {"id": 152, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 30.9375, "y": 0, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.25, "y": 10, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 88.125, "y": 0, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 0, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 4.99999994039535, "y": 48.333332379658955, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:25:12.150626Z", "updated_at": "2021-06-11T13:46:56.386332Z", "lead_time": 295.349, "prediction": {}, "result_count": 0, "task": 191}], "predictions": [{"id": 36, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 21.25, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 92.5, "y": 22.916666666666668, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 39.583333333333336, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 1.875, "y": 17.5, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 191}], "file_upload": "Highway20030201_8002476.jpg", "data": {"image": "/data/upload/Highway20030201_8002476.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T13:46:56.314731Z", "project": 7}, {"id": 191, "annotations": [{"id": 130, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 8.75, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 22.5, "width": 14.0625, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 93.4375, "y": 22.916666666666668, "width": 6.5625, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 0, "y": 39.583333333333336, "width": 100, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 0, "y": 17.5, "width": 48.125, "height": 41.66666666666666, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:47:38.867146Z", "updated_at": "2021-05-12T19:43:46.700787Z", "lead_time": 11064.568, "prediction": {}, "result_count": 0, "task": 191}, {"id": 147, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 21.25, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 92.5, "y": 22.916666666666668, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 39.583333333333336, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 1.875, "y": 17.5, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:46.987697Z", "updated_at": "2021-05-24T13:23:46.987697Z", "lead_time": 0.631, "prediction": {}, "result_count": 0, "task": 191}, {"id": 152, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 30.9375, "y": 0, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.25, "y": 10, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 88.125, "y": 0, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 0, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 4.99999994039535, "y": 48.333332379658955, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:25:12.150626Z", "updated_at": "2021-06-11T13:46:56.386332Z", "lead_time": 295.349, "prediction": {}, "result_count": 0, "task": 191}], "predictions": [{"id": 36, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 21.25, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 92.5, "y": 22.916666666666668, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 39.583333333333336, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 1.875, "y": 17.5, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 191}], "file_upload": "Highway20030201_8002476.jpg", "data": {"image": "/data/upload/Highway20030201_8002476.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T13:46:56.314731Z", "project": 7}, {"id": 188, "annotations": [{"id": 127, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 21.666666666666668, "width": 11.25, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.875, "y": 20.416666666666668, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 54.6875, "y": 22.083333333333332, "width": 45.3125, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 47.5, "width": 100, "height": 52.083333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:46:06.659977Z", "updated_at": "2021-05-12T19:42:47.876653Z", "lead_time": 11005.751, "prediction": {}, "result_count": 0, "task": 188}, {"id": 144, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 17.916666666666668, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:40.090034Z", "updated_at": "2021-05-24T13:23:40.090034Z", "lead_time": 1.374, "prediction": {}, "result_count": 0, "task": 188}, {"id": 149, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": -5.921189464667502e-15, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:42.214965Z", "updated_at": "2021-06-11T13:43:01.638568Z", "lead_time": 60.589, "prediction": {}, "result_count": 0, "task": 188}], "predictions": [{"id": 33, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 17.916666666666668, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 188}], "file_upload": "Highway20030201_1005916.jpg", "data": {"image": "/data/upload/Highway20030201_1005916.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T13:43:01.566550Z", "project": 7}, {"id": 188, "annotations": [{"id": 127, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 21.666666666666668, "width": 11.25, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.875, "y": 20.416666666666668, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 54.6875, "y": 22.083333333333332, "width": 45.3125, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 47.5, "width": 100, "height": 52.083333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:46:06.659977Z", "updated_at": "2021-05-12T19:42:47.876653Z", "lead_time": 11005.751, "prediction": {}, "result_count": 0, "task": 188}, {"id": 144, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 17.916666666666668, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:40.090034Z", "updated_at": "2021-05-24T13:23:40.090034Z", "lead_time": 1.374, "prediction": {}, "result_count": 0, "task": 188}, {"id": 149, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": -5.921189464667502e-15, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:42.214965Z", "updated_at": "2021-06-11T13:43:01.638568Z", "lead_time": 60.589, "prediction": {}, "result_count": 0, "task": 188}], "predictions": [{"id": 33, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 17.916666666666668, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 188}], "file_upload": "Highway20030201_1005916.jpg", "data": {"image": "/data/upload/Highway20030201_1005916.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T13:43:01.566550Z", "project": 7}, {"id": 188, "annotations": [{"id": 127, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 21.666666666666668, "width": 11.25, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.875, "y": 20.416666666666668, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 54.6875, "y": 22.083333333333332, "width": 45.3125, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 47.5, "width": 100, "height": 52.083333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:46:06.659977Z", "updated_at": "2021-05-12T19:42:47.876653Z", "lead_time": 11005.751, "prediction": {}, "result_count": 0, "task": 188}, {"id": 144, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 17.916666666666668, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:40.090034Z", "updated_at": "2021-05-24T13:23:40.090034Z", "lead_time": 1.374, "prediction": {}, "result_count": 0, "task": 188}, {"id": 149, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": -5.921189464667502e-15, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:42.214965Z", "updated_at": "2021-06-11T13:43:01.638568Z", "lead_time": 60.589, "prediction": {}, "result_count": 0, "task": 188}], "predictions": [{"id": 33, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 17.916666666666668, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 188}], "file_upload": "Highway20030201_1005916.jpg", "data": {"image": "/data/upload/Highway20030201_1005916.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T13:43:01.566550Z", "project": 7}, {"id": 189, "annotations": [{"id": 128, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 51.5625, "y": 21.666666666666668, "width": 7.8125, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 6.25, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 87.5, "y": 21.666666666666668, "width": 12.5, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 46.666666666666664, "width": 65.9375, "height": 53.333333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 45.625, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:46:40.902305Z", "updated_at": "2021-05-12T19:43:06.054031Z", "lead_time": 11023.941, "prediction": {}, "result_count": 0, "task": 189}, {"id": 145, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50, "y": 21.666666666666668, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 21.666666666666668, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 36.25, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:42.293104Z", "updated_at": "2021-05-24T13:23:42.293104Z", "lead_time": 0.801, "prediction": {}, "result_count": 0, "task": 189}, {"id": 150, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50.625, "y": 11.666666666666666, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 61.875, "y": 11.666666666666666, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 72.1875, "y": 19.583333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 9.166666666666666, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 25.416666666666668, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 2.1875, "y": 35.416666666666664, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0, "y": 13.333333333333334, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:51.461011Z", "updated_at": "2021-05-24T13:24:51.461011Z", "lead_time": 7.59, "prediction": {}, "result_count": 0, "task": 189}], "predictions": [{"id": 34, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50, "y": 21.666666666666668, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 21.666666666666668, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 36.25, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 189}], "file_upload": "Highway20030201_7922411.jpg", "data": {"image": "/data/upload/Highway20030201_7922411.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-05-12T19:43:06.008801Z", "project": 7}, {"id": 189, "annotations": [{"id": 128, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 51.5625, "y": 21.666666666666668, "width": 7.8125, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 6.25, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 87.5, "y": 21.666666666666668, "width": 12.5, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 46.666666666666664, "width": 65.9375, "height": 53.333333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 45.625, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:46:40.902305Z", "updated_at": "2021-05-12T19:43:06.054031Z", "lead_time": 11023.941, "prediction": {}, "result_count": 0, "task": 189}, {"id": 145, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50, "y": 21.666666666666668, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 21.666666666666668, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 36.25, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:42.293104Z", "updated_at": "2021-05-24T13:23:42.293104Z", "lead_time": 0.801, "prediction": {}, "result_count": 0, "task": 189}, {"id": 150, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50.625, "y": 11.666666666666666, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 61.875, "y": 11.666666666666666, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 72.1875, "y": 19.583333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 9.166666666666666, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 25.416666666666668, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 2.1875, "y": 35.416666666666664, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0, "y": 13.333333333333334, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:51.461011Z", "updated_at": "2021-05-24T13:24:51.461011Z", "lead_time": 7.59, "prediction": {}, "result_count": 0, "task": 189}], "predictions": [{"id": 34, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50, "y": 21.666666666666668, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 21.666666666666668, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 36.25, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 189}], "file_upload": "Highway20030201_7922411.jpg", "data": {"image": "/data/upload/Highway20030201_7922411.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-05-12T19:43:06.008801Z", "project": 7}, {"id": 189, "annotations": [{"id": 128, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 51.5625, "y": 21.666666666666668, "width": 7.8125, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 6.25, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 87.5, "y": 21.666666666666668, "width": 12.5, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 46.666666666666664, "width": 65.9375, "height": 53.333333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 45.625, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:46:40.902305Z", "updated_at": "2021-05-12T19:43:06.054031Z", "lead_time": 11023.941, "prediction": {}, "result_count": 0, "task": 189}, {"id": 145, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50, "y": 21.666666666666668, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 21.666666666666668, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 36.25, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:42.293104Z", "updated_at": "2021-05-24T13:23:42.293104Z", "lead_time": 0.801, "prediction": {}, "result_count": 0, "task": 189}, {"id": 150, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50.625, "y": 11.666666666666666, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 61.875, "y": 11.666666666666666, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 72.1875, "y": 19.583333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 9.166666666666666, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 25.416666666666668, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 2.1875, "y": 35.416666666666664, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0, "y": 13.333333333333334, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:51.461011Z", "updated_at": "2021-05-24T13:24:51.461011Z", "lead_time": 7.59, "prediction": {}, "result_count": 0, "task": 189}], "predictions": [{"id": 34, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50, "y": 21.666666666666668, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 21.666666666666668, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 36.25, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 189}], "file_upload": "Highway20030201_7922411.jpg", "data": {"image": "/data/upload/Highway20030201_7922411.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-05-12T19:43:06.008801Z", "project": 7}] \ No newline at end of file From f9987d1a2c59d5265a2762a95dc0f9b634064172 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Wed, 7 Jul 2021 22:45:30 +0300 Subject: [PATCH 02/53] Import fixes --- flash/core/data/data_module.py | 3 +-- flash/core/data/data_source.py | 7 ------- .../labelstudio/image_classification.py | 19 ++++++++++++------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/flash/core/data/data_module.py b/flash/core/data/data_module.py index f9d47ce32f..97a5790d49 100644 --- a/flash/core/data/data_module.py +++ b/flash/core/data/data_module.py @@ -29,8 +29,7 @@ from flash.core.data.base_viz import BaseVisualization from flash.core.data.callback import BaseDataFetcher from flash.core.data.data_pipeline import DataPipeline, DefaultPreprocess, Postprocess, Preprocess -from flash.core.data.data_source import DataSource, DefaultDataSources, LabelStudioDataset, LabelStudioDataSource, \ - PathsDataSource +from flash.core.data.data_source import DataSource, DefaultDataSources, LabelStudioDataset from flash.core.data.splits import SplitDataset from flash.core.data.utils import _STAGES_PREFIX from flash.core.utilities.imports import _FIFTYONE_AVAILABLE diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index 083ed8614a..4d2aff8110 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -607,10 +607,3 @@ def __getitem__(self, idx): def __len__(self): return len(self.results) - - def items(self): - item = [] - for anno in self.results: - for label in anno['result']: - item.append((anno['file_upload'], label)) - return item diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py index e5f416afe4..149dbc5ebc 100644 --- a/flash_examples/integrations/labelstudio/image_classification.py +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -1,14 +1,19 @@ from itertools import chain +from flash.core.data.utils import download_data + import flash from flash.core.classification import Labels from flash.core.finetuning import FreezeUnfreeze from flash.image import ImageClassificationData, ImageClassifier +# 1 Download data +download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") + # 1. Load export data datamodule = ImageClassificationData.from_labelstudio( - export_json='project.json', - img_folder=r'C:\Users\MI\AppData\Local\label-studio\label-studio\media\upload', + export_json='data/project.json', + img_folder='data/upload/', val_split=0.8, ) @@ -27,10 +32,10 @@ trainer.save_checkpoint("image_classification_model.pt") # 3. Predict from checkpoint -model = ImageClassifier.load_from_checkpoint("../../image_classification_model.pt") +model = ImageClassifier.load_from_checkpoint("image_classification_model.pt") model.serializer = Labels() -predictions = trainer.predict(model, datamodule=datamodule) -predictions = list(chain.from_iterable(predictions)) - -# 5 Visualize predictions in FiftyOne App +predictions = model.predict([ + "data/test/1.jpg", + "data/test/2.jpg", +]) From 81d2de375f711042f0f4e91f5f2a0fe261fabd88 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Wed, 7 Jul 2021 22:51:16 +0300 Subject: [PATCH 03/53] Moving project.json to test data in S3 --- flash_examples/integrations/labelstudio/project.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 flash_examples/integrations/labelstudio/project.json diff --git a/flash_examples/integrations/labelstudio/project.json b/flash_examples/integrations/labelstudio/project.json deleted file mode 100644 index 3af0dab4e7..0000000000 --- a/flash_examples/integrations/labelstudio/project.json +++ /dev/null @@ -1 +0,0 @@ -[{"id": 187, "annotations": [{"id": 126, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 36.25, "y": 61.666666666666664, "width": 8.125, "height": 9.583333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 45.625, "y": 24.166666666666668, "width": 7.5, "height": 9.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 17.1875, "y": 76.66666666666667, "width": 8.4375, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 15.625, "y": 62.5, "width": 9.0625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 36.666666666666664, "width": 99.375, "height": 63.333333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 55.3125, "y": 33.33333333333334, "width": 43.4375, "height": 20.416666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:45:40.563712Z", "updated_at": "2021-05-12T19:42:28.202961Z", "lead_time": 10986.086, "prediction": {}, "result_count": 0, "task": 187}, {"id": 148, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 20.9375, "y": 63.75, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 39.375, "y": 65.83333333333331, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 23.75, "y": 50.833333333333336, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 3.125, "y": 55.416666666666664, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0.625, "y": 31.24999999999999, "width": 99.375, "height": 64.16666666666669, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 38.12499827146513, "y": 13.333330869674537, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:27.482555Z", "updated_at": "2021-06-11T14:07:10.013057Z", "lead_time": 1508.967, "prediction": {}, "result_count": 0, "task": 187}, {"id": 143, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 38.75, "y": 45.416666666666664, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 17.8125, "y": 64.58333333333331, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 19.375, "y": 49.583333333333336, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 0.3125, "y": 21.666666666666668, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 45.416666666666664, "width": 99.375, "height": 54.583333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 49.6875, "y": 41.666666666666664, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jbP06Unl4Y", "type": "rectanglelabels", "value": {"x": 66.875, "y": 13.75, "width": 25.625, "height": 10, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:37.449558Z", "updated_at": "2021-05-24T13:23:37.449558Z", "lead_time": 8.586, "prediction": {}, "result_count": 0, "task": 187}], "predictions": [{"id": 32, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 31.875, "y": 20, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 45, "y": 21.666666666666668, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 17.5, "y": 20.833333333333332, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 0.3125, "y": 21.666666666666668, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 45.416666666666664, "width": 99.375, "height": 54.583333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.916666666666668, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 187}], "file_upload": "Highway20030201_1002591.jpg", "data": {"image": "/data/upload/Highway20030201_1002591.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T14:07:09.933059Z", "project": 7}, {"id": 187, "annotations": [{"id": 126, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 36.25, "y": 61.666666666666664, "width": 8.125, "height": 9.583333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 45.625, "y": 24.166666666666668, "width": 7.5, "height": 9.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 17.1875, "y": 76.66666666666667, "width": 8.4375, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 15.625, "y": 62.5, "width": 9.0625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 36.666666666666664, "width": 99.375, "height": 63.333333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 55.3125, "y": 33.33333333333334, "width": 43.4375, "height": 20.416666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:45:40.563712Z", "updated_at": "2021-05-12T19:42:28.202961Z", "lead_time": 10986.086, "prediction": {}, "result_count": 0, "task": 187}, {"id": 148, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 20.9375, "y": 63.75, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 39.375, "y": 65.83333333333331, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 23.75, "y": 50.833333333333336, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 3.125, "y": 55.416666666666664, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0.625, "y": 31.24999999999999, "width": 99.375, "height": 64.16666666666669, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 38.12499827146513, "y": 13.333330869674537, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:27.482555Z", "updated_at": "2021-06-11T14:07:10.013057Z", "lead_time": 1508.967, "prediction": {}, "result_count": 0, "task": 187}, {"id": 143, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 38.75, "y": 45.416666666666664, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 17.8125, "y": 64.58333333333331, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 19.375, "y": 49.583333333333336, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 0.3125, "y": 21.666666666666668, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 45.416666666666664, "width": 99.375, "height": 54.583333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 49.6875, "y": 41.666666666666664, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jbP06Unl4Y", "type": "rectanglelabels", "value": {"x": 66.875, "y": 13.75, "width": 25.625, "height": 10, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:37.449558Z", "updated_at": "2021-05-24T13:23:37.449558Z", "lead_time": 8.586, "prediction": {}, "result_count": 0, "task": 187}], "predictions": [{"id": 32, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 31.875, "y": 20, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 45, "y": 21.666666666666668, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 17.5, "y": 20.833333333333332, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 0.3125, "y": 21.666666666666668, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 45.416666666666664, "width": 99.375, "height": 54.583333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.916666666666668, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 187}], "file_upload": "Highway20030201_1002591.jpg", "data": {"image": "/data/upload/Highway20030201_1002591.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T14:07:09.933059Z", "project": 7}, {"id": 187, "annotations": [{"id": 126, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 36.25, "y": 61.666666666666664, "width": 8.125, "height": 9.583333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 45.625, "y": 24.166666666666668, "width": 7.5, "height": 9.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 17.1875, "y": 76.66666666666667, "width": 8.4375, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 15.625, "y": 62.5, "width": 9.0625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 36.666666666666664, "width": 99.375, "height": 63.333333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 55.3125, "y": 33.33333333333334, "width": 43.4375, "height": 20.416666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:45:40.563712Z", "updated_at": "2021-05-12T19:42:28.202961Z", "lead_time": 10986.086, "prediction": {}, "result_count": 0, "task": 187}, {"id": 148, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 20.9375, "y": 63.75, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 39.375, "y": 65.83333333333331, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 23.75, "y": 50.833333333333336, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 3.125, "y": 55.416666666666664, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0.625, "y": 31.24999999999999, "width": 99.375, "height": 64.16666666666669, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 38.12499827146513, "y": 13.333330869674537, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:27.482555Z", "updated_at": "2021-06-11T14:07:10.013057Z", "lead_time": 1508.967, "prediction": {}, "result_count": 0, "task": 187}, {"id": 143, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 38.75, "y": 45.416666666666664, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 17.8125, "y": 64.58333333333331, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 19.375, "y": 49.583333333333336, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 0.3125, "y": 21.666666666666668, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 45.416666666666664, "width": 99.375, "height": 54.583333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 49.6875, "y": 41.666666666666664, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jbP06Unl4Y", "type": "rectanglelabels", "value": {"x": 66.875, "y": 13.75, "width": 25.625, "height": 10, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:37.449558Z", "updated_at": "2021-05-24T13:23:37.449558Z", "lead_time": 8.586, "prediction": {}, "result_count": 0, "task": 187}], "predictions": [{"id": 32, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "SMiPhTvFAt", "type": "rectanglelabels", "value": {"x": 31.875, "y": 20, "width": 8.75, "height": 13.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "upbpvLotCq", "type": "rectanglelabels", "value": {"x": 45, "y": 21.666666666666668, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "OC8neWBhAO", "type": "rectanglelabels", "value": {"x": 17.5, "y": 20.833333333333332, "width": 9.375, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7glE8KAaWz", "type": "rectanglelabels", "value": {"x": 0.3125, "y": 21.666666666666668, "width": 11.5625, "height": 17.916666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "QDIKDN6mZQ", "type": "rectanglelabels", "value": {"x": 0, "y": 45.416666666666664, "width": 99.375, "height": 54.583333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "S7VOMsfkvC", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.916666666666668, "width": 43.75, "height": 19.583333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 187}], "file_upload": "Highway20030201_1002591.jpg", "data": {"image": "/data/upload/Highway20030201_1002591.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T14:07:09.933059Z", "project": 7}, {"id": 190, "annotations": [{"id": 129, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 42.5, "y": 20.833333333333332, "width": 7.5, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 24.166666666666668, "width": 7.1875, "height": 9.583333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 51.875, "y": 23.333333333333332, "width": 7.5, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 39.166666666666664, "width": 72.5, "height": 60.83333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 0, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.875, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:47:03.921658Z", "updated_at": "2021-05-12T19:43:30.961382Z", "lead_time": 11048.845, "prediction": {}, "result_count": 0, "task": 190}, {"id": 146, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 41.25, "y": 20.833333333333332, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 22.5, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 52.5, "y": 23.333333333333332, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 32.91666666666666, "width": 72.5, "height": 67.08333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:44.241688Z", "updated_at": "2021-05-24T13:23:44.241688Z", "lead_time": 0.707, "prediction": {}, "result_count": 0, "task": 190}, {"id": 151, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 38.125, "y": 17.5, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 57.50000020861628, "y": 37.08333455191726, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 46.875, "y": 21.25, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 16.249998927116287, "y": 3.3333314524755346, "width": 72.5, "height": 67.08333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 58.75, "y": 72.08333333333333, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:25:01.543103Z", "updated_at": "2021-06-11T14:01:50.540876Z", "lead_time": 1189.484, "prediction": {}, "result_count": 0, "task": 190}], "predictions": [{"id": 35, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 41.25, "y": 20.833333333333332, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 22.5, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 52.5, "y": 23.333333333333332, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 32.916666666666664, "width": 72.5, "height": 67.08333333333333, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 190}], "file_upload": "Highway20030201_7960376.jpg", "data": {"image": "/data/upload/Highway20030201_7960376.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T14:01:50.462875Z", "project": 7}, {"id": 190, "annotations": [{"id": 129, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 42.5, "y": 20.833333333333332, "width": 7.5, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 24.166666666666668, "width": 7.1875, "height": 9.583333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 51.875, "y": 23.333333333333332, "width": 7.5, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 39.166666666666664, "width": 72.5, "height": 60.83333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 0, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.875, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:47:03.921658Z", "updated_at": "2021-05-12T19:43:30.961382Z", "lead_time": 11048.845, "prediction": {}, "result_count": 0, "task": 190}, {"id": 146, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 41.25, "y": 20.833333333333332, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 22.5, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 52.5, "y": 23.333333333333332, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 32.91666666666666, "width": 72.5, "height": 67.08333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:44.241688Z", "updated_at": "2021-05-24T13:23:44.241688Z", "lead_time": 0.707, "prediction": {}, "result_count": 0, "task": 190}, {"id": 151, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 38.125, "y": 17.5, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 57.50000020861628, "y": 37.08333455191726, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 46.875, "y": 21.25, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 16.249998927116287, "y": 3.3333314524755346, "width": 72.5, "height": 67.08333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 58.75, "y": 72.08333333333333, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:25:01.543103Z", "updated_at": "2021-06-11T14:01:50.540876Z", "lead_time": 1189.484, "prediction": {}, "result_count": 0, "task": 190}], "predictions": [{"id": 35, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 41.25, "y": 20.833333333333332, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 22.5, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 52.5, "y": 23.333333333333332, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 32.916666666666664, "width": 72.5, "height": 67.08333333333333, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 190}], "file_upload": "Highway20030201_7960376.jpg", "data": {"image": "/data/upload/Highway20030201_7960376.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T14:01:50.462875Z", "project": 7}, {"id": 190, "annotations": [{"id": 129, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 42.5, "y": 20.833333333333332, "width": 7.5, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 24.166666666666668, "width": 7.1875, "height": 9.583333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 51.875, "y": 23.333333333333332, "width": 7.5, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 39.166666666666664, "width": 72.5, "height": 60.83333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 0, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.875, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:47:03.921658Z", "updated_at": "2021-05-12T19:43:30.961382Z", "lead_time": 11048.845, "prediction": {}, "result_count": 0, "task": 190}, {"id": 146, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 41.25, "y": 20.833333333333332, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 22.5, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 52.5, "y": 23.333333333333332, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 32.91666666666666, "width": 72.5, "height": 67.08333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:44.241688Z", "updated_at": "2021-05-24T13:23:44.241688Z", "lead_time": 0.707, "prediction": {}, "result_count": 0, "task": 190}, {"id": 151, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 38.125, "y": 17.5, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 57.50000020861628, "y": 37.08333455191726, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 46.875, "y": 21.25, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 16.249998927116287, "y": 3.3333314524755346, "width": 72.5, "height": 67.08333333333331, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 58.75, "y": 72.08333333333333, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:25:01.543103Z", "updated_at": "2021-06-11T14:01:50.540876Z", "lead_time": 1189.484, "prediction": {}, "result_count": 0, "task": 190}], "predictions": [{"id": 35, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "MAieLaIEwn", "type": "rectanglelabels", "value": {"x": 41.25, "y": 20.833333333333332, "width": 8.75, "height": 10.416666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "7wyQvJB-MC", "type": "rectanglelabels", "value": {"x": 58.75, "y": 22.5, "width": 9.6875, "height": 11.25, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "A522zzqqdX", "type": "rectanglelabels", "value": {"x": 52.5, "y": 23.333333333333332, "width": 6.875, "height": 7.083333333333333, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "G33zn-HVQv", "type": "rectanglelabels", "value": {"x": 27.5, "y": 32.916666666666664, "width": 72.5, "height": 67.08333333333333, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "peCH2t2YGo", "type": "rectanglelabels", "value": {"x": 1.5625, "y": 50.833333333333336, "width": 23.125, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "iewQz5Jf3e", "type": "rectanglelabels", "value": {"x": 0, "y": 24.166666666666668, "width": 41.25, "height": 27.916666666666668, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 190}], "file_upload": "Highway20030201_7960376.jpg", "data": {"image": "/data/upload/Highway20030201_7960376.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T14:01:50.462875Z", "project": 7}, {"id": 191, "annotations": [{"id": 130, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 8.75, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 22.5, "width": 14.0625, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 93.4375, "y": 22.916666666666668, "width": 6.5625, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 0, "y": 39.583333333333336, "width": 100, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 0, "y": 17.5, "width": 48.125, "height": 41.66666666666666, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:47:38.867146Z", "updated_at": "2021-05-12T19:43:46.700787Z", "lead_time": 11064.568, "prediction": {}, "result_count": 0, "task": 191}, {"id": 147, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 21.25, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 92.5, "y": 22.916666666666668, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 39.583333333333336, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 1.875, "y": 17.5, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:46.987697Z", "updated_at": "2021-05-24T13:23:46.987697Z", "lead_time": 0.631, "prediction": {}, "result_count": 0, "task": 191}, {"id": 152, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 30.9375, "y": 0, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.25, "y": 10, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 88.125, "y": 0, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 0, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 4.99999994039535, "y": 48.333332379658955, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:25:12.150626Z", "updated_at": "2021-06-11T13:46:56.386332Z", "lead_time": 295.349, "prediction": {}, "result_count": 0, "task": 191}], "predictions": [{"id": 36, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 21.25, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 92.5, "y": 22.916666666666668, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 39.583333333333336, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 1.875, "y": 17.5, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 191}], "file_upload": "Highway20030201_8002476.jpg", "data": {"image": "/data/upload/Highway20030201_8002476.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T13:46:56.314731Z", "project": 7}, {"id": 191, "annotations": [{"id": 130, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 8.75, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 22.5, "width": 14.0625, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 93.4375, "y": 22.916666666666668, "width": 6.5625, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 0, "y": 39.583333333333336, "width": 100, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 0, "y": 17.5, "width": 48.125, "height": 41.66666666666666, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:47:38.867146Z", "updated_at": "2021-05-12T19:43:46.700787Z", "lead_time": 11064.568, "prediction": {}, "result_count": 0, "task": 191}, {"id": 147, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 21.25, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 92.5, "y": 22.916666666666668, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 39.583333333333336, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 1.875, "y": 17.5, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:46.987697Z", "updated_at": "2021-05-24T13:23:46.987697Z", "lead_time": 0.631, "prediction": {}, "result_count": 0, "task": 191}, {"id": 152, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 30.9375, "y": 0, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.25, "y": 10, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 88.125, "y": 0, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 0, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 4.99999994039535, "y": 48.333332379658955, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:25:12.150626Z", "updated_at": "2021-06-11T13:46:56.386332Z", "lead_time": 295.349, "prediction": {}, "result_count": 0, "task": 191}], "predictions": [{"id": 36, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 21.25, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 92.5, "y": 22.916666666666668, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 39.583333333333336, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 1.875, "y": 17.5, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 191}], "file_upload": "Highway20030201_8002476.jpg", "data": {"image": "/data/upload/Highway20030201_8002476.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T13:46:56.314731Z", "project": 7}, {"id": 191, "annotations": [{"id": 130, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 8.75, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 22.5, "width": 14.0625, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 93.4375, "y": 22.916666666666668, "width": 6.5625, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 0, "y": 39.583333333333336, "width": 100, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 0, "y": 17.5, "width": 48.125, "height": 41.66666666666666, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:47:38.867146Z", "updated_at": "2021-05-12T19:43:46.700787Z", "lead_time": 11064.568, "prediction": {}, "result_count": 0, "task": 191}, {"id": 147, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 21.25, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 92.5, "y": 22.916666666666668, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 39.583333333333336, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 1.875, "y": 17.5, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:46.987697Z", "updated_at": "2021-05-24T13:23:46.987697Z", "lead_time": 0.631, "prediction": {}, "result_count": 0, "task": 191}, {"id": 152, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 30.9375, "y": 0, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.25, "y": 10, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 88.125, "y": 0, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 0, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 4.99999994039535, "y": 48.333332379658955, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:25:12.150626Z", "updated_at": "2021-06-11T13:46:56.386332Z", "lead_time": 295.349, "prediction": {}, "result_count": 0, "task": 191}], "predictions": [{"id": 36, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "dv1Tn-zdez", "type": "rectanglelabels", "value": {"x": 46.5625, "y": 21.666666666666668, "width": 10.3125, "height": 12.083333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "KRa8jEvpK0", "type": "rectanglelabels", "value": {"x": 66.875, "y": 21.25, "width": 16.25, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "kAKaSxNnvH", "type": "rectanglelabels", "value": {"x": 92.5, "y": 22.916666666666668, "width": 7.5, "height": 18.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "_VXKV2nz14", "type": "rectanglelabels", "value": {"x": 5.9375, "y": 39.583333333333336, "width": 94.0625, "height": 60.416666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "vCuvi_jLHn", "type": "rectanglelabels", "value": {"x": 1.875, "y": 17.5, "width": 46.25, "height": 36.666666666666664, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 191}], "file_upload": "Highway20030201_8002476.jpg", "data": {"image": "/data/upload/Highway20030201_8002476.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T13:46:56.314731Z", "project": 7}, {"id": 188, "annotations": [{"id": 127, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 21.666666666666668, "width": 11.25, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.875, "y": 20.416666666666668, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 54.6875, "y": 22.083333333333332, "width": 45.3125, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 47.5, "width": 100, "height": 52.083333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:46:06.659977Z", "updated_at": "2021-05-12T19:42:47.876653Z", "lead_time": 11005.751, "prediction": {}, "result_count": 0, "task": 188}, {"id": 144, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 17.916666666666668, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:40.090034Z", "updated_at": "2021-05-24T13:23:40.090034Z", "lead_time": 1.374, "prediction": {}, "result_count": 0, "task": 188}, {"id": 149, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": -5.921189464667502e-15, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:42.214965Z", "updated_at": "2021-06-11T13:43:01.638568Z", "lead_time": 60.589, "prediction": {}, "result_count": 0, "task": 188}], "predictions": [{"id": 33, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 17.916666666666668, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 188}], "file_upload": "Highway20030201_1005916.jpg", "data": {"image": "/data/upload/Highway20030201_1005916.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T13:43:01.566550Z", "project": 7}, {"id": 188, "annotations": [{"id": 127, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 21.666666666666668, "width": 11.25, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.875, "y": 20.416666666666668, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 54.6875, "y": 22.083333333333332, "width": 45.3125, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 47.5, "width": 100, "height": 52.083333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:46:06.659977Z", "updated_at": "2021-05-12T19:42:47.876653Z", "lead_time": 11005.751, "prediction": {}, "result_count": 0, "task": 188}, {"id": 144, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 17.916666666666668, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:40.090034Z", "updated_at": "2021-05-24T13:23:40.090034Z", "lead_time": 1.374, "prediction": {}, "result_count": 0, "task": 188}, {"id": 149, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": -5.921189464667502e-15, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:42.214965Z", "updated_at": "2021-06-11T13:43:01.638568Z", "lead_time": 60.589, "prediction": {}, "result_count": 0, "task": 188}], "predictions": [{"id": 33, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 17.916666666666668, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 188}], "file_upload": "Highway20030201_1005916.jpg", "data": {"image": "/data/upload/Highway20030201_1005916.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T13:43:01.566550Z", "project": 7}, {"id": 188, "annotations": [{"id": 127, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 21.666666666666668, "width": 11.25, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.875, "y": 20.416666666666668, "width": 8.125, "height": 11.666666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 54.6875, "y": 22.083333333333332, "width": 45.3125, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 47.5, "width": 100, "height": 52.083333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:46:06.659977Z", "updated_at": "2021-05-12T19:42:47.876653Z", "lead_time": 11005.751, "prediction": {}, "result_count": 0, "task": 188}, {"id": 144, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 17.916666666666668, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:40.090034Z", "updated_at": "2021-05-24T13:23:40.090034Z", "lead_time": 1.374, "prediction": {}, "result_count": 0, "task": 188}, {"id": 149, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": -5.921189464667502e-15, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:42.214965Z", "updated_at": "2021-06-11T13:43:01.638568Z", "lead_time": 60.589, "prediction": {}, "result_count": 0, "task": 188}], "predictions": [{"id": 33, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "nQld0F0eIH", "type": "rectanglelabels", "value": {"x": 15.625, "y": 19.166666666666668, "width": 11.25, "height": 14.166666666666666, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "HwDPIFAbuS", "type": "rectanglelabels", "value": {"x": 46.25, "y": 18.75, "width": 8.75, "height": 17.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "uVgO5NRkoY", "type": "rectanglelabels", "value": {"x": 28.125, "y": 21.25, "width": 6.875, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "4sZjs0PP40", "type": "rectanglelabels", "value": {"x": 35.3125, "y": 23.333333333333332, "width": 8.4375, "height": 6.666666666666667, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "nMgiJtGHCg", "type": "rectanglelabels", "value": {"x": 56.25, "y": 22.083333333333332, "width": 43.75, "height": 22.083333333333332, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "cACp2O2WuP", "type": "rectanglelabels", "value": {"x": 0, "y": 17.916666666666668, "width": 100, "height": 81.66666666666667, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 188}], "file_upload": "Highway20030201_1005916.jpg", "data": {"image": "/data/upload/Highway20030201_1005916.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-06-11T13:43:01.566550Z", "project": 7}, {"id": 189, "annotations": [{"id": 128, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 51.5625, "y": 21.666666666666668, "width": 7.8125, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 6.25, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 87.5, "y": 21.666666666666668, "width": 12.5, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 46.666666666666664, "width": 65.9375, "height": 53.333333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 45.625, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:46:40.902305Z", "updated_at": "2021-05-12T19:43:06.054031Z", "lead_time": 11023.941, "prediction": {}, "result_count": 0, "task": 189}, {"id": 145, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50, "y": 21.666666666666668, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 21.666666666666668, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 36.25, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:42.293104Z", "updated_at": "2021-05-24T13:23:42.293104Z", "lead_time": 0.801, "prediction": {}, "result_count": 0, "task": 189}, {"id": 150, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50.625, "y": 11.666666666666666, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 61.875, "y": 11.666666666666666, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 72.1875, "y": 19.583333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 9.166666666666666, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 25.416666666666668, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 2.1875, "y": 35.416666666666664, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0, "y": 13.333333333333334, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:51.461011Z", "updated_at": "2021-05-24T13:24:51.461011Z", "lead_time": 7.59, "prediction": {}, "result_count": 0, "task": 189}], "predictions": [{"id": 34, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50, "y": 21.666666666666668, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 21.666666666666668, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 36.25, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 189}], "file_upload": "Highway20030201_7922411.jpg", "data": {"image": "/data/upload/Highway20030201_7922411.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-05-12T19:43:06.008801Z", "project": 7}, {"id": 189, "annotations": [{"id": 128, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 51.5625, "y": 21.666666666666668, "width": 7.8125, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 6.25, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 87.5, "y": 21.666666666666668, "width": 12.5, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 46.666666666666664, "width": 65.9375, "height": 53.333333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 45.625, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:46:40.902305Z", "updated_at": "2021-05-12T19:43:06.054031Z", "lead_time": 11023.941, "prediction": {}, "result_count": 0, "task": 189}, {"id": 145, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50, "y": 21.666666666666668, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 21.666666666666668, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 36.25, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:42.293104Z", "updated_at": "2021-05-24T13:23:42.293104Z", "lead_time": 0.801, "prediction": {}, "result_count": 0, "task": 189}, {"id": 150, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50.625, "y": 11.666666666666666, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 61.875, "y": 11.666666666666666, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 72.1875, "y": 19.583333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 9.166666666666666, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 25.416666666666668, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 2.1875, "y": 35.416666666666664, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0, "y": 13.333333333333334, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:51.461011Z", "updated_at": "2021-05-24T13:24:51.461011Z", "lead_time": 7.59, "prediction": {}, "result_count": 0, "task": 189}], "predictions": [{"id": 34, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50, "y": 21.666666666666668, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 21.666666666666668, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 36.25, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 189}], "file_upload": "Highway20030201_7922411.jpg", "data": {"image": "/data/upload/Highway20030201_7922411.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-05-12T19:43:06.008801Z", "project": 7}, {"id": 189, "annotations": [{"id": 128, "completed_by": {"id": 1, "email": "pagocmb@bk.ru", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 51.5625, "y": 21.666666666666668, "width": 7.8125, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 6.25, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 87.5, "y": 21.666666666666668, "width": 12.5, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 46.666666666666664, "width": 65.9375, "height": 53.333333333333336, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 45.625, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-12T18:46:40.902305Z", "updated_at": "2021-05-12T19:43:06.054031Z", "lead_time": 11023.941, "prediction": {}, "result_count": 0, "task": 189}, {"id": 145, "completed_by": {"id": 3, "email": "jack@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50, "y": 21.666666666666668, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 21.666666666666668, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 36.25, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:23:42.293104Z", "updated_at": "2021-05-24T13:23:42.293104Z", "lead_time": 0.801, "prediction": {}, "result_count": 0, "task": 189}, {"id": 150, "completed_by": {"id": 2, "email": "anna@ai.com", "first_name": "", "last_name": ""}, "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50.625, "y": 11.666666666666666, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 61.875, "y": 11.666666666666666, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 72.1875, "y": 19.583333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 9.166666666666666, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 25.416666666666668, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 2.1875, "y": 35.416666666666664, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0, "y": 13.333333333333334, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "was_cancelled": false, "ground_truth": false, "created_at": "2021-05-24T13:24:51.461011Z", "updated_at": "2021-05-24T13:24:51.461011Z", "lead_time": 7.59, "prediction": {}, "result_count": 0, "task": 189}], "predictions": [{"id": 34, "model_version": "1", "created_ago": "1 month, 3 weeks", "result": [{"id": "AssZHGMLlF", "type": "rectanglelabels", "value": {"x": 50, "y": 21.666666666666668, "width": 9.375, "height": 10.833333333333334, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "MCXiw3h68g", "type": "rectanglelabels", "value": {"x": 60.9375, "y": 22.5, "width": 6.5625, "height": 8.75, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dJpF0iQllH", "type": "rectanglelabels", "value": {"x": 73.125, "y": 22.083333333333332, "width": 8.75, "height": 12.5, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "2tz_Ld3-Qo", "type": "rectanglelabels", "value": {"x": 86.25, "y": 21.666666666666668, "width": 13.75, "height": 31.666666666666668, "rotation": 0, "rectanglelabels": ["Car"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "W6ik1JK_sN", "type": "rectanglelabels", "value": {"x": 34.0625, "y": 36.25, "width": 65.9375, "height": 63.75, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "dTCEzb-bI6", "type": "rectanglelabels", "value": {"x": 1.875, "y": 50.833333333333336, "width": 33.75, "height": 49.166666666666664, "rotation": 0, "rectanglelabels": ["Road"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}, {"id": "jsYuQwa48A", "type": "rectanglelabels", "value": {"x": 0.625, "y": 26.666666666666668, "width": 50, "height": 26.25, "rotation": 0, "rectanglelabels": ["Obstacle"]}, "to_name": "image", "from_name": "label", "image_rotation": 0, "original_width": 320, "original_height": 240}], "score": 0.95, "cluster": null, "neighbors": null, "mislabeling": 0.02, "created_at": "2021-05-12T19:40:48.688571Z", "updated_at": "2021-05-12T19:40:48.688571Z", "task": 189}], "file_upload": "Highway20030201_7922411.jpg", "data": {"image": "/data/upload/Highway20030201_7922411.jpg"}, "meta": {}, "created_at": "2021-05-12T18:43:41.241095Z", "updated_at": "2021-05-12T19:43:06.008801Z", "project": 7}] \ No newline at end of file From ae1cbe7fdb8ef64181686f8a70570a9255adf65f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 7 Jul 2021 21:15:05 +0000 Subject: [PATCH 04/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- flash/core/data/data_module.py | 2 +- flash/core/data/data_source.py | 4 ++-- .../integrations/labelstudio/image_classification.py | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/flash/core/data/data_module.py b/flash/core/data/data_module.py index 97a5790d49..bfa29843a6 100644 --- a/flash/core/data/data_module.py +++ b/flash/core/data/data_module.py @@ -22,7 +22,7 @@ from pytorch_lightning.trainer.states import RunningStage from pytorch_lightning.utilities.exceptions import MisconfigurationException from torch.utils.data import DataLoader, Dataset -from torch.utils.data.dataset import IterableDataset, Subset, random_split +from torch.utils.data.dataset import IterableDataset, random_split, Subset from torch.utils.data.sampler import Sampler from flash.core.data.auto_dataset import BaseAutoDataset, IterableAutoDataset diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index 4d2aff8110..eebd86aa9c 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -556,6 +556,7 @@ class LabelStudioDataset(Dataset): *js: json of export file *img_folder: path to image folder of label studio """ + def __init__(self, js, img_folder, val=False): self._raw_data = js self._img_folder = img_folder @@ -601,8 +602,7 @@ def __getitem__(self, idx): sorted_labels = sorted(list(self.classes)) # checking index of class label = sorted_labels.index(r['label']) - result = {DefaultDataKeys.INPUT: sample, - DefaultDataKeys.TARGET: label} + result = {DefaultDataKeys.INPUT: sample, DefaultDataKeys.TARGET: label} return result def __len__(self): diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py index 149dbc5ebc..d72a52b097 100644 --- a/flash_examples/integrations/labelstudio/image_classification.py +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -1,9 +1,8 @@ from itertools import chain -from flash.core.data.utils import download_data - import flash from flash.core.classification import Labels +from flash.core.data.utils import download_data from flash.core.finetuning import FreezeUnfreeze from flash.image import ImageClassificationData, ImageClassifier From c51dd64374b6822ef6243020190cf5d182a7ee09 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Fri, 13 Aug 2021 16:33:09 +0300 Subject: [PATCH 05/53] Moving from dataset to datasource - Move from dataset to datasource - Add text processing example --- flash/core/data/data_module.py | 26 ++-- flash/core/data/data_source.py | 135 +++++++++++++++++- .../labelstudio/image_classification.py | 4 +- .../labelstudio/text_classification.py | 32 +++++ .../labelstudio/video_classification.py | 37 +++++ 5 files changed, 217 insertions(+), 17 deletions(-) create mode 100644 flash_examples/integrations/labelstudio/text_classification.py create mode 100644 flash_examples/integrations/labelstudio/video_classification.py diff --git a/flash/core/data/data_module.py b/flash/core/data/data_module.py index 97a5790d49..7bf4d4d4db 100644 --- a/flash/core/data/data_module.py +++ b/flash/core/data/data_module.py @@ -29,7 +29,7 @@ from flash.core.data.base_viz import BaseVisualization from flash.core.data.callback import BaseDataFetcher from flash.core.data.data_pipeline import DataPipeline, DefaultPreprocess, Postprocess, Preprocess -from flash.core.data.data_source import DataSource, DefaultDataSources, LabelStudioDataset +from flash.core.data.data_source import DataSource, DefaultDataSources, LabelStudioDataset, LabelStudioDataSource from flash.core.data.splits import SplitDataset from flash.core.data.utils import _STAGES_PREFIX from flash.core.utilities.imports import _FIFTYONE_AVAILABLE @@ -1158,7 +1158,7 @@ def from_fiftyone( def from_labelstudio( cls, export_json: str = None, - img_folder: str = None, + data_folder: str = None, train_transform: Optional[Dict[str, Callable]] = None, val_transform: Optional[Dict[str, Callable]] = None, test_transform: Optional[Dict[str, Callable]] = None, @@ -1179,7 +1179,7 @@ def from_labelstudio( Args: export_json: path to label studio export file - img_folder: path to label studio data folder + data_folder: path to label studio data folder train_transform: The dictionary of transforms to use during training which maps :class:`~flash.core.data.process.Preprocess` hook names to callable transforms. val_transform: The dictionary of transforms to use during validation which maps @@ -1207,21 +1207,23 @@ def from_labelstudio( data_module = DataModule.from_labelstudio( export_json='project.json', - img_folder='label-studio/media/upload', + data_folder='label-studio/media/upload', val_split=0.8, ) """ # loading export data - with open(export_json) as f: - js = json.load(f) + data_source = LabelStudioDataSource(data_folder=data_folder, + export_json=export_json, + backbone=preprocess_kwargs.get('backbone'), + max_length=preprocess_kwargs.get('max_length', 128)) + data_source.load_data() # loading data sets - full_dataset = LabelStudioDataset(js, img_folder) - val_dataset = LabelStudioDataset(js, img_folder, val=True) + train_dataset, val_dataset, test_dataset, predict_dataset = data_source.to_datasets() # creating splitting params - l = len(full_dataset) + l = len(train_dataset) prop = int(l * val_split) # splitting full data set - train_dataset, test_dataset = random_split(full_dataset, [prop, l - prop]) + train_dataset, val_dataset = random_split(train_dataset, [prop, l - prop]) preprocess = preprocess or cls.preprocess_cls( train_transform, @@ -1230,12 +1232,12 @@ def from_labelstudio( predict_transform, **preprocess_kwargs, ) - data_source = preprocess.data_source_of_name(DefaultDataSources.FOLDERS) + data = cls( train_dataset, val_dataset, test_dataset, - None, + predict_dataset, data_source=data_source, preprocess=preprocess, data_fetcher=data_fetcher, diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index 4d2aff8110..f5fae633c1 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -11,6 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import json import os import typing from dataclasses import dataclass @@ -43,7 +44,7 @@ from flash.core.data.auto_dataset import AutoDataset, BaseAutoDataset, IterableAutoDataset from flash.core.data.properties import ProcessState, Properties from flash.core.data.utils import CurrentRunningStageFuncContext -from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, lazy_import +from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, lazy_import, _TEXT_AVAILABLE SampleCollection = None if _FIFTYONE_AVAILABLE: @@ -548,7 +549,7 @@ def _get_classes(self, data): class LabelStudioDataset(Dataset): - r"""Dataset wrapping label studio annotations. + """Dataset wrapping label studio annotations. Each sample will be retrieved by checking result field of the annotation. @@ -607,3 +608,133 @@ def __getitem__(self, idx): def __len__(self): return len(self.results) + + +class LabelStudioDataSource(DataSource): + """The ``LabelStudioDatasource`` expects the input to + :meth:`~flash.core.data.data_source.DataSource.load_data` to be a ``fiftyone.core.collections.SampleCollection``.""" + + def __init__(self, data_folder: str, export_json: str, multi_label=False, backbone=None, max_length=128): + + super().__init__() + self._data_folder = data_folder + with open(export_json) as f: + self._raw_data = json.load(f) + self.results = list() + self.test_results = list() + self.classes = set() + self.num_classes = 0 + self.multi_label = multi_label + if backbone: + if _TEXT_AVAILABLE: + from transformers import AutoTokenizer + self.backbone = backbone + self.tokenizer = AutoTokenizer.from_pretrained(backbone, use_fast=True) + self.max_length = max_length + + def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: + # iterate through all tasks in exported data + if data: + self._raw_data = data + for task in self._raw_data: + for annotation in task['annotations']: + # Adding ground_truth annotation to separate dataset + result = annotation['result'] + for res in result: + t = res['type'] + for label in res['value'][t]: + # check if labeling result is a list of labels + if isinstance(label, list): + for sublabel in label: + self.classes.add(sublabel) + temp = dict() + temp['file_upload'] = task.get('file_upload') + temp['data'] = task.get('data') + temp['label'] = sublabel + temp['result'] = res.get('value') + if annotation['ground_truth']: + self.test_results.append(temp) + elif not annotation['ground_truth']: + self.results.append(temp) + else: + self.classes.add(label) + temp = dict() + temp['file_upload'] = task.get('file_upload') + temp['data'] = task.get('data') + temp['label'] = label + temp['result'] = res.get('value') + if annotation['ground_truth']: + self.test_results.append(temp) + elif not annotation['ground_truth']: + self.results.append(temp) + self.num_classes = len(self.classes) + + def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: + data_types = sample.get('data') + data_type = None + # casting to list and sorting classes + sorted_labels = sorted(list(self.classes)) + # checking index of class + label = sorted_labels.index(sample['label']) + + if isinstance(data_types, dict): + # extracting data types from sample + data_types = list(data_types.keys()) + if len(data_types) == 1: + data_type = data_types[0] + else: + data_type = None + if data_type == 'image': + # extracting path to file + if sample['file_upload']: + p = os.path.join(self._data_folder, sample['file_upload']) + else: + p = sample.get('data').get('image') + # loading image + image = default_loader(p) + result = {DefaultDataKeys.INPUT: image, + DefaultDataKeys.TARGET: label} + elif data_type == 'text' and self.backbone: + tokenized_data = self.tokenizer(sample.get('data').get(data_type), + max_length=self.max_length, + truncation=True, + padding="max_length") + for key in tokenized_data: + tokenized_data[key] = torch.tensor(tokenized_data[key]) + tokenized_data['labels'] = label + # separate text data type block + result = tokenized_data + elif data_type == 'video': + # extract path to file + if sample['file_upload']: + p = os.path.join(self._data_folder, sample['file_upload']) + else: + p = sample.get('data').get('image') + result = {DefaultDataKeys.INPUT: p, + DefaultDataKeys.TARGET: label} + else: + # all other data types + result = {DefaultDataKeys.INPUT: sample.get('data').get(data_type), + DefaultDataKeys.TARGET: label} + return result + + def generate_dataset( + self, + data: Optional[DATA_TYPE], + running_stage: RunningStage, + ) -> Optional[Union[AutoDataset, IterableAutoDataset]]: + if running_stage in (RunningStage.TRAINING, RunningStage.TUNING): + data = self.results + elif running_stage == RunningStage.VALIDATING: + data = [] + elif running_stage == RunningStage.TESTING: + data = self.test_results + elif running_stage == RunningStage.PREDICTING: + data = [] + + if has_len(data): + dataset = AutoDataset(data, self, running_stage) + else: + dataset = IterableAutoDataset(data, self, running_stage) + dataset.num_classes = self.num_classes + return dataset diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py index 149dbc5ebc..9f05a4c978 100644 --- a/flash_examples/integrations/labelstudio/image_classification.py +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -1,5 +1,3 @@ -from itertools import chain - from flash.core.data.utils import download_data import flash @@ -13,7 +11,7 @@ # 1. Load export data datamodule = ImageClassificationData.from_labelstudio( export_json='data/project.json', - img_folder='data/upload/', + data_folder='data/upload/', val_split=0.8, ) diff --git a/flash_examples/integrations/labelstudio/text_classification.py b/flash_examples/integrations/labelstudio/text_classification.py new file mode 100644 index 0000000000..d7077e0922 --- /dev/null +++ b/flash_examples/integrations/labelstudio/text_classification.py @@ -0,0 +1,32 @@ +import flash +from flash.core.data.utils import download_data +from flash.text import TextClassificationData, TextClassifier + +# 1. Create the DataModule +download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/text_data.zip", "./data/") + +backbone = "prajjwal1/bert-medium" + +datamodule = TextClassificationData.from_labelstudio( + export_json='data/project.json', + val_split=0.8, + backbone=backbone, +) + +# 2. Build the task +model = TextClassifier(backbone=backbone, num_classes=datamodule.num_classes) + +# 3. Create the trainer and finetune the model +trainer = flash.Trainer(max_epochs=3) +trainer.finetune(model, datamodule=datamodule, strategy="freeze") + +# 4. Classify a few sentences! How was the movie? +predictions = model.predict([ + "Turgid dialogue, feeble characterization - Harvey Keitel a judge?.", + "The worst movie in the history of cinema.", + "I come from Bulgaria where it 's almost impossible to have a tornado.", +]) +print(predictions) + +# 5. Save the model! +trainer.save_checkpoint("text_classification_model.pt") \ No newline at end of file diff --git a/flash_examples/integrations/labelstudio/video_classification.py b/flash_examples/integrations/labelstudio/video_classification.py new file mode 100644 index 0000000000..472127e8e2 --- /dev/null +++ b/flash_examples/integrations/labelstudio/video_classification.py @@ -0,0 +1,37 @@ +import os + +from flash.core.data.utils import download_data + +import flash +from flash.video import VideoClassificationData, VideoClassifier +from flash.core.finetuning import FreezeUnfreeze + +# 1 Download data +download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/video_data.zip") + +# 1. Load export data +datamodule = VideoClassificationData.from_labelstudio( + export_json='data/project.json', + data_folder='data/upload/', + val_split=0.8, + clip_sampler="uniform", + clip_duration=1, + decode_audio=False, +) + +# 2. Build the task +model = VideoClassifier( + backbone="x3d_xs", + num_classes=datamodule.num_classes, +) + +# 3. Create the trainer and finetune the model +trainer = flash.Trainer(max_epochs=3) +trainer.finetune(model, datamodule=datamodule, strategy="freeze") + +# 4. Make a prediction +predictions = model.predict(os.path.join(os.getcwd(), "data/test")) +print(predictions) + +# 5. Save the model! +trainer.save_checkpoint("video_classification.pt") From 718b1524f194c6314f455e26292cf634522fa0fb Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Tue, 17 Aug 2021 15:44:44 +0300 Subject: [PATCH 06/53] Add video example - Add video example - Add data type for DataSource - Move split to load_data --- flash/core/data/data_module.py | 30 ++-- flash/core/data/data_source.py | 138 ++++++++++++------ .../labelstudio/image_classification.py | 1 + .../labelstudio/text_classification.py | 3 +- .../labelstudio/video_classification.py | 4 +- 5 files changed, 114 insertions(+), 62 deletions(-) diff --git a/flash/core/data/data_module.py b/flash/core/data/data_module.py index b58dc6a533..9e9484a7c3 100644 --- a/flash/core/data/data_module.py +++ b/flash/core/data/data_module.py @@ -1169,6 +1169,7 @@ def from_labelstudio( batch_size: int = 4, num_workers: Optional[int] = None, sampler: Optional[Sampler] = None, + data_type: str = 'other', **preprocess_kwargs: Any, ) -> 'DataModule': """Creates a :class:`~flash.core.data.data_module.DataModule` object @@ -1211,20 +1212,7 @@ def from_labelstudio( val_split=0.8, ) """ - # loading export data - data_source = LabelStudioDataSource(data_folder=data_folder, - export_json=export_json, - backbone=preprocess_kwargs.get('backbone'), - max_length=preprocess_kwargs.get('max_length', 128)) - data_source.load_data() - # loading data sets - train_dataset, val_dataset, test_dataset, predict_dataset = data_source.to_datasets() - # creating splitting params - l = len(train_dataset) - prop = int(l * val_split) - # splitting full data set - train_dataset, val_dataset = random_split(train_dataset, [prop, l - prop]) - + # create preprocess preprocess = preprocess or cls.preprocess_cls( train_transform, val_transform, @@ -1232,6 +1220,20 @@ def from_labelstudio( predict_transform, **preprocess_kwargs, ) + # loading export data + data_source = LabelStudioDataSource(data_folder=data_folder, + export_json=export_json, + data_type=data_type, + backbone=preprocess_kwargs.get('backbone'), + max_length=preprocess_kwargs.get('max_length', 128), + clip_sampler=preprocess_kwargs.get('clip_sampler'), + clip_duration=preprocess_kwargs.get('clip_duration', 1), + decode_audio=preprocess_kwargs.get('decode_audio', False), + decoder=preprocess_kwargs.get('decoder', 'pyav'), + multi_label=preprocess_kwargs.get('multi_label', False),) + data_source.load_data() + # loading data sets + train_dataset, val_dataset, test_dataset, predict_dataset = data_source.to_datasets() data = cls( train_dataset, diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index 02232de191..f3d1431508 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -14,6 +14,7 @@ import json import os import typing +from copy import deepcopy from dataclasses import dataclass from inspect import signature from typing import ( @@ -44,7 +45,7 @@ from flash.core.data.auto_dataset import AutoDataset, BaseAutoDataset, IterableAutoDataset from flash.core.data.properties import ProcessState, Properties from flash.core.data.utils import CurrentRunningStageFuncContext -from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, lazy_import, _TEXT_AVAILABLE +from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, lazy_import, _TEXT_AVAILABLE, _PYTORCHVIDEO_AVAILABLE SampleCollection = None if _FIFTYONE_AVAILABLE: @@ -612,16 +613,29 @@ def __len__(self): class LabelStudioDataSource(DataSource): """The ``LabelStudioDatasource`` expects the input to - :meth:`~flash.core.data.data_source.DataSource.load_data` to be a ``fiftyone.core.collections.SampleCollection``.""" - - def __init__(self, data_folder: str, export_json: str, multi_label=False, backbone=None, max_length=128): - + :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio.""" + + def __init__(self, + data_folder: str, + export_json: str, + data_type: str = 'other', + multi_label=False, + backbone=None, + max_length=128, + video_sampler=None, + clip_sampler=None, + clip_duration=1, + decode_audio=False, + decoder: str = "pyav", + split: float = 0.8): super().__init__() self._data_folder = data_folder + self._data_type = data_type with open(export_json) as f: self._raw_data = json.load(f) self.results = list() self.test_results = list() + self.val_results = list() self.classes = set() self.num_classes = 0 self.multi_label = multi_label @@ -631,6 +645,15 @@ def __init__(self, data_folder: str, export_json: str, multi_label=False, backbo self.backbone = backbone self.tokenizer = AutoTokenizer.from_pretrained(backbone, use_fast=True) self.max_length = max_length + self.video_sampler = video_sampler or torch.utils.data.RandomSampler + if clip_sampler: + if _PYTORCHVIDEO_AVAILABLE: + from pytorchvideo.data.clip_sampling import make_clip_sampler + self.clip_sampler = make_clip_sampler(clip_sampler, clip_duration) + self.decode_audio = decode_audio + self.decoder = decoder + self.data_types = set() + self.split = split def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: # iterate through all tasks in exported data @@ -638,13 +661,15 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - self._raw_data = data for task in self._raw_data: for annotation in task['annotations']: + # extracting data types from tasks + [self.data_types.add(key) for key in task.get('data')] # Adding ground_truth annotation to separate dataset result = annotation['result'] for res in result: t = res['type'] for label in res['value'][t]: # check if labeling result is a list of labels - if isinstance(label, list): + if isinstance(label, list) and not self.multi_label: for sublabel in label: self.classes.add(sublabel) temp = dict() @@ -657,7 +682,11 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - elif not annotation['ground_truth']: self.results.append(temp) else: - self.classes.add(label) + if isinstance(label, list): + for item in label: + self.classes.add(item) + else: + self.classes.add(label) temp = dict() temp['file_upload'] = task.get('file_upload') temp['data'] = task.get('data') @@ -668,54 +697,51 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - elif not annotation['ground_truth']: self.results.append(temp) self.num_classes = len(self.classes) + # splitting result to train and val sets + import random + random.shuffle(self.results) + l = len(self.results) + prop = l - int(l * self.split) + self.val_results = self.results[:prop] + self.results = self.results[prop:] def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: - data_types = sample.get('data') - data_type = None - # casting to list and sorting classes - sorted_labels = sorted(list(self.classes)) - # checking index of class - label = sorted_labels.index(sample['label']) - - if isinstance(data_types, dict): - # extracting data types from sample - data_types = list(data_types.keys()) - if len(data_types) == 1: - data_type = data_types[0] - else: - data_type = None - if data_type == 'image': + if self._check_data_type('image'): # extracting path to file if sample['file_upload']: p = os.path.join(self._data_folder, sample['file_upload']) else: - p = sample.get('data').get('image') + for key in sample.get('data'): + p = sample.get('data').get(key) # loading image image = default_loader(p) result = {DefaultDataKeys.INPUT: image, - DefaultDataKeys.TARGET: label} - elif data_type == 'text' and self.backbone: - tokenized_data = self.tokenizer(sample.get('data').get(data_type), + DefaultDataKeys.TARGET: self._get_labels_from_sample(sample['label'])} + elif self._check_data_type('text') and self.backbone: + data = "" + for key in sample.get('data'): + data += sample.get('data').get(key) + tokenized_data = self.tokenizer(data, max_length=self.max_length, truncation=True, padding="max_length") for key in tokenized_data: tokenized_data[key] = torch.tensor(tokenized_data[key]) - tokenized_data['labels'] = label + tokenized_data['labels'] = self._get_labels_from_sample(sample['label']) # separate text data type block result = tokenized_data - elif data_type == 'video': - # extract path to file - if sample['file_upload']: - p = os.path.join(self._data_folder, sample['file_upload']) - else: - p = sample.get('data').get('image') - result = {DefaultDataKeys.INPUT: p, - DefaultDataKeys.TARGET: label} + elif self._check_data_type('video'): + result = sample else: # all other data types - result = {DefaultDataKeys.INPUT: sample.get('data').get(data_type), - DefaultDataKeys.TARGET: label} + input_data = deepcopy(sample) + try: + del input_data['label'] + except: + # no label in input data + pass + result = {DefaultDataKeys.INPUT: input_data, + DefaultDataKeys.TARGET: self._get_labels_from_sample(sample['label'])} return result def generate_dataset( @@ -724,17 +750,39 @@ def generate_dataset( running_stage: RunningStage, ) -> Optional[Union[AutoDataset, IterableAutoDataset]]: if running_stage in (RunningStage.TRAINING, RunningStage.TUNING): - data = self.results - elif running_stage == RunningStage.VALIDATING: - data = [] + dataset = self.results elif running_stage == RunningStage.TESTING: - data = self.test_results + dataset = self.test_results elif running_stage == RunningStage.PREDICTING: - data = [] - + dataset = data or [] + elif running_stage == RunningStage.VALIDATING: + dataset = self.val_results + + if self._check_data_type('video') and len(dataset) > 0: + from pytorchvideo.data import EncodedVideoDataset + dataset = EncodedVideoDataset( + [(os.path.join(self._data_folder, sample['file_upload']), + {"label": self._get_labels_from_sample(sample['label'])}) for sample in dataset], + self.clip_sampler, + decode_audio=self.decode_audio, + decoder=self.decoder, + ) if has_len(data): - dataset = AutoDataset(data, self, running_stage) + dataset = AutoDataset(dataset, self, running_stage) else: - dataset = IterableAutoDataset(data, self, running_stage) + dataset = IterableAutoDataset(dataset, self, running_stage) dataset.num_classes = self.num_classes return dataset + + def _get_labels_from_sample(self, labels): + sorted_labels = sorted(list(self.classes)) + if isinstance(labels, list): + label = [] + for item in labels: + label.append(sorted_labels.index(item)) + else: + label = sorted_labels.index(labels) + return label + + def _check_data_type(self, data_type): + return data_type == self._data_type diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py index 9f05a4c978..18c275890d 100644 --- a/flash_examples/integrations/labelstudio/image_classification.py +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -13,6 +13,7 @@ export_json='data/project.json', data_folder='data/upload/', val_split=0.8, + data_type='image' ) # 2. Fine tune a model diff --git a/flash_examples/integrations/labelstudio/text_classification.py b/flash_examples/integrations/labelstudio/text_classification.py index d7077e0922..02fdda48cd 100644 --- a/flash_examples/integrations/labelstudio/text_classification.py +++ b/flash_examples/integrations/labelstudio/text_classification.py @@ -9,6 +9,7 @@ datamodule = TextClassificationData.from_labelstudio( export_json='data/project.json', + data_type='text', val_split=0.8, backbone=backbone, ) @@ -29,4 +30,4 @@ print(predictions) # 5. Save the model! -trainer.save_checkpoint("text_classification_model.pt") \ No newline at end of file +trainer.save_checkpoint("text_classification_model.pt") diff --git a/flash_examples/integrations/labelstudio/video_classification.py b/flash_examples/integrations/labelstudio/video_classification.py index 472127e8e2..ac56b41e1d 100644 --- a/flash_examples/integrations/labelstudio/video_classification.py +++ b/flash_examples/integrations/labelstudio/video_classification.py @@ -4,7 +4,6 @@ import flash from flash.video import VideoClassificationData, VideoClassifier -from flash.core.finetuning import FreezeUnfreeze # 1 Download data download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/video_data.zip") @@ -13,6 +12,7 @@ datamodule = VideoClassificationData.from_labelstudio( export_json='data/project.json', data_folder='data/upload/', + data_type='video', val_split=0.8, clip_sampler="uniform", clip_duration=1, @@ -21,7 +21,7 @@ # 2. Build the task model = VideoClassifier( - backbone="x3d_xs", + backbone="slow_r50", num_classes=datamodule.num_classes, ) From 02c4cea7fee728beb3197c9b6c247cbcb8131a90 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Wed, 18 Aug 2021 14:24:31 +0300 Subject: [PATCH 07/53] Fix merge conflict and Analysis checks --- flash/core/data/data_source.py | 46 +++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index f3d1431508..e6557b344b 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -14,9 +14,9 @@ import json import os import typing -from copy import deepcopy from dataclasses import dataclass from inspect import signature +from pathlib import Path from typing import ( Any, Callable, @@ -24,6 +24,7 @@ Dict, Generic, Iterable, + Iterator, List, Mapping, Optional, @@ -35,17 +36,19 @@ ) import numpy as np +import pandas as pd import torch from pytorch_lightning.trainer.states import RunningStage from pytorch_lightning.utilities.enums import LightningEnum from torch.nn import Module from torch.utils.data.dataset import Dataset +from tqdm import tqdm from torchvision.datasets.folder import default_loader from flash.core.data.auto_dataset import AutoDataset, BaseAutoDataset, IterableAutoDataset from flash.core.data.properties import ProcessState, Properties from flash.core.data.utils import CurrentRunningStageFuncContext -from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, lazy_import, _TEXT_AVAILABLE, _PYTORCHVIDEO_AVAILABLE +from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, lazy_import, requires, _TEXT_AVAILABLE, _PYTORCHVIDEO_AVAILABLE SampleCollection = None if _FIFTYONE_AVAILABLE: @@ -54,6 +57,7 @@ from fiftyone.core.collections import SampleCollection else: fol = None +from copy import deepcopy # Credit to the PyTorchVision Team: @@ -562,7 +566,7 @@ class LabelStudioDataset(Dataset): def __init__(self, js, img_folder, val=False): self._raw_data = js self._img_folder = img_folder - self.results = list() + self.results = [] self.classes = set() # iterate through all tasks in exported data for task in self._raw_data: @@ -576,7 +580,7 @@ def __init__(self, js, img_folder, val=False): if isinstance(label, list): for sublabel in label: self.classes.add(sublabel) - temp = dict() + temp = {} temp['file_upload'] = task['file_upload'] temp['label'] = sublabel if annotation['ground_truth'] & val: @@ -585,7 +589,7 @@ def __init__(self, js, img_folder, val=False): self.results.append(temp) else: self.classes.add(label) - temp = dict() + temp = {} temp['file_upload'] = task['file_upload'] temp['label'] = label if annotation['ground_truth'] & val: @@ -633,9 +637,9 @@ def __init__(self, self._data_type = data_type with open(export_json) as f: self._raw_data = json.load(f) - self.results = list() - self.test_results = list() - self.val_results = list() + self.results = [] + self.test_results = [] + self.val_results = [] self.classes = set() self.num_classes = 0 self.multi_label = multi_label @@ -656,7 +660,9 @@ def __init__(self, self.split = split def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: - # iterate through all tasks in exported data + """ + Iterate through all tasks in exported data and construct train\test\val results + """ if data: self._raw_data = data for task in self._raw_data: @@ -672,7 +678,7 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - if isinstance(label, list) and not self.multi_label: for sublabel in label: self.classes.add(sublabel) - temp = dict() + temp = {} temp['file_upload'] = task.get('file_upload') temp['data'] = task.get('data') temp['label'] = sublabel @@ -687,7 +693,7 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - self.classes.add(item) else: self.classes.add(label) - temp = dict() + temp = {} temp['file_upload'] = task.get('file_upload') temp['data'] = task.get('data') temp['label'] = label @@ -700,12 +706,15 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - # splitting result to train and val sets import random random.shuffle(self.results) - l = len(self.results) - prop = l - int(l * self.split) + data_length = len(self.results) + prop = data_length - int(data_length * self.split) self.val_results = self.results[:prop] self.results = self.results[prop:] def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: + """ + Load 1 sample from dataset + """ if self._check_data_type('image'): # extracting path to file if sample['file_upload']: @@ -737,7 +746,7 @@ def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = input_data = deepcopy(sample) try: del input_data['label'] - except: + except KeyError: # no label in input data pass result = {DefaultDataKeys.INPUT: input_data, @@ -749,6 +758,9 @@ def generate_dataset( data: Optional[DATA_TYPE], running_stage: RunningStage, ) -> Optional[Union[AutoDataset, IterableAutoDataset]]: + """ + Generate dataset from loaded data + """ if running_stage in (RunningStage.TRAINING, RunningStage.TUNING): dataset = self.results elif running_stage == RunningStage.TESTING: @@ -775,6 +787,9 @@ def generate_dataset( return dataset def _get_labels_from_sample(self, labels): + """ + Translate string labels to int + """ sorted_labels = sorted(list(self.classes)) if isinstance(labels, list): label = [] @@ -785,4 +800,7 @@ def _get_labels_from_sample(self, labels): return label def _check_data_type(self, data_type): + """ + Check if data type exist in datasource + """ return data_type == self._data_type From 0c3f2fbedb9deb3e08744f6791aaff43d59b2103 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Wed, 18 Aug 2021 14:38:27 +0300 Subject: [PATCH 08/53] Updating imports to solve conflict --- flash/core/data/data_source.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index e6557b344b..50a674c6a9 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -43,12 +43,11 @@ from torch.nn import Module from torch.utils.data.dataset import Dataset from tqdm import tqdm -from torchvision.datasets.folder import default_loader from flash.core.data.auto_dataset import AutoDataset, BaseAutoDataset, IterableAutoDataset from flash.core.data.properties import ProcessState, Properties from flash.core.data.utils import CurrentRunningStageFuncContext -from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, lazy_import, requires, _TEXT_AVAILABLE, _PYTORCHVIDEO_AVAILABLE +from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, lazy_import, requires SampleCollection = None if _FIFTYONE_AVAILABLE: @@ -58,7 +57,8 @@ else: fol = None from copy import deepcopy - +from torchvision.datasets.folder import default_loader +from flash.core.utilities.imports import _TEXT_AVAILABLE, _PYTORCHVIDEO_AVAILABLE # Credit to the PyTorchVision Team: # https://github.com/pytorch/vision/blob/master/torchvision/datasets/folder.py#L10 From 92672efb340db84d6488388cf1f17821eb55322c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 18 Aug 2021 11:36:21 +0000 Subject: [PATCH 09/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- flash/core/data/data_module.py | 26 +-- flash/core/data/data_source.py | 173 +++++++++--------- .../labelstudio/image_classification.py | 18 +- .../labelstudio/text_classification.py | 16 +- .../labelstudio/video_classification.py | 9 +- 5 files changed, 123 insertions(+), 119 deletions(-) diff --git a/flash/core/data/data_module.py b/flash/core/data/data_module.py index 9e9484a7c3..fd594f5edc 100644 --- a/flash/core/data/data_module.py +++ b/flash/core/data/data_module.py @@ -1169,9 +1169,9 @@ def from_labelstudio( batch_size: int = 4, num_workers: Optional[int] = None, sampler: Optional[Sampler] = None, - data_type: str = 'other', + data_type: str = "other", **preprocess_kwargs: Any, - ) -> 'DataModule': + ) -> "DataModule": """Creates a :class:`~flash.core.data.data_module.DataModule` object from the given export file and data directory using the :class:`~flash.core.data.data_source.DataSource` of name @@ -1221,16 +1221,18 @@ def from_labelstudio( **preprocess_kwargs, ) # loading export data - data_source = LabelStudioDataSource(data_folder=data_folder, - export_json=export_json, - data_type=data_type, - backbone=preprocess_kwargs.get('backbone'), - max_length=preprocess_kwargs.get('max_length', 128), - clip_sampler=preprocess_kwargs.get('clip_sampler'), - clip_duration=preprocess_kwargs.get('clip_duration', 1), - decode_audio=preprocess_kwargs.get('decode_audio', False), - decoder=preprocess_kwargs.get('decoder', 'pyav'), - multi_label=preprocess_kwargs.get('multi_label', False),) + data_source = LabelStudioDataSource( + data_folder=data_folder, + export_json=export_json, + data_type=data_type, + backbone=preprocess_kwargs.get("backbone"), + max_length=preprocess_kwargs.get("max_length", 128), + clip_sampler=preprocess_kwargs.get("clip_sampler"), + clip_duration=preprocess_kwargs.get("clip_duration", 1), + decode_audio=preprocess_kwargs.get("decode_audio", False), + decoder=preprocess_kwargs.get("decoder", "pyav"), + multi_label=preprocess_kwargs.get("multi_label", False), + ) data_source.load_data() # loading data sets train_dataset, val_dataset, test_dataset, predict_dataset = data_source.to_datasets() diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index 50a674c6a9..24aa2c3a7a 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -57,8 +57,11 @@ else: fol = None from copy import deepcopy + from torchvision.datasets.folder import default_loader -from flash.core.utilities.imports import _TEXT_AVAILABLE, _PYTORCHVIDEO_AVAILABLE + +from flash.core.utilities.imports import _PYTORCHVIDEO_AVAILABLE, _TEXT_AVAILABLE + # Credit to the PyTorchVision Team: # https://github.com/pytorch/vision/blob/master/torchvision/datasets/folder.py#L10 @@ -570,44 +573,44 @@ def __init__(self, js, img_folder, val=False): self.classes = set() # iterate through all tasks in exported data for task in self._raw_data: - for annotation in task['annotations']: + for annotation in task["annotations"]: # Adding ground_truth annotation to separate dataset - result = annotation['result'] + result = annotation["result"] for res in result: - t = res['type'] - for label in res['value'][t]: + t = res["type"] + for label in res["value"][t]: # check if labeling result is a list of labels if isinstance(label, list): for sublabel in label: self.classes.add(sublabel) temp = {} - temp['file_upload'] = task['file_upload'] - temp['label'] = sublabel - if annotation['ground_truth'] & val: + temp["file_upload"] = task["file_upload"] + temp["label"] = sublabel + if annotation["ground_truth"] & val: self.results.append(temp) - elif not annotation['ground_truth'] or not val: + elif not annotation["ground_truth"] or not val: self.results.append(temp) else: self.classes.add(label) temp = {} - temp['file_upload'] = task['file_upload'] - temp['label'] = label - if annotation['ground_truth'] & val: + temp["file_upload"] = task["file_upload"] + temp["label"] = label + if annotation["ground_truth"] & val: self.results.append(temp) - elif not annotation['ground_truth'] or not val: + elif not annotation["ground_truth"] or not val: self.results.append(temp) self.num_classes = len(self.classes) def __getitem__(self, idx): r = self.results[idx] # extracting path to file - p = os.path.join(self._img_folder, r['file_upload']) + p = os.path.join(self._img_folder, r["file_upload"]) # loading image sample = default_loader(p) # casting to list and sorting classes sorted_labels = sorted(list(self.classes)) # checking index of class - label = sorted_labels.index(r['label']) + label = sorted_labels.index(r["label"]) result = {DefaultDataKeys.INPUT: sample, DefaultDataKeys.TARGET: label} return result @@ -619,19 +622,21 @@ class LabelStudioDataSource(DataSource): """The ``LabelStudioDatasource`` expects the input to :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio.""" - def __init__(self, - data_folder: str, - export_json: str, - data_type: str = 'other', - multi_label=False, - backbone=None, - max_length=128, - video_sampler=None, - clip_sampler=None, - clip_duration=1, - decode_audio=False, - decoder: str = "pyav", - split: float = 0.8): + def __init__( + self, + data_folder: str, + export_json: str, + data_type: str = "other", + multi_label=False, + backbone=None, + max_length=128, + video_sampler=None, + clip_sampler=None, + clip_duration=1, + decode_audio=False, + decoder: str = "pyav", + split: float = 0.8, + ): super().__init__() self._data_folder = data_folder self._data_type = data_type @@ -660,32 +665,30 @@ def __init__(self, self.split = split def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: - """ - Iterate through all tasks in exported data and construct train\test\val results - """ + """Iterate through all tasks in exported data and construct train\test\val results.""" if data: self._raw_data = data for task in self._raw_data: - for annotation in task['annotations']: + for annotation in task["annotations"]: # extracting data types from tasks - [self.data_types.add(key) for key in task.get('data')] + [self.data_types.add(key) for key in task.get("data")] # Adding ground_truth annotation to separate dataset - result = annotation['result'] + result = annotation["result"] for res in result: - t = res['type'] - for label in res['value'][t]: + t = res["type"] + for label in res["value"][t]: # check if labeling result is a list of labels if isinstance(label, list) and not self.multi_label: for sublabel in label: self.classes.add(sublabel) temp = {} - temp['file_upload'] = task.get('file_upload') - temp['data'] = task.get('data') - temp['label'] = sublabel - temp['result'] = res.get('value') - if annotation['ground_truth']: + temp["file_upload"] = task.get("file_upload") + temp["data"] = task.get("data") + temp["label"] = sublabel + temp["result"] = res.get("value") + if annotation["ground_truth"]: self.test_results.append(temp) - elif not annotation['ground_truth']: + elif not annotation["ground_truth"]: self.results.append(temp) else: if isinstance(label, list): @@ -694,17 +697,18 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - else: self.classes.add(label) temp = {} - temp['file_upload'] = task.get('file_upload') - temp['data'] = task.get('data') - temp['label'] = label - temp['result'] = res.get('value') - if annotation['ground_truth']: + temp["file_upload"] = task.get("file_upload") + temp["data"] = task.get("data") + temp["label"] = label + temp["result"] = res.get("value") + if annotation["ground_truth"]: self.test_results.append(temp) - elif not annotation['ground_truth']: + elif not annotation["ground_truth"]: self.results.append(temp) self.num_classes = len(self.classes) # splitting result to train and val sets import random + random.shuffle(self.results) data_length = len(self.results) prop = data_length - int(data_length * self.split) @@ -712,55 +716,52 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - self.results = self.results[prop:] def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: - """ - Load 1 sample from dataset - """ - if self._check_data_type('image'): + """Load 1 sample from dataset.""" + if self._check_data_type("image"): # extracting path to file - if sample['file_upload']: - p = os.path.join(self._data_folder, sample['file_upload']) + if sample["file_upload"]: + p = os.path.join(self._data_folder, sample["file_upload"]) else: - for key in sample.get('data'): - p = sample.get('data').get(key) + for key in sample.get("data"): + p = sample.get("data").get(key) # loading image image = default_loader(p) - result = {DefaultDataKeys.INPUT: image, - DefaultDataKeys.TARGET: self._get_labels_from_sample(sample['label'])} - elif self._check_data_type('text') and self.backbone: + result = { + DefaultDataKeys.INPUT: image, + DefaultDataKeys.TARGET: self._get_labels_from_sample(sample["label"]), + } + elif self._check_data_type("text") and self.backbone: data = "" - for key in sample.get('data'): - data += sample.get('data').get(key) - tokenized_data = self.tokenizer(data, - max_length=self.max_length, - truncation=True, - padding="max_length") + for key in sample.get("data"): + data += sample.get("data").get(key) + tokenized_data = self.tokenizer(data, max_length=self.max_length, truncation=True, padding="max_length") for key in tokenized_data: tokenized_data[key] = torch.tensor(tokenized_data[key]) - tokenized_data['labels'] = self._get_labels_from_sample(sample['label']) + tokenized_data["labels"] = self._get_labels_from_sample(sample["label"]) # separate text data type block result = tokenized_data - elif self._check_data_type('video'): + elif self._check_data_type("video"): result = sample else: # all other data types input_data = deepcopy(sample) try: - del input_data['label'] + del input_data["label"] except KeyError: # no label in input data pass - result = {DefaultDataKeys.INPUT: input_data, - DefaultDataKeys.TARGET: self._get_labels_from_sample(sample['label'])} + result = { + DefaultDataKeys.INPUT: input_data, + DefaultDataKeys.TARGET: self._get_labels_from_sample(sample["label"]), + } return result def generate_dataset( - self, - data: Optional[DATA_TYPE], - running_stage: RunningStage, + self, + data: Optional[DATA_TYPE], + running_stage: RunningStage, ) -> Optional[Union[AutoDataset, IterableAutoDataset]]: - """ - Generate dataset from loaded data - """ + """Generate dataset from loaded data.""" if running_stage in (RunningStage.TRAINING, RunningStage.TUNING): dataset = self.results elif running_stage == RunningStage.TESTING: @@ -770,11 +771,17 @@ def generate_dataset( elif running_stage == RunningStage.VALIDATING: dataset = self.val_results - if self._check_data_type('video') and len(dataset) > 0: + if self._check_data_type("video") and len(dataset) > 0: from pytorchvideo.data import EncodedVideoDataset + dataset = EncodedVideoDataset( - [(os.path.join(self._data_folder, sample['file_upload']), - {"label": self._get_labels_from_sample(sample['label'])}) for sample in dataset], + [ + ( + os.path.join(self._data_folder, sample["file_upload"]), + {"label": self._get_labels_from_sample(sample["label"])}, + ) + for sample in dataset + ], self.clip_sampler, decode_audio=self.decode_audio, decoder=self.decoder, @@ -787,9 +794,7 @@ def generate_dataset( return dataset def _get_labels_from_sample(self, labels): - """ - Translate string labels to int - """ + """Translate string labels to int.""" sorted_labels = sorted(list(self.classes)) if isinstance(labels, list): label = [] @@ -800,7 +805,5 @@ def _get_labels_from_sample(self, labels): return label def _check_data_type(self, data_type): - """ - Check if data type exist in datasource - """ + """Check if data type exist in datasource.""" return data_type == self._data_type diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py index 18c275890d..15ecdaf90c 100644 --- a/flash_examples/integrations/labelstudio/image_classification.py +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -1,7 +1,6 @@ -from flash.core.data.utils import download_data - import flash from flash.core.classification import Labels +from flash.core.data.utils import download_data from flash.core.finetuning import FreezeUnfreeze from flash.image import ImageClassificationData, ImageClassifier @@ -10,10 +9,7 @@ # 1. Load export data datamodule = ImageClassificationData.from_labelstudio( - export_json='data/project.json', - data_folder='data/upload/', - val_split=0.8, - data_type='image' + export_json="data/project.json", data_folder="data/upload/", val_split=0.8, data_type="image" ) # 2. Fine tune a model @@ -34,7 +30,9 @@ model = ImageClassifier.load_from_checkpoint("image_classification_model.pt") model.serializer = Labels() -predictions = model.predict([ - "data/test/1.jpg", - "data/test/2.jpg", -]) +predictions = model.predict( + [ + "data/test/1.jpg", + "data/test/2.jpg", + ] +) diff --git a/flash_examples/integrations/labelstudio/text_classification.py b/flash_examples/integrations/labelstudio/text_classification.py index 02fdda48cd..95e7ec6ba0 100644 --- a/flash_examples/integrations/labelstudio/text_classification.py +++ b/flash_examples/integrations/labelstudio/text_classification.py @@ -8,8 +8,8 @@ backbone = "prajjwal1/bert-medium" datamodule = TextClassificationData.from_labelstudio( - export_json='data/project.json', - data_type='text', + export_json="data/project.json", + data_type="text", val_split=0.8, backbone=backbone, ) @@ -22,11 +22,13 @@ trainer.finetune(model, datamodule=datamodule, strategy="freeze") # 4. Classify a few sentences! How was the movie? -predictions = model.predict([ - "Turgid dialogue, feeble characterization - Harvey Keitel a judge?.", - "The worst movie in the history of cinema.", - "I come from Bulgaria where it 's almost impossible to have a tornado.", -]) +predictions = model.predict( + [ + "Turgid dialogue, feeble characterization - Harvey Keitel a judge?.", + "The worst movie in the history of cinema.", + "I come from Bulgaria where it 's almost impossible to have a tornado.", + ] +) print(predictions) # 5. Save the model! diff --git a/flash_examples/integrations/labelstudio/video_classification.py b/flash_examples/integrations/labelstudio/video_classification.py index ac56b41e1d..c3cfebc073 100644 --- a/flash_examples/integrations/labelstudio/video_classification.py +++ b/flash_examples/integrations/labelstudio/video_classification.py @@ -1,8 +1,7 @@ import os -from flash.core.data.utils import download_data - import flash +from flash.core.data.utils import download_data from flash.video import VideoClassificationData, VideoClassifier # 1 Download data @@ -10,9 +9,9 @@ # 1. Load export data datamodule = VideoClassificationData.from_labelstudio( - export_json='data/project.json', - data_folder='data/upload/', - data_type='video', + export_json="data/project.json", + data_folder="data/upload/", + data_type="video", val_split=0.8, clip_sampler="uniform", clip_duration=1, From 6049faed0d84e36f5e5b3a66f619ebd37c2e2547 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Mon, 23 Aug 2021 15:52:40 +0300 Subject: [PATCH 10/53] Moving to separate classes for image, video and text --- flash/core/data/data_module.py | 54 +-- flash/core/data/data_source.py | 334 ++++++++---------- flash/image/classification/data.py | 2 + flash/text/classification/data.py | 2 + flash/video/classification/data.py | 8 + .../labelstudio/image_classification.py | 4 +- .../labelstudio/text_classification.py | 3 +- .../labelstudio/video_classification.py | 5 +- 8 files changed, 183 insertions(+), 229 deletions(-) diff --git a/flash/core/data/data_module.py b/flash/core/data/data_module.py index fd594f5edc..5e6d1c8aab 100644 --- a/flash/core/data/data_module.py +++ b/flash/core/data/data_module.py @@ -29,7 +29,7 @@ from flash.core.data.base_viz import BaseVisualization from flash.core.data.callback import BaseDataFetcher from flash.core.data.data_pipeline import DataPipeline, DefaultPreprocess, Postprocess, Preprocess -from flash.core.data.data_source import DataSource, DefaultDataSources, LabelStudioDataset, LabelStudioDataSource +from flash.core.data.data_source import DataSource, DefaultDataSources, LabelStudioDataSource from flash.core.data.splits import SplitDataset from flash.core.data.utils import _STAGES_PREFIX from flash.core.utilities.imports import _FIFTYONE_AVAILABLE @@ -1169,9 +1169,8 @@ def from_labelstudio( batch_size: int = 4, num_workers: Optional[int] = None, sampler: Optional[Sampler] = None, - data_type: str = "other", **preprocess_kwargs: Any, - ) -> "DataModule": + ) -> 'DataModule': """Creates a :class:`~flash.core.data.data_module.DataModule` object from the given export file and data directory using the :class:`~flash.core.data.data_source.DataSource` of name @@ -1212,42 +1211,23 @@ def from_labelstudio( val_split=0.8, ) """ - # create preprocess - preprocess = preprocess or cls.preprocess_cls( - train_transform, - val_transform, - test_transform, - predict_transform, - **preprocess_kwargs, - ) - # loading export data - data_source = LabelStudioDataSource( - data_folder=data_folder, - export_json=export_json, - data_type=data_type, - backbone=preprocess_kwargs.get("backbone"), - max_length=preprocess_kwargs.get("max_length", 128), - clip_sampler=preprocess_kwargs.get("clip_sampler"), - clip_duration=preprocess_kwargs.get("clip_duration", 1), - decode_audio=preprocess_kwargs.get("decode_audio", False), - decoder=preprocess_kwargs.get("decoder", "pyav"), - multi_label=preprocess_kwargs.get("multi_label", False), - ) - data_source.load_data() - # loading data sets - train_dataset, val_dataset, test_dataset, predict_dataset = data_source.to_datasets() - - data = cls( - train_dataset, - val_dataset, - test_dataset, - predict_dataset, - data_source=data_source, - preprocess=preprocess, + data = { + 'data_folder': data_folder, + 'export_json': export_json, + 'split': val_split, + 'multi_label': preprocess_kwargs.get('multi_label', False) + } + return cls.from_data_source( + DefaultDataSources.LABELSTUDIO, + train_data=data, + train_transform=train_transform, + val_transform=val_transform, + test_transform=test_transform, + predict_transform=predict_transform, data_fetcher=data_fetcher, + preprocess=preprocess, val_split=val_split, batch_size=batch_size, num_workers=num_workers, - sampler=sampler, + **preprocess_kwargs, ) - return data diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index 24aa2c3a7a..b43c42766c 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -57,11 +57,9 @@ else: fol = None from copy import deepcopy - -from torchvision.datasets.folder import default_loader - -from flash.core.utilities.imports import _PYTORCHVIDEO_AVAILABLE, _TEXT_AVAILABLE - +from flash.core.utilities.imports import _TEXT_AVAILABLE, _PYTORCHVIDEO_AVAILABLE +if _PYTORCHVIDEO_AVAILABLE: + from torchvision.datasets.folder import default_loader # Credit to the PyTorchVision Team: # https://github.com/pytorch/vision/blob/master/torchvision/datasets/folder.py#L10 @@ -556,139 +554,49 @@ def _get_classes(self, data): return classes -class LabelStudioDataset(Dataset): - """Dataset wrapping label studio annotations. - - Each sample will be retrieved by checking result field of the annotation. - - Args: - *js: json of export file - *img_folder: path to image folder of label studio - """ - - def __init__(self, js, img_folder, val=False): - self._raw_data = js - self._img_folder = img_folder - self.results = [] - self.classes = set() - # iterate through all tasks in exported data - for task in self._raw_data: - for annotation in task["annotations"]: - # Adding ground_truth annotation to separate dataset - result = annotation["result"] - for res in result: - t = res["type"] - for label in res["value"][t]: - # check if labeling result is a list of labels - if isinstance(label, list): - for sublabel in label: - self.classes.add(sublabel) - temp = {} - temp["file_upload"] = task["file_upload"] - temp["label"] = sublabel - if annotation["ground_truth"] & val: - self.results.append(temp) - elif not annotation["ground_truth"] or not val: - self.results.append(temp) - else: - self.classes.add(label) - temp = {} - temp["file_upload"] = task["file_upload"] - temp["label"] = label - if annotation["ground_truth"] & val: - self.results.append(temp) - elif not annotation["ground_truth"] or not val: - self.results.append(temp) - self.num_classes = len(self.classes) - - def __getitem__(self, idx): - r = self.results[idx] - # extracting path to file - p = os.path.join(self._img_folder, r["file_upload"]) - # loading image - sample = default_loader(p) - # casting to list and sorting classes - sorted_labels = sorted(list(self.classes)) - # checking index of class - label = sorted_labels.index(r["label"]) - result = {DefaultDataKeys.INPUT: sample, DefaultDataKeys.TARGET: label} - return result - - def __len__(self): - return len(self.results) - - class LabelStudioDataSource(DataSource): """The ``LabelStudioDatasource`` expects the input to :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio.""" - - def __init__( - self, - data_folder: str, - export_json: str, - data_type: str = "other", - multi_label=False, - backbone=None, - max_length=128, - video_sampler=None, - clip_sampler=None, - clip_duration=1, - decode_audio=False, - decoder: str = "pyav", - split: float = 0.8, - ): + def __init__(self): super().__init__() - self._data_folder = data_folder - self._data_type = data_type - with open(export_json) as f: - self._raw_data = json.load(f) self.results = [] self.test_results = [] self.val_results = [] self.classes = set() - self.num_classes = 0 - self.multi_label = multi_label - if backbone: - if _TEXT_AVAILABLE: - from transformers import AutoTokenizer - self.backbone = backbone - self.tokenizer = AutoTokenizer.from_pretrained(backbone, use_fast=True) - self.max_length = max_length - self.video_sampler = video_sampler or torch.utils.data.RandomSampler - if clip_sampler: - if _PYTORCHVIDEO_AVAILABLE: - from pytorchvideo.data.clip_sampling import make_clip_sampler - self.clip_sampler = make_clip_sampler(clip_sampler, clip_duration) - self.decode_audio = decode_audio - self.decoder = decoder self.data_types = set() - self.split = split + self.num_classes = 0 def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: - """Iterate through all tasks in exported data and construct train\test\val results.""" - if data: - self._raw_data = data + """ + Iterate through all tasks in exported data and construct train\test\val results + """ + if data and isinstance(data, dict): + self._data_folder = data.get('data_folder') + with open(data.get('export_json')) as f: + self._raw_data = json.load(f) + self.multi_label = data.get('multi_label') + self.split = data.get('split') for task in self._raw_data: - for annotation in task["annotations"]: + for annotation in task['annotations']: # extracting data types from tasks - [self.data_types.add(key) for key in task.get("data")] + [self.data_types.add(key) for key in task.get('data')] # Adding ground_truth annotation to separate dataset - result = annotation["result"] + result = annotation['result'] for res in result: - t = res["type"] - for label in res["value"][t]: + t = res['type'] + for label in res['value'][t]: # check if labeling result is a list of labels if isinstance(label, list) and not self.multi_label: for sublabel in label: self.classes.add(sublabel) temp = {} - temp["file_upload"] = task.get("file_upload") - temp["data"] = task.get("data") - temp["label"] = sublabel - temp["result"] = res.get("value") - if annotation["ground_truth"]: + temp['file_upload'] = task.get('file_upload') + temp['data'] = task.get('data') + temp['label'] = sublabel + temp['result'] = res.get('value') + if annotation['ground_truth']: self.test_results.append(temp) - elif not annotation["ground_truth"]: + elif not annotation['ground_truth']: self.results.append(temp) else: if isinstance(label, list): @@ -697,18 +605,17 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - else: self.classes.add(label) temp = {} - temp["file_upload"] = task.get("file_upload") - temp["data"] = task.get("data") - temp["label"] = label - temp["result"] = res.get("value") - if annotation["ground_truth"]: + temp['file_upload'] = task.get('file_upload') + temp['data'] = task.get('data') + temp['label'] = label + temp['result'] = res.get('value') + if annotation['ground_truth']: self.test_results.append(temp) - elif not annotation["ground_truth"]: + elif not annotation['ground_truth']: self.results.append(temp) self.num_classes = len(self.classes) # splitting result to train and val sets import random - random.shuffle(self.results) data_length = len(self.results) prop = data_length - int(data_length * self.split) @@ -716,53 +623,30 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - self.results = self.results[prop:] def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: - """Load 1 sample from dataset.""" - if self._check_data_type("image"): - # extracting path to file - if sample["file_upload"]: - p = os.path.join(self._data_folder, sample["file_upload"]) - else: - for key in sample.get("data"): - p = sample.get("data").get(key) - # loading image - image = default_loader(p) - result = { - DefaultDataKeys.INPUT: image, - DefaultDataKeys.TARGET: self._get_labels_from_sample(sample["label"]), - } - elif self._check_data_type("text") and self.backbone: - data = "" - for key in sample.get("data"): - data += sample.get("data").get(key) - tokenized_data = self.tokenizer(data, max_length=self.max_length, truncation=True, padding="max_length") - for key in tokenized_data: - tokenized_data[key] = torch.tensor(tokenized_data[key]) - tokenized_data["labels"] = self._get_labels_from_sample(sample["label"]) - # separate text data type block - result = tokenized_data - elif self._check_data_type("video"): - result = sample - else: - # all other data types - input_data = deepcopy(sample) - try: - del input_data["label"] - except KeyError: - # no label in input data - pass - result = { - DefaultDataKeys.INPUT: input_data, - DefaultDataKeys.TARGET: self._get_labels_from_sample(sample["label"]), - } + """ + Load 1 sample from dataset + """ + # all other data types + input_data = deepcopy(sample) + try: + del input_data['label'] + except KeyError: + # no label in input data + pass + result = {DefaultDataKeys.INPUT: input_data, + DefaultDataKeys.TARGET: self._get_labels_from_sample(sample['label'])} return result def generate_dataset( - self, - data: Optional[DATA_TYPE], - running_stage: RunningStage, + self, + data: Optional[DATA_TYPE], + running_stage: RunningStage, ) -> Optional[Union[AutoDataset, IterableAutoDataset]]: - """Generate dataset from loaded data.""" + """ + Generate dataset from loaded data + """ if running_stage in (RunningStage.TRAINING, RunningStage.TUNING): + self.load_data(data) dataset = self.results elif running_stage == RunningStage.TESTING: dataset = self.test_results @@ -771,22 +655,7 @@ def generate_dataset( elif running_stage == RunningStage.VALIDATING: dataset = self.val_results - if self._check_data_type("video") and len(dataset) > 0: - from pytorchvideo.data import EncodedVideoDataset - - dataset = EncodedVideoDataset( - [ - ( - os.path.join(self._data_folder, sample["file_upload"]), - {"label": self._get_labels_from_sample(sample["label"])}, - ) - for sample in dataset - ], - self.clip_sampler, - decode_audio=self.decode_audio, - decoder=self.decoder, - ) - if has_len(data): + if has_len(dataset): dataset = AutoDataset(dataset, self, running_stage) else: dataset = IterableAutoDataset(dataset, self, running_stage) @@ -794,7 +663,9 @@ def generate_dataset( return dataset def _get_labels_from_sample(self, labels): - """Translate string labels to int.""" + """ + Translate string labels to int + """ sorted_labels = sorted(list(self.classes)) if isinstance(labels, list): label = [] @@ -804,6 +675,97 @@ def _get_labels_from_sample(self, labels): label = sorted_labels.index(labels) return label - def _check_data_type(self, data_type): - """Check if data type exist in datasource.""" - return data_type == self._data_type + +class LabelStudioImageDataSource(LabelStudioDataSource): + def __init__(self): + super().__init__() + pass + + def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: + """ + Load 1 sample from dataset + """ + if sample['file_upload']: + p = os.path.join(self._data_folder, sample['file_upload']) + else: + for key in sample.get('data'): + p = sample.get('data').get(key) + # loading image + image = default_loader(p) + result = {DefaultDataKeys.INPUT: image, + DefaultDataKeys.TARGET: self._get_labels_from_sample(sample['label'])} + return result + + +class LabelStudioTextDataSource(LabelStudioDataSource): + def __init__(self, + backbone=None, + max_length=128 + ): + super().__init__() + if backbone: + if _TEXT_AVAILABLE: + from transformers import AutoTokenizer + self.backbone = backbone + self.tokenizer = AutoTokenizer.from_pretrained(backbone, use_fast=True) + self.max_length = max_length + + def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: + """ + Load 1 sample from dataset + """ + if self.backbone: + data = "" + for key in sample.get('data'): + data += sample.get('data').get(key) + tokenized_data = self.tokenizer(data, + max_length=self.max_length, + truncation=True, + padding="max_length") + for key in tokenized_data: + tokenized_data[key] = torch.tensor(tokenized_data[key]) + tokenized_data['labels'] = self._get_labels_from_sample(sample['label']) + # separate text data type block + result = tokenized_data + return result + + +class LabelStudioVideoDataSource(LabelStudioDataSource): + def __init__(self, + video_sampler=None, + clip_sampler=None, + clip_duration=1, + decode_audio=False, + decoder: str = "pyav" + ): + super().__init__() + self.video_sampler = video_sampler or torch.utils.data.RandomSampler + self.clip_sampler = clip_sampler + self.decode_audio = decode_audio + self.decoder = decoder + + def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: + """ + Load 1 sample from dataset + """ + return sample + + def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: + super().load_data(data, dataset) + self.results = self.convert_to_encodedvideo(self.results) + self.test_results = self.convert_to_encodedvideo(self.test_results) + self.val_results = self.convert_to_encodedvideo(self.val_results) + + def convert_to_encodedvideo(self, dataset): + if len(dataset) > 0: + from pytorchvideo.data import EncodedVideoDataset + dataset = EncodedVideoDataset( + [(os.path.join(self._data_folder, sample['file_upload']), + {"label": self._get_labels_from_sample(sample['label'])}) for sample in dataset], + self.clip_sampler, + decode_audio=self.decode_audio, + decoder=self.decoder, + ) + return dataset + else: + return [] \ No newline at end of file diff --git a/flash/image/classification/data.py b/flash/image/classification/data.py index deb84f82a4..fa4010800c 100644 --- a/flash/image/classification/data.py +++ b/flash/image/classification/data.py @@ -31,6 +31,7 @@ ImagePathsDataSource, ImageTensorDataSource, ) +from flash.core.data.data_source import LabelStudioImageDataSource if _MATPLOTLIB_AVAILABLE: import matplotlib.pyplot as plt @@ -70,6 +71,7 @@ def __init__( DefaultDataSources.FOLDERS: ImagePathsDataSource(), DefaultDataSources.NUMPY: ImageNumpyDataSource(), DefaultDataSources.TENSORS: ImageTensorDataSource(), + DefaultDataSources.LABELSTUDIO: LabelStudioImageDataSource(**data_source_kwargs) }, deserializer=deserializer or ImageDeserializer(), default_data_source=DefaultDataSources.FILES, diff --git a/flash/text/classification/data.py b/flash/text/classification/data.py index 5049c0e975..826ab87e3d 100644 --- a/flash/text/classification/data.py +++ b/flash/text/classification/data.py @@ -29,6 +29,7 @@ from transformers import AutoTokenizer, default_data_collator from transformers.modeling_outputs import SequenceClassifierOutput +from flash.core.data.data_source import LabelStudioTextDataSource class TextDeserializer(Deserializer): @@ -249,6 +250,7 @@ def __init__( DefaultDataSources.CSV: TextCSVDataSource(self.backbone, max_length=max_length), DefaultDataSources.JSON: TextJSONDataSource(self.backbone, max_length=max_length), "sentences": TextSentencesDataSource(self.backbone, max_length=max_length), + DefaultDataSources.LABELSTUDIO: LabelStudioTextDataSource(backbone=self.backbone, max_length=max_length) }, default_data_source="sentences", deserializer=TextDeserializer(backbone, max_length), diff --git a/flash/video/classification/data.py b/flash/video/classification/data.py index 318cc70ab2..db9cddc6f8 100644 --- a/flash/video/classification/data.py +++ b/flash/video/classification/data.py @@ -26,6 +26,7 @@ FiftyOneDataSource, LabelsState, PathsDataSource, + LabelStudioVideoDataSource ) from flash.core.data.process import Preprocess from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, _KORNIA_AVAILABLE, _PYTORCHVIDEO_AVAILABLE, lazy_import @@ -259,6 +260,13 @@ def __init__( decoder=decoder, **data_source_kwargs, ), + DefaultDataSources.LABELSTUDIO: LabelStudioVideoDataSource( + clip_sampler=clip_sampler, + video_sampler=video_sampler, + decode_audio=decode_audio, + decoder=decoder, + **data_source_kwargs, + ) }, default_data_source=DefaultDataSources.FILES, ) diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py index 15ecdaf90c..1ef31c6b2e 100644 --- a/flash_examples/integrations/labelstudio/image_classification.py +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -9,7 +9,9 @@ # 1. Load export data datamodule = ImageClassificationData.from_labelstudio( - export_json="data/project.json", data_folder="data/upload/", val_split=0.8, data_type="image" + export_json='data/project.json', + data_folder='data/upload/', + val_split=0.8, ) # 2. Fine tune a model diff --git a/flash_examples/integrations/labelstudio/text_classification.py b/flash_examples/integrations/labelstudio/text_classification.py index 95e7ec6ba0..4d4f260991 100644 --- a/flash_examples/integrations/labelstudio/text_classification.py +++ b/flash_examples/integrations/labelstudio/text_classification.py @@ -8,8 +8,7 @@ backbone = "prajjwal1/bert-medium" datamodule = TextClassificationData.from_labelstudio( - export_json="data/project.json", - data_type="text", + export_json='data/project.json', val_split=0.8, backbone=backbone, ) diff --git a/flash_examples/integrations/labelstudio/video_classification.py b/flash_examples/integrations/labelstudio/video_classification.py index c3cfebc073..26315fe4a9 100644 --- a/flash_examples/integrations/labelstudio/video_classification.py +++ b/flash_examples/integrations/labelstudio/video_classification.py @@ -9,9 +9,8 @@ # 1. Load export data datamodule = VideoClassificationData.from_labelstudio( - export_json="data/project.json", - data_folder="data/upload/", - data_type="video", + export_json='data/project.json', + data_folder='data/upload/', val_split=0.8, clip_sampler="uniform", clip_duration=1, From e995d8ce2b82a7fb99cc54159a971bbe64fb970f Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Mon, 23 Aug 2021 16:03:19 +0300 Subject: [PATCH 11/53] Fixing merge conflict --- flash/image/classification/data.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flash/image/classification/data.py b/flash/image/classification/data.py index fa4010800c..d579c5a1ea 100644 --- a/flash/image/classification/data.py +++ b/flash/image/classification/data.py @@ -71,6 +71,8 @@ def __init__( DefaultDataSources.FOLDERS: ImagePathsDataSource(), DefaultDataSources.NUMPY: ImageNumpyDataSource(), DefaultDataSources.TENSORS: ImageTensorDataSource(), + "data_frame": ImageClassificationDataFrameDataSource(), + DefaultDataSources.CSV: ImageClassificationDataFrameDataSource(), DefaultDataSources.LABELSTUDIO: LabelStudioImageDataSource(**data_source_kwargs) }, deserializer=deserializer or ImageDeserializer(), From 33958d006fc184a03a6e50ff1109757f0568d944 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 13:12:58 +0000 Subject: [PATCH 12/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- flash/core/data/data_module.py | 10 +- flash/core/data/data_source.py | 139 ++++++++---------- flash/image/classification/data.py | 10 +- flash/text/classification/data.py | 5 +- flash/video/classification/data.py | 4 +- .../labelstudio/image_classification.py | 4 +- .../labelstudio/text_classification.py | 2 +- .../labelstudio/video_classification.py | 4 +- 8 files changed, 86 insertions(+), 92 deletions(-) diff --git a/flash/core/data/data_module.py b/flash/core/data/data_module.py index 7daf30bb36..c0ea53dd98 100644 --- a/flash/core/data/data_module.py +++ b/flash/core/data/data_module.py @@ -1270,7 +1270,7 @@ def from_labelstudio( num_workers: Optional[int] = None, sampler: Optional[Sampler] = None, **preprocess_kwargs: Any, - ) -> 'DataModule': + ) -> "DataModule": """Creates a :class:`~flash.core.data.data_module.DataModule` object from the given export file and data directory using the :class:`~flash.core.data.data_source.DataSource` of name @@ -1312,10 +1312,10 @@ def from_labelstudio( ) """ data = { - 'data_folder': data_folder, - 'export_json': export_json, - 'split': val_split, - 'multi_label': preprocess_kwargs.get('multi_label', False) + "data_folder": data_folder, + "export_json": export_json, + "split": val_split, + "multi_label": preprocess_kwargs.get("multi_label", False), } return cls.from_data_source( DefaultDataSources.LABELSTUDIO, diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index 0fe553713c..085e9510cb 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -59,7 +59,9 @@ else: fol = None from copy import deepcopy -from flash.core.utilities.imports import _TEXT_AVAILABLE, _PYTORCHVIDEO_AVAILABLE + +from flash.core.utilities.imports import _PYTORCHVIDEO_AVAILABLE, _TEXT_AVAILABLE + if _PYTORCHVIDEO_AVAILABLE: from torchvision.datasets.folder import default_loader @@ -707,6 +709,7 @@ def _get_classes(self, data): class LabelStudioDataSource(DataSource): """The ``LabelStudioDatasource`` expects the input to :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio.""" + def __init__(self): super().__init__() self.results = [] @@ -717,36 +720,34 @@ def __init__(self): self.num_classes = 0 def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: - """ - Iterate through all tasks in exported data and construct train\test\val results - """ + """Iterate through all tasks in exported data and construct train\test\val results.""" if data and isinstance(data, dict): - self._data_folder = data.get('data_folder') - with open(data.get('export_json')) as f: + self._data_folder = data.get("data_folder") + with open(data.get("export_json")) as f: self._raw_data = json.load(f) - self.multi_label = data.get('multi_label') - self.split = data.get('split') + self.multi_label = data.get("multi_label") + self.split = data.get("split") for task in self._raw_data: - for annotation in task['annotations']: + for annotation in task["annotations"]: # extracting data types from tasks - [self.data_types.add(key) for key in task.get('data')] + [self.data_types.add(key) for key in task.get("data")] # Adding ground_truth annotation to separate dataset - result = annotation['result'] + result = annotation["result"] for res in result: - t = res['type'] - for label in res['value'][t]: + t = res["type"] + for label in res["value"][t]: # check if labeling result is a list of labels if isinstance(label, list) and not self.multi_label: for sublabel in label: self.classes.add(sublabel) temp = {} - temp['file_upload'] = task.get('file_upload') - temp['data'] = task.get('data') - temp['label'] = sublabel - temp['result'] = res.get('value') - if annotation['ground_truth']: + temp["file_upload"] = task.get("file_upload") + temp["data"] = task.get("data") + temp["label"] = sublabel + temp["result"] = res.get("value") + if annotation["ground_truth"]: self.test_results.append(temp) - elif not annotation['ground_truth']: + elif not annotation["ground_truth"]: self.results.append(temp) else: if isinstance(label, list): @@ -755,17 +756,18 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - else: self.classes.add(label) temp = {} - temp['file_upload'] = task.get('file_upload') - temp['data'] = task.get('data') - temp['label'] = label - temp['result'] = res.get('value') - if annotation['ground_truth']: + temp["file_upload"] = task.get("file_upload") + temp["data"] = task.get("data") + temp["label"] = label + temp["result"] = res.get("value") + if annotation["ground_truth"]: self.test_results.append(temp) - elif not annotation['ground_truth']: + elif not annotation["ground_truth"]: self.results.append(temp) self.num_classes = len(self.classes) # splitting result to train and val sets import random + random.shuffle(self.results) data_length = len(self.results) prop = data_length - int(data_length * self.split) @@ -773,28 +775,26 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - self.results = self.results[prop:] def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: - """ - Load 1 sample from dataset - """ + """Load 1 sample from dataset.""" # all other data types input_data = deepcopy(sample) try: - del input_data['label'] + del input_data["label"] except KeyError: # no label in input data pass - result = {DefaultDataKeys.INPUT: input_data, - DefaultDataKeys.TARGET: self._get_labels_from_sample(sample['label'])} + result = { + DefaultDataKeys.INPUT: input_data, + DefaultDataKeys.TARGET: self._get_labels_from_sample(sample["label"]), + } return result def generate_dataset( - self, - data: Optional[DATA_TYPE], - running_stage: RunningStage, + self, + data: Optional[DATA_TYPE], + running_stage: RunningStage, ) -> Optional[Union[AutoDataset, IterableAutoDataset]]: - """ - Generate dataset from loaded data - """ + """Generate dataset from loaded data.""" if running_stage in (RunningStage.TRAINING, RunningStage.TUNING): self.load_data(data) dataset = self.results @@ -813,9 +813,7 @@ def generate_dataset( return dataset def _get_labels_from_sample(self, labels): - """ - Translate string labels to int - """ + """Translate string labels to int.""" sorted_labels = sorted(list(self.classes)) if isinstance(labels, list): label = [] @@ -832,26 +830,20 @@ def __init__(self): pass def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: - """ - Load 1 sample from dataset - """ - if sample['file_upload']: - p = os.path.join(self._data_folder, sample['file_upload']) + """Load 1 sample from dataset.""" + if sample["file_upload"]: + p = os.path.join(self._data_folder, sample["file_upload"]) else: - for key in sample.get('data'): - p = sample.get('data').get(key) + for key in sample.get("data"): + p = sample.get("data").get(key) # loading image image = default_loader(p) - result = {DefaultDataKeys.INPUT: image, - DefaultDataKeys.TARGET: self._get_labels_from_sample(sample['label'])} + result = {DefaultDataKeys.INPUT: image, DefaultDataKeys.TARGET: self._get_labels_from_sample(sample["label"])} return result class LabelStudioTextDataSource(LabelStudioDataSource): - def __init__(self, - backbone=None, - max_length=128 - ): + def __init__(self, backbone=None, max_length=128): super().__init__() if backbone: if _TEXT_AVAILABLE: @@ -861,33 +853,24 @@ def __init__(self, self.max_length = max_length def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: - """ - Load 1 sample from dataset - """ + """Load 1 sample from dataset.""" if self.backbone: data = "" - for key in sample.get('data'): - data += sample.get('data').get(key) - tokenized_data = self.tokenizer(data, - max_length=self.max_length, - truncation=True, - padding="max_length") + for key in sample.get("data"): + data += sample.get("data").get(key) + tokenized_data = self.tokenizer(data, max_length=self.max_length, truncation=True, padding="max_length") for key in tokenized_data: tokenized_data[key] = torch.tensor(tokenized_data[key]) - tokenized_data['labels'] = self._get_labels_from_sample(sample['label']) + tokenized_data["labels"] = self._get_labels_from_sample(sample["label"]) # separate text data type block result = tokenized_data return result class LabelStudioVideoDataSource(LabelStudioDataSource): - def __init__(self, - video_sampler=None, - clip_sampler=None, - clip_duration=1, - decode_audio=False, - decoder: str = "pyav" - ): + def __init__( + self, video_sampler=None, clip_sampler=None, clip_duration=1, decode_audio=False, decoder: str = "pyav" + ): super().__init__() self.video_sampler = video_sampler or torch.utils.data.RandomSampler self.clip_sampler = clip_sampler @@ -895,9 +878,7 @@ def __init__(self, self.decoder = decoder def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: - """ - Load 1 sample from dataset - """ + """Load 1 sample from dataset.""" return sample def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: @@ -909,13 +890,19 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - def convert_to_encodedvideo(self, dataset): if len(dataset) > 0: from pytorchvideo.data import EncodedVideoDataset + dataset = EncodedVideoDataset( - [(os.path.join(self._data_folder, sample['file_upload']), - {"label": self._get_labels_from_sample(sample['label'])}) for sample in dataset], + [ + ( + os.path.join(self._data_folder, sample["file_upload"]), + {"label": self._get_labels_from_sample(sample["label"])}, + ) + for sample in dataset + ], self.clip_sampler, decode_audio=self.decode_audio, decoder=self.decoder, ) return dataset else: - return [] \ No newline at end of file + return [] diff --git a/flash/image/classification/data.py b/flash/image/classification/data.py index 961f8b7b9c..f83185e3f2 100644 --- a/flash/image/classification/data.py +++ b/flash/image/classification/data.py @@ -22,7 +22,12 @@ from flash.core.data.base_viz import BaseVisualization # for viz from flash.core.data.callback import BaseDataFetcher from flash.core.data.data_module import DataModule -from flash.core.data.data_source import DefaultDataKeys, DefaultDataSources, LoaderDataFrameDataSource +from flash.core.data.data_source import ( + DefaultDataKeys, + DefaultDataSources, + LabelStudioImageDataSource, + LoaderDataFrameDataSource, +) from flash.core.data.process import Deserializer, Preprocess from flash.core.utilities.imports import _MATPLOTLIB_AVAILABLE, Image, requires, requires_extras from flash.image.classification.transforms import default_transforms, train_default_transforms @@ -34,7 +39,6 @@ ImagePathsDataSource, ImageTensorDataSource, ) -from flash.core.data.data_source import LabelStudioImageDataSource if _MATPLOTLIB_AVAILABLE: import matplotlib.pyplot as plt @@ -80,7 +84,7 @@ def __init__( DefaultDataSources.TENSORS: ImageTensorDataSource(), "data_frame": ImageClassificationDataFrameDataSource(), DefaultDataSources.CSV: ImageClassificationDataFrameDataSource(), - DefaultDataSources.LABELSTUDIO: LabelStudioImageDataSource(**data_source_kwargs) + DefaultDataSources.LABELSTUDIO: LabelStudioImageDataSource(**data_source_kwargs), }, deserializer=deserializer or ImageDeserializer(), default_data_source=DefaultDataSources.FILES, diff --git a/flash/text/classification/data.py b/flash/text/classification/data.py index b244951201..c7b130543d 100644 --- a/flash/text/classification/data.py +++ b/flash/text/classification/data.py @@ -31,6 +31,7 @@ from flash.core.data.data_source import LabelStudioTextDataSource + class TextDeserializer(Deserializer): @requires_extras("text") def __init__(self, backbone: str, max_length: int, use_fast: bool = True): @@ -268,7 +269,9 @@ def __init__( DefaultDataSources.CSV: TextCSVDataSource(self.backbone, max_length=max_length), DefaultDataSources.JSON: TextJSONDataSource(self.backbone, max_length=max_length), "sentences": TextSentencesDataSource(self.backbone, max_length=max_length), - DefaultDataSources.LABELSTUDIO: LabelStudioTextDataSource(backbone=self.backbone, max_length=max_length) + DefaultDataSources.LABELSTUDIO: LabelStudioTextDataSource( + backbone=self.backbone, max_length=max_length + ), }, default_data_source="sentences", deserializer=TextDeserializer(backbone, max_length), diff --git a/flash/video/classification/data.py b/flash/video/classification/data.py index dea71ca33a..a57de670d7 100644 --- a/flash/video/classification/data.py +++ b/flash/video/classification/data.py @@ -25,8 +25,8 @@ DefaultDataSources, FiftyOneDataSource, LabelsState, + LabelStudioVideoDataSource, PathsDataSource, - LabelStudioVideoDataSource ) from flash.core.data.process import Preprocess from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, _KORNIA_AVAILABLE, _PYTORCHVIDEO_AVAILABLE, lazy_import @@ -263,7 +263,7 @@ def __init__( decode_audio=decode_audio, decoder=decoder, **data_source_kwargs, - ) + ), }, default_data_source=DefaultDataSources.FILES, ) diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py index 1ef31c6b2e..12d9df7952 100644 --- a/flash_examples/integrations/labelstudio/image_classification.py +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -9,8 +9,8 @@ # 1. Load export data datamodule = ImageClassificationData.from_labelstudio( - export_json='data/project.json', - data_folder='data/upload/', + export_json="data/project.json", + data_folder="data/upload/", val_split=0.8, ) diff --git a/flash_examples/integrations/labelstudio/text_classification.py b/flash_examples/integrations/labelstudio/text_classification.py index 4d4f260991..88a315d535 100644 --- a/flash_examples/integrations/labelstudio/text_classification.py +++ b/flash_examples/integrations/labelstudio/text_classification.py @@ -8,7 +8,7 @@ backbone = "prajjwal1/bert-medium" datamodule = TextClassificationData.from_labelstudio( - export_json='data/project.json', + export_json="data/project.json", val_split=0.8, backbone=backbone, ) diff --git a/flash_examples/integrations/labelstudio/video_classification.py b/flash_examples/integrations/labelstudio/video_classification.py index 26315fe4a9..af4c206590 100644 --- a/flash_examples/integrations/labelstudio/video_classification.py +++ b/flash_examples/integrations/labelstudio/video_classification.py @@ -9,8 +9,8 @@ # 1. Load export data datamodule = VideoClassificationData.from_labelstudio( - export_json='data/project.json', - data_folder='data/upload/', + export_json="data/project.json", + data_folder="data/upload/", val_split=0.8, clip_sampler="uniform", clip_duration=1, From 34e7a754361c6c7abdd68c2dca2a83747b451a33 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 15:00:10 +0000 Subject: [PATCH 13/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- flash/core/data/data_source.py | 40 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index fa786bb9e2..6232cec0d9 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -15,6 +15,7 @@ import os import typing import warnings +from copy import deepcopy from dataclasses import dataclass from functools import partial from inspect import signature @@ -49,9 +50,13 @@ from flash.core.data.auto_dataset import AutoDataset, BaseAutoDataset, IterableAutoDataset from flash.core.data.properties import ProcessState, Properties from flash.core.data.utils import CurrentRunningStageFuncContext -from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, lazy_import, requires, \ - _PYTORCHVIDEO_AVAILABLE, _TEXT_AVAILABLE -from copy import deepcopy +from flash.core.utilities.imports import ( + _FIFTYONE_AVAILABLE, + _PYTORCHVIDEO_AVAILABLE, + _TEXT_AVAILABLE, + lazy_import, + requires, +) SampleCollection = None if _FIFTYONE_AVAILABLE: @@ -826,8 +831,9 @@ def _get_labels_from_sample(self, labels): class LabelStudioImageDataSource(LabelStudioDataSource): """The ``LabelStudioImageDataSource`` expects the input to - :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. - Export data should point to image files""" + :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. + Export data should point to image files""" + def __init__(self): super().__init__() @@ -846,9 +852,10 @@ def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = class LabelStudioTextDataSource(LabelStudioDataSource): """The ``LabelStudioTextDataSource`` expects the input to - :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. - Export data should point to text data - """ + :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. + Export data should point to text data + """ + def __init__(self, backbone=None, max_length=128): super().__init__() if backbone: @@ -875,11 +882,10 @@ def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = class LabelStudioVideoDataSource(LabelStudioDataSource): """The ``LabelStudioVideoDataSource`` expects the input to - :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. - Export data should point to video files""" - def __init__( - self, video_sampler=None, clip_sampler=None, decode_audio=False, decoder: str = "pyav" - ): + :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. + Export data should point to video files""" + + def __init__(self, video_sampler=None, clip_sampler=None, decode_audio=False, decoder: str = "pyav"): super().__init__() self.video_sampler = video_sampler or torch.utils.data.RandomSampler self.clip_sampler = clip_sampler @@ -891,18 +897,14 @@ def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = return sample def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: - """ - load_data produces a sequence or iterable of samples - """ + """load_data produces a sequence or iterable of samples.""" super().load_data(data, dataset) self.results = self.convert_to_encodedvideo(self.results) self.test_results = self.convert_to_encodedvideo(self.test_results) self.val_results = self.convert_to_encodedvideo(self.val_results) def convert_to_encodedvideo(self, dataset): - """ - Converting dataset to EncodedVideoDataset - """ + """Converting dataset to EncodedVideoDataset.""" if len(dataset) > 0: from pytorchvideo.data import EncodedVideoDataset From 595f2660d2793fd8618d7b8d72be693ec18888ab Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Mon, 23 Aug 2021 18:00:50 +0300 Subject: [PATCH 14/53] Fixing DeepSource analysis issues --- flash/core/data/data_module.py | 5 ++--- flash/core/data/data_source.py | 30 ++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/flash/core/data/data_module.py b/flash/core/data/data_module.py index c0ea53dd98..3f43e1241d 100644 --- a/flash/core/data/data_module.py +++ b/flash/core/data/data_module.py @@ -11,7 +11,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -import json import os import platform from typing import ( @@ -35,7 +34,7 @@ from pytorch_lightning.trainer.states import RunningStage from pytorch_lightning.utilities.exceptions import MisconfigurationException from torch.utils.data import DataLoader, Dataset -from torch.utils.data.dataset import IterableDataset, random_split, Subset +from torch.utils.data.dataset import IterableDataset, Subset from torch.utils.data.sampler import Sampler import flash @@ -43,7 +42,7 @@ from flash.core.data.base_viz import BaseVisualization from flash.core.data.callback import BaseDataFetcher from flash.core.data.data_pipeline import DataPipeline, DefaultPreprocess, Postprocess, Preprocess -from flash.core.data.data_source import DataSource, DefaultDataSources, LabelStudioDataSource +from flash.core.data.data_source import DataSource, DefaultDataSources from flash.core.data.splits import SplitDataset from flash.core.data.utils import _STAGES_PREFIX from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, requires diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index 085e9510cb..fa786bb9e2 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -49,7 +49,9 @@ from flash.core.data.auto_dataset import AutoDataset, BaseAutoDataset, IterableAutoDataset from flash.core.data.properties import ProcessState, Properties from flash.core.data.utils import CurrentRunningStageFuncContext -from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, lazy_import, requires +from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, lazy_import, requires, \ + _PYTORCHVIDEO_AVAILABLE, _TEXT_AVAILABLE +from copy import deepcopy SampleCollection = None if _FIFTYONE_AVAILABLE: @@ -58,13 +60,11 @@ from fiftyone.core.collections import SampleCollection else: fol = None -from copy import deepcopy - -from flash.core.utilities.imports import _PYTORCHVIDEO_AVAILABLE, _TEXT_AVAILABLE if _PYTORCHVIDEO_AVAILABLE: from torchvision.datasets.folder import default_loader + # Credit to the PyTorchVision Team: # https://github.com/pytorch/vision/blob/master/torchvision/datasets/folder.py#L10 def has_file_allowed_extension(filename: str, extensions: Tuple[str, ...]) -> bool: @@ -825,9 +825,11 @@ def _get_labels_from_sample(self, labels): class LabelStudioImageDataSource(LabelStudioDataSource): + """The ``LabelStudioImageDataSource`` expects the input to + :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. + Export data should point to image files""" def __init__(self): super().__init__() - pass def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: """Load 1 sample from dataset.""" @@ -843,6 +845,10 @@ def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = class LabelStudioTextDataSource(LabelStudioDataSource): + """The ``LabelStudioTextDataSource`` expects the input to + :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. + Export data should point to text data + """ def __init__(self, backbone=None, max_length=128): super().__init__() if backbone: @@ -868,8 +874,11 @@ def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = class LabelStudioVideoDataSource(LabelStudioDataSource): + """The ``LabelStudioVideoDataSource`` expects the input to + :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. + Export data should point to video files""" def __init__( - self, video_sampler=None, clip_sampler=None, clip_duration=1, decode_audio=False, decoder: str = "pyav" + self, video_sampler=None, clip_sampler=None, decode_audio=False, decoder: str = "pyav" ): super().__init__() self.video_sampler = video_sampler or torch.utils.data.RandomSampler @@ -882,12 +891,18 @@ def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = return sample def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: + """ + load_data produces a sequence or iterable of samples + """ super().load_data(data, dataset) self.results = self.convert_to_encodedvideo(self.results) self.test_results = self.convert_to_encodedvideo(self.test_results) self.val_results = self.convert_to_encodedvideo(self.val_results) def convert_to_encodedvideo(self, dataset): + """ + Converting dataset to EncodedVideoDataset + """ if len(dataset) > 0: from pytorchvideo.data import EncodedVideoDataset @@ -904,5 +919,4 @@ def convert_to_encodedvideo(self, dataset): decoder=self.decoder, ) return dataset - else: - return [] + return [] From 8ba9f4ccf15ccd1fedd60a563127177486fbdded Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Mon, 23 Aug 2021 18:58:53 +0300 Subject: [PATCH 15/53] Fix last DeepSource analysis issues --- flash/core/data/data_source.py | 11 ++++++++--- flash/text/classification/data.py | 4 +--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index fa786bb9e2..c1c6c0049a 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -718,6 +718,10 @@ def __init__(self): self.classes = set() self.data_types = set() self.num_classes = 0 + self._data_folder = "" + self._raw_data = {} + self.multi_label = False + self.split = 0.8 def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: """Iterate through all tasks in exported data and construct train\test\val results.""" @@ -725,12 +729,13 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - self._data_folder = data.get("data_folder") with open(data.get("export_json")) as f: self._raw_data = json.load(f) - self.multi_label = data.get("multi_label") - self.split = data.get("split") + self.multi_label = data.get("multi_label", False) + self.split = data.get("split", 0.8) for task in self._raw_data: for annotation in task["annotations"]: # extracting data types from tasks - [self.data_types.add(key) for key in task.get("data")] + for key in task.get("data"): + self.data_types.add(key) # Adding ground_truth annotation to separate dataset result = annotation["result"] for res in result: diff --git a/flash/text/classification/data.py b/flash/text/classification/data.py index c7b130543d..91e92b19c1 100644 --- a/flash/text/classification/data.py +++ b/flash/text/classification/data.py @@ -20,7 +20,7 @@ import flash from flash.core.data.auto_dataset import AutoDataset from flash.core.data.data_module import DataModule -from flash.core.data.data_source import DataSource, DefaultDataSources, LabelsState +from flash.core.data.data_source import DataSource, DefaultDataSources, LabelsState, LabelStudioTextDataSource from flash.core.data.process import Deserializer, Postprocess, Preprocess from flash.core.utilities.imports import _TEXT_AVAILABLE, requires_extras @@ -29,8 +29,6 @@ from transformers import AutoTokenizer, default_data_collator from transformers.modeling_outputs import SequenceClassifierOutput -from flash.core.data.data_source import LabelStudioTextDataSource - class TextDeserializer(Deserializer): @requires_extras("text") From fb3103fc581a90498d88927346eb476dc5681c04 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Mon, 23 Aug 2021 19:27:04 +0300 Subject: [PATCH 16/53] Delete useless init --- flash/core/data/data_source.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index 33c687391c..59cdac3726 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -839,9 +839,6 @@ class LabelStudioImageDataSource(LabelStudioDataSource): :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. Export data should point to image files""" - def __init__(self): - super().__init__() - def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: """Load 1 sample from dataset.""" if sample["file_upload"]: From bf82fd907494c341af895c3674df80432c075510 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Fri, 27 Aug 2021 20:08:37 +0300 Subject: [PATCH 17/53] Move label studio datasource to separate file - Move label studio datasource to separate file - Add train/val/test/predict params to .from_label_studio method --- flash/core/data/data_module.py | 51 +++- flash/core/data/data_source.py | 222 --------------- .../integrations/labelstudio/data_source.py | 263 ++++++++++++++++++ flash/image/classification/data.py | 4 +- flash/text/classification/data.py | 5 +- flash/video/classification/data.py | 4 +- .../labelstudio/image_classification.py | 4 +- .../labelstudio/text_classification.py | 2 +- .../labelstudio/video_classification.py | 2 +- 9 files changed, 323 insertions(+), 234 deletions(-) create mode 100644 flash/core/integrations/labelstudio/data_source.py diff --git a/flash/core/data/data_module.py b/flash/core/data/data_module.py index 3f43e1241d..5c63a15d70 100644 --- a/flash/core/data/data_module.py +++ b/flash/core/data/data_module.py @@ -1257,7 +1257,15 @@ def from_fiftyone( def from_labelstudio( cls, export_json: str = None, + train_export_json: str = None, + val_export_json: str = None, + test_export_json: str = None, + predict_export_json: str = None, data_folder: str = None, + train_data_folder: str = None, + val_data_folder: str = None, + test_data_folder: str = None, + predict_data_folder: str = None, train_transform: Optional[Dict[str, Callable]] = None, val_transform: Optional[Dict[str, Callable]] = None, test_transform: Optional[Dict[str, Callable]] = None, @@ -1267,7 +1275,6 @@ def from_labelstudio( val_split: Optional[float] = None, batch_size: int = 4, num_workers: Optional[int] = None, - sampler: Optional[Sampler] = None, **preprocess_kwargs: Any, ) -> "DataModule": """Creates a :class:`~flash.core.data.data_module.DataModule` object @@ -1278,7 +1285,15 @@ def from_labelstudio( Args: export_json: path to label studio export file + train_export_json: path to label studio export file for train + val_export_json: path to label studio export file for validation + test_export_json: path to label studio export file for test + predict_export_json: path to label studio export file for predict data_folder: path to label studio data folder + train_data_folder: path to label studio data folder for train data + val_data_folder: path to label studio data folder for validation data + test_data_folder: path to label studio data folder for test data + predict_data_folder: path to label studio data folder for predict data train_transform: The dictionary of transforms to use during training which maps :class:`~flash.core.data.process.Preprocess` hook names to callable transforms. val_transform: The dictionary of transforms to use during validation which maps @@ -1295,7 +1310,6 @@ def from_labelstudio( val_split: The ``val_split`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`. batch_size: The ``batch_size`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`. num_workers: The ``num_workers`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`. - sampler: The ``sampler`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`. preprocess_kwargs: Additional keyword arguments to use when constructing the preprocess. Will only be used if ``preprocess = None``. @@ -1316,9 +1330,40 @@ def from_labelstudio( "split": val_split, "multi_label": preprocess_kwargs.get("multi_label", False), } + train_data = None + val_data = None + test_data = None + predict_data = None + if (train_data_folder or data_folder) and train_export_json: + train_data = { + "data_folder": train_data_folder or data_folder, + "export_json": train_export_json, + "multi_label": preprocess_kwargs.get("multi_label", False), + } + if (val_data_folder or data_folder) and val_export_json: + val_data = { + "data_folder": val_data_folder or data_folder, + "export_json": val_export_json, + "multi_label": preprocess_kwargs.get("multi_label", False), + } + if (test_data_folder or data_folder) and test_export_json: + test_data = { + "data_folder": test_data_folder or data_folder, + "export_json": test_export_json, + "multi_label": preprocess_kwargs.get("multi_label", False), + } + if (predict_data_folder or data_folder) and predict_export_json: + predict_data = { + "data_folder": predict_data_folder or data_folder, + "export_json": predict_export_json, + "multi_label": preprocess_kwargs.get("multi_label", False), + } return cls.from_data_source( DefaultDataSources.LABELSTUDIO, - train_data=data, + train_data=train_data if train_data else data, + val_data=val_data, + test_data=test_data, + predict_data=predict_data, train_transform=train_transform, val_transform=val_transform, test_transform=test_transform, diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index 59cdac3726..44263ca88c 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -11,11 +11,9 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -import json import os import typing import warnings -from copy import deepcopy from dataclasses import dataclass from functools import partial from inspect import signature @@ -52,8 +50,6 @@ from flash.core.data.utils import CurrentRunningStageFuncContext from flash.core.utilities.imports import ( _FIFTYONE_AVAILABLE, - _PYTORCHVIDEO_AVAILABLE, - _TEXT_AVAILABLE, lazy_import, requires, ) @@ -66,9 +62,6 @@ else: fol = None -if _PYTORCHVIDEO_AVAILABLE: - from torchvision.datasets.folder import default_loader - # Credit to the PyTorchVision Team: # https://github.com/pytorch/vision/blob/master/torchvision/datasets/folder.py#L10 @@ -709,218 +702,3 @@ def _get_classes(self, data): classes = data.distinct(label_path) return classes - - -class LabelStudioDataSource(DataSource): - """The ``LabelStudioDatasource`` expects the input to - :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio.""" - - def __init__(self): - super().__init__() - self.results = [] - self.test_results = [] - self.val_results = [] - self.classes = set() - self.data_types = set() - self.num_classes = 0 - self._data_folder = "" - self._raw_data = {} - self.multi_label = False - self.split = 0.8 - - def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: - """Iterate through all tasks in exported data and construct train\test\val results.""" - if data and isinstance(data, dict): - self._data_folder = data.get("data_folder") - with open(data.get("export_json")) as f: - self._raw_data = json.load(f) - self.multi_label = data.get("multi_label", False) - self.split = data.get("split", 0.8) - for task in self._raw_data: - for annotation in task["annotations"]: - # extracting data types from tasks - for key in task.get("data"): - self.data_types.add(key) - # Adding ground_truth annotation to separate dataset - result = annotation["result"] - for res in result: - t = res["type"] - for label in res["value"][t]: - # check if labeling result is a list of labels - if isinstance(label, list) and not self.multi_label: - for sublabel in label: - self.classes.add(sublabel) - temp = {} - temp["file_upload"] = task.get("file_upload") - temp["data"] = task.get("data") - temp["label"] = sublabel - temp["result"] = res.get("value") - if annotation["ground_truth"]: - self.test_results.append(temp) - elif not annotation["ground_truth"]: - self.results.append(temp) - else: - if isinstance(label, list): - for item in label: - self.classes.add(item) - else: - self.classes.add(label) - temp = {} - temp["file_upload"] = task.get("file_upload") - temp["data"] = task.get("data") - temp["label"] = label - temp["result"] = res.get("value") - if annotation["ground_truth"]: - self.test_results.append(temp) - elif not annotation["ground_truth"]: - self.results.append(temp) - self.num_classes = len(self.classes) - # splitting result to train and val sets - import random - - random.shuffle(self.results) - data_length = len(self.results) - prop = data_length - int(data_length * self.split) - self.val_results = self.results[:prop] - self.results = self.results[prop:] - - def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: - """Load 1 sample from dataset.""" - # all other data types - input_data = deepcopy(sample) - try: - del input_data["label"] - except KeyError: - # no label in input data - pass - result = { - DefaultDataKeys.INPUT: input_data, - DefaultDataKeys.TARGET: self._get_labels_from_sample(sample["label"]), - } - return result - - def generate_dataset( - self, - data: Optional[DATA_TYPE], - running_stage: RunningStage, - ) -> Optional[Union[AutoDataset, IterableAutoDataset]]: - """Generate dataset from loaded data.""" - if running_stage in (RunningStage.TRAINING, RunningStage.TUNING): - self.load_data(data) - dataset = self.results - elif running_stage == RunningStage.TESTING: - dataset = self.test_results - elif running_stage == RunningStage.PREDICTING: - dataset = data or [] - elif running_stage == RunningStage.VALIDATING: - dataset = self.val_results - - if has_len(dataset): - dataset = AutoDataset(dataset, self, running_stage) - else: - dataset = IterableAutoDataset(dataset, self, running_stage) - dataset.num_classes = self.num_classes - return dataset - - def _get_labels_from_sample(self, labels): - """Translate string labels to int.""" - sorted_labels = sorted(list(self.classes)) - if isinstance(labels, list): - label = [] - for item in labels: - label.append(sorted_labels.index(item)) - else: - label = sorted_labels.index(labels) - return label - - -class LabelStudioImageDataSource(LabelStudioDataSource): - """The ``LabelStudioImageDataSource`` expects the input to - :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. - Export data should point to image files""" - - def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: - """Load 1 sample from dataset.""" - if sample["file_upload"]: - p = os.path.join(self._data_folder, sample["file_upload"]) - else: - for key in sample.get("data"): - p = sample.get("data").get(key) - # loading image - image = default_loader(p) - result = {DefaultDataKeys.INPUT: image, DefaultDataKeys.TARGET: self._get_labels_from_sample(sample["label"])} - return result - - -class LabelStudioTextDataSource(LabelStudioDataSource): - """The ``LabelStudioTextDataSource`` expects the input to - :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. - Export data should point to text data - """ - - def __init__(self, backbone=None, max_length=128): - super().__init__() - if backbone: - if _TEXT_AVAILABLE: - from transformers import AutoTokenizer - self.backbone = backbone - self.tokenizer = AutoTokenizer.from_pretrained(backbone, use_fast=True) - self.max_length = max_length - - def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: - """Load 1 sample from dataset.""" - if self.backbone: - data = "" - for key in sample.get("data"): - data += sample.get("data").get(key) - tokenized_data = self.tokenizer(data, max_length=self.max_length, truncation=True, padding="max_length") - for key in tokenized_data: - tokenized_data[key] = torch.tensor(tokenized_data[key]) - tokenized_data["labels"] = self._get_labels_from_sample(sample["label"]) - # separate text data type block - result = tokenized_data - return result - - -class LabelStudioVideoDataSource(LabelStudioDataSource): - """The ``LabelStudioVideoDataSource`` expects the input to - :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. - Export data should point to video files""" - - def __init__(self, video_sampler=None, clip_sampler=None, decode_audio=False, decoder: str = "pyav"): - super().__init__() - self.video_sampler = video_sampler or torch.utils.data.RandomSampler - self.clip_sampler = clip_sampler - self.decode_audio = decode_audio - self.decoder = decoder - - def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: - """Load 1 sample from dataset.""" - return sample - - def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: - """load_data produces a sequence or iterable of samples.""" - super().load_data(data, dataset) - self.results = self.convert_to_encodedvideo(self.results) - self.test_results = self.convert_to_encodedvideo(self.test_results) - self.val_results = self.convert_to_encodedvideo(self.val_results) - - def convert_to_encodedvideo(self, dataset): - """Converting dataset to EncodedVideoDataset.""" - if len(dataset) > 0: - from pytorchvideo.data import EncodedVideoDataset - - dataset = EncodedVideoDataset( - [ - ( - os.path.join(self._data_folder, sample["file_upload"]), - {"label": self._get_labels_from_sample(sample["label"])}, - ) - for sample in dataset - ], - self.clip_sampler, - decode_audio=self.decode_audio, - decoder=self.decoder, - ) - return dataset - return [] diff --git a/flash/core/integrations/labelstudio/data_source.py b/flash/core/integrations/labelstudio/data_source.py new file mode 100644 index 0000000000..6f911ba229 --- /dev/null +++ b/flash/core/integrations/labelstudio/data_source.py @@ -0,0 +1,263 @@ +from flash.core.data.data_source import DefaultDataKeys, has_len +from pytorch_lightning.trainer.states import RunningStage +from flash.core.data.auto_dataset import AutoDataset, IterableAutoDataset +from flash import DataSource +import os +from copy import deepcopy +from typing import ( + Any, + Mapping, + Optional, + Sequence, + TypeVar, + Union, +) +import json +import torch +from pytorch_lightning.utilities.cloud_io import get_filesystem +from flash.core.utilities.imports import ( + _PYTORCHVIDEO_AVAILABLE, + _TEXT_AVAILABLE, +) +if _PYTORCHVIDEO_AVAILABLE: + from torchvision.datasets.folder import default_loader +DATA_TYPE = TypeVar("DATA_TYPE") + + +class LabelStudioDataSource(DataSource): + """The ``LabelStudioDatasource`` expects the input to + :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio.""" + + def __init__(self): + super().__init__() + self.results = [] + self.test_results = [] + self.val_results = [] + self.classes = set() + self.data_types = set() + self.num_classes = 0 + self._data_folder = "" + self._raw_data = {} + self.multi_label = False + self.split = None + + def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: + """Iterate through all tasks in exported data and construct train\test\val results.""" + if data and isinstance(data, dict): + data_folder = data.get("data_folder") + file_path = data.get("export_json") + fs = get_filesystem(file_path) + with fs.open(file_path) as f: + _raw_data = json.load(f) + self.multi_label = data.get("multi_label", False) + self.split = data.get("split") + results, test_results, classes, data_types = LabelStudioDataSource._load_json_data(_raw_data, + data_folder=data_folder, + multi_label=self.multi_label) + self.classes = self.classes | classes + self.data_types = self.data_types | data_types + self.num_classes = len(self.classes) + # splitting result to train and val sets + if self.split: + import random + random.shuffle(results) + prop = int(len(results) * self.split) + self.val_results = results[:prop] + self.results = results[prop:] + self.test_results = test_results + return self.results + else: + return results + test_results + else: + return [] + + def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: + """Load 1 sample from dataset.""" + # all other data types + input_data = deepcopy(sample) + try: + del input_data["label"] + except KeyError: + # no label in input data + pass + result = { + DefaultDataKeys.INPUT: input_data, + DefaultDataKeys.TARGET: self._get_labels_from_sample(sample["label"]), + } + return result + + def generate_dataset( + self, + data: Optional[DATA_TYPE], + running_stage: RunningStage, + ) -> Optional[Union[AutoDataset, IterableAutoDataset]]: + """Generate dataset from loaded data.""" + res = self.load_data(data) + if running_stage in (RunningStage.TRAINING, RunningStage.TUNING): + dataset = res + elif running_stage == RunningStage.TESTING: + dataset = res or self.test_results + elif running_stage == RunningStage.PREDICTING: + dataset = res or [] + elif running_stage == RunningStage.VALIDATING: + dataset = res or self.val_results + + if has_len(dataset): + dataset = AutoDataset(dataset, self, running_stage) + else: + dataset = IterableAutoDataset(dataset, self, running_stage) + dataset.num_classes = self.num_classes + return dataset + + def _get_labels_from_sample(self, labels): + """Translate string labels to int.""" + sorted_labels = sorted(list(self.classes)) + if isinstance(labels, list): + label = [] + for item in labels: + label.append(sorted_labels.index(item)) + else: + label = sorted_labels.index(labels) + return label + + @staticmethod + def _load_json_data(data, data_folder, multi_label=False): + """ + Utility method to extract data from Label Studio json files + """ + results = [] + test_results = [] + data_types = set() + classes = set() + for task in data: + for annotation in task["annotations"]: + # extracting data types from tasks + for key in task.get("data"): + data_types.add(key) + # Adding ground_truth annotation to separate dataset + result = annotation["result"] + for res in result: + t = res["type"] + for label in res["value"][t]: + # check if labeling result is a list of labels + if isinstance(label, list) and not multi_label: + for sublabel in label: + classes.add(sublabel) + temp = {} + temp["file_upload"] = task.get("file_upload") + if temp["file_upload"]: + temp["file_upload"] = os.path.join(data_folder, temp["file_upload"]) + temp["data"] = task.get("data") + temp["label"] = sublabel + temp["result"] = res.get("value") + if annotation["ground_truth"]: + test_results.append(temp) + elif not annotation["ground_truth"]: + results.append(temp) + else: + if isinstance(label, list): + for item in label: + classes.add(item) + else: + classes.add(label) + temp = {} + temp["file_upload"] = task.get("file_upload") + if temp["file_upload"] and data_folder: + temp["file_upload"] = os.path.join(data_folder, temp["file_upload"]) + temp["data"] = task.get("data") + temp["label"] = label + temp["result"] = res.get("value") + if annotation["ground_truth"]: + test_results.append(temp) + elif not annotation["ground_truth"]: + results.append(temp) + return results, test_results, classes, data_types + + +class LabelStudioImageClassificationDataSource(LabelStudioDataSource): + """The ``LabelStudioImageDataSource`` expects the input to + :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. + Export data should point to image files""" + + def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: + """Load 1 sample from dataset.""" + if sample["file_upload"]: + p = sample["file_upload"] + else: + for key in sample.get("data"): + p = sample.get("data").get(key) + # loading image + image = default_loader(p) + result = {DefaultDataKeys.INPUT: image, DefaultDataKeys.TARGET: self._get_labels_from_sample(sample["label"])} + return result + + +class LabelStudioTextClassificationDataSource(LabelStudioDataSource): + """The ``LabelStudioTextDataSource`` expects the input to + :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. + Export data should point to text data + """ + def __init__(self, backbone=None, max_length=128): + super().__init__() + if backbone: + if _TEXT_AVAILABLE: + from transformers import AutoTokenizer + self.backbone = backbone + self.tokenizer = AutoTokenizer.from_pretrained(backbone, use_fast=True) + self.max_length = max_length + + def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: + """Load 1 sample from dataset.""" + if self.backbone: + data = "" + for key in sample.get("data"): + data += sample.get("data").get(key) + tokenized_data = self.tokenizer(data, max_length=self.max_length, truncation=True, padding="max_length") + for key in tokenized_data: + tokenized_data[key] = torch.tensor(tokenized_data[key]) + tokenized_data["labels"] = self._get_labels_from_sample(sample["label"]) + # separate text data type block + result = tokenized_data + return result + + +class LabelStudioVideoClassificationDataSource(LabelStudioDataSource): + """The ``LabelStudioVideoDataSource`` expects the input to + :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. + Export data should point to video files""" + + def __init__(self, video_sampler=None, clip_sampler=None, decode_audio=False, decoder: str = "pyav"): + super().__init__() + self.video_sampler = video_sampler or torch.utils.data.RandomSampler + self.clip_sampler = clip_sampler + self.decode_audio = decode_audio + self.decoder = decoder + + def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: + """Load 1 sample from dataset.""" + return sample + + def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) -> Sequence[Mapping[str, Any]]: + """load_data produces a sequence or iterable of samples.""" + res = super().load_data(data, dataset) + return self.convert_to_encodedvideo(res) + + def convert_to_encodedvideo(self, dataset): + """Converting dataset to EncodedVideoDataset.""" + if len(dataset) > 0: + from pytorchvideo.data import LabeledVideoDataset + + dataset = LabeledVideoDataset( + [ + ( + os.path.join(self._data_folder, sample["file_upload"]), + {"label": self._get_labels_from_sample(sample["label"])}, + ) + for sample in dataset + ], + self.clip_sampler, + decode_audio=self.decode_audio, + decoder=self.decoder, + ) + return dataset + return [] diff --git a/flash/image/classification/data.py b/flash/image/classification/data.py index f83185e3f2..85381bd388 100644 --- a/flash/image/classification/data.py +++ b/flash/image/classification/data.py @@ -25,9 +25,9 @@ from flash.core.data.data_source import ( DefaultDataKeys, DefaultDataSources, - LabelStudioImageDataSource, LoaderDataFrameDataSource, ) +from flash.core.integrations.labelstudio.data_source import LabelStudioImageClassificationDataSource from flash.core.data.process import Deserializer, Preprocess from flash.core.utilities.imports import _MATPLOTLIB_AVAILABLE, Image, requires, requires_extras from flash.image.classification.transforms import default_transforms, train_default_transforms @@ -84,7 +84,7 @@ def __init__( DefaultDataSources.TENSORS: ImageTensorDataSource(), "data_frame": ImageClassificationDataFrameDataSource(), DefaultDataSources.CSV: ImageClassificationDataFrameDataSource(), - DefaultDataSources.LABELSTUDIO: LabelStudioImageDataSource(**data_source_kwargs), + DefaultDataSources.LABELSTUDIO: LabelStudioImageClassificationDataSource(**data_source_kwargs), }, deserializer=deserializer or ImageDeserializer(), default_data_source=DefaultDataSources.FILES, diff --git a/flash/text/classification/data.py b/flash/text/classification/data.py index 91e92b19c1..54a35ca3fb 100644 --- a/flash/text/classification/data.py +++ b/flash/text/classification/data.py @@ -20,7 +20,8 @@ import flash from flash.core.data.auto_dataset import AutoDataset from flash.core.data.data_module import DataModule -from flash.core.data.data_source import DataSource, DefaultDataSources, LabelsState, LabelStudioTextDataSource +from flash.core.data.data_source import DataSource, DefaultDataSources, LabelsState +from flash.core.integrations.labelstudio.data_source import LabelStudioTextClassificationDataSource from flash.core.data.process import Deserializer, Postprocess, Preprocess from flash.core.utilities.imports import _TEXT_AVAILABLE, requires_extras @@ -267,7 +268,7 @@ def __init__( DefaultDataSources.CSV: TextCSVDataSource(self.backbone, max_length=max_length), DefaultDataSources.JSON: TextJSONDataSource(self.backbone, max_length=max_length), "sentences": TextSentencesDataSource(self.backbone, max_length=max_length), - DefaultDataSources.LABELSTUDIO: LabelStudioTextDataSource( + DefaultDataSources.LABELSTUDIO: LabelStudioTextClassificationDataSource( backbone=self.backbone, max_length=max_length ), }, diff --git a/flash/video/classification/data.py b/flash/video/classification/data.py index a57de670d7..a9cfbefd80 100644 --- a/flash/video/classification/data.py +++ b/flash/video/classification/data.py @@ -25,9 +25,9 @@ DefaultDataSources, FiftyOneDataSource, LabelsState, - LabelStudioVideoDataSource, PathsDataSource, ) +from flash.core.integrations.labelstudio.data_source import LabelStudioVideoClassificationDataSource from flash.core.data.process import Preprocess from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, _KORNIA_AVAILABLE, _PYTORCHVIDEO_AVAILABLE, lazy_import @@ -257,7 +257,7 @@ def __init__( decoder=decoder, **data_source_kwargs, ), - DefaultDataSources.LABELSTUDIO: LabelStudioVideoDataSource( + DefaultDataSources.LABELSTUDIO: LabelStudioVideoClassificationDataSource( clip_sampler=clip_sampler, video_sampler=video_sampler, decode_audio=decode_audio, diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py index 12d9df7952..5fb6de2a21 100644 --- a/flash_examples/integrations/labelstudio/image_classification.py +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -11,7 +11,7 @@ datamodule = ImageClassificationData.from_labelstudio( export_json="data/project.json", data_folder="data/upload/", - val_split=0.8, + val_split=0.2, ) # 2. Fine tune a model @@ -38,3 +38,5 @@ "data/test/2.jpg", ] ) + +print(predictions) diff --git a/flash_examples/integrations/labelstudio/text_classification.py b/flash_examples/integrations/labelstudio/text_classification.py index 88a315d535..706cfd2416 100644 --- a/flash_examples/integrations/labelstudio/text_classification.py +++ b/flash_examples/integrations/labelstudio/text_classification.py @@ -9,7 +9,7 @@ datamodule = TextClassificationData.from_labelstudio( export_json="data/project.json", - val_split=0.8, + val_split=0.2, backbone=backbone, ) diff --git a/flash_examples/integrations/labelstudio/video_classification.py b/flash_examples/integrations/labelstudio/video_classification.py index af4c206590..7a630d342b 100644 --- a/flash_examples/integrations/labelstudio/video_classification.py +++ b/flash_examples/integrations/labelstudio/video_classification.py @@ -11,7 +11,7 @@ datamodule = VideoClassificationData.from_labelstudio( export_json="data/project.json", data_folder="data/upload/", - val_split=0.8, + val_split=0.2, clip_sampler="uniform", clip_duration=1, decode_audio=False, From 7f67ce184696a5015c9ecac89ef7951999d2e908 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 27 Aug 2021 17:06:21 +0000 Subject: [PATCH 18/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- flash/core/data/data_source.py | 6 +-- .../integrations/labelstudio/data_source.py | 39 ++++++++----------- flash/image/classification/data.py | 8 +--- flash/text/classification/data.py | 2 +- flash/video/classification/data.py | 2 +- 5 files changed, 21 insertions(+), 36 deletions(-) diff --git a/flash/core/data/data_source.py b/flash/core/data/data_source.py index 44263ca88c..e95e29ec2d 100644 --- a/flash/core/data/data_source.py +++ b/flash/core/data/data_source.py @@ -48,11 +48,7 @@ from flash.core.data.auto_dataset import AutoDataset, BaseAutoDataset, IterableAutoDataset from flash.core.data.properties import ProcessState, Properties from flash.core.data.utils import CurrentRunningStageFuncContext -from flash.core.utilities.imports import ( - _FIFTYONE_AVAILABLE, - lazy_import, - requires, -) +from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, lazy_import, requires SampleCollection = None if _FIFTYONE_AVAILABLE: diff --git a/flash/core/integrations/labelstudio/data_source.py b/flash/core/integrations/labelstudio/data_source.py index 6f911ba229..4842435c61 100644 --- a/flash/core/integrations/labelstudio/data_source.py +++ b/flash/core/integrations/labelstudio/data_source.py @@ -1,24 +1,17 @@ -from flash.core.data.data_source import DefaultDataKeys, has_len -from pytorch_lightning.trainer.states import RunningStage -from flash.core.data.auto_dataset import AutoDataset, IterableAutoDataset -from flash import DataSource +import json import os from copy import deepcopy -from typing import ( - Any, - Mapping, - Optional, - Sequence, - TypeVar, - Union, -) -import json +from typing import Any, Mapping, Optional, Sequence, TypeVar, Union + import torch +from pytorch_lightning.trainer.states import RunningStage from pytorch_lightning.utilities.cloud_io import get_filesystem -from flash.core.utilities.imports import ( - _PYTORCHVIDEO_AVAILABLE, - _TEXT_AVAILABLE, -) + +from flash import DataSource +from flash.core.data.auto_dataset import AutoDataset, IterableAutoDataset +from flash.core.data.data_source import DefaultDataKeys, has_len +from flash.core.utilities.imports import _PYTORCHVIDEO_AVAILABLE, _TEXT_AVAILABLE + if _PYTORCHVIDEO_AVAILABLE: from torchvision.datasets.folder import default_loader DATA_TYPE = TypeVar("DATA_TYPE") @@ -51,15 +44,16 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - _raw_data = json.load(f) self.multi_label = data.get("multi_label", False) self.split = data.get("split") - results, test_results, classes, data_types = LabelStudioDataSource._load_json_data(_raw_data, - data_folder=data_folder, - multi_label=self.multi_label) + results, test_results, classes, data_types = LabelStudioDataSource._load_json_data( + _raw_data, data_folder=data_folder, multi_label=self.multi_label + ) self.classes = self.classes | classes self.data_types = self.data_types | data_types self.num_classes = len(self.classes) # splitting result to train and val sets if self.split: import random + random.shuffle(results) prop = int(len(results) * self.split) self.val_results = results[:prop] @@ -122,9 +116,7 @@ def _get_labels_from_sample(self, labels): @staticmethod def _load_json_data(data, data_folder, multi_label=False): - """ - Utility method to extract data from Label Studio json files - """ + """Utility method to extract data from Label Studio json files.""" results = [] test_results = [] data_types = set() @@ -197,6 +189,7 @@ class LabelStudioTextClassificationDataSource(LabelStudioDataSource): :meth:`~flash.core.data.data_source.DataSource.load_data` to be a json export from label studio. Export data should point to text data """ + def __init__(self, backbone=None, max_length=128): super().__init__() if backbone: diff --git a/flash/image/classification/data.py b/flash/image/classification/data.py index 85381bd388..beee45a237 100644 --- a/flash/image/classification/data.py +++ b/flash/image/classification/data.py @@ -22,13 +22,9 @@ from flash.core.data.base_viz import BaseVisualization # for viz from flash.core.data.callback import BaseDataFetcher from flash.core.data.data_module import DataModule -from flash.core.data.data_source import ( - DefaultDataKeys, - DefaultDataSources, - LoaderDataFrameDataSource, -) -from flash.core.integrations.labelstudio.data_source import LabelStudioImageClassificationDataSource +from flash.core.data.data_source import DefaultDataKeys, DefaultDataSources, LoaderDataFrameDataSource from flash.core.data.process import Deserializer, Preprocess +from flash.core.integrations.labelstudio.data_source import LabelStudioImageClassificationDataSource from flash.core.utilities.imports import _MATPLOTLIB_AVAILABLE, Image, requires, requires_extras from flash.image.classification.transforms import default_transforms, train_default_transforms from flash.image.data import ( diff --git a/flash/text/classification/data.py b/flash/text/classification/data.py index 54a35ca3fb..714c652d29 100644 --- a/flash/text/classification/data.py +++ b/flash/text/classification/data.py @@ -21,8 +21,8 @@ from flash.core.data.auto_dataset import AutoDataset from flash.core.data.data_module import DataModule from flash.core.data.data_source import DataSource, DefaultDataSources, LabelsState -from flash.core.integrations.labelstudio.data_source import LabelStudioTextClassificationDataSource from flash.core.data.process import Deserializer, Postprocess, Preprocess +from flash.core.integrations.labelstudio.data_source import LabelStudioTextClassificationDataSource from flash.core.utilities.imports import _TEXT_AVAILABLE, requires_extras if _TEXT_AVAILABLE: diff --git a/flash/video/classification/data.py b/flash/video/classification/data.py index a9cfbefd80..cf69c97883 100644 --- a/flash/video/classification/data.py +++ b/flash/video/classification/data.py @@ -27,8 +27,8 @@ LabelsState, PathsDataSource, ) -from flash.core.integrations.labelstudio.data_source import LabelStudioVideoClassificationDataSource from flash.core.data.process import Preprocess +from flash.core.integrations.labelstudio.data_source import LabelStudioVideoClassificationDataSource from flash.core.utilities.imports import _FIFTYONE_AVAILABLE, _KORNIA_AVAILABLE, _PYTORCHVIDEO_AVAILABLE, lazy_import SampleCollection = None From 5ecd88ec95b8b6a11617c31dc22aade531e0c0dd Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Mon, 30 Aug 2021 12:28:52 +0300 Subject: [PATCH 19/53] Add test for LabelStudioDataSource._load_json_data --- flash/image/classification/data.py | 2 +- .../labelstudio/test_labelstudio.py | 121 ++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 tests/core/integrations/labelstudio/test_labelstudio.py diff --git a/flash/image/classification/data.py b/flash/image/classification/data.py index beee45a237..816aeae081 100644 --- a/flash/image/classification/data.py +++ b/flash/image/classification/data.py @@ -80,7 +80,7 @@ def __init__( DefaultDataSources.TENSORS: ImageTensorDataSource(), "data_frame": ImageClassificationDataFrameDataSource(), DefaultDataSources.CSV: ImageClassificationDataFrameDataSource(), - DefaultDataSources.LABELSTUDIO: LabelStudioImageClassificationDataSource(**data_source_kwargs), + DefaultDataSources.LABELSTUDIO: LabelStudioImageClassificationDataSource(), }, deserializer=deserializer or ImageDeserializer(), default_data_source=DefaultDataSources.FILES, diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py new file mode 100644 index 0000000000..184bac6dc6 --- /dev/null +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -0,0 +1,121 @@ +from flash.core.integrations.labelstudio.data_source import LabelStudioDataSource + + +def test_utility_load(): + data = [{ + "id": 191, + "annotations": [{ + "id": 130, + "completed_by": { + "id": 1, + "email": "test@heartex.com", + "first_name": "", + "last_name": "" + }, + "result": [{ + "id": "dv1Tn-zdez", + "type": "rectanglelabels", + "value": { + "x": 46.5625, + "y": 21.666666666666668, + "width": 8.75, + "height": 12.083333333333334, + "rotation": 0, + "rectanglelabels": ["Car"] + }, + "to_name": "image", + "from_name": "label", + "image_rotation": 0, + "original_width": 320, + "original_height": 240 + }, { + "id": "KRa8jEvpK0", + "type": "rectanglelabels", + "value": { + "x": 66.875, + "y": 22.5, + "width": 14.0625, + "height": 17.5, + "rotation": 0, + "rectanglelabels": ["Car"] + }, + "to_name": "image", + "from_name": "label", + "image_rotation": 0, + "original_width": 320, + "original_height": 240 + }, { + "id": "kAKaSxNnvH", + "type": "rectanglelabels", + "value": { + "x": 93.4375, + "y": 22.916666666666668, + "width": 6.5625, + "height": 18.75, + "rotation": 0, + "rectanglelabels": ["Car"] + }, + "to_name": "image", + "from_name": "label", + "image_rotation": 0, + "original_width": 320, + "original_height": 240 + }, { + "id": "_VXKV2nz14", + "type": "rectanglelabels", + "value": { + "x": 0, + "y": 39.583333333333336, + "width": 100, + "height": 60.416666666666664, + "rotation": 0, + "rectanglelabels": ["Road"] + }, + "to_name": "image", + "from_name": "label", + "image_rotation": 0, + "original_width": 320, + "original_height": 240 + }, { + "id": "vCuvi_jLHn", + "type": "rectanglelabels", + "value": { + "x": 0, + "y": 17.5, + "width": 48.125, + "height": 41.66666666666666, + "rotation": 0, + "rectanglelabels": ["Obstacle"] + }, + "to_name": "image", + "from_name": "label", + "image_rotation": 0, + "original_width": 320, + "original_height": 240 + } + ], + "was_cancelled": False, + "ground_truth": False, + "prediction": {}, + "result_count": 0, + "task": 191 + }], + "file_upload": "Highway20030201_1002591.jpg", + "data": { + "image": "/data/upload/Highway20030201_1002591.jpg" + }, + "meta": {}, + "created_at": "2021-05-12T18:43:41.241095Z", + "updated_at": "2021-05-12T19:42:28.156609Z", + "project": 7 + }] + ds = LabelStudioDataSource._load_json_data(data=data, data_folder=".", multi_label=False) + assert ds[3] == set(["image"]) + assert ds[2] == set(["Road", "Car", "Obstacle"]) + assert len(ds[1]) == 0 + assert len(ds[0]) == 5 + ds_multi = LabelStudioDataSource._load_json_data(data=data, data_folder=".", multi_label=True) + assert ds_multi[3] == set(["image"]) + assert ds_multi[2] == set(["Road", "Car", "Obstacle"]) + assert len(ds_multi[1]) == 0 + assert len(ds_multi[0]) == 5 From ba560c728d4b10c599b7750e95684a85e93669b0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 30 Aug 2021 09:26:40 +0000 Subject: [PATCH 20/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../labelstudio/test_labelstudio.py | 222 +++++++++--------- 1 file changed, 112 insertions(+), 110 deletions(-) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 184bac6dc6..c40e3c11ca 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -2,120 +2,122 @@ def test_utility_load(): - data = [{ - "id": 191, - "annotations": [{ - "id": 130, - "completed_by": { - "id": 1, - "email": "test@heartex.com", - "first_name": "", - "last_name": "" - }, - "result": [{ - "id": "dv1Tn-zdez", - "type": "rectanglelabels", - "value": { - "x": 46.5625, - "y": 21.666666666666668, - "width": 8.75, - "height": 12.083333333333334, - "rotation": 0, - "rectanglelabels": ["Car"] - }, - "to_name": "image", - "from_name": "label", - "image_rotation": 0, - "original_width": 320, - "original_height": 240 - }, { - "id": "KRa8jEvpK0", - "type": "rectanglelabels", - "value": { - "x": 66.875, - "y": 22.5, - "width": 14.0625, - "height": 17.5, - "rotation": 0, - "rectanglelabels": ["Car"] - }, - "to_name": "image", - "from_name": "label", - "image_rotation": 0, - "original_width": 320, - "original_height": 240 - }, { - "id": "kAKaSxNnvH", - "type": "rectanglelabels", - "value": { - "x": 93.4375, - "y": 22.916666666666668, - "width": 6.5625, - "height": 18.75, - "rotation": 0, - "rectanglelabels": ["Car"] - }, - "to_name": "image", - "from_name": "label", - "image_rotation": 0, - "original_width": 320, - "original_height": 240 - }, { - "id": "_VXKV2nz14", - "type": "rectanglelabels", - "value": { - "x": 0, - "y": 39.583333333333336, - "width": 100, - "height": 60.416666666666664, - "rotation": 0, - "rectanglelabels": ["Road"] - }, - "to_name": "image", - "from_name": "label", - "image_rotation": 0, - "original_width": 320, - "original_height": 240 - }, { - "id": "vCuvi_jLHn", - "type": "rectanglelabels", - "value": { - "x": 0, - "y": 17.5, - "width": 48.125, - "height": 41.66666666666666, - "rotation": 0, - "rectanglelabels": ["Obstacle"] - }, - "to_name": "image", - "from_name": "label", - "image_rotation": 0, - "original_width": 320, - "original_height": 240 - } + data = [ + { + "id": 191, + "annotations": [ + { + "id": 130, + "completed_by": {"id": 1, "email": "test@heartex.com", "first_name": "", "last_name": ""}, + "result": [ + { + "id": "dv1Tn-zdez", + "type": "rectanglelabels", + "value": { + "x": 46.5625, + "y": 21.666666666666668, + "width": 8.75, + "height": 12.083333333333334, + "rotation": 0, + "rectanglelabels": ["Car"], + }, + "to_name": "image", + "from_name": "label", + "image_rotation": 0, + "original_width": 320, + "original_height": 240, + }, + { + "id": "KRa8jEvpK0", + "type": "rectanglelabels", + "value": { + "x": 66.875, + "y": 22.5, + "width": 14.0625, + "height": 17.5, + "rotation": 0, + "rectanglelabels": ["Car"], + }, + "to_name": "image", + "from_name": "label", + "image_rotation": 0, + "original_width": 320, + "original_height": 240, + }, + { + "id": "kAKaSxNnvH", + "type": "rectanglelabels", + "value": { + "x": 93.4375, + "y": 22.916666666666668, + "width": 6.5625, + "height": 18.75, + "rotation": 0, + "rectanglelabels": ["Car"], + }, + "to_name": "image", + "from_name": "label", + "image_rotation": 0, + "original_width": 320, + "original_height": 240, + }, + { + "id": "_VXKV2nz14", + "type": "rectanglelabels", + "value": { + "x": 0, + "y": 39.583333333333336, + "width": 100, + "height": 60.416666666666664, + "rotation": 0, + "rectanglelabels": ["Road"], + }, + "to_name": "image", + "from_name": "label", + "image_rotation": 0, + "original_width": 320, + "original_height": 240, + }, + { + "id": "vCuvi_jLHn", + "type": "rectanglelabels", + "value": { + "x": 0, + "y": 17.5, + "width": 48.125, + "height": 41.66666666666666, + "rotation": 0, + "rectanglelabels": ["Obstacle"], + }, + "to_name": "image", + "from_name": "label", + "image_rotation": 0, + "original_width": 320, + "original_height": 240, + }, + ], + "was_cancelled": False, + "ground_truth": False, + "prediction": {}, + "result_count": 0, + "task": 191, + } ], - "was_cancelled": False, - "ground_truth": False, - "prediction": {}, - "result_count": 0, - "task": 191 - }], - "file_upload": "Highway20030201_1002591.jpg", - "data": { - "image": "/data/upload/Highway20030201_1002591.jpg" - }, - "meta": {}, - "created_at": "2021-05-12T18:43:41.241095Z", - "updated_at": "2021-05-12T19:42:28.156609Z", - "project": 7 - }] + "file_upload": "Highway20030201_1002591.jpg", + "data": {"image": "/data/upload/Highway20030201_1002591.jpg"}, + "meta": {}, + "created_at": "2021-05-12T18:43:41.241095Z", + "updated_at": "2021-05-12T19:42:28.156609Z", + "project": 7, + } + ] ds = LabelStudioDataSource._load_json_data(data=data, data_folder=".", multi_label=False) - assert ds[3] == set(["image"]) - assert ds[2] == set(["Road", "Car", "Obstacle"]) + assert ds[3] == {"image"} + assert ds[2] == {"Road", "Car", "Obstacle"} assert len(ds[1]) == 0 assert len(ds[0]) == 5 ds_multi = LabelStudioDataSource._load_json_data(data=data, data_folder=".", multi_label=True) - assert ds_multi[3] == set(["image"]) - assert ds_multi[2] == set(["Road", "Car", "Obstacle"]) + assert ds_multi[3] == {"image"} + assert ds_multi[2] == {"Road", "Car", "Obstacle"} assert len(ds_multi[1]) == 0 assert len(ds_multi[0]) == 5 From 19fe4a88ef02a4fa8be0150125b4f0ba554fe109 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Mon, 30 Aug 2021 13:09:17 +0300 Subject: [PATCH 21/53] Fix DeepSource analysis issues --- flash/core/integrations/labelstudio/data_source.py | 7 ++----- tests/core/integrations/labelstudio/test_labelstudio.py | 3 +++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/flash/core/integrations/labelstudio/data_source.py b/flash/core/integrations/labelstudio/data_source.py index 4842435c61..d4b5c59909 100644 --- a/flash/core/integrations/labelstudio/data_source.py +++ b/flash/core/integrations/labelstudio/data_source.py @@ -53,17 +53,14 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - # splitting result to train and val sets if self.split: import random - random.shuffle(results) prop = int(len(results) * self.split) self.val_results = results[:prop] self.results = results[prop:] self.test_results = test_results return self.results - else: - return results + test_results - else: - return [] + return results + test_results + return [] def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: """Load 1 sample from dataset.""" diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index c40e3c11ca..0b4e054d5e 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -2,6 +2,9 @@ def test_utility_load(): + """ + Test for label studio json loader + """ data = [ { "id": 191, From 7b44ea18ce2d7120274a7eea04c7d889861e7ffb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 30 Aug 2021 10:07:05 +0000 Subject: [PATCH 22/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- flash/core/integrations/labelstudio/data_source.py | 1 + tests/core/integrations/labelstudio/test_labelstudio.py | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/flash/core/integrations/labelstudio/data_source.py b/flash/core/integrations/labelstudio/data_source.py index d4b5c59909..df398d34be 100644 --- a/flash/core/integrations/labelstudio/data_source.py +++ b/flash/core/integrations/labelstudio/data_source.py @@ -53,6 +53,7 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - # splitting result to train and val sets if self.split: import random + random.shuffle(results) prop = int(len(results) * self.split) self.val_results = results[:prop] diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 0b4e054d5e..c6488bd894 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -2,9 +2,7 @@ def test_utility_load(): - """ - Test for label studio json loader - """ + """Test for label studio json loader.""" data = [ { "id": 191, From 3c117f01e7294db2fa9f2e80cb3c8d7696fc6612 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Wed, 8 Sep 2021 16:26:39 +0300 Subject: [PATCH 23/53] Adding test for each Label Studio datasource --- .../integrations/labelstudio/data_source.py | 15 +-- .../labelstudio/test_labelstudio.py | 127 +++++++++++++++++- 2 files changed, 132 insertions(+), 10 deletions(-) diff --git a/flash/core/integrations/labelstudio/data_source.py b/flash/core/integrations/labelstudio/data_source.py index df398d34be..4ceff109a8 100644 --- a/flash/core/integrations/labelstudio/data_source.py +++ b/flash/core/integrations/labelstudio/data_source.py @@ -1,6 +1,5 @@ import json import os -from copy import deepcopy from typing import Any, Mapping, Optional, Sequence, TypeVar, Union import torch @@ -66,15 +65,13 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: """Load 1 sample from dataset.""" # all other data types - input_data = deepcopy(sample) - try: - del input_data["label"] - except KeyError: - # no label in input data - pass + # separate label from data + label = self._get_labels_from_sample(sample["label"]) + # delete label from input data + del sample["label"] result = { - DefaultDataKeys.INPUT: input_data, - DefaultDataKeys.TARGET: self._get_labels_from_sample(sample["label"]), + DefaultDataKeys.INPUT: sample, + DefaultDataKeys.TARGET: label, } return result diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index c6488bd894..12cb1fe4e0 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -1,4 +1,12 @@ -from flash.core.integrations.labelstudio.data_source import LabelStudioDataSource +from flash.text.classification.data import TextClassificationData + +from flash.video.classification.data import VideoClassificationPreprocess, VideoClassificationData + +from data.data_source import DefaultDataSources +from flash.core.integrations.labelstudio.data_source import LabelStudioDataSource, \ + LabelStudioImageClassificationDataSource, LabelStudioTextClassificationDataSource +from flash.core.data.utils import download_data +from image import ImageClassificationData def test_utility_load(): @@ -122,3 +130,120 @@ def test_utility_load(): assert ds_multi[2] == {"Road", "Car", "Obstacle"} assert len(ds_multi[1]) == 0 assert len(ds_multi[0]) == 5 + + +def test_datasource_labelstudio(): + """ + Test creation of LabelStudioDataSource + """ + download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") + ds = LabelStudioDataSource() + data = { + "data_folder": "data/upload/", + "export_json": "data/project.json", + "split": 0.2, + "multi_label": False, + } + train, val, test, predict = ds.to_datasets(train_data=data) + sample = train[0] + assert sample + ds_no_split = LabelStudioDatsaSource() + data = { + "data_folder": "data/upload/", + "export_json": "data/project.json", + "multi_label": True, + } + train, val, test, predict = ds_no_split.to_datasets(train_data=data) + sample = train[0] + assert sample + + +def test_datasource_labelstudio_image(): + """ + Test creation of LabelStudioImageClassificationDataSource and Datamodule from images + """ + download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") + + data = { + "data_folder": "data/upload/", + "export_json": "data/project.json", + "split": 0.2, + "multi_label": False, + } + ds = LabelStudioImageClassificationDataSource() + train, val, test, predict = ds.to_datasets(train_data=data, val_data=data, test_data=data, predict_data=data) + train_sample = train[0] + val_sample = val[0] + test_sample = test[0] + predict_sample = predict[0] + assert train_sample + assert val_sample + assert test_sample + assert predict_sample + + datamodule = ImageClassificationData.from_labelstudio( + export_json="data/project.json", + data_folder="data/upload/", + val_split=0.5, + ) + assert datamodule + + +def test_datasource_labelstudio_text(): + """ + Test creation of LabelStudioTextClassificationDataSource and Datamodule from text + """ + download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/text_data.zip", "./data/") + backbone = "prajjwal1/bert-medium" + data = { + "data_folder": "data/upload/", + "export_json": "data/project.json", + "split": 0.2, + "multi_label": False, + } + ds = LabelStudioTextClassificationDataSource(backbone=backbone) + train, val, test, predict = ds.to_datasets(train_data=data, test_data=data) + train_sample = train[0] + test_sample = test[0] + val_sample = val[0] + + assert train_sample + assert test_sample + assert val_sample + + datamodule = TextClassificationData.from_labelstudio( + export_json="data/project.json", + val_split=0.2, + backbone=backbone, + ) + assert datamodule + + +def test_datasource_labelstudio_video(): + """ + Test creation of Datamodule from video + """ + download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/video_data.zip") + + data = { + "data_folder": "data/upload/", + "export_json": "data/project.json", + "multi_label": True + } + preprocess = VideoClassificationPreprocess() + ds = preprocess.data_source_of_name(DefaultDataSources.LABELSTUDIO) + + train, val, test, predict = ds.to_datasets(train_data=data, test_data=data) + + assert train + assert test + + datamodule = VideoClassificationData.from_labelstudio( + export_json="data/project.json", + data_folder="data/upload/", + val_split=0.2, + clip_sampler="uniform", + clip_duration=1, + decode_audio=False, + ) + assert datamodule From 23b6d7ea7adbc945766b58ce359504f11097f7e6 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Wed, 8 Sep 2021 17:02:12 +0300 Subject: [PATCH 24/53] Fixing typo and grouping import --- tests/core/integrations/labelstudio/test_labelstudio.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 12cb1fe4e0..f26fbc7944 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -3,8 +3,11 @@ from flash.video.classification.data import VideoClassificationPreprocess, VideoClassificationData from data.data_source import DefaultDataSources -from flash.core.integrations.labelstudio.data_source import LabelStudioDataSource, \ - LabelStudioImageClassificationDataSource, LabelStudioTextClassificationDataSource +from flash.core.integrations.labelstudio.data_source import ( + LabelStudioDataSource, + LabelStudioImageClassificationDataSource, + LabelStudioTextClassificationDataSource, +) from flash.core.data.utils import download_data from image import ImageClassificationData @@ -147,7 +150,7 @@ def test_datasource_labelstudio(): train, val, test, predict = ds.to_datasets(train_data=data) sample = train[0] assert sample - ds_no_split = LabelStudioDatsaSource() + ds_no_split = LabelStudioDataSource() data = { "data_folder": "data/upload/", "export_json": "data/project.json", From 4964a6c5a420546c9c013cb9d3da7ece12c7b937 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 8 Sep 2021 16:33:58 +0000 Subject: [PATCH 25/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- flash/image/classification/data.py | 2 +- flash/text/classification/data.py | 2 +- .../labelstudio/test_labelstudio.py | 33 ++++++------------- 3 files changed, 12 insertions(+), 25 deletions(-) diff --git a/flash/image/classification/data.py b/flash/image/classification/data.py index 04e21aab03..a482cc0e53 100644 --- a/flash/image/classification/data.py +++ b/flash/image/classification/data.py @@ -24,6 +24,7 @@ from flash.core.data.data_module import DataModule from flash.core.data.data_source import DefaultDataKeys, DefaultDataSources, LoaderDataFrameDataSource from flash.core.data.process import Deserializer, Preprocess +from flash.core.integrations.labelstudio.data_source import LabelStudioImageClassificationDataSource from flash.core.utilities.imports import _MATPLOTLIB_AVAILABLE, Image, requires from flash.image.classification.transforms import default_transforms, train_default_transforms from flash.image.data import ( @@ -34,7 +35,6 @@ ImagePathsDataSource, ImageTensorDataSource, ) -from flash.core.integrations.labelstudio.data_source import LabelStudioImageClassificationDataSource if _MATPLOTLIB_AVAILABLE: import matplotlib.pyplot as plt diff --git a/flash/text/classification/data.py b/flash/text/classification/data.py index 9b4ed65150..a7171af128 100644 --- a/flash/text/classification/data.py +++ b/flash/text/classification/data.py @@ -22,8 +22,8 @@ from flash.core.data.data_module import DataModule from flash.core.data.data_source import DataSource, DefaultDataSources, LabelsState from flash.core.data.process import Deserializer, Postprocess, Preprocess -from flash.core.utilities.imports import _TEXT_AVAILABLE, requires from flash.core.integrations.labelstudio.data_source import LabelStudioTextClassificationDataSource +from flash.core.utilities.imports import _TEXT_AVAILABLE, requires if _TEXT_AVAILABLE: from datasets import DatasetDict, load_dataset diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index f26fbc7944..37bab1e685 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -1,15 +1,14 @@ -from flash.text.classification.data import TextClassificationData - -from flash.video.classification.data import VideoClassificationPreprocess, VideoClassificationData - from data.data_source import DefaultDataSources +from image import ImageClassificationData + +from flash.core.data.utils import download_data from flash.core.integrations.labelstudio.data_source import ( LabelStudioDataSource, LabelStudioImageClassificationDataSource, LabelStudioTextClassificationDataSource, ) -from flash.core.data.utils import download_data -from image import ImageClassificationData +from flash.text.classification.data import TextClassificationData +from flash.video.classification.data import VideoClassificationData, VideoClassificationPreprocess def test_utility_load(): @@ -136,9 +135,7 @@ def test_utility_load(): def test_datasource_labelstudio(): - """ - Test creation of LabelStudioDataSource - """ + """Test creation of LabelStudioDataSource.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") ds = LabelStudioDataSource() data = { @@ -162,9 +159,7 @@ def test_datasource_labelstudio(): def test_datasource_labelstudio_image(): - """ - Test creation of LabelStudioImageClassificationDataSource and Datamodule from images - """ + """Test creation of LabelStudioImageClassificationDataSource and Datamodule from images.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") data = { @@ -193,9 +188,7 @@ def test_datasource_labelstudio_image(): def test_datasource_labelstudio_text(): - """ - Test creation of LabelStudioTextClassificationDataSource and Datamodule from text - """ + """Test creation of LabelStudioTextClassificationDataSource and Datamodule from text.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/text_data.zip", "./data/") backbone = "prajjwal1/bert-medium" data = { @@ -223,16 +216,10 @@ def test_datasource_labelstudio_text(): def test_datasource_labelstudio_video(): - """ - Test creation of Datamodule from video - """ + """Test creation of Datamodule from video.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/video_data.zip") - data = { - "data_folder": "data/upload/", - "export_json": "data/project.json", - "multi_label": True - } + data = {"data_folder": "data/upload/", "export_json": "data/project.json", "multi_label": True} preprocess = VideoClassificationPreprocess() ds = preprocess.data_source_of_name(DefaultDataSources.LABELSTUDIO) From 55b1345d95bfe48da8a053c2ffcb9c590dd5f0ce Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Wed, 8 Sep 2021 21:32:33 +0300 Subject: [PATCH 26/53] Fix import for DefaultDataSources --- tests/core/integrations/labelstudio/test_labelstudio.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 37bab1e685..3c89994e4b 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -1,6 +1,5 @@ -from data.data_source import DefaultDataSources +from flash.core.data.data_source import DefaultDataSources from image import ImageClassificationData - from flash.core.data.utils import download_data from flash.core.integrations.labelstudio.data_source import ( LabelStudioDataSource, From e41151de626de6e21d3d35c2fae51fcea4c77c72 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 8 Sep 2021 18:31:26 +0000 Subject: [PATCH 27/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/core/integrations/labelstudio/test_labelstudio.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 3c89994e4b..f570b9c095 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -1,5 +1,6 @@ -from flash.core.data.data_source import DefaultDataSources from image import ImageClassificationData + +from flash.core.data.data_source import DefaultDataSources from flash.core.data.utils import download_data from flash.core.integrations.labelstudio.data_source import ( LabelStudioDataSource, From c5c11d7121e80e3e6ef29ec9dfcf2e2827637466 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Wed, 8 Sep 2021 21:45:50 +0300 Subject: [PATCH 28/53] Fix import for ImageClassificationData --- tests/core/integrations/labelstudio/test_labelstudio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index f570b9c095..454288a876 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -1,4 +1,4 @@ -from image import ImageClassificationData +from flash.image.classification.data import ImageClassificationData from flash.core.data.data_source import DefaultDataSources from flash.core.data.utils import download_data From ea2e474647f1e872660b9c608c55be0062bde850 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 8 Sep 2021 18:43:37 +0000 Subject: [PATCH 29/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/core/integrations/labelstudio/test_labelstudio.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 454288a876..64571075a1 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -1,5 +1,3 @@ -from flash.image.classification.data import ImageClassificationData - from flash.core.data.data_source import DefaultDataSources from flash.core.data.utils import download_data from flash.core.integrations.labelstudio.data_source import ( @@ -7,6 +5,7 @@ LabelStudioImageClassificationDataSource, LabelStudioTextClassificationDataSource, ) +from flash.image.classification.data import ImageClassificationData from flash.text.classification.data import TextClassificationData from flash.video.classification.data import VideoClassificationData, VideoClassificationPreprocess From a940f6f76adab985f1ea4799499ba99d696cd8cb Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Thu, 9 Sep 2021 11:25:32 +0300 Subject: [PATCH 30/53] Fix tests conditions --- .../core/integrations/labelstudio/test_labelstudio.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 64571075a1..1da3fd0041 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -1,3 +1,4 @@ +import pytest from flash.core.data.data_source import DefaultDataSources from flash.core.data.utils import download_data from flash.core.integrations.labelstudio.data_source import ( @@ -8,7 +9,11 @@ from flash.image.classification.data import ImageClassificationData from flash.text.classification.data import TextClassificationData from flash.video.classification.data import VideoClassificationData, VideoClassificationPreprocess - +from tests.helpers.utils import ( + _VIDEO_TESTING, + _TEXT_TESTING, + _IMAGE_TESTING, +) def test_utility_load(): """Test for label studio json loader.""" @@ -157,6 +162,7 @@ def test_datasource_labelstudio(): assert sample +@pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") def test_datasource_labelstudio_image(): """Test creation of LabelStudioImageClassificationDataSource and Datamodule from images.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") @@ -186,6 +192,7 @@ def test_datasource_labelstudio_image(): assert datamodule +@pytest.mark.skipif(not _TEXT_TESTING, reason="text libraries aren't installed.") def test_datasource_labelstudio_text(): """Test creation of LabelStudioTextClassificationDataSource and Datamodule from text.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/text_data.zip", "./data/") @@ -214,6 +221,7 @@ def test_datasource_labelstudio_text(): assert datamodule +@pytest.mark.skipif(not _VIDEO_TESTING, reason="PyTorchVideo isn't installed.") def test_datasource_labelstudio_video(): """Test creation of Datamodule from video.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/video_data.zip") From 0cc7bd9a3b8061a6e450a26bfa6419be9f13386a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Sep 2021 08:23:18 +0000 Subject: [PATCH 31/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/core/integrations/labelstudio/test_labelstudio.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 1da3fd0041..11e17329cc 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -1,4 +1,5 @@ import pytest + from flash.core.data.data_source import DefaultDataSources from flash.core.data.utils import download_data from flash.core.integrations.labelstudio.data_source import ( @@ -9,11 +10,8 @@ from flash.image.classification.data import ImageClassificationData from flash.text.classification.data import TextClassificationData from flash.video.classification.data import VideoClassificationData, VideoClassificationPreprocess -from tests.helpers.utils import ( - _VIDEO_TESTING, - _TEXT_TESTING, - _IMAGE_TESTING, -) +from tests.helpers.utils import _IMAGE_TESTING, _TEXT_TESTING, _VIDEO_TESTING + def test_utility_load(): """Test for label studio json loader.""" From a3066d838fdc4d6e7e5338daf31a12699c2b00ba Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Thu, 9 Sep 2021 11:47:24 +0300 Subject: [PATCH 32/53] Fix data sources prerequisite --- flash/core/integrations/labelstudio/data_source.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/flash/core/integrations/labelstudio/data_source.py b/flash/core/integrations/labelstudio/data_source.py index 4ceff109a8..158116cd13 100644 --- a/flash/core/integrations/labelstudio/data_source.py +++ b/flash/core/integrations/labelstudio/data_source.py @@ -9,9 +9,13 @@ from flash import DataSource from flash.core.data.auto_dataset import AutoDataset, IterableAutoDataset from flash.core.data.data_source import DefaultDataKeys, has_len -from flash.core.utilities.imports import _PYTORCHVIDEO_AVAILABLE, _TEXT_AVAILABLE +from flash.core.utilities.imports import ( + _TORCHVISION_AVAILABLE, + _TEXT_AVAILABLE, + _PYTORCHVIDEO_AVAILABLE, +) -if _PYTORCHVIDEO_AVAILABLE: +if _TORCHVISION_AVAILABLE: from torchvision.datasets.folder import default_loader DATA_TYPE = TypeVar("DATA_TYPE") @@ -215,6 +219,8 @@ class LabelStudioVideoClassificationDataSource(LabelStudioDataSource): Export data should point to video files""" def __init__(self, video_sampler=None, clip_sampler=None, decode_audio=False, decoder: str = "pyav"): + if not _PYTORCHVIDEO_AVAILABLE: + raise ModuleNotFoundError("Please, run `pip install pytorchvideo`.") super().__init__() self.video_sampler = video_sampler or torch.utils.data.RandomSampler self.clip_sampler = clip_sampler From f59a1faf537e05640221813da1c00687ff793430 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Sep 2021 08:45:08 +0000 Subject: [PATCH 33/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- flash/core/integrations/labelstudio/data_source.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/flash/core/integrations/labelstudio/data_source.py b/flash/core/integrations/labelstudio/data_source.py index 158116cd13..6de9fffa5a 100644 --- a/flash/core/integrations/labelstudio/data_source.py +++ b/flash/core/integrations/labelstudio/data_source.py @@ -9,11 +9,7 @@ from flash import DataSource from flash.core.data.auto_dataset import AutoDataset, IterableAutoDataset from flash.core.data.data_source import DefaultDataKeys, has_len -from flash.core.utilities.imports import ( - _TORCHVISION_AVAILABLE, - _TEXT_AVAILABLE, - _PYTORCHVIDEO_AVAILABLE, -) +from flash.core.utilities.imports import _PYTORCHVIDEO_AVAILABLE, _TEXT_AVAILABLE, _TORCHVISION_AVAILABLE if _TORCHVISION_AVAILABLE: from torchvision.datasets.folder import default_loader From 119593e873a1ade4eaf45fcc20e1e8bd40bc0b6f Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Thu, 9 Sep 2021 15:11:34 +0300 Subject: [PATCH 34/53] Separating tests for Datamodule --- .../integrations/labelstudio/data_source.py | 1 - .../labelstudio/test_labelstudio.py | 44 ++++++++++++++----- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/flash/core/integrations/labelstudio/data_source.py b/flash/core/integrations/labelstudio/data_source.py index 6de9fffa5a..1be1ec9230 100644 --- a/flash/core/integrations/labelstudio/data_source.py +++ b/flash/core/integrations/labelstudio/data_source.py @@ -52,7 +52,6 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - # splitting result to train and val sets if self.split: import random - random.shuffle(results) prop = int(len(results) * self.split) self.val_results = results[:prop] diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 11e17329cc..a58c5be6ac 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -162,7 +162,7 @@ def test_datasource_labelstudio(): @pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") def test_datasource_labelstudio_image(): - """Test creation of LabelStudioImageClassificationDataSource and Datamodule from images.""" + """Test creation of LabelStudioImageClassificationDataSource from images.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") data = { @@ -182,14 +182,21 @@ def test_datasource_labelstudio_image(): assert test_sample assert predict_sample + +@pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") +def test_datamodule_labelstudio_image(): + """Test creation of LabelStudioImageClassificationDataSource and Datamodule from images.""" + download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") + datamodule = ImageClassificationData.from_labelstudio( - export_json="data/project.json", - data_folder="data/upload/", + train_export_json="data/project.json", + train_data_folder="data/upload/", + test_export_json="data/project.json", + test_data_folder="data/upload/", val_split=0.5, ) assert datamodule - @pytest.mark.skipif(not _TEXT_TESTING, reason="text libraries aren't installed.") def test_datasource_labelstudio_text(): """Test creation of LabelStudioTextClassificationDataSource and Datamodule from text.""" @@ -206,14 +213,25 @@ def test_datasource_labelstudio_text(): train_sample = train[0] test_sample = test[0] val_sample = val[0] - assert train_sample assert test_sample assert val_sample + assert not predict + +@pytest.mark.skipif(not _TEXT_TESTING, reason="text libraries aren't installed.") +def test_datamodule_labelstudio_text(): + """Test creation of LabelStudioTextClassificationDataSource and Datamodule from text.""" + download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/text_data.zip", + "./data/") + backbone = "prajjwal1/bert-medium" datamodule = TextClassificationData.from_labelstudio( - export_json="data/project.json", - val_split=0.2, + train_export_json="data/project.json", + val_export_json="data/project.json", + test_export_json="data/project.json", + predict_export_json="data/project.json", + data_folder="data/upload/", + val_split=0.8, backbone=backbone, ) assert datamodule @@ -221,18 +239,22 @@ def test_datasource_labelstudio_text(): @pytest.mark.skipif(not _VIDEO_TESTING, reason="PyTorchVideo isn't installed.") def test_datasource_labelstudio_video(): - """Test creation of Datamodule from video.""" + """Test creation of LabelStudioVideoClassificationDataSource from video.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/video_data.zip") - data = {"data_folder": "data/upload/", "export_json": "data/project.json", "multi_label": True} preprocess = VideoClassificationPreprocess() ds = preprocess.data_source_of_name(DefaultDataSources.LABELSTUDIO) - train, val, test, predict = ds.to_datasets(train_data=data, test_data=data) - assert train + assert not val assert test + assert not predict + +@pytest.mark.skipif(not _VIDEO_TESTING, reason="PyTorchVideo isn't installed.") +def test_datamodule_labelstudio_video(): + """Test creation of Datamodule from video.""" + download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/video_data.zip") datamodule = VideoClassificationData.from_labelstudio( export_json="data/project.json", data_folder="data/upload/", From 20c0c482092d7fe93411e0ab120935a055c6801c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Sep 2021 12:10:03 +0000 Subject: [PATCH 35/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- flash/core/integrations/labelstudio/data_source.py | 1 + tests/core/integrations/labelstudio/test_labelstudio.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/flash/core/integrations/labelstudio/data_source.py b/flash/core/integrations/labelstudio/data_source.py index 1be1ec9230..6de9fffa5a 100644 --- a/flash/core/integrations/labelstudio/data_source.py +++ b/flash/core/integrations/labelstudio/data_source.py @@ -52,6 +52,7 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - # splitting result to train and val sets if self.split: import random + random.shuffle(results) prop = int(len(results) * self.split) self.val_results = results[:prop] diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index a58c5be6ac..64e570b36b 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -197,6 +197,7 @@ def test_datamodule_labelstudio_image(): ) assert datamodule + @pytest.mark.skipif(not _TEXT_TESTING, reason="text libraries aren't installed.") def test_datasource_labelstudio_text(): """Test creation of LabelStudioTextClassificationDataSource and Datamodule from text.""" @@ -222,8 +223,7 @@ def test_datasource_labelstudio_text(): @pytest.mark.skipif(not _TEXT_TESTING, reason="text libraries aren't installed.") def test_datamodule_labelstudio_text(): """Test creation of LabelStudioTextClassificationDataSource and Datamodule from text.""" - download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/text_data.zip", - "./data/") + download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/text_data.zip", "./data/") backbone = "prajjwal1/bert-medium" datamodule = TextClassificationData.from_labelstudio( train_export_json="data/project.json", From 28c51ee92fd5341bb0b88fa8d0f440e2f613a501 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Thu, 9 Sep 2021 18:37:45 +0300 Subject: [PATCH 36/53] Fixing link to file for image data sets --- .../integrations/labelstudio/data_source.py | 21 ++++++++++++------- .../labelstudio/test_labelstudio.py | 16 +++++++++----- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/flash/core/integrations/labelstudio/data_source.py b/flash/core/integrations/labelstudio/data_source.py index 6de9fffa5a..ee18ebeed1 100644 --- a/flash/core/integrations/labelstudio/data_source.py +++ b/flash/core/integrations/labelstudio/data_source.py @@ -1,5 +1,6 @@ import json import os +from pathlib import Path from typing import Any, Mapping, Optional, Sequence, TypeVar, Union import torch @@ -132,9 +133,14 @@ def _load_json_data(data, data_folder, multi_label=False): classes.add(sublabel) temp = {} temp["file_upload"] = task.get("file_upload") + temp["data"] = task.get("data") if temp["file_upload"]: temp["file_upload"] = os.path.join(data_folder, temp["file_upload"]) - temp["data"] = task.get("data") + else: + for key in temp["data"]: + p = temp["data"].get(key) + path = Path(p) + temp["file_upload"] = os.path.join(data_folder, path.name) temp["label"] = sublabel temp["result"] = res.get("value") if annotation["ground_truth"]: @@ -149,9 +155,14 @@ def _load_json_data(data, data_folder, multi_label=False): classes.add(label) temp = {} temp["file_upload"] = task.get("file_upload") + temp["data"] = task.get("data") if temp["file_upload"] and data_folder: temp["file_upload"] = os.path.join(data_folder, temp["file_upload"]) - temp["data"] = task.get("data") + else: + for key in temp["data"]: + p = temp["data"].get(key) + path = Path(p) + temp["file_upload"] = os.path.join(data_folder, path.name) temp["label"] = label temp["result"] = res.get("value") if annotation["ground_truth"]: @@ -168,11 +179,7 @@ class LabelStudioImageClassificationDataSource(LabelStudioDataSource): def load_sample(self, sample: Mapping[str, Any] = None, dataset: Optional[Any] = None) -> Any: """Load 1 sample from dataset.""" - if sample["file_upload"]: - p = sample["file_upload"] - else: - for key in sample.get("data"): - p = sample.get("data").get(key) + p = sample["file_upload"] # loading image image = default_loader(p) result = {DefaultDataKeys.INPUT: image, DefaultDataKeys.TARGET: self._get_labels_from_sample(sample["label"])} diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 64e570b36b..2a0690a5d6 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -147,8 +147,12 @@ def test_datasource_labelstudio(): "multi_label": False, } train, val, test, predict = ds.to_datasets(train_data=data) - sample = train[0] - assert sample + train_sample = train[0] + val_sample = val[0] + assert train_sample + assert val_sample + assert not test + assert not predict ds_no_split = LabelStudioDataSource() data = { "data_folder": "data/upload/", @@ -160,16 +164,16 @@ def test_datasource_labelstudio(): assert sample -@pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") +#@pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") def test_datasource_labelstudio_image(): """Test creation of LabelStudioImageClassificationDataSource from images.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") data = { "data_folder": "data/upload/", - "export_json": "data/project.json", + "export_json": "data/project_nofile.json", "split": 0.2, - "multi_label": False, + "multi_label": True, } ds = LabelStudioImageClassificationDataSource() train, val, test, predict = ds.to_datasets(train_data=data, val_data=data, test_data=data, predict_data=data) @@ -245,10 +249,12 @@ def test_datasource_labelstudio_video(): preprocess = VideoClassificationPreprocess() ds = preprocess.data_source_of_name(DefaultDataSources.LABELSTUDIO) train, val, test, predict = ds.to_datasets(train_data=data, test_data=data) + sample = train[0] assert train assert not val assert test assert not predict + assert sample @pytest.mark.skipif(not _VIDEO_TESTING, reason="PyTorchVideo isn't installed.") From a46140b7d9287df89e8cc382e3dd4da710657f07 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Sep 2021 15:35:46 +0000 Subject: [PATCH 37/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/core/integrations/labelstudio/test_labelstudio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 2a0690a5d6..3647905c4d 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -164,7 +164,7 @@ def test_datasource_labelstudio(): assert sample -#@pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") +# @pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") def test_datasource_labelstudio_image(): """Test creation of LabelStudioImageClassificationDataSource from images.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") From 466bd6961f7c2c51bbe39fade1a272c475b1044e Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Thu, 9 Sep 2021 19:13:08 +0300 Subject: [PATCH 38/53] Fix LabelStudioImageClassificationDataSource test --- tests/core/integrations/labelstudio/test_labelstudio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 3647905c4d..0be85391f5 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -164,7 +164,7 @@ def test_datasource_labelstudio(): assert sample -# @pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") +@pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") def test_datasource_labelstudio_image(): """Test creation of LabelStudioImageClassificationDataSource from images.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") From 18ae7939f2ecf2fa82529b29f6ea9a2300b94cd8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Sep 2021 17:06:13 +0000 Subject: [PATCH 39/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- flash/core/integrations/labelstudio/app.py | 14 +++++++------- .../labelstudio/image_classification.py | 6 +++--- .../labelstudio/text_classification.py | 8 ++++---- .../labelstudio/video_classification.py | 6 +++--- .../integrations/labelstudio/test_labelstudio.py | 7 +++---- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/flash/core/integrations/labelstudio/app.py b/flash/core/integrations/labelstudio/app.py index 530ec88044..af922e3cbe 100644 --- a/flash/core/integrations/labelstudio/app.py +++ b/flash/core/integrations/labelstudio/app.py @@ -1,9 +1,11 @@ -import string import random +import string + import flash from flash.core.data.data_module import DataModule from flash.core.data.data_source import DefaultDataKeys + class App: def __init__(self, datamodule: DataModule): self.datamodule = datamodule @@ -34,16 +36,14 @@ def construct_result(self, pred): js = { "result": [ { - "id": ''.join( + "id": "".join( random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) - for _ in - range(10)), + for _ in range(10) + ), "from_name": "tag", "to_name": data_type, "type": tag_type, - "value": { - tag_type: label if isinstance(label, list) else [label] - } + "value": {tag_type: label if isinstance(label, list) else [label]}, } ] } diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py index 79acfa5654..56f8722419 100644 --- a/flash_examples/integrations/labelstudio/image_classification.py +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -1,12 +1,12 @@ +# 1 Download data +from integrations.labelstudio.app import launch_app + import flash from flash.core.classification import Labels from flash.core.data.utils import download_data from flash.core.finetuning import FreezeUnfreeze from flash.image import ImageClassificationData, ImageClassifier -# 1 Download data -from integrations.labelstudio.app import launch_app - download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") # 1. Load export data diff --git a/flash_examples/integrations/labelstudio/text_classification.py b/flash_examples/integrations/labelstudio/text_classification.py index 0eeb5b62eb..93925b4291 100644 --- a/flash_examples/integrations/labelstudio/text_classification.py +++ b/flash_examples/integrations/labelstudio/text_classification.py @@ -1,10 +1,10 @@ +# 1. Create the DataModule +from integrations.labelstudio.app import launch_app + import flash from flash.core.data.utils import download_data from flash.text import TextClassificationData, TextClassifier -# 1. Create the DataModule -from integrations.labelstudio.app import launch_app - download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/text_data.zip", "./data/") backbone = "prajjwal1/bert-medium" @@ -37,4 +37,4 @@ # 6. Visualize predictions app = launch_app(datamodule) # app.show_train_dataset() -print(app.show_predictions(predictions)) \ No newline at end of file +print(app.show_predictions(predictions)) diff --git a/flash_examples/integrations/labelstudio/video_classification.py b/flash_examples/integrations/labelstudio/video_classification.py index d9584b15ee..faad341fcb 100644 --- a/flash_examples/integrations/labelstudio/video_classification.py +++ b/flash_examples/integrations/labelstudio/video_classification.py @@ -1,12 +1,12 @@ import os +# 1 Download data +from integrations.labelstudio.app import launch_app + import flash from flash.core.data.utils import download_data from flash.video import VideoClassificationData, VideoClassifier -# 1 Download data -from integrations.labelstudio.app import launch_app - download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/video_data.zip") # 1. Load export data diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 6778c44ce1..7ccd9e8b1b 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -1,4 +1,5 @@ import pytest +from integrations.labelstudio.app import launch_app from flash.core.data.data_source import DefaultDataSources from flash.core.data.utils import download_data @@ -10,7 +11,6 @@ from flash.image.classification.data import ImageClassificationData from flash.text.classification.data import TextClassificationData from flash.video.classification.data import VideoClassificationData, VideoClassificationPreprocess -from integrations.labelstudio.app import launch_app from tests.helpers.utils import _IMAGE_TESTING, _TEXT_TESTING, _VIDEO_TESTING @@ -220,8 +220,8 @@ def test_label_studio_predictions_visualization(): predictions = [0, 1, 1, 0] vis_predictions = app.show_predictions(predictions) assert len(vis_predictions) == 4 - assert vis_predictions[0]['result'][0]['id'] != vis_predictions[3]['result'][0]['id'] - assert vis_predictions[1]['result'][0]['id'] != vis_predictions[2]['result'][0]['id'] + assert vis_predictions[0]["result"][0]["id"] != vis_predictions[3]["result"][0]["id"] + assert vis_predictions[1]["result"][0]["id"] != vis_predictions[2]["result"][0]["id"] @pytest.mark.skipif(not _TEXT_TESTING, reason="text libraries aren't installed.") @@ -292,4 +292,3 @@ def test_datamodule_labelstudio_video(): decode_audio=False, ) assert datamodule - From 77f1338fff05bcffc4a7fbda4f506bdcf79c5f4e Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Thu, 9 Sep 2021 20:08:28 +0300 Subject: [PATCH 40/53] Adding App for visualizing predictions --- flash/core/integrations/labelstudio/app.py | 54 +++++++++++++++++++ .../integrations/labelstudio/data_source.py | 14 +++-- .../labelstudio/image_classification.py | 7 ++- .../labelstudio/text_classification.py | 8 ++- .../labelstudio/video_classification.py | 7 +++ .../labelstudio/test_labelstudio.py | 23 ++++++++ 6 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 flash/core/integrations/labelstudio/app.py diff --git a/flash/core/integrations/labelstudio/app.py b/flash/core/integrations/labelstudio/app.py new file mode 100644 index 0000000000..530ec88044 --- /dev/null +++ b/flash/core/integrations/labelstudio/app.py @@ -0,0 +1,54 @@ +import string +import random +import flash +from flash.core.data.data_module import DataModule +from flash.core.data.data_source import DefaultDataKeys + +class App: + def __init__(self, datamodule: DataModule): + self.datamodule = datamodule + self._enabled = not flash._IS_TESTING + + def get_dataset(self, stage: str = "train"): + dataloader = getattr(self.datamodule, f"{stage}_dataloader")() + return dataloader.dataset + + def show_predictions(self, predictions): + results = [] + if self._enabled: + for pred in predictions: + results.append(self.construct_result(pred)) + return results + + def construct_result(self, pred): + ds = self.datamodule.data_source + # get label + if isinstance(pred, list): + label = [list(ds.classes)[p] for p in pred] + else: + label = list(ds.classes)[pred] + # get data type, if len(data_types) > 1 take first data type + data_type = list(ds.data_types)[0] + # get tag type, if len(tag_types) > 1 take first tag + tag_type = list(ds.tag_types)[0] + js = { + "result": [ + { + "id": ''.join( + random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) + for _ in + range(10)), + "from_name": "tag", + "to_name": data_type, + "type": tag_type, + "value": { + tag_type: label if isinstance(label, list) else [label] + } + } + ] + } + return js + + +def launch_app(datamodule: DataModule) -> "App": + return App(datamodule) diff --git a/flash/core/integrations/labelstudio/data_source.py b/flash/core/integrations/labelstudio/data_source.py index ee18ebeed1..5e2587f7f6 100644 --- a/flash/core/integrations/labelstudio/data_source.py +++ b/flash/core/integrations/labelstudio/data_source.py @@ -28,6 +28,7 @@ def __init__(self): self.val_results = [] self.classes = set() self.data_types = set() + self.tag_types = set() self.num_classes = 0 self._data_folder = "" self._raw_data = {} @@ -44,12 +45,13 @@ def load_data(self, data: Optional[Any] = None, dataset: Optional[Any] = None) - _raw_data = json.load(f) self.multi_label = data.get("multi_label", False) self.split = data.get("split") - results, test_results, classes, data_types = LabelStudioDataSource._load_json_data( + results, test_results, classes, data_types, tag_types = LabelStudioDataSource._load_json_data( _raw_data, data_folder=data_folder, multi_label=self.multi_label ) self.classes = self.classes | classes self.data_types = self.data_types | data_types self.num_classes = len(self.classes) + self.tag_types = self.tag_types | tag_types # splitting result to train and val sets if self.split: import random @@ -116,6 +118,7 @@ def _load_json_data(data, data_folder, multi_label=False): results = [] test_results = [] data_types = set() + tag_types = set() classes = set() for task in data: for annotation in task["annotations"]: @@ -126,6 +129,7 @@ def _load_json_data(data, data_folder, multi_label=False): result = annotation["result"] for res in result: t = res["type"] + tag_types.add(t) for label in res["value"][t]: # check if labeling result is a list of labels if isinstance(label, list) and not multi_label: @@ -140,7 +144,8 @@ def _load_json_data(data, data_folder, multi_label=False): for key in temp["data"]: p = temp["data"].get(key) path = Path(p) - temp["file_upload"] = os.path.join(data_folder, path.name) + if path and data_folder: + temp["file_upload"] = os.path.join(data_folder, path.name) temp["label"] = sublabel temp["result"] = res.get("value") if annotation["ground_truth"]: @@ -162,14 +167,15 @@ def _load_json_data(data, data_folder, multi_label=False): for key in temp["data"]: p = temp["data"].get(key) path = Path(p) - temp["file_upload"] = os.path.join(data_folder, path.name) + if path and data_folder: + temp["file_upload"] = os.path.join(data_folder, path.name) temp["label"] = label temp["result"] = res.get("value") if annotation["ground_truth"]: test_results.append(temp) elif not annotation["ground_truth"]: results.append(temp) - return results, test_results, classes, data_types + return results, test_results, classes, data_types, tag_types class LabelStudioImageClassificationDataSource(LabelStudioDataSource): diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py index 5fb6de2a21..79acfa5654 100644 --- a/flash_examples/integrations/labelstudio/image_classification.py +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -5,6 +5,8 @@ from flash.image import ImageClassificationData, ImageClassifier # 1 Download data +from integrations.labelstudio.app import launch_app + download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") # 1. Load export data @@ -39,4 +41,7 @@ ] ) -print(predictions) +# 4. Visualize predictions +app = launch_app(datamodule) +# app.show_train_dataset() +print(app.show_predictions(predictions)) diff --git a/flash_examples/integrations/labelstudio/text_classification.py b/flash_examples/integrations/labelstudio/text_classification.py index 706cfd2416..0eeb5b62eb 100644 --- a/flash_examples/integrations/labelstudio/text_classification.py +++ b/flash_examples/integrations/labelstudio/text_classification.py @@ -3,6 +3,8 @@ from flash.text import TextClassificationData, TextClassifier # 1. Create the DataModule +from integrations.labelstudio.app import launch_app + download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/text_data.zip", "./data/") backbone = "prajjwal1/bert-medium" @@ -28,7 +30,11 @@ "I come from Bulgaria where it 's almost impossible to have a tornado.", ] ) -print(predictions) # 5. Save the model! trainer.save_checkpoint("text_classification_model.pt") + +# 6. Visualize predictions +app = launch_app(datamodule) +# app.show_train_dataset() +print(app.show_predictions(predictions)) \ No newline at end of file diff --git a/flash_examples/integrations/labelstudio/video_classification.py b/flash_examples/integrations/labelstudio/video_classification.py index 7a630d342b..d9584b15ee 100644 --- a/flash_examples/integrations/labelstudio/video_classification.py +++ b/flash_examples/integrations/labelstudio/video_classification.py @@ -5,6 +5,8 @@ from flash.video import VideoClassificationData, VideoClassifier # 1 Download data +from integrations.labelstudio.app import launch_app + download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/video_data.zip") # 1. Load export data @@ -33,3 +35,8 @@ # 5. Save the model! trainer.save_checkpoint("video_classification.pt") + +# 6. Visualize predictions +app = launch_app(datamodule) +# app.show_train_dataset() +print(app.show_predictions(predictions)) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 0be85391f5..6778c44ce1 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -10,6 +10,7 @@ from flash.image.classification.data import ImageClassificationData from flash.text.classification.data import TextClassificationData from flash.video.classification.data import VideoClassificationData, VideoClassificationPreprocess +from integrations.labelstudio.app import launch_app from tests.helpers.utils import _IMAGE_TESTING, _TEXT_TESTING, _VIDEO_TESTING @@ -202,6 +203,27 @@ def test_datamodule_labelstudio_image(): assert datamodule +@pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") +def test_label_studio_predictions_visualization(): + """Test creation of LabelStudioImageClassificationDataSource and Datamodule from images.""" + download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") + + datamodule = ImageClassificationData.from_labelstudio( + train_export_json="data/project.json", + train_data_folder="data/upload/", + test_export_json="data/project.json", + test_data_folder="data/upload/", + val_split=0.5, + ) + assert datamodule + app = launch_app(datamodule) + predictions = [0, 1, 1, 0] + vis_predictions = app.show_predictions(predictions) + assert len(vis_predictions) == 4 + assert vis_predictions[0]['result'][0]['id'] != vis_predictions[3]['result'][0]['id'] + assert vis_predictions[1]['result'][0]['id'] != vis_predictions[2]['result'][0]['id'] + + @pytest.mark.skipif(not _TEXT_TESTING, reason="text libraries aren't installed.") def test_datasource_labelstudio_text(): """Test creation of LabelStudioTextClassificationDataSource and Datamodule from text.""" @@ -270,3 +292,4 @@ def test_datamodule_labelstudio_video(): decode_audio=False, ) assert datamodule + From 5bf56b21275a3994a7fdd4a21afd529da0f75882 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Thu, 9 Sep 2021 20:26:20 +0300 Subject: [PATCH 41/53] Fix import for label studio launch_app --- flash/core/integrations/labelstudio/app.py | 22 ++++++++++--------- .../labelstudio/image_classification.py | 12 +++++----- .../labelstudio/text_classification.py | 4 +--- .../labelstudio/video_classification.py | 17 ++++++-------- .../labelstudio/test_labelstudio.py | 3 ++- 5 files changed, 27 insertions(+), 31 deletions(-) diff --git a/flash/core/integrations/labelstudio/app.py b/flash/core/integrations/labelstudio/app.py index 530ec88044..4d41b9bafb 100644 --- a/flash/core/integrations/labelstudio/app.py +++ b/flash/core/integrations/labelstudio/app.py @@ -1,26 +1,28 @@ import string import random -import flash from flash.core.data.data_module import DataModule -from flash.core.data.data_source import DefaultDataKeys + class App: + """ + App for visualizing predictions in Label Studio results format + """ def __init__(self, datamodule: DataModule): self.datamodule = datamodule - self._enabled = not flash._IS_TESTING - - def get_dataset(self, stage: str = "train"): - dataloader = getattr(self.datamodule, f"{stage}_dataloader")() - return dataloader.dataset def show_predictions(self, predictions): + """ + Converts predictions to Label Studio results + """ results = [] - if self._enabled: - for pred in predictions: - results.append(self.construct_result(pred)) + for pred in predictions: + results.append(self.construct_result(pred)) return results def construct_result(self, pred): + """ + Construction Label Studio result from data source and prediction values + """ ds = self.datamodule.data_source # get label if isinstance(pred, list): diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py index 79acfa5654..9992a46551 100644 --- a/flash_examples/integrations/labelstudio/image_classification.py +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -3,20 +3,19 @@ from flash.core.data.utils import download_data from flash.core.finetuning import FreezeUnfreeze from flash.image import ImageClassificationData, ImageClassifier +from flash.core.integrations.labelstudio.app import launch_app # 1 Download data -from integrations.labelstudio.app import launch_app - download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") -# 1. Load export data +# 2. Load export data datamodule = ImageClassificationData.from_labelstudio( export_json="data/project.json", data_folder="data/upload/", val_split=0.2, ) -# 2. Fine tune a model +# 3. Fine tune a model model = ImageClassifier( backbone="resnet18", num_classes=datamodule.num_classes, @@ -30,7 +29,7 @@ ) trainer.save_checkpoint("image_classification_model.pt") -# 3. Predict from checkpoint +# 4. Predict from checkpoint model = ImageClassifier.load_from_checkpoint("image_classification_model.pt") model.serializer = Labels() @@ -41,7 +40,6 @@ ] ) -# 4. Visualize predictions +# 5. Visualize predictions app = launch_app(datamodule) -# app.show_train_dataset() print(app.show_predictions(predictions)) diff --git a/flash_examples/integrations/labelstudio/text_classification.py b/flash_examples/integrations/labelstudio/text_classification.py index 0eeb5b62eb..4b6db2f24d 100644 --- a/flash_examples/integrations/labelstudio/text_classification.py +++ b/flash_examples/integrations/labelstudio/text_classification.py @@ -1,10 +1,9 @@ import flash from flash.core.data.utils import download_data from flash.text import TextClassificationData, TextClassifier +from flash.core.integrations.labelstudio.app import launch_app # 1. Create the DataModule -from integrations.labelstudio.app import launch_app - download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/text_data.zip", "./data/") backbone = "prajjwal1/bert-medium" @@ -36,5 +35,4 @@ # 6. Visualize predictions app = launch_app(datamodule) -# app.show_train_dataset() print(app.show_predictions(predictions)) \ No newline at end of file diff --git a/flash_examples/integrations/labelstudio/video_classification.py b/flash_examples/integrations/labelstudio/video_classification.py index d9584b15ee..c31c580c9d 100644 --- a/flash_examples/integrations/labelstudio/video_classification.py +++ b/flash_examples/integrations/labelstudio/video_classification.py @@ -1,15 +1,13 @@ import os - import flash from flash.core.data.utils import download_data from flash.video import VideoClassificationData, VideoClassifier +from flash.core.integrations.labelstudio.app import launch_app # 1 Download data -from integrations.labelstudio.app import launch_app - download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/video_data.zip") -# 1. Load export data +# 2. Load export data datamodule = VideoClassificationData.from_labelstudio( export_json="data/project.json", data_folder="data/upload/", @@ -19,24 +17,23 @@ decode_audio=False, ) -# 2. Build the task +# 3. Build the task model = VideoClassifier( backbone="slow_r50", num_classes=datamodule.num_classes, ) -# 3. Create the trainer and finetune the model +# 4. Create the trainer and finetune the model trainer = flash.Trainer(max_epochs=3) trainer.finetune(model, datamodule=datamodule, strategy="freeze") -# 4. Make a prediction +# 5. Make a prediction predictions = model.predict(os.path.join(os.getcwd(), "data/test")) print(predictions) -# 5. Save the model! +# 6. Save the model! trainer.save_checkpoint("video_classification.pt") -# 6. Visualize predictions +# 7. Visualize predictions app = launch_app(datamodule) -# app.show_train_dataset() print(app.show_predictions(predictions)) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 6778c44ce1..1a5a146dca 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -10,7 +10,8 @@ from flash.image.classification.data import ImageClassificationData from flash.text.classification.data import TextClassificationData from flash.video.classification.data import VideoClassificationData, VideoClassificationPreprocess -from integrations.labelstudio.app import launch_app +from flash.core.integrations.labelstudio.app import launch_app + from tests.helpers.utils import _IMAGE_TESTING, _TEXT_TESTING, _VIDEO_TESTING From c172b01a08301b561de6392092bc5b702346c31f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Sep 2021 17:30:39 +0000 Subject: [PATCH 42/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- flash/core/integrations/labelstudio/app.py | 24 +++++++------------ .../labelstudio/image_classification.py | 2 +- .../labelstudio/text_classification.py | 4 ++-- .../labelstudio/video_classification.py | 3 ++- .../labelstudio/test_labelstudio.py | 4 +--- 5 files changed, 15 insertions(+), 22 deletions(-) diff --git a/flash/core/integrations/labelstudio/app.py b/flash/core/integrations/labelstudio/app.py index 94612a2a60..57b28fada5 100644 --- a/flash/core/integrations/labelstudio/app.py +++ b/flash/core/integrations/labelstudio/app.py @@ -1,28 +1,24 @@ -import string import random +import string + from flash.core.data.data_module import DataModule class App: - """ - App for visualizing predictions in Label Studio results format - """ + """App for visualizing predictions in Label Studio results format.""" + def __init__(self, datamodule: DataModule): self.datamodule = datamodule def show_predictions(self, predictions): - """ - Converts predictions to Label Studio results - """ + """Converts predictions to Label Studio results.""" results = [] for pred in predictions: results.append(self.construct_result(pred)) return results def construct_result(self, pred): - """ - Construction Label Studio result from data source and prediction values - """ + """Construction Label Studio result from data source and prediction values.""" ds = self.datamodule.data_source # get label if isinstance(pred, list): @@ -38,14 +34,12 @@ def construct_result(self, pred): { "id": "".join( random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) - for _ in - range(10)), + for _ in range(10) + ), "from_name": "tag", "to_name": data_type, "type": tag_type, - "value": { - tag_type: label if isinstance(label, list) else [label] - } + "value": {tag_type: label if isinstance(label, list) else [label]}, } ] } diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py index 9992a46551..5781c129fe 100644 --- a/flash_examples/integrations/labelstudio/image_classification.py +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -2,8 +2,8 @@ from flash.core.classification import Labels from flash.core.data.utils import download_data from flash.core.finetuning import FreezeUnfreeze -from flash.image import ImageClassificationData, ImageClassifier from flash.core.integrations.labelstudio.app import launch_app +from flash.image import ImageClassificationData, ImageClassifier # 1 Download data download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") diff --git a/flash_examples/integrations/labelstudio/text_classification.py b/flash_examples/integrations/labelstudio/text_classification.py index 4b6db2f24d..0e8299e9d2 100644 --- a/flash_examples/integrations/labelstudio/text_classification.py +++ b/flash_examples/integrations/labelstudio/text_classification.py @@ -1,7 +1,7 @@ import flash from flash.core.data.utils import download_data -from flash.text import TextClassificationData, TextClassifier from flash.core.integrations.labelstudio.app import launch_app +from flash.text import TextClassificationData, TextClassifier # 1. Create the DataModule download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/text_data.zip", "./data/") @@ -35,4 +35,4 @@ # 6. Visualize predictions app = launch_app(datamodule) -print(app.show_predictions(predictions)) \ No newline at end of file +print(app.show_predictions(predictions)) diff --git a/flash_examples/integrations/labelstudio/video_classification.py b/flash_examples/integrations/labelstudio/video_classification.py index c31c580c9d..617f368456 100644 --- a/flash_examples/integrations/labelstudio/video_classification.py +++ b/flash_examples/integrations/labelstudio/video_classification.py @@ -1,8 +1,9 @@ import os + import flash from flash.core.data.utils import download_data -from flash.video import VideoClassificationData, VideoClassifier from flash.core.integrations.labelstudio.app import launch_app +from flash.video import VideoClassificationData, VideoClassifier # 1 Download data download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/video_data.zip") diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 1fca4f484d..1b021e31a3 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -2,6 +2,7 @@ from flash.core.data.data_source import DefaultDataSources from flash.core.data.utils import download_data +from flash.core.integrations.labelstudio.app import launch_app from flash.core.integrations.labelstudio.data_source import ( LabelStudioDataSource, LabelStudioImageClassificationDataSource, @@ -10,8 +11,6 @@ from flash.image.classification.data import ImageClassificationData from flash.text.classification.data import TextClassificationData from flash.video.classification.data import VideoClassificationData, VideoClassificationPreprocess -from flash.core.integrations.labelstudio.app import launch_app - from tests.helpers.utils import _IMAGE_TESTING, _TEXT_TESTING, _VIDEO_TESTING @@ -293,4 +292,3 @@ def test_datamodule_labelstudio_video(): decode_audio=False, ) assert datamodule - From 81fd7a74a24ebbad7c5c17d3bbb3c8cc08d605e9 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Thu, 9 Sep 2021 20:49:58 +0300 Subject: [PATCH 43/53] Rename visualizer module --- flash/core/integrations/labelstudio/{app.py => visualizer.py} | 1 - flash_examples/integrations/labelstudio/image_classification.py | 2 +- flash_examples/integrations/labelstudio/text_classification.py | 2 +- flash_examples/integrations/labelstudio/video_classification.py | 2 +- tests/core/integrations/labelstudio/test_labelstudio.py | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) rename flash/core/integrations/labelstudio/{app.py => visualizer.py} (99%) diff --git a/flash/core/integrations/labelstudio/app.py b/flash/core/integrations/labelstudio/visualizer.py similarity index 99% rename from flash/core/integrations/labelstudio/app.py rename to flash/core/integrations/labelstudio/visualizer.py index 57b28fada5..c4f75d4004 100644 --- a/flash/core/integrations/labelstudio/app.py +++ b/flash/core/integrations/labelstudio/visualizer.py @@ -6,7 +6,6 @@ class App: """App for visualizing predictions in Label Studio results format.""" - def __init__(self, datamodule: DataModule): self.datamodule = datamodule diff --git a/flash_examples/integrations/labelstudio/image_classification.py b/flash_examples/integrations/labelstudio/image_classification.py index 5781c129fe..41e3aa7332 100644 --- a/flash_examples/integrations/labelstudio/image_classification.py +++ b/flash_examples/integrations/labelstudio/image_classification.py @@ -2,7 +2,7 @@ from flash.core.classification import Labels from flash.core.data.utils import download_data from flash.core.finetuning import FreezeUnfreeze -from flash.core.integrations.labelstudio.app import launch_app +from flash.core.integrations.labelstudio.visualizer import launch_app from flash.image import ImageClassificationData, ImageClassifier # 1 Download data diff --git a/flash_examples/integrations/labelstudio/text_classification.py b/flash_examples/integrations/labelstudio/text_classification.py index 0e8299e9d2..930b75bc07 100644 --- a/flash_examples/integrations/labelstudio/text_classification.py +++ b/flash_examples/integrations/labelstudio/text_classification.py @@ -1,6 +1,6 @@ import flash from flash.core.data.utils import download_data -from flash.core.integrations.labelstudio.app import launch_app +from flash.core.integrations.labelstudio.visualizer import launch_app from flash.text import TextClassificationData, TextClassifier # 1. Create the DataModule diff --git a/flash_examples/integrations/labelstudio/video_classification.py b/flash_examples/integrations/labelstudio/video_classification.py index 617f368456..c9e76c88ab 100644 --- a/flash_examples/integrations/labelstudio/video_classification.py +++ b/flash_examples/integrations/labelstudio/video_classification.py @@ -2,7 +2,7 @@ import flash from flash.core.data.utils import download_data -from flash.core.integrations.labelstudio.app import launch_app +from flash.core.integrations.labelstudio.visualizer import launch_app from flash.video import VideoClassificationData, VideoClassifier # 1 Download data diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 1b021e31a3..851df2ba3b 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -2,7 +2,7 @@ from flash.core.data.data_source import DefaultDataSources from flash.core.data.utils import download_data -from flash.core.integrations.labelstudio.app import launch_app +from flash.core.integrations.labelstudio.visualizer import launch_app from flash.core.integrations.labelstudio.data_source import ( LabelStudioDataSource, LabelStudioImageClassificationDataSource, From f512e0fa5fdd1207bc2b620113fcf2631c0caf43 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Sep 2021 17:47:40 +0000 Subject: [PATCH 44/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- flash/core/integrations/labelstudio/visualizer.py | 1 + tests/core/integrations/labelstudio/test_labelstudio.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/flash/core/integrations/labelstudio/visualizer.py b/flash/core/integrations/labelstudio/visualizer.py index c4f75d4004..57b28fada5 100644 --- a/flash/core/integrations/labelstudio/visualizer.py +++ b/flash/core/integrations/labelstudio/visualizer.py @@ -6,6 +6,7 @@ class App: """App for visualizing predictions in Label Studio results format.""" + def __init__(self, datamodule: DataModule): self.datamodule = datamodule diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 851df2ba3b..7d54fefa21 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -2,12 +2,12 @@ from flash.core.data.data_source import DefaultDataSources from flash.core.data.utils import download_data -from flash.core.integrations.labelstudio.visualizer import launch_app from flash.core.integrations.labelstudio.data_source import ( LabelStudioDataSource, LabelStudioImageClassificationDataSource, LabelStudioTextClassificationDataSource, ) +from flash.core.integrations.labelstudio.visualizer import launch_app from flash.image.classification.data import ImageClassificationData from flash.text.classification.data import TextClassificationData from flash.video.classification.data import VideoClassificationData, VideoClassificationPreprocess From 5590a2ab5414b9d6dbd220aee073d5b4f20fe0ad Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Thu, 9 Sep 2021 22:07:41 +0300 Subject: [PATCH 45/53] Fix test for video and image multilabel --- tests/core/integrations/labelstudio/test_labelstudio.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 7d54fefa21..504d5859d1 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -165,10 +165,10 @@ def test_datasource_labelstudio(): assert sample -@pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") +#@pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") def test_datasource_labelstudio_image(): """Test creation of LabelStudioImageClassificationDataSource from images.""" - download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data.zip") + download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data_nofile.zip") data = { "data_folder": "data/upload/", @@ -271,12 +271,10 @@ def test_datasource_labelstudio_video(): preprocess = VideoClassificationPreprocess() ds = preprocess.data_source_of_name(DefaultDataSources.LABELSTUDIO) train, val, test, predict = ds.to_datasets(train_data=data, test_data=data) - sample = train[0] assert train assert not val assert test assert not predict - assert sample @pytest.mark.skipif(not _VIDEO_TESTING, reason="PyTorchVideo isn't installed.") From a19712f60bef21aa4016f88ff7b10546589ad3ea Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Sep 2021 19:05:24 +0000 Subject: [PATCH 46/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/core/integrations/labelstudio/test_labelstudio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 504d5859d1..707784bfe5 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -165,7 +165,7 @@ def test_datasource_labelstudio(): assert sample -#@pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") +# @pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") def test_datasource_labelstudio_image(): """Test creation of LabelStudioImageClassificationDataSource from images.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data_nofile.zip") From 0d9dd955f397d6a255cbfdfeab8e46e92e1f6bc9 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Thu, 9 Sep 2021 22:26:34 +0300 Subject: [PATCH 47/53] Fixing docstring and test condition --- flash/core/integrations/labelstudio/visualizer.py | 3 +++ tests/core/integrations/labelstudio/test_labelstudio.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/flash/core/integrations/labelstudio/visualizer.py b/flash/core/integrations/labelstudio/visualizer.py index 57b28fada5..7d251d2826 100644 --- a/flash/core/integrations/labelstudio/visualizer.py +++ b/flash/core/integrations/labelstudio/visualizer.py @@ -47,4 +47,7 @@ def construct_result(self, pred): def launch_app(datamodule: DataModule) -> "App": + """ + Creating instance of Visualizing App + """ return App(datamodule) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 707784bfe5..021c354a15 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -165,7 +165,7 @@ def test_datasource_labelstudio(): assert sample -# @pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") +@pytest.mark.skipif(not _IMAGE_TESTING, reason="image libraries aren't installed.") def test_datasource_labelstudio_image(): """Test creation of LabelStudioImageClassificationDataSource from images.""" download_data("https://label-studio-testdata.s3.us-east-2.amazonaws.com/lightning-flash/data_nofile.zip") From 54186b7134f6640c3b568eb4268e2620ed11b0be Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Sep 2021 19:24:17 +0000 Subject: [PATCH 48/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- flash/core/integrations/labelstudio/visualizer.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/flash/core/integrations/labelstudio/visualizer.py b/flash/core/integrations/labelstudio/visualizer.py index 7d251d2826..b9fff963c3 100644 --- a/flash/core/integrations/labelstudio/visualizer.py +++ b/flash/core/integrations/labelstudio/visualizer.py @@ -47,7 +47,5 @@ def construct_result(self, pred): def launch_app(datamodule: DataModule) -> "App": - """ - Creating instance of Visualizing App - """ + """Creating instance of Visualizing App.""" return App(datamodule) From 593e51e559d5707513d40480cb111cb43578f0e8 Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Tue, 14 Sep 2021 00:24:13 +0300 Subject: [PATCH 49/53] Fix docstring and CODEOWNERS --- .github/CODEOWNERS | 1 + flash/core/data/data_module.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6d0283c18c..f60c2461c8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -26,3 +26,4 @@ /.github/*.md @edenlightning @ethanwharris @ananyahjha93 /.github/ISSUE_TEMPLATE/*.md @edenlightning @ethanwharris @ananyahjha93 /docs/source/conf.py @borda @ethanwharris @ananyahjha93 +/flash/core/integrations/labelstudio @KonstantinKorotaev @niklub diff --git a/flash/core/data/data_module.py b/flash/core/data/data_module.py index 3e97a3d7e0..7f94c039b7 100644 --- a/flash/core/data/data_module.py +++ b/flash/core/data/data_module.py @@ -1267,12 +1267,14 @@ def from_labelstudio( Args: export_json: path to label studio export file - train_export_json: path to label studio export file for train + train_export_json: path to label studio export file for train set, + overrides export_json if specified val_export_json: path to label studio export file for validation test_export_json: path to label studio export file for test predict_export_json: path to label studio export file for predict data_folder: path to label studio data folder - train_data_folder: path to label studio data folder for train data + train_data_folder: path to label studio data folder for train data set, + overrides data_folder if specified val_data_folder: path to label studio data folder for validation data test_data_folder: path to label studio data folder for test data predict_data_folder: path to label studio data folder for predict data From 022e1ab9b972c11090899d2d37b494068967a38f Mon Sep 17 00:00:00 2001 From: KonstantinKorotaev Date: Wed, 15 Sep 2021 01:03:33 +0300 Subject: [PATCH 50/53] Adding converter to tasks --- .../integrations/labelstudio/visualizer.py | 59 ++++++++++++++++++- .../labelstudio/test_labelstudio.py | 7 +++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/flash/core/integrations/labelstudio/visualizer.py b/flash/core/integrations/labelstudio/visualizer.py index b9fff963c3..683c46e9e8 100644 --- a/flash/core/integrations/labelstudio/visualizer.py +++ b/flash/core/integrations/labelstudio/visualizer.py @@ -1,12 +1,14 @@ +import json import random import string +from pytorch_lightning.utilities.cloud_io import get_filesystem + from flash.core.data.data_module import DataModule class App: """App for visualizing predictions in Label Studio results format.""" - def __init__(self, datamodule: DataModule): self.datamodule = datamodule @@ -17,6 +19,61 @@ def show_predictions(self, predictions): results.append(self.construct_result(pred)) return results + def show_tasks(self, predictions, export_json=None): + """Converts predictions to tasks format""" + results = self.show_predictions(predictions) + ds = self.datamodule.data_source + data_type = list(ds.data_types)[0] + meta = { + "ids": [], + "data": [], + "meta": [], + "max_predictions_id": 0, + "project": None + } + if export_json: + fs = get_filesystem(export_json) + with fs.open(export_json) as f: + _raw_data = json.load(f) + for task in _raw_data: + if results: + res = results.pop() + meta["max_predictions_id"] = meta["max_predictions_id"] + 1 + temp = { + "result": res["result"], + "id": meta["max_predictions_id"], + "model_version": "", + "score": 0.0, + "task": task["id"] + } + if task.get("predictions"): + task["predictions"].append(temp) + else: + task["predictions"] = [temp] + return _raw_data + else: + print("No export file provided, meta information is generated!") + final_results = [] + for res in results: + temp = { + "result": [res], + "id": meta["max_predictions_id"], + "model_version": "", + "score": 0.0, + "task": meta["max_predictions_id"] + } + task = { + "id": meta["max_predictions_id"], + "predictions": [temp], + "data": { + data_type: "" + }, + "project": 1, + } + meta["max_predictions_id"] = meta["max_predictions_id"] + 1 + final_results.append(task) + return final_results + def construct_result(self, pred): """Construction Label Studio result from data source and prediction values.""" ds = self.datamodule.data_source diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 021c354a15..78428f9824 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -222,6 +222,10 @@ def test_label_studio_predictions_visualization(): assert len(vis_predictions) == 4 assert vis_predictions[0]["result"][0]["id"] != vis_predictions[3]["result"][0]["id"] assert vis_predictions[1]["result"][0]["id"] != vis_predictions[2]["result"][0]["id"] + tasks_predictions = app.show_tasks(predictions) + assert len(tasks_predictions) == 4 + tasks_predictions_json = app.show_tasks(predictions, export_json="data/project.json") + assert tasks_predictions_json @pytest.mark.skipif(not _TEXT_TESTING, reason="text libraries aren't installed.") @@ -271,10 +275,13 @@ def test_datasource_labelstudio_video(): preprocess = VideoClassificationPreprocess() ds = preprocess.data_source_of_name(DefaultDataSources.LABELSTUDIO) train, val, test, predict = ds.to_datasets(train_data=data, test_data=data) + sample_iter = iter(train) + sample = next(sample_iter) assert train assert not val assert test assert not predict + assert sample @pytest.mark.skipif(not _VIDEO_TESTING, reason="PyTorchVideo isn't installed.") From 0e1080a9863fdeac4799b7e87d9461a03e72dd8a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Sep 2021 22:04:10 +0000 Subject: [PATCH 51/53] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../integrations/labelstudio/visualizer.py | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/flash/core/integrations/labelstudio/visualizer.py b/flash/core/integrations/labelstudio/visualizer.py index 683c46e9e8..a284eee10b 100644 --- a/flash/core/integrations/labelstudio/visualizer.py +++ b/flash/core/integrations/labelstudio/visualizer.py @@ -9,6 +9,7 @@ class App: """App for visualizing predictions in Label Studio results format.""" + def __init__(self, datamodule: DataModule): self.datamodule = datamodule @@ -20,17 +21,11 @@ def show_predictions(self, predictions): return results def show_tasks(self, predictions, export_json=None): - """Converts predictions to tasks format""" + """Converts predictions to tasks format.""" results = self.show_predictions(predictions) ds = self.datamodule.data_source data_type = list(ds.data_types)[0] - meta = { - "ids": [], - "data": [], - "meta": [], - "max_predictions_id": 0, - "project": None - } + meta = {"ids": [], "data": [], "meta": [], "max_predictions_id": 0, "project": None} if export_json: fs = get_filesystem(export_json) with fs.open(export_json) as f: @@ -44,7 +39,7 @@ def show_tasks(self, predictions, export_json=None): "id": meta["max_predictions_id"], "model_version": "", "score": 0.0, - "task": task["id"] + "task": task["id"], } if task.get("predictions"): task["predictions"].append(temp) @@ -60,14 +55,12 @@ def show_tasks(self, predictions, export_json=None): "id": meta["max_predictions_id"], "model_version": "", "score": 0.0, - "task": meta["max_predictions_id"] + "task": meta["max_predictions_id"], } task = { "id": meta["max_predictions_id"], "predictions": [temp], - "data": { - data_type: "" - }, + "data": {data_type: ""}, "project": 1, } meta["max_predictions_id"] = meta["max_predictions_id"] + 1 From b81f53fd2ae3e2d83ace10a06e64d483c4e5daa8 Mon Sep 17 00:00:00 2001 From: tchaton Date: Tue, 28 Sep 2021 21:52:41 +0100 Subject: [PATCH 52/53] update --- tests/core/integrations/labelstudio/test_labelstudio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/integrations/labelstudio/test_labelstudio.py b/tests/core/integrations/labelstudio/test_labelstudio.py index 78428f9824..4f586dc00b 100644 --- a/tests/core/integrations/labelstudio/test_labelstudio.py +++ b/tests/core/integrations/labelstudio/test_labelstudio.py @@ -152,7 +152,7 @@ def test_datasource_labelstudio(): val_sample = val[0] assert train_sample assert val_sample - assert not test + assert test assert not predict ds_no_split = LabelStudioDataSource() data = { From b89d6bbe7fb182984d9a988195496ba9d00d947d Mon Sep 17 00:00:00 2001 From: tchaton Date: Tue, 28 Sep 2021 21:55:55 +0100 Subject: [PATCH 53/53] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11d4b0accf..91f7061a4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added +- Added `LabelStudio` integration ([#554](https://github.com/PyTorchLightning/lightning-flash/pull/554)) + - Added support `learn2learn` training_strategy for `ImageClassifier` ([#737](https://github.com/PyTorchLightning/lightning-flash/pull/737)) - Added `vissl` training_strategies for `ImageEmbedder` ([#682](https://github.com/PyTorchLightning/lightning-flash/pull/682))