Spaces:
Build error
Build error
deploy: 63a85616f5fc427cf1e1e7b425293131f2fce2b8
Browse files- README.md +164 -0
- requirements.txt +137 -90
README.md
CHANGED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: Layout Maximum IoU
|
| 3 |
+
emoji: 📊
|
| 4 |
+
colorFrom: pink
|
| 5 |
+
colorTo: purple
|
| 6 |
+
sdk: gradio
|
| 7 |
+
sdk_version: 4.36.1
|
| 8 |
+
app_file: app.py
|
| 9 |
+
pinned: false
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
# Layout Maximum IoU
|
| 13 |
+
|
| 14 |
+
## Description
|
| 15 |
+
|
| 16 |
+
The Layout Maximum IoU metric computes the optimal matching between two sets of layouts and measures their similarity using Intersection over Union (IoU). This metric is particularly useful for evaluating conditional layout generation models by comparing generated layouts against reference layouts with the same element composition.
|
| 17 |
+
|
| 18 |
+
## What It Measures
|
| 19 |
+
|
| 20 |
+
This metric:
|
| 21 |
+
|
| 22 |
+
1. Groups layouts by their element category composition (e.g., layouts with {text, image, logo})
|
| 23 |
+
2. Finds the optimal one-to-one matching between layouts in each group using the Hungarian algorithm
|
| 24 |
+
3. Computes IoU for matched element pairs within each layout
|
| 25 |
+
4. Returns the average IoU across all optimally matched layout pairs
|
| 26 |
+
|
| 27 |
+
Higher values indicate better similarity between the two layout sets.
|
| 28 |
+
|
| 29 |
+
## Metric Details
|
| 30 |
+
|
| 31 |
+
- **Category-conditional matching**: Only compares layouts with identical element type compositions
|
| 32 |
+
- **Optimal assignment**: Uses linear sum assignment (Hungarian algorithm) to find the best matching
|
| 33 |
+
- **Element-wise IoU**: Computes IoU for each element pair after optimal matching
|
| 34 |
+
- **Normalized by layout size**: Final score is divided by the number of elements per layout
|
| 35 |
+
- Returns 0.0 if no layouts share the same category composition
|
| 36 |
+
|
| 37 |
+
## Usage
|
| 38 |
+
|
| 39 |
+
### Installation
|
| 40 |
+
|
| 41 |
+
```bash
|
| 42 |
+
pip install evaluate scipy
|
| 43 |
+
```
|
| 44 |
+
|
| 45 |
+
### Basic Example
|
| 46 |
+
|
| 47 |
+
```python
|
| 48 |
+
import evaluate
|
| 49 |
+
import numpy as np
|
| 50 |
+
|
| 51 |
+
# Load the metric
|
| 52 |
+
metric = evaluate.load("creative-graphic-design/layout-maximum-iou")
|
| 53 |
+
|
| 54 |
+
# Single pair of layouts
|
| 55 |
+
num_samples, num_coordinates = 24, 4
|
| 56 |
+
layout1 = {
|
| 57 |
+
"bboxes": np.random.rand(num_samples, num_coordinates),
|
| 58 |
+
"categories": np.random.randint(0, num_coordinates, size=(num_samples,)),
|
| 59 |
+
}
|
| 60 |
+
layout2 = {
|
| 61 |
+
"bboxes": np.random.rand(num_samples, num_coordinates),
|
| 62 |
+
"categories": np.random.randint(0, num_coordinates, size=(num_samples,)),
|
| 63 |
+
}
|
| 64 |
+
metric.add(layouts1=layout1, layouts2=layout2)
|
| 65 |
+
print(metric.compute())
|
| 66 |
+
```
|
| 67 |
+
|
| 68 |
+
### Batch Processing Example
|
| 69 |
+
|
| 70 |
+
```python
|
| 71 |
+
import evaluate
|
| 72 |
+
import numpy as np
|
| 73 |
+
|
| 74 |
+
# Load the metric
|
| 75 |
+
metric = evaluate.load("creative-graphic-design/layout-maximum-iou")
|
| 76 |
+
|
| 77 |
+
# Batch processing (recommended)
|
| 78 |
+
batch_size, num_samples, num_coordinates = 512, 24, 4
|
| 79 |
+
layouts1 = [
|
| 80 |
+
{
|
| 81 |
+
"bboxes": np.random.rand(num_samples, num_coordinates),
|
| 82 |
+
"categories": np.random.randint(0, num_coordinates, size=(num_samples,)),
|
| 83 |
+
}
|
| 84 |
+
for _ in range(batch_size)
|
| 85 |
+
]
|
| 86 |
+
layouts2 = [
|
| 87 |
+
{
|
| 88 |
+
"bboxes": np.random.rand(num_samples, num_coordinates),
|
| 89 |
+
"categories": np.random.randint(0, num_coordinates, size=(num_samples,)),
|
| 90 |
+
}
|
| 91 |
+
for _ in range(batch_size)
|
| 92 |
+
]
|
| 93 |
+
metric.add_batch(layouts1=layouts1, layouts2=layouts2)
|
| 94 |
+
print(metric.compute())
|
| 95 |
+
```
|
| 96 |
+
|
| 97 |
+
## Parameters
|
| 98 |
+
|
| 99 |
+
### Initialization Parameters
|
| 100 |
+
|
| 101 |
+
This metric does not require any initialization parameters.
|
| 102 |
+
|
| 103 |
+
### Computation Parameters
|
| 104 |
+
|
| 105 |
+
- **layouts1** (`list` of `dict`): First set of layouts, where each dictionary contains:
|
| 106 |
+
|
| 107 |
+
- **bboxes** (`list` of `float`): Bounding boxes in center-x, center-y, width, height (xywh) format
|
| 108 |
+
- **categories** (`list` of `int`): Category labels for each element
|
| 109 |
+
|
| 110 |
+
- **layouts2** (`list` of `dict`): Second set of layouts (same structure as layouts1)
|
| 111 |
+
|
| 112 |
+
**Note**: Layouts are automatically grouped by their category composition. Only layouts with matching categories are compared.
|
| 113 |
+
|
| 114 |
+
## Returns
|
| 115 |
+
|
| 116 |
+
Returns a single `float` value representing:
|
| 117 |
+
|
| 118 |
+
- The mean maximum IoU across all optimally matched layout pairs
|
| 119 |
+
- Range: 0.0 to 1.0
|
| 120 |
+
|
| 121 |
+
## Interpretation
|
| 122 |
+
|
| 123 |
+
- **Higher is better** (range: 0.0 to 1.0)
|
| 124 |
+
- **Value of 1.0**: Perfect match - all elements in matched layouts have identical positions and sizes
|
| 125 |
+
- **Value of 0.8-1.0**: Very high similarity - generated layouts closely match references
|
| 126 |
+
- **Value of 0.5-0.8**: Moderate similarity - layouts capture general structure but differ in details
|
| 127 |
+
- **Value of 0.0-0.5**: Low similarity - significant differences in element placement
|
| 128 |
+
- **Value of 0.0**: Either no overlap in matched elements, or no layouts share the same category composition
|
| 129 |
+
|
| 130 |
+
### Use Cases
|
| 131 |
+
|
| 132 |
+
- **Conditional generation evaluation**: Assess how well a model generates layouts matching specific element compositions
|
| 133 |
+
- **Layout retrieval**: Find the best matching layouts between two collections
|
| 134 |
+
- **Dataset comparison**: Compare layout distributions between different sources
|
| 135 |
+
|
| 136 |
+
### Key Features
|
| 137 |
+
|
| 138 |
+
- **Optimal matching**: Ensures fair comparison by finding the best possible pairing
|
| 139 |
+
- **Category-aware**: Only compares layouts that should be comparable (same elements)
|
| 140 |
+
- **Robust to ordering**: Element order within layouts doesn't affect the score
|
| 141 |
+
|
| 142 |
+
## Citations
|
| 143 |
+
|
| 144 |
+
```bibtex
|
| 145 |
+
@inproceedings{kikuchi2021constrained,
|
| 146 |
+
title={Constrained graphic layout generation via latent optimization},
|
| 147 |
+
author={Kikuchi, Kotaro and Simo-Serra, Edgar and Otani, Mayu and Yamaguchi, Kota},
|
| 148 |
+
booktitle={Proceedings of the 29th ACM International Conference on Multimedia},
|
| 149 |
+
pages={88--96},
|
| 150 |
+
year={2021}
|
| 151 |
+
}
|
| 152 |
+
```
|
| 153 |
+
|
| 154 |
+
## References
|
| 155 |
+
|
| 156 |
+
- **Paper**: [Constrained Graphic Layout Generation via Latent Optimization (Kikuchi et al., ACM MM 2021)](https://arxiv.org/abs/2108.00871)
|
| 157 |
+
- **Reference Implementation**: [layout-dm metric implementation](https://github.com/CyberAgentAILab/layout-dm/blob/main/src/trainer/trainer/helpers/metric.py#L206-L371)
|
| 158 |
+
- **Hugging Face Space**: [creative-graphic-design/layout-maximum-iou](https://huggingface.co/spaces/creative-graphic-design/layout-maximum-iou)
|
| 159 |
+
|
| 160 |
+
## Related Metrics
|
| 161 |
+
|
| 162 |
+
- [Layout Average IoU](../layout_average_iou/): Measures average overlap within single layouts
|
| 163 |
+
- [Layout Overlap](../layout_overlap/): Alternative overlap metrics
|
| 164 |
+
- [Layout Validity](../layout_validity/): Validates layout constraints
|
requirements.txt
CHANGED
|
@@ -1,90 +1,137 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
requests
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This file was autogenerated by uv via the following command:
|
| 2 |
+
# uv export --package layout_maximum_iou --no-dev --no-hashes --format requirements-txt
|
| 3 |
+
aiohappyeyeballs==2.6.1
|
| 4 |
+
# via aiohttp
|
| 5 |
+
aiohttp==3.13.2
|
| 6 |
+
# via fsspec
|
| 7 |
+
aiosignal==1.4.0
|
| 8 |
+
# via aiohttp
|
| 9 |
+
anyio==4.12.0
|
| 10 |
+
# via httpx
|
| 11 |
+
attrs==25.4.0
|
| 12 |
+
# via aiohttp
|
| 13 |
+
certifi==2025.11.12
|
| 14 |
+
# via
|
| 15 |
+
# httpcore
|
| 16 |
+
# httpx
|
| 17 |
+
# requests
|
| 18 |
+
charset-normalizer==3.4.4
|
| 19 |
+
# via requests
|
| 20 |
+
click==8.3.1
|
| 21 |
+
# via typer-slim
|
| 22 |
+
colorama==0.4.6 ; sys_platform == 'win32'
|
| 23 |
+
# via
|
| 24 |
+
# click
|
| 25 |
+
# tqdm
|
| 26 |
+
datasets==4.4.2
|
| 27 |
+
# via evaluate
|
| 28 |
+
dill==0.4.0
|
| 29 |
+
# via
|
| 30 |
+
# datasets
|
| 31 |
+
# evaluate
|
| 32 |
+
# multiprocess
|
| 33 |
+
evaluate==0.4.6
|
| 34 |
+
# via layout-maximum-iou
|
| 35 |
+
filelock==3.20.1
|
| 36 |
+
# via
|
| 37 |
+
# datasets
|
| 38 |
+
# huggingface-hub
|
| 39 |
+
frozenlist==1.8.0
|
| 40 |
+
# via
|
| 41 |
+
# aiohttp
|
| 42 |
+
# aiosignal
|
| 43 |
+
fsspec==2025.10.0
|
| 44 |
+
# via
|
| 45 |
+
# datasets
|
| 46 |
+
# evaluate
|
| 47 |
+
# huggingface-hub
|
| 48 |
+
h11==0.16.0
|
| 49 |
+
# via httpcore
|
| 50 |
+
hf-xet==1.2.0 ; platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'
|
| 51 |
+
# via huggingface-hub
|
| 52 |
+
httpcore==1.0.9
|
| 53 |
+
# via httpx
|
| 54 |
+
httpx==0.28.1
|
| 55 |
+
# via
|
| 56 |
+
# datasets
|
| 57 |
+
# huggingface-hub
|
| 58 |
+
huggingface-hub==1.2.3
|
| 59 |
+
# via
|
| 60 |
+
# datasets
|
| 61 |
+
# evaluate
|
| 62 |
+
idna==3.11
|
| 63 |
+
# via
|
| 64 |
+
# anyio
|
| 65 |
+
# httpx
|
| 66 |
+
# requests
|
| 67 |
+
# yarl
|
| 68 |
+
multidict==6.7.0
|
| 69 |
+
# via
|
| 70 |
+
# aiohttp
|
| 71 |
+
# yarl
|
| 72 |
+
multiprocess==0.70.18
|
| 73 |
+
# via
|
| 74 |
+
# datasets
|
| 75 |
+
# evaluate
|
| 76 |
+
numpy==2.2.6
|
| 77 |
+
# via
|
| 78 |
+
# datasets
|
| 79 |
+
# evaluate
|
| 80 |
+
# pandas
|
| 81 |
+
# scipy
|
| 82 |
+
packaging==25.0
|
| 83 |
+
# via
|
| 84 |
+
# datasets
|
| 85 |
+
# evaluate
|
| 86 |
+
# huggingface-hub
|
| 87 |
+
pandas==2.3.3
|
| 88 |
+
# via
|
| 89 |
+
# datasets
|
| 90 |
+
# evaluate
|
| 91 |
+
propcache==0.4.1
|
| 92 |
+
# via
|
| 93 |
+
# aiohttp
|
| 94 |
+
# yarl
|
| 95 |
+
pyarrow==22.0.0
|
| 96 |
+
# via datasets
|
| 97 |
+
python-dateutil==2.9.0.post0
|
| 98 |
+
# via pandas
|
| 99 |
+
pytz==2025.2
|
| 100 |
+
# via pandas
|
| 101 |
+
pyyaml==6.0.3
|
| 102 |
+
# via
|
| 103 |
+
# datasets
|
| 104 |
+
# huggingface-hub
|
| 105 |
+
requests==2.32.5
|
| 106 |
+
# via
|
| 107 |
+
# datasets
|
| 108 |
+
# evaluate
|
| 109 |
+
scipy==1.16.3
|
| 110 |
+
# via layout-maximum-iou
|
| 111 |
+
shellingham==1.5.4
|
| 112 |
+
# via huggingface-hub
|
| 113 |
+
six==1.17.0
|
| 114 |
+
# via python-dateutil
|
| 115 |
+
tqdm==4.67.1
|
| 116 |
+
# via
|
| 117 |
+
# datasets
|
| 118 |
+
# evaluate
|
| 119 |
+
# huggingface-hub
|
| 120 |
+
typer-slim==0.21.0
|
| 121 |
+
# via huggingface-hub
|
| 122 |
+
typing-extensions==4.15.0
|
| 123 |
+
# via
|
| 124 |
+
# aiosignal
|
| 125 |
+
# anyio
|
| 126 |
+
# huggingface-hub
|
| 127 |
+
# typer-slim
|
| 128 |
+
tzdata==2025.3
|
| 129 |
+
# via pandas
|
| 130 |
+
urllib3==2.6.2
|
| 131 |
+
# via requests
|
| 132 |
+
xxhash==3.6.0
|
| 133 |
+
# via
|
| 134 |
+
# datasets
|
| 135 |
+
# evaluate
|
| 136 |
+
yarl==1.22.0
|
| 137 |
+
# via aiohttp
|