Enhancement for PyTorch DataLoader default collate. If dataset already returns a list of batch data that generated in transforms, need to merge all data to 1 list. Then it's same as the default collate behavior. Note: Need to use this collate if apply some transforms that c
(batch: Sequence)
| 453 | |
| 454 | |
| 455 | def list_data_collate(batch: Sequence): |
| 456 | """ |
| 457 | Enhancement for PyTorch DataLoader default collate. |
| 458 | If dataset already returns a list of batch data that generated in transforms, need to merge all data to 1 list. |
| 459 | Then it's same as the default collate behavior. |
| 460 | |
| 461 | Note: |
| 462 | Need to use this collate if apply some transforms that can generate batch data. |
| 463 | |
| 464 | """ |
| 465 | from torch.utils.data._utils.collate import default_collate_fn_map |
| 466 | |
| 467 | from monai.data.meta_tensor import MetaTensor |
| 468 | |
| 469 | default_collate_fn_map.update({MetaTensor: collate_meta_tensor_fn}) |
| 470 | elem = batch[0] |
| 471 | data = [i for k in batch for i in k] if isinstance(elem, list) else batch |
| 472 | key = None |
| 473 | collate_fn = default_collate |
| 474 | try: |
| 475 | # if config.USE_META_DICT: |
| 476 | # data = pickle_operations(data) # bc 0.9.0 |
| 477 | if isinstance(elem, Mapping): |
| 478 | ret = {} |
| 479 | for k in elem: |
| 480 | key = k |
| 481 | data_for_batch = [d[key] for d in data] |
| 482 | ret[key] = collate_fn(data_for_batch) |
| 483 | else: |
| 484 | ret = collate_fn(data) |
| 485 | return ret |
| 486 | except RuntimeError as re: |
| 487 | re_str = str(re) |
| 488 | if "equal size" in re_str: |
| 489 | if key is not None: |
| 490 | re_str += f"\nCollate error on the key '{key}' of dictionary data." |
| 491 | re_str += ( |
| 492 | "\n\nMONAI hint: if your transforms intentionally create images of different shapes, creating your " |
| 493 | + "`DataLoader` with `collate_fn=pad_list_data_collate` might solve this problem (check its " |
| 494 | + "documentation)." |
| 495 | ) |
| 496 | _ = dev_collate(data) |
| 497 | raise RuntimeError(re_str) from re |
| 498 | except TypeError as re: |
| 499 | re_str = str(re) |
| 500 | if "numpy" in re_str and "Tensor" in re_str: |
| 501 | if key is not None: |
| 502 | re_str += f"\nCollate error on the key '{key}' of dictionary data." |
| 503 | re_str += ( |
| 504 | "\n\nMONAI hint: if your transforms intentionally create mixtures of torch Tensor and numpy ndarray, " |
| 505 | + "creating your `DataLoader` with `collate_fn=pad_list_data_collate` might solve this problem " |
| 506 | + "(check its documentation)." |
| 507 | ) |
| 508 | _ = dev_collate(data) |
| 509 | raise TypeError(re_str) from re |
| 510 | |
| 511 | |
| 512 | def _non_zipping_check(batch_data: Mapping | Iterable, detach: bool, pad: bool, fill_value): |
searching dependent graphs…