Depth Estimation
Transformers
Safetensors
tipsv2_dpt
feature-extraction
vision
surface-normals
semantic-segmentation
dense-prediction
custom_code
Instructions to use CollectionStudio/tipsv2-l14-dpt with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use CollectionStudio/tipsv2-l14-dpt with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("depth-estimation", model="CollectionStudio/tipsv2-l14-dpt", trust_remote_code=True)# pip install -U transformers accelerate # Load model directly from transformers import AutoImageProcessor, AutoModel processor = AutoImageProcessor.from_pretrained("CollectionStudio/tipsv2-l14-dpt", trust_remote_code=True) model = AutoModel.from_pretrained("CollectionStudio/tipsv2-l14-dpt", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
Commit ·
6f989b9
0
Parent(s):
Duplicate from google/tipsv2-l14-dpt
Browse filesCo-authored-by: Gabriele Berton <gberton@users.noreply.huggingface.co>
- .gitattributes +35 -0
- README.md +80 -0
- config.json +397 -0
- configuration_dpt.py +44 -0
- dpt_head.py +702 -0
- model.safetensors +3 -0
- modeling_dpt.py +115 -0
- preprocessor_config.json +13 -0
.gitattributes
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
tags:
|
| 4 |
+
- vision
|
| 5 |
+
- depth-estimation
|
| 6 |
+
- surface-normals
|
| 7 |
+
- semantic-segmentation
|
| 8 |
+
- dense-prediction
|
| 9 |
+
- arxiv:2604.12012
|
| 10 |
+
library_name: transformers
|
| 11 |
+
pipeline_tag: depth-estimation
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
# TIPSv2 — L/14 DPT Heads
|
| 15 |
+
|
| 16 |
+
DPT (Dense Prediction Transformer) heads for depth estimation, surface normal prediction, and semantic segmentation on top of the frozen [TIPSv2 L/14](https://huggingface.co/google/tipsv2-l14) backbone. The backbone is loaded automatically. The depth and normals heads are trained on the NYU Depth V2 dataset and segmentation is trained on the ADE20K dataset (150 classes).
|
| 17 |
+
|
| 18 |
+
| Variant | Vision params | Text params | Embed dim | DPT Heads |
|
| 19 |
+
|---------|--------------|-------------|-----------|-----------|
|
| 20 |
+
| [B/14](https://huggingface.co/google/tipsv2-b14) | 86M | 110M | 768 | [B/14-dpt](https://huggingface.co/google/tipsv2-b14-dpt) |
|
| 21 |
+
| [L/14](https://huggingface.co/google/tipsv2-l14) | 303M | 184M | 1024 | [L/14-dpt](https://huggingface.co/google/tipsv2-l14-dpt) |
|
| 22 |
+
| [SO400m/14](https://huggingface.co/google/tipsv2-so400m14) | 412M | 448M | 1152 | [SO400m/14-dpt](https://huggingface.co/google/tipsv2-so400m14-dpt) |
|
| 23 |
+
| [g/14](https://huggingface.co/google/tipsv2-g14) | 1.1B | 389M | 1536 | [g/14-dpt](https://huggingface.co/google/tipsv2-g14-dpt) |
|
| 24 |
+
|
| 25 |
+
## Usage
|
| 26 |
+
|
| 27 |
+
```bash
|
| 28 |
+
pip install transformers torch torchvision sentencepiece
|
| 29 |
+
```
|
| 30 |
+
|
| 31 |
+
```python
|
| 32 |
+
from transformers import AutoModel
|
| 33 |
+
from torchvision import transforms
|
| 34 |
+
from PIL import Image
|
| 35 |
+
import requests
|
| 36 |
+
|
| 37 |
+
model = AutoModel.from_pretrained("google/tipsv2-l14-dpt", trust_remote_code=True)
|
| 38 |
+
model.eval().cuda()
|
| 39 |
+
|
| 40 |
+
url = "https://huggingface.co/spaces/google/tipsv2/resolve/main/examples/depth/ade20k_00014.png"
|
| 41 |
+
image = Image.open(requests.get(url, stream=True).raw)
|
| 42 |
+
transform = transforms.Compose([transforms.Resize((448, 448)), transforms.ToTensor()])
|
| 43 |
+
pixel_values = transform(image).unsqueeze(0).cuda()
|
| 44 |
+
|
| 45 |
+
# All tasks at once
|
| 46 |
+
outputs = model(pixel_values)
|
| 47 |
+
print(outputs.depth.shape) # (1, 1, 448, 448) — depth map
|
| 48 |
+
print(outputs.normals.shape) # (1, 3, 448, 448) — surface normals
|
| 49 |
+
print(outputs.segmentation.shape) # (1, 150, 448, 448) — segmentation logits
|
| 50 |
+
|
| 51 |
+
# Or individual tasks (only runs the requested head)
|
| 52 |
+
depth = model.predict_depth(pixel_values)
|
| 53 |
+
normals = model.predict_normals(pixel_values)
|
| 54 |
+
seg = model.predict_segmentation(pixel_values)
|
| 55 |
+
print(seg.argmax(dim=1).shape) # (1, 448, 448) — per-pixel class prediction
|
| 56 |
+
```
|
| 57 |
+
|
| 58 |
+
## Model details
|
| 59 |
+
|
| 60 |
+
- **Backbone**: [TIPSv2 L/14](https://huggingface.co/google/tipsv2-l14) (loaded automatically)
|
| 61 |
+
- **Heads**: ~102M total params (depth + normals + segmentation)
|
| 62 |
+
- **Depth & normals**: NYU Depth V2
|
| 63 |
+
- **Segmentation**: ADE20K, 150 classes
|
| 64 |
+
- **Input**: images in `[0, 1]` range, any resolution (multiples of 14 recommended)
|
| 65 |
+
|
| 66 |
+
## License
|
| 67 |
+
|
| 68 |
+
Apache 2.0
|
| 69 |
+
|
| 70 |
+
## Citation
|
| 71 |
+
|
| 72 |
+
```bibtex
|
| 73 |
+
@inproceedings{cao2026tipsv2,
|
| 74 |
+
title = {{TIPSv2: Advancing Vision-Language Pretraining with Enhanced Patch-Text Alignment}},
|
| 75 |
+
author = {Cao, Bingyi and Chen, Koert and Maninis, Kevis-Kokitsi and Chen, Kaifeng and Karpur, Arjun and Xia, Ye and Dua, Sahil and Dabral, Tanmaya and Han, Guangxing and Han, Bohyung and Ainslie, Joshua and Bewley, Alex and Jacob, Mithun and Wagner, Rene and Ramos, Washington and Choromanski, Krzysztof and Seyedhosseini, Mojtaba and Zhou, Howard and Araujo, Andre},
|
| 76 |
+
booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},
|
| 77 |
+
year = {2026},
|
| 78 |
+
url = {https://arxiv.org/abs/2604.12012}
|
| 79 |
+
}
|
| 80 |
+
```
|
config.json
ADDED
|
@@ -0,0 +1,397 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"TIPSv2DPTModel"
|
| 4 |
+
],
|
| 5 |
+
"auto_map": {
|
| 6 |
+
"AutoConfig": "configuration_dpt.TIPSv2DPTConfig",
|
| 7 |
+
"AutoModel": "modeling_dpt.TIPSv2DPTModel"
|
| 8 |
+
},
|
| 9 |
+
"backbone_config": {
|
| 10 |
+
"apply_layernorm": true,
|
| 11 |
+
"attention_probs_dropout_prob": 0.0,
|
| 12 |
+
"drop_path_rate": 0.0,
|
| 13 |
+
"hidden_act": "gelu",
|
| 14 |
+
"hidden_dropout_prob": 0.0,
|
| 15 |
+
"hidden_size": 1024,
|
| 16 |
+
"image_size": 448,
|
| 17 |
+
"initializer_range": 0.02,
|
| 18 |
+
"interpolate_antialias": true,
|
| 19 |
+
"interpolate_offset": 0.0,
|
| 20 |
+
"layer_norm_eps": 1e-06,
|
| 21 |
+
"layerscale_value": 1.0,
|
| 22 |
+
"mlp_ratio": 4,
|
| 23 |
+
"model_type": "tipsv2_vision_model",
|
| 24 |
+
"num_attention_heads": 16,
|
| 25 |
+
"num_channels": 3,
|
| 26 |
+
"num_hidden_layers": 24,
|
| 27 |
+
"num_register_tokens": 1,
|
| 28 |
+
"out_features": [
|
| 29 |
+
"stage6",
|
| 30 |
+
"stage12",
|
| 31 |
+
"stage18",
|
| 32 |
+
"stage24"
|
| 33 |
+
],
|
| 34 |
+
"out_indices": [
|
| 35 |
+
6,
|
| 36 |
+
12,
|
| 37 |
+
18,
|
| 38 |
+
24
|
| 39 |
+
],
|
| 40 |
+
"patch_size": 14,
|
| 41 |
+
"qkv_bias": true,
|
| 42 |
+
"reshape_hidden_states": false,
|
| 43 |
+
"stage_names": [
|
| 44 |
+
"stem",
|
| 45 |
+
"stage1",
|
| 46 |
+
"stage2",
|
| 47 |
+
"stage3",
|
| 48 |
+
"stage4",
|
| 49 |
+
"stage5",
|
| 50 |
+
"stage6",
|
| 51 |
+
"stage7",
|
| 52 |
+
"stage8",
|
| 53 |
+
"stage9",
|
| 54 |
+
"stage10",
|
| 55 |
+
"stage11",
|
| 56 |
+
"stage12",
|
| 57 |
+
"stage13",
|
| 58 |
+
"stage14",
|
| 59 |
+
"stage15",
|
| 60 |
+
"stage16",
|
| 61 |
+
"stage17",
|
| 62 |
+
"stage18",
|
| 63 |
+
"stage19",
|
| 64 |
+
"stage20",
|
| 65 |
+
"stage21",
|
| 66 |
+
"stage22",
|
| 67 |
+
"stage23",
|
| 68 |
+
"stage24"
|
| 69 |
+
],
|
| 70 |
+
"use_swiglu_ffn": false
|
| 71 |
+
},
|
| 72 |
+
"depth_decoder_activation": "relu",
|
| 73 |
+
"fusion_hidden_size": 256,
|
| 74 |
+
"id2label": {
|
| 75 |
+
"0": "wall",
|
| 76 |
+
"1": "building",
|
| 77 |
+
"10": "cabinet",
|
| 78 |
+
"100": "poster",
|
| 79 |
+
"101": "stage",
|
| 80 |
+
"102": "van",
|
| 81 |
+
"103": "ship",
|
| 82 |
+
"104": "fountain",
|
| 83 |
+
"105": "conveyer belt",
|
| 84 |
+
"106": "canopy",
|
| 85 |
+
"107": "washer",
|
| 86 |
+
"108": "plaything",
|
| 87 |
+
"109": "swimming pool",
|
| 88 |
+
"11": "sidewalk",
|
| 89 |
+
"110": "stool",
|
| 90 |
+
"111": "barrel",
|
| 91 |
+
"112": "basket",
|
| 92 |
+
"113": "waterfall",
|
| 93 |
+
"114": "tent",
|
| 94 |
+
"115": "bag",
|
| 95 |
+
"116": "minibike",
|
| 96 |
+
"117": "cradle",
|
| 97 |
+
"118": "oven",
|
| 98 |
+
"119": "ball",
|
| 99 |
+
"12": "person",
|
| 100 |
+
"120": "food",
|
| 101 |
+
"121": "step",
|
| 102 |
+
"122": "tank",
|
| 103 |
+
"123": "trade name",
|
| 104 |
+
"124": "microwave",
|
| 105 |
+
"125": "pot",
|
| 106 |
+
"126": "animal",
|
| 107 |
+
"127": "bicycle",
|
| 108 |
+
"128": "lake",
|
| 109 |
+
"129": "dishwasher",
|
| 110 |
+
"13": "earth",
|
| 111 |
+
"130": "screen",
|
| 112 |
+
"131": "blanket",
|
| 113 |
+
"132": "sculpture",
|
| 114 |
+
"133": "hood",
|
| 115 |
+
"134": "sconce",
|
| 116 |
+
"135": "vase",
|
| 117 |
+
"136": "traffic light",
|
| 118 |
+
"137": "tray",
|
| 119 |
+
"138": "ashcan",
|
| 120 |
+
"139": "fan",
|
| 121 |
+
"14": "door",
|
| 122 |
+
"140": "pier",
|
| 123 |
+
"141": "crt screen",
|
| 124 |
+
"142": "plate",
|
| 125 |
+
"143": "monitor",
|
| 126 |
+
"144": "bulletin board",
|
| 127 |
+
"145": "shower",
|
| 128 |
+
"146": "radiator",
|
| 129 |
+
"147": "glass",
|
| 130 |
+
"148": "clock",
|
| 131 |
+
"149": "flag",
|
| 132 |
+
"15": "table",
|
| 133 |
+
"16": "mountain",
|
| 134 |
+
"17": "plant",
|
| 135 |
+
"18": "curtain",
|
| 136 |
+
"19": "chair",
|
| 137 |
+
"2": "sky",
|
| 138 |
+
"20": "car",
|
| 139 |
+
"21": "water",
|
| 140 |
+
"22": "painting",
|
| 141 |
+
"23": "sofa",
|
| 142 |
+
"24": "shelf",
|
| 143 |
+
"25": "house",
|
| 144 |
+
"26": "sea",
|
| 145 |
+
"27": "mirror",
|
| 146 |
+
"28": "rug",
|
| 147 |
+
"29": "field",
|
| 148 |
+
"3": "floor",
|
| 149 |
+
"30": "armchair",
|
| 150 |
+
"31": "seat",
|
| 151 |
+
"32": "fence",
|
| 152 |
+
"33": "desk",
|
| 153 |
+
"34": "rock",
|
| 154 |
+
"35": "wardrobe",
|
| 155 |
+
"36": "lamp",
|
| 156 |
+
"37": "bathtub",
|
| 157 |
+
"38": "railing",
|
| 158 |
+
"39": "cushion",
|
| 159 |
+
"4": "tree",
|
| 160 |
+
"40": "base",
|
| 161 |
+
"41": "box",
|
| 162 |
+
"42": "column",
|
| 163 |
+
"43": "signboard",
|
| 164 |
+
"44": "chest of drawers",
|
| 165 |
+
"45": "counter",
|
| 166 |
+
"46": "sand",
|
| 167 |
+
"47": "sink",
|
| 168 |
+
"48": "skyscraper",
|
| 169 |
+
"49": "fireplace",
|
| 170 |
+
"5": "ceiling",
|
| 171 |
+
"50": "refrigerator",
|
| 172 |
+
"51": "grandstand",
|
| 173 |
+
"52": "path",
|
| 174 |
+
"53": "stairs",
|
| 175 |
+
"54": "runway",
|
| 176 |
+
"55": "case",
|
| 177 |
+
"56": "pool table",
|
| 178 |
+
"57": "pillow",
|
| 179 |
+
"58": "screen door",
|
| 180 |
+
"59": "stairway",
|
| 181 |
+
"6": "road",
|
| 182 |
+
"60": "river",
|
| 183 |
+
"61": "bridge",
|
| 184 |
+
"62": "bookcase",
|
| 185 |
+
"63": "blind",
|
| 186 |
+
"64": "coffee table",
|
| 187 |
+
"65": "toilet",
|
| 188 |
+
"66": "flower",
|
| 189 |
+
"67": "book",
|
| 190 |
+
"68": "hill",
|
| 191 |
+
"69": "bench",
|
| 192 |
+
"7": "bed ",
|
| 193 |
+
"70": "countertop",
|
| 194 |
+
"71": "stove",
|
| 195 |
+
"72": "palm",
|
| 196 |
+
"73": "kitchen island",
|
| 197 |
+
"74": "computer",
|
| 198 |
+
"75": "swivel chair",
|
| 199 |
+
"76": "boat",
|
| 200 |
+
"77": "bar",
|
| 201 |
+
"78": "arcade machine",
|
| 202 |
+
"79": "hovel",
|
| 203 |
+
"8": "windowpane",
|
| 204 |
+
"80": "bus",
|
| 205 |
+
"81": "towel",
|
| 206 |
+
"82": "light",
|
| 207 |
+
"83": "truck",
|
| 208 |
+
"84": "tower",
|
| 209 |
+
"85": "chandelier",
|
| 210 |
+
"86": "awning",
|
| 211 |
+
"87": "streetlight",
|
| 212 |
+
"88": "booth",
|
| 213 |
+
"89": "television receiver",
|
| 214 |
+
"9": "grass",
|
| 215 |
+
"90": "airplane",
|
| 216 |
+
"91": "dirt track",
|
| 217 |
+
"92": "apparel",
|
| 218 |
+
"93": "pole",
|
| 219 |
+
"94": "land",
|
| 220 |
+
"95": "bannister",
|
| 221 |
+
"96": "escalator",
|
| 222 |
+
"97": "ottoman",
|
| 223 |
+
"98": "bottle",
|
| 224 |
+
"99": "buffet"
|
| 225 |
+
},
|
| 226 |
+
"label2id": {
|
| 227 |
+
"airplane": 90,
|
| 228 |
+
"animal": 126,
|
| 229 |
+
"apparel": 92,
|
| 230 |
+
"arcade machine": 78,
|
| 231 |
+
"armchair": 30,
|
| 232 |
+
"ashcan": 138,
|
| 233 |
+
"awning": 86,
|
| 234 |
+
"bag": 115,
|
| 235 |
+
"ball": 119,
|
| 236 |
+
"bannister": 95,
|
| 237 |
+
"bar": 77,
|
| 238 |
+
"barrel": 111,
|
| 239 |
+
"base": 40,
|
| 240 |
+
"basket": 112,
|
| 241 |
+
"bathtub": 37,
|
| 242 |
+
"bed ": 7,
|
| 243 |
+
"bench": 69,
|
| 244 |
+
"bicycle": 127,
|
| 245 |
+
"blanket": 131,
|
| 246 |
+
"blind": 63,
|
| 247 |
+
"boat": 76,
|
| 248 |
+
"book": 67,
|
| 249 |
+
"bookcase": 62,
|
| 250 |
+
"booth": 88,
|
| 251 |
+
"bottle": 98,
|
| 252 |
+
"box": 41,
|
| 253 |
+
"bridge": 61,
|
| 254 |
+
"buffet": 99,
|
| 255 |
+
"building": 1,
|
| 256 |
+
"bulletin board": 144,
|
| 257 |
+
"bus": 80,
|
| 258 |
+
"cabinet": 10,
|
| 259 |
+
"canopy": 106,
|
| 260 |
+
"car": 20,
|
| 261 |
+
"case": 55,
|
| 262 |
+
"ceiling": 5,
|
| 263 |
+
"chair": 19,
|
| 264 |
+
"chandelier": 85,
|
| 265 |
+
"chest of drawers": 44,
|
| 266 |
+
"clock": 148,
|
| 267 |
+
"coffee table": 64,
|
| 268 |
+
"column": 42,
|
| 269 |
+
"computer": 74,
|
| 270 |
+
"conveyer belt": 105,
|
| 271 |
+
"counter": 45,
|
| 272 |
+
"countertop": 70,
|
| 273 |
+
"cradle": 117,
|
| 274 |
+
"crt screen": 141,
|
| 275 |
+
"curtain": 18,
|
| 276 |
+
"cushion": 39,
|
| 277 |
+
"desk": 33,
|
| 278 |
+
"dirt track": 91,
|
| 279 |
+
"dishwasher": 129,
|
| 280 |
+
"door": 14,
|
| 281 |
+
"earth": 13,
|
| 282 |
+
"escalator": 96,
|
| 283 |
+
"fan": 139,
|
| 284 |
+
"fence": 32,
|
| 285 |
+
"field": 29,
|
| 286 |
+
"fireplace": 49,
|
| 287 |
+
"flag": 149,
|
| 288 |
+
"floor": 3,
|
| 289 |
+
"flower": 66,
|
| 290 |
+
"food": 120,
|
| 291 |
+
"fountain": 104,
|
| 292 |
+
"glass": 147,
|
| 293 |
+
"grandstand": 51,
|
| 294 |
+
"grass": 9,
|
| 295 |
+
"hill": 68,
|
| 296 |
+
"hood": 133,
|
| 297 |
+
"house": 25,
|
| 298 |
+
"hovel": 79,
|
| 299 |
+
"kitchen island": 73,
|
| 300 |
+
"lake": 128,
|
| 301 |
+
"lamp": 36,
|
| 302 |
+
"land": 94,
|
| 303 |
+
"light": 82,
|
| 304 |
+
"microwave": 124,
|
| 305 |
+
"minibike": 116,
|
| 306 |
+
"mirror": 27,
|
| 307 |
+
"monitor": 143,
|
| 308 |
+
"mountain": 16,
|
| 309 |
+
"ottoman": 97,
|
| 310 |
+
"oven": 118,
|
| 311 |
+
"painting": 22,
|
| 312 |
+
"palm": 72,
|
| 313 |
+
"path": 52,
|
| 314 |
+
"person": 12,
|
| 315 |
+
"pier": 140,
|
| 316 |
+
"pillow": 57,
|
| 317 |
+
"plant": 17,
|
| 318 |
+
"plate": 142,
|
| 319 |
+
"plaything": 108,
|
| 320 |
+
"pole": 93,
|
| 321 |
+
"pool table": 56,
|
| 322 |
+
"poster": 100,
|
| 323 |
+
"pot": 125,
|
| 324 |
+
"radiator": 146,
|
| 325 |
+
"railing": 38,
|
| 326 |
+
"refrigerator": 50,
|
| 327 |
+
"river": 60,
|
| 328 |
+
"road": 6,
|
| 329 |
+
"rock": 34,
|
| 330 |
+
"rug": 28,
|
| 331 |
+
"runway": 54,
|
| 332 |
+
"sand": 46,
|
| 333 |
+
"sconce": 134,
|
| 334 |
+
"screen": 130,
|
| 335 |
+
"screen door": 58,
|
| 336 |
+
"sculpture": 132,
|
| 337 |
+
"sea": 26,
|
| 338 |
+
"seat": 31,
|
| 339 |
+
"shelf": 24,
|
| 340 |
+
"ship": 103,
|
| 341 |
+
"shower": 145,
|
| 342 |
+
"sidewalk": 11,
|
| 343 |
+
"signboard": 43,
|
| 344 |
+
"sink": 47,
|
| 345 |
+
"sky": 2,
|
| 346 |
+
"skyscraper": 48,
|
| 347 |
+
"sofa": 23,
|
| 348 |
+
"stage": 101,
|
| 349 |
+
"stairs": 53,
|
| 350 |
+
"stairway": 59,
|
| 351 |
+
"step": 121,
|
| 352 |
+
"stool": 110,
|
| 353 |
+
"stove": 71,
|
| 354 |
+
"streetlight": 87,
|
| 355 |
+
"swimming pool": 109,
|
| 356 |
+
"swivel chair": 75,
|
| 357 |
+
"table": 15,
|
| 358 |
+
"tank": 122,
|
| 359 |
+
"television receiver": 89,
|
| 360 |
+
"tent": 114,
|
| 361 |
+
"toilet": 65,
|
| 362 |
+
"towel": 81,
|
| 363 |
+
"tower": 84,
|
| 364 |
+
"trade name": 123,
|
| 365 |
+
"traffic light": 136,
|
| 366 |
+
"tray": 137,
|
| 367 |
+
"tree": 4,
|
| 368 |
+
"truck": 83,
|
| 369 |
+
"van": 102,
|
| 370 |
+
"vase": 135,
|
| 371 |
+
"wall": 0,
|
| 372 |
+
"wardrobe": 35,
|
| 373 |
+
"washer": 107,
|
| 374 |
+
"water": 21,
|
| 375 |
+
"waterfall": 113,
|
| 376 |
+
"windowpane": 8
|
| 377 |
+
},
|
| 378 |
+
"max_depth": 10.0,
|
| 379 |
+
"min_depth": 0.001,
|
| 380 |
+
"model_type": "tipsv2_dpt",
|
| 381 |
+
"neck_hidden_sizes": [
|
| 382 |
+
128,
|
| 383 |
+
256,
|
| 384 |
+
512,
|
| 385 |
+
1024
|
| 386 |
+
],
|
| 387 |
+
"num_depth_bins": 256,
|
| 388 |
+
"readout_act": "gelu_pytorch_tanh",
|
| 389 |
+
"reassemble_factors": [
|
| 390 |
+
4,
|
| 391 |
+
2,
|
| 392 |
+
1,
|
| 393 |
+
0.5
|
| 394 |
+
],
|
| 395 |
+
"semantic_loss_ignore_index": 255,
|
| 396 |
+
"transformers_version": "5.10.0.dev0"
|
| 397 |
+
}
|
configuration_dpt.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""TIPSv2 DPT head configuration."""
|
| 2 |
+
|
| 3 |
+
from transformers import PretrainedConfig
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
_BACKBONE_REPO_BY_HIDDEN_SIZE = {
|
| 7 |
+
768: "google/tipsv2-b14",
|
| 8 |
+
1024: "google/tipsv2-l14",
|
| 9 |
+
1152: "google/tipsv2-so400m14",
|
| 10 |
+
1536: "google/tipsv2-g14",
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
class TIPSv2DPTConfig(PretrainedConfig):
|
| 15 |
+
"""Configuration for TIPSv2 DPT dense prediction heads."""
|
| 16 |
+
|
| 17 |
+
model_type = "tipsv2_dpt"
|
| 18 |
+
|
| 19 |
+
def __init__(
|
| 20 |
+
self,
|
| 21 |
+
backbone_config=None,
|
| 22 |
+
neck_hidden_sizes=(96, 192, 384, 768),
|
| 23 |
+
fusion_hidden_size=256,
|
| 24 |
+
reassemble_factors=(4, 2, 1, 0.5),
|
| 25 |
+
readout_type="project",
|
| 26 |
+
num_depth_bins=256,
|
| 27 |
+
min_depth=1e-3,
|
| 28 |
+
max_depth=10.0,
|
| 29 |
+
**kwargs,
|
| 30 |
+
):
|
| 31 |
+
super().__init__(**kwargs)
|
| 32 |
+
backbone_config = backbone_config or {}
|
| 33 |
+
hidden_size = backbone_config.get("hidden_size", 768)
|
| 34 |
+
out_indices = backbone_config.get("out_indices", (3, 6, 9, 12))
|
| 35 |
+
self.backbone_repo = _BACKBONE_REPO_BY_HIDDEN_SIZE[hidden_size]
|
| 36 |
+
self.embed_dim = hidden_size
|
| 37 |
+
self.channels = fusion_hidden_size
|
| 38 |
+
self.post_process_channels = list(neck_hidden_sizes)
|
| 39 |
+
self.block_indices = [out_index - 1 for out_index in out_indices]
|
| 40 |
+
self.readout_type = readout_type
|
| 41 |
+
self.num_depth_bins = num_depth_bins
|
| 42 |
+
self.min_depth = min_depth
|
| 43 |
+
self.max_depth = max_depth
|
| 44 |
+
self.num_seg_classes = self.num_labels
|
dpt_head.py
ADDED
|
@@ -0,0 +1,702 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 Google LLC
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
|
| 16 |
+
"""DPT (Dense Prediction Transformer) depth head in PyTorch.
|
| 17 |
+
|
| 18 |
+
Ported from the Scenic/Flax implementation at:
|
| 19 |
+
research/vision/scene_understanding/imsight/modules/dpt.py
|
| 20 |
+
scenic/projects/dense_features/models/decoders.py
|
| 21 |
+
|
| 22 |
+
Architecture:
|
| 23 |
+
ReassembleBlocks → 4×Conv3x3 → 4×FeatureFusionBlock → project → DepthHead
|
| 24 |
+
"""
|
| 25 |
+
|
| 26 |
+
import io
|
| 27 |
+
import os
|
| 28 |
+
import urllib.request
|
| 29 |
+
import zipfile
|
| 30 |
+
|
| 31 |
+
import numpy as np
|
| 32 |
+
import torch
|
| 33 |
+
from torch import nn
|
| 34 |
+
import torch.nn.functional as F
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
# ── Building blocks ─────────────────────────────────────────────────────────
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
class PreActResidualConvUnit(nn.Module):
|
| 41 |
+
"""Pre-activation residual convolution unit."""
|
| 42 |
+
|
| 43 |
+
def __init__(self, features: int):
|
| 44 |
+
super().__init__()
|
| 45 |
+
self.conv1 = nn.Conv2d(features, features, 3, padding=1, bias=False)
|
| 46 |
+
self.conv2 = nn.Conv2d(features, features, 3, padding=1, bias=False)
|
| 47 |
+
|
| 48 |
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
| 49 |
+
residual = x
|
| 50 |
+
x = F.relu(x)
|
| 51 |
+
x = self.conv1(x)
|
| 52 |
+
x = F.relu(x)
|
| 53 |
+
x = self.conv2(x)
|
| 54 |
+
return x + residual
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
class FeatureFusionBlock(nn.Module):
|
| 58 |
+
"""Fuses features with optional residual input, then upsamples 2×."""
|
| 59 |
+
|
| 60 |
+
def __init__(self, features: int, has_residual: bool = False,
|
| 61 |
+
expand: bool = False):
|
| 62 |
+
super().__init__()
|
| 63 |
+
self.has_residual = has_residual
|
| 64 |
+
if has_residual:
|
| 65 |
+
self.residual_unit = PreActResidualConvUnit(features)
|
| 66 |
+
self.main_unit = PreActResidualConvUnit(features)
|
| 67 |
+
out_features = features // 2 if expand else features
|
| 68 |
+
self.out_conv = nn.Conv2d(features, out_features, 1, bias=True)
|
| 69 |
+
|
| 70 |
+
def forward(self, x: torch.Tensor,
|
| 71 |
+
residual: torch.Tensor = None) -> torch.Tensor:
|
| 72 |
+
if self.has_residual and residual is not None:
|
| 73 |
+
if residual.shape != x.shape:
|
| 74 |
+
residual = F.interpolate(
|
| 75 |
+
residual, size=x.shape[2:], mode="bilinear",
|
| 76 |
+
align_corners=False)
|
| 77 |
+
residual = self.residual_unit(residual)
|
| 78 |
+
x = x + residual
|
| 79 |
+
x = self.main_unit(x)
|
| 80 |
+
# Upsample 2× with align_corners=True (matches Scenic reference)
|
| 81 |
+
x = F.interpolate(x, scale_factor=2, mode="bilinear",
|
| 82 |
+
align_corners=True)
|
| 83 |
+
x = self.out_conv(x)
|
| 84 |
+
return x
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
class ReassembleBlocks(nn.Module):
|
| 88 |
+
"""Projects and resizes intermediate ViT features to different scales."""
|
| 89 |
+
|
| 90 |
+
def __init__(self, input_embed_dim: int = 1024,
|
| 91 |
+
out_channels: tuple = (128, 256, 512, 1024),
|
| 92 |
+
readout_type: str = "project"):
|
| 93 |
+
super().__init__()
|
| 94 |
+
self.readout_type = readout_type
|
| 95 |
+
|
| 96 |
+
# 1×1 conv to project to per-level channels
|
| 97 |
+
self.out_projections = nn.ModuleList([
|
| 98 |
+
nn.Conv2d(input_embed_dim, ch, 1) for ch in out_channels
|
| 99 |
+
])
|
| 100 |
+
|
| 101 |
+
# Spatial resize layers: 4× up, 2× up, identity, 2× down
|
| 102 |
+
self.resize_layers = nn.ModuleList([
|
| 103 |
+
nn.ConvTranspose2d(out_channels[0], out_channels[0],
|
| 104 |
+
kernel_size=4, stride=4, padding=0),
|
| 105 |
+
nn.ConvTranspose2d(out_channels[1], out_channels[1],
|
| 106 |
+
kernel_size=2, stride=2, padding=0),
|
| 107 |
+
nn.Identity(),
|
| 108 |
+
nn.Conv2d(out_channels[3], out_channels[3], 3, stride=2,
|
| 109 |
+
padding=1),
|
| 110 |
+
])
|
| 111 |
+
|
| 112 |
+
# Readout projection (concatenate cls_token with patch features)
|
| 113 |
+
if readout_type == "project":
|
| 114 |
+
self.readout_projects = nn.ModuleList([
|
| 115 |
+
nn.Linear(2 * input_embed_dim, input_embed_dim)
|
| 116 |
+
for _ in out_channels
|
| 117 |
+
])
|
| 118 |
+
|
| 119 |
+
def forward(self, features):
|
| 120 |
+
"""Process list of (cls_token, spatial_features) tuples.
|
| 121 |
+
|
| 122 |
+
Args:
|
| 123 |
+
features: list of (cls_token [B,D], patch_feats [B,D,H,W])
|
| 124 |
+
|
| 125 |
+
Returns:
|
| 126 |
+
list of tensors at different scales.
|
| 127 |
+
"""
|
| 128 |
+
out = []
|
| 129 |
+
for i, (cls_token, x) in enumerate(features):
|
| 130 |
+
B, D, H, W = x.shape
|
| 131 |
+
|
| 132 |
+
if self.readout_type == "project":
|
| 133 |
+
# Flatten spatial → (B, HW, D)
|
| 134 |
+
x_flat = x.flatten(2).transpose(1, 2)
|
| 135 |
+
# Expand cls_token → (B, HW, D)
|
| 136 |
+
readout = cls_token.unsqueeze(1).expand(-1, x_flat.shape[1], -1)
|
| 137 |
+
# Concat + project + GELU
|
| 138 |
+
x_cat = torch.cat([x_flat, readout], dim=-1)
|
| 139 |
+
x_proj = F.gelu(self.readout_projects[i](x_cat))
|
| 140 |
+
# Reshape back to spatial
|
| 141 |
+
x = x_proj.transpose(1, 2).reshape(B, D, H, W)
|
| 142 |
+
|
| 143 |
+
# 1×1 projection
|
| 144 |
+
x = self.out_projections[i](x)
|
| 145 |
+
# Spatial resize
|
| 146 |
+
x = self.resize_layers[i](x)
|
| 147 |
+
out.append(x)
|
| 148 |
+
return out
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
class DPTDepthHead(nn.Module):
|
| 152 |
+
"""Full DPT head + depth classification decoder.
|
| 153 |
+
|
| 154 |
+
Takes 4 intermediate ViT features and produces a depth map.
|
| 155 |
+
"""
|
| 156 |
+
|
| 157 |
+
def __init__(self, input_embed_dim: int = 1024,
|
| 158 |
+
channels: int = 256,
|
| 159 |
+
post_process_channels: tuple = (128, 256, 512, 1024),
|
| 160 |
+
readout_type: str = "project",
|
| 161 |
+
num_depth_bins: int = 256,
|
| 162 |
+
min_depth: float = 1e-3,
|
| 163 |
+
max_depth: float = 10.0):
|
| 164 |
+
super().__init__()
|
| 165 |
+
self.num_depth_bins = num_depth_bins
|
| 166 |
+
self.min_depth = min_depth
|
| 167 |
+
self.max_depth = max_depth
|
| 168 |
+
|
| 169 |
+
# Reassemble: project + resize
|
| 170 |
+
self.reassemble = ReassembleBlocks(
|
| 171 |
+
input_embed_dim=input_embed_dim,
|
| 172 |
+
out_channels=post_process_channels,
|
| 173 |
+
readout_type=readout_type,
|
| 174 |
+
)
|
| 175 |
+
|
| 176 |
+
# 3×3 convs to map each level to `channels`
|
| 177 |
+
self.convs = nn.ModuleList([
|
| 178 |
+
nn.Conv2d(ch, channels, 3, padding=1, bias=False)
|
| 179 |
+
for ch in post_process_channels
|
| 180 |
+
])
|
| 181 |
+
|
| 182 |
+
# Fusion blocks: first has no residual, rest have residual
|
| 183 |
+
self.fusion_blocks = nn.ModuleList([
|
| 184 |
+
FeatureFusionBlock(channels, has_residual=False),
|
| 185 |
+
FeatureFusionBlock(channels, has_residual=True),
|
| 186 |
+
FeatureFusionBlock(channels, has_residual=True),
|
| 187 |
+
FeatureFusionBlock(channels, has_residual=True),
|
| 188 |
+
])
|
| 189 |
+
|
| 190 |
+
# Final projection
|
| 191 |
+
self.project = nn.Conv2d(channels, channels, 3, padding=1, bias=True)
|
| 192 |
+
|
| 193 |
+
# Depth classification head (Dense layer)
|
| 194 |
+
self.depth_head = nn.Linear(channels, num_depth_bins)
|
| 195 |
+
|
| 196 |
+
def forward(self, intermediate_features, image_size=None):
|
| 197 |
+
"""Run DPT depth prediction.
|
| 198 |
+
|
| 199 |
+
Args:
|
| 200 |
+
intermediate_features: list of 4 (cls_token, patch_feats) tuples
|
| 201 |
+
image_size: (H, W) to resize output to, or None
|
| 202 |
+
|
| 203 |
+
Returns:
|
| 204 |
+
depth map tensor (B, 1, H, W)
|
| 205 |
+
"""
|
| 206 |
+
# Reassemble
|
| 207 |
+
x = self.reassemble(intermediate_features)
|
| 208 |
+
# 3×3 conv per level
|
| 209 |
+
x = [self.convs[i](feat) for i, feat in enumerate(x)]
|
| 210 |
+
|
| 211 |
+
# Fuse bottom-up: start from deepest (x[-1])
|
| 212 |
+
out = self.fusion_blocks[0](x[-1])
|
| 213 |
+
for i in range(1, 4):
|
| 214 |
+
out = self.fusion_blocks[i](out, residual=x[-(i + 1)])
|
| 215 |
+
|
| 216 |
+
# Project
|
| 217 |
+
out = self.project(out)
|
| 218 |
+
out = F.relu(out)
|
| 219 |
+
|
| 220 |
+
# Depth classification
|
| 221 |
+
# out: (B, C, H, W) → (B, H, W, C)
|
| 222 |
+
out = out.permute(0, 2, 3, 1)
|
| 223 |
+
out = self.depth_head(out) # (B, H, W, num_bins)
|
| 224 |
+
|
| 225 |
+
# Classification-based depth prediction
|
| 226 |
+
bin_centers = torch.linspace(
|
| 227 |
+
self.min_depth, self.max_depth, self.num_depth_bins,
|
| 228 |
+
device=out.device)
|
| 229 |
+
out = F.relu(out) + self.min_depth
|
| 230 |
+
out_norm = out / out.sum(dim=-1, keepdim=True)
|
| 231 |
+
depth = torch.einsum("bhwn,n->bhw", out_norm, bin_centers)
|
| 232 |
+
depth = depth.unsqueeze(1) # (B, 1, H, W)
|
| 233 |
+
|
| 234 |
+
# Resize to original image size
|
| 235 |
+
if image_size is not None:
|
| 236 |
+
depth = F.interpolate(depth, size=image_size, mode="bilinear",
|
| 237 |
+
align_corners=False)
|
| 238 |
+
|
| 239 |
+
return depth
|
| 240 |
+
|
| 241 |
+
|
| 242 |
+
class DPTNormalsHead(nn.Module):
|
| 243 |
+
"""Full DPT head + surface normals decoder.
|
| 244 |
+
|
| 245 |
+
Takes 4 intermediate ViT features and produces a normal map.
|
| 246 |
+
"""
|
| 247 |
+
|
| 248 |
+
def __init__(self, input_embed_dim: int = 1024,
|
| 249 |
+
channels: int = 256,
|
| 250 |
+
post_process_channels: tuple = (128, 256, 512, 1024),
|
| 251 |
+
readout_type: str = "project"):
|
| 252 |
+
super().__init__()
|
| 253 |
+
|
| 254 |
+
# Reassemble: project + resize
|
| 255 |
+
self.reassemble = ReassembleBlocks(
|
| 256 |
+
input_embed_dim=input_embed_dim,
|
| 257 |
+
out_channels=post_process_channels,
|
| 258 |
+
readout_type=readout_type,
|
| 259 |
+
)
|
| 260 |
+
|
| 261 |
+
# 3×3 convs to map each level to `channels`
|
| 262 |
+
self.convs = nn.ModuleList([
|
| 263 |
+
nn.Conv2d(ch, channels, 3, padding=1, bias=False)
|
| 264 |
+
for ch in post_process_channels
|
| 265 |
+
])
|
| 266 |
+
|
| 267 |
+
# Fusion blocks: first has no residual, rest have residual
|
| 268 |
+
self.fusion_blocks = nn.ModuleList([
|
| 269 |
+
FeatureFusionBlock(channels, has_residual=False),
|
| 270 |
+
FeatureFusionBlock(channels, has_residual=True),
|
| 271 |
+
FeatureFusionBlock(channels, has_residual=True),
|
| 272 |
+
FeatureFusionBlock(channels, has_residual=True),
|
| 273 |
+
])
|
| 274 |
+
|
| 275 |
+
# Final projection
|
| 276 |
+
self.project = nn.Conv2d(channels, channels, 3, padding=1, bias=True)
|
| 277 |
+
|
| 278 |
+
# Normals head (Dense layer)
|
| 279 |
+
self.normals_head = nn.Linear(channels, 3)
|
| 280 |
+
|
| 281 |
+
def forward(self, intermediate_features, image_size=None):
|
| 282 |
+
"""Run DPT normals prediction.
|
| 283 |
+
|
| 284 |
+
Args:
|
| 285 |
+
intermediate_features: list of 4 (cls_token, patch_feats) tuples
|
| 286 |
+
image_size: (H, W) to resize output to, or None
|
| 287 |
+
|
| 288 |
+
Returns:
|
| 289 |
+
normal map tensor (B, 3, H, W)
|
| 290 |
+
"""
|
| 291 |
+
# Reassemble
|
| 292 |
+
x = self.reassemble(intermediate_features)
|
| 293 |
+
# 3×3 conv per level
|
| 294 |
+
x = [self.convs[i](feat) for i, feat in enumerate(x)]
|
| 295 |
+
|
| 296 |
+
# Fuse bottom-up: start from deepest (x[-1])
|
| 297 |
+
out = self.fusion_blocks[0](x[-1])
|
| 298 |
+
for i in range(1, 4):
|
| 299 |
+
out = self.fusion_blocks[i](out, residual=x[-(i + 1)])
|
| 300 |
+
|
| 301 |
+
# Project
|
| 302 |
+
out = self.project(out)
|
| 303 |
+
|
| 304 |
+
# Normals head
|
| 305 |
+
# out: (B, C, H, W) → (B, H, W, C)
|
| 306 |
+
out = out.permute(0, 2, 3, 1)
|
| 307 |
+
out = self.normals_head(out) # (B, H, W, 3)
|
| 308 |
+
|
| 309 |
+
# Normalize to unit length
|
| 310 |
+
out = F.normalize(out, p=2, dim=-1)
|
| 311 |
+
|
| 312 |
+
# Resize to original image size
|
| 313 |
+
if image_size is not None:
|
| 314 |
+
# PyTorch interpolate expects (B, C, H, W)
|
| 315 |
+
out = out.permute(0, 3, 1, 2)
|
| 316 |
+
out = F.interpolate(out, size=image_size, mode="bilinear",
|
| 317 |
+
align_corners=False)
|
| 318 |
+
else:
|
| 319 |
+
out = out.permute(0, 3, 1, 2)
|
| 320 |
+
|
| 321 |
+
return out
|
| 322 |
+
|
| 323 |
+
|
| 324 |
+
class DPTSegmentationHead(nn.Module):
|
| 325 |
+
"""Full DPT head + segmentation decoder.
|
| 326 |
+
|
| 327 |
+
Takes 4 intermediate ViT features and produces a segmentation map.
|
| 328 |
+
"""
|
| 329 |
+
|
| 330 |
+
def __init__(self, input_embed_dim: int = 1024,
|
| 331 |
+
channels: int = 256,
|
| 332 |
+
post_process_channels: tuple = (128, 256, 512, 1024),
|
| 333 |
+
readout_type: str = "project",
|
| 334 |
+
num_classes: int = 150):
|
| 335 |
+
super().__init__()
|
| 336 |
+
|
| 337 |
+
# Reassemble: project + resize
|
| 338 |
+
self.reassemble = ReassembleBlocks(
|
| 339 |
+
input_embed_dim=input_embed_dim,
|
| 340 |
+
out_channels=post_process_channels,
|
| 341 |
+
readout_type=readout_type,
|
| 342 |
+
)
|
| 343 |
+
|
| 344 |
+
# 3×3 convs to map each level to `channels`
|
| 345 |
+
self.convs = nn.ModuleList([
|
| 346 |
+
nn.Conv2d(ch, channels, 3, padding=1, bias=False)
|
| 347 |
+
for ch in post_process_channels
|
| 348 |
+
])
|
| 349 |
+
|
| 350 |
+
# Fusion blocks: first has no residual, rest have residual
|
| 351 |
+
self.fusion_blocks = nn.ModuleList([
|
| 352 |
+
FeatureFusionBlock(channels, has_residual=False),
|
| 353 |
+
FeatureFusionBlock(channels, has_residual=True),
|
| 354 |
+
FeatureFusionBlock(channels, has_residual=True),
|
| 355 |
+
FeatureFusionBlock(channels, has_residual=True),
|
| 356 |
+
])
|
| 357 |
+
|
| 358 |
+
# Final projection
|
| 359 |
+
self.project = nn.Conv2d(channels, channels, 3, padding=1, bias=True)
|
| 360 |
+
|
| 361 |
+
# Segmentation head (Dense layer)
|
| 362 |
+
self.segmentation_head = nn.Linear(channels, num_classes)
|
| 363 |
+
|
| 364 |
+
def forward(self, intermediate_features, image_size=None):
|
| 365 |
+
"""Run DPT segmentation prediction.
|
| 366 |
+
|
| 367 |
+
Args:
|
| 368 |
+
intermediate_features: list of 4 (cls_token, patch_feats) tuples
|
| 369 |
+
image_size: (H, W) to resize output to, or None
|
| 370 |
+
|
| 371 |
+
Returns:
|
| 372 |
+
segmentation map tensor (B, num_classes, H, W)
|
| 373 |
+
"""
|
| 374 |
+
# Reassemble
|
| 375 |
+
x = self.reassemble(intermediate_features)
|
| 376 |
+
# 3×3 conv per level
|
| 377 |
+
x = [self.convs[i](feat) for i, feat in enumerate(x)]
|
| 378 |
+
|
| 379 |
+
# Fuse bottom-up: start from deepest (x[-1])
|
| 380 |
+
out = self.fusion_blocks[0](x[-1])
|
| 381 |
+
for i in range(1, 4):
|
| 382 |
+
out = self.fusion_blocks[i](out, residual=x[-(i + 1)])
|
| 383 |
+
|
| 384 |
+
# Project
|
| 385 |
+
out = self.project(out)
|
| 386 |
+
|
| 387 |
+
# Segmentation head
|
| 388 |
+
# out: (B, C, H, W) → (B, H, W, C)
|
| 389 |
+
out = out.permute(0, 2, 3, 1)
|
| 390 |
+
out = self.segmentation_head(out) # (B, H, W, num_classes)
|
| 391 |
+
|
| 392 |
+
# Resize to original image size
|
| 393 |
+
if image_size is not None:
|
| 394 |
+
# PyTorch interpolate expects (B, C, H, W)
|
| 395 |
+
out = out.permute(0, 3, 1, 2)
|
| 396 |
+
out = F.interpolate(out, size=image_size, mode="bilinear",
|
| 397 |
+
align_corners=False)
|
| 398 |
+
else:
|
| 399 |
+
out = out.permute(0, 3, 1, 2)
|
| 400 |
+
|
| 401 |
+
return out
|
| 402 |
+
|
| 403 |
+
|
| 404 |
+
# ── Weight loading from Scenic/Flax checkpoint ─────────────────────────────
|
| 405 |
+
|
| 406 |
+
|
| 407 |
+
def _load_npy_from_zip(zf, name):
|
| 408 |
+
"""Load a single .npy array from a zipfile."""
|
| 409 |
+
with zf.open(name) as f:
|
| 410 |
+
return np.load(io.BytesIO(f.read()))
|
| 411 |
+
|
| 412 |
+
|
| 413 |
+
def _conv_kernel_flax_to_torch(w):
|
| 414 |
+
"""Convert Flax conv kernel (H,W,Cin,Cout) → PyTorch (Cout,Cin,H,W)."""
|
| 415 |
+
return torch.from_numpy(w.transpose(3, 2, 0, 1).copy())
|
| 416 |
+
|
| 417 |
+
|
| 418 |
+
def _conv_transpose_kernel_flax_to_torch(w):
|
| 419 |
+
"""Convert Flax ConvTranspose kernel (H,W,Cin,Cout) → PyTorch (Cin,Cout,H,W)."""
|
| 420 |
+
return torch.from_numpy(w.transpose(2, 3, 0, 1).copy())
|
| 421 |
+
|
| 422 |
+
|
| 423 |
+
def _linear_kernel_flax_to_torch(w):
|
| 424 |
+
"""Convert Flax Dense kernel (in,out) → PyTorch Linear (out,in)."""
|
| 425 |
+
return torch.from_numpy(w.T.copy())
|
| 426 |
+
|
| 427 |
+
|
| 428 |
+
def _bias(w):
|
| 429 |
+
return torch.from_numpy(w.copy())
|
| 430 |
+
|
| 431 |
+
|
| 432 |
+
def load_dpt_weights(model: DPTDepthHead, zip_path: str):
|
| 433 |
+
"""Load Scenic/Flax DPT weights from a zip/npz file into PyTorch model."""
|
| 434 |
+
zf = zipfile.ZipFile(zip_path, "r")
|
| 435 |
+
npy = lambda name: _load_npy_from_zip(zf, name)
|
| 436 |
+
sd = {}
|
| 437 |
+
prefix = "decoder/dpt/"
|
| 438 |
+
|
| 439 |
+
# --- ReassembleBlocks ---
|
| 440 |
+
for i in range(4):
|
| 441 |
+
# out_projections (Conv2d 1×1)
|
| 442 |
+
sd[f"reassemble.out_projections.{i}.weight"] = _conv_kernel_flax_to_torch(
|
| 443 |
+
npy(f"{prefix}reassemble_blocks/out_projection_{i}/kernel.npy"))
|
| 444 |
+
sd[f"reassemble.out_projections.{i}.bias"] = _bias(
|
| 445 |
+
npy(f"{prefix}reassemble_blocks/out_projection_{i}/bias.npy"))
|
| 446 |
+
|
| 447 |
+
# readout_projects (Linear)
|
| 448 |
+
sd[f"reassemble.readout_projects.{i}.weight"] = _linear_kernel_flax_to_torch(
|
| 449 |
+
npy(f"{prefix}reassemble_blocks/readout_projects_{i}/kernel.npy"))
|
| 450 |
+
sd[f"reassemble.readout_projects.{i}.bias"] = _bias(
|
| 451 |
+
npy(f"{prefix}reassemble_blocks/readout_projects_{i}/bias.npy"))
|
| 452 |
+
|
| 453 |
+
# resize_layers: 0=ConvTranspose, 1=ConvTranspose, 2=Identity, 3=Conv
|
| 454 |
+
sd["reassemble.resize_layers.0.weight"] = _conv_transpose_kernel_flax_to_torch(
|
| 455 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_0/kernel.npy"))
|
| 456 |
+
sd["reassemble.resize_layers.0.bias"] = _bias(
|
| 457 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_0/bias.npy"))
|
| 458 |
+
sd["reassemble.resize_layers.1.weight"] = _conv_transpose_kernel_flax_to_torch(
|
| 459 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_1/kernel.npy"))
|
| 460 |
+
sd["reassemble.resize_layers.1.bias"] = _bias(
|
| 461 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_1/bias.npy"))
|
| 462 |
+
# resize_layers_2 = Identity (no weights)
|
| 463 |
+
sd["reassemble.resize_layers.3.weight"] = _conv_kernel_flax_to_torch(
|
| 464 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_3/kernel.npy"))
|
| 465 |
+
sd["reassemble.resize_layers.3.bias"] = _bias(
|
| 466 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_3/bias.npy"))
|
| 467 |
+
|
| 468 |
+
# --- Convs (3×3, no bias) ---
|
| 469 |
+
for i in range(4):
|
| 470 |
+
sd[f"convs.{i}.weight"] = _conv_kernel_flax_to_torch(
|
| 471 |
+
npy(f"{prefix}convs_{i}/kernel.npy"))
|
| 472 |
+
|
| 473 |
+
# --- Fusion blocks ---
|
| 474 |
+
for i in range(4):
|
| 475 |
+
fb = f"{prefix}fusion_blocks_{i}/"
|
| 476 |
+
if i == 0:
|
| 477 |
+
# No residual unit, only 1 PreActResidualConvUnit
|
| 478 |
+
sd[f"fusion_blocks.{i}.main_unit.conv1.weight"] = _conv_kernel_flax_to_torch(
|
| 479 |
+
npy(f"{fb}PreActResidualConvUnit_0/conv1/kernel.npy"))
|
| 480 |
+
sd[f"fusion_blocks.{i}.main_unit.conv2.weight"] = _conv_kernel_flax_to_torch(
|
| 481 |
+
npy(f"{fb}PreActResidualConvUnit_0/conv2/kernel.npy"))
|
| 482 |
+
else:
|
| 483 |
+
# Residual unit (index 0) + main unit (index 1)
|
| 484 |
+
sd[f"fusion_blocks.{i}.residual_unit.conv1.weight"] = _conv_kernel_flax_to_torch(
|
| 485 |
+
npy(f"{fb}PreActResidualConvUnit_0/conv1/kernel.npy"))
|
| 486 |
+
sd[f"fusion_blocks.{i}.residual_unit.conv2.weight"] = _conv_kernel_flax_to_torch(
|
| 487 |
+
npy(f"{fb}PreActResidualConvUnit_0/conv2/kernel.npy"))
|
| 488 |
+
sd[f"fusion_blocks.{i}.main_unit.conv1.weight"] = _conv_kernel_flax_to_torch(
|
| 489 |
+
npy(f"{fb}PreActResidualConvUnit_1/conv1/kernel.npy"))
|
| 490 |
+
sd[f"fusion_blocks.{i}.main_unit.conv2.weight"] = _conv_kernel_flax_to_torch(
|
| 491 |
+
npy(f"{fb}PreActResidualConvUnit_1/conv2/kernel.npy"))
|
| 492 |
+
|
| 493 |
+
# out_conv (Conv2d 1×1)
|
| 494 |
+
sd[f"fusion_blocks.{i}.out_conv.weight"] = _conv_kernel_flax_to_torch(
|
| 495 |
+
npy(f"{fb}Conv_0/kernel.npy"))
|
| 496 |
+
sd[f"fusion_blocks.{i}.out_conv.bias"] = _bias(
|
| 497 |
+
npy(f"{fb}Conv_0/bias.npy"))
|
| 498 |
+
|
| 499 |
+
# --- Project ---
|
| 500 |
+
sd["project.weight"] = _conv_kernel_flax_to_torch(
|
| 501 |
+
npy(f"{prefix}project/kernel.npy"))
|
| 502 |
+
sd["project.bias"] = _bias(
|
| 503 |
+
npy(f"{prefix}project/bias.npy"))
|
| 504 |
+
|
| 505 |
+
# --- Depth classification head ---
|
| 506 |
+
sd["depth_head.weight"] = _linear_kernel_flax_to_torch(
|
| 507 |
+
npy("decoder/pixel_depth_classif/kernel.npy"))
|
| 508 |
+
sd["depth_head.bias"] = _bias(
|
| 509 |
+
npy("decoder/pixel_depth_classif/bias.npy"))
|
| 510 |
+
|
| 511 |
+
zf.close()
|
| 512 |
+
|
| 513 |
+
# Load into model
|
| 514 |
+
missing, unexpected = model.load_state_dict(sd, strict=True)
|
| 515 |
+
if missing:
|
| 516 |
+
print(f"WARNING: Missing keys: {missing}")
|
| 517 |
+
if unexpected:
|
| 518 |
+
print(f"WARNING: Unexpected keys: {unexpected}")
|
| 519 |
+
print(f"Loaded DPT depth head weights ({len(sd)} tensors)")
|
| 520 |
+
return model
|
| 521 |
+
|
| 522 |
+
|
| 523 |
+
def load_normals_weights(model: DPTNormalsHead, zip_path: str):
|
| 524 |
+
"""Load Scenic/Flax DPT weights from a zip/npz file into PyTorch model."""
|
| 525 |
+
zf = zipfile.ZipFile(zip_path, "r")
|
| 526 |
+
npy = lambda name: _load_npy_from_zip(zf, name)
|
| 527 |
+
sd = {}
|
| 528 |
+
prefix = "decoder/dpt/"
|
| 529 |
+
|
| 530 |
+
# --- ReassembleBlocks ---
|
| 531 |
+
for i in range(4):
|
| 532 |
+
# out_projections (Conv2d 1×1)
|
| 533 |
+
sd[f"reassemble.out_projections.{i}.weight"] = _conv_kernel_flax_to_torch(
|
| 534 |
+
npy(f"{prefix}reassemble_blocks/out_projection_{i}/kernel.npy"))
|
| 535 |
+
sd[f"reassemble.out_projections.{i}.bias"] = _bias(
|
| 536 |
+
npy(f"{prefix}reassemble_blocks/out_projection_{i}/bias.npy"))
|
| 537 |
+
|
| 538 |
+
# readout_projects (Linear)
|
| 539 |
+
sd[f"reassemble.readout_projects.{i}.weight"] = _linear_kernel_flax_to_torch(
|
| 540 |
+
npy(f"{prefix}reassemble_blocks/readout_projects_{i}/kernel.npy"))
|
| 541 |
+
sd[f"reassemble.readout_projects.{i}.bias"] = _bias(
|
| 542 |
+
npy(f"{prefix}reassemble_blocks/readout_projects_{i}/bias.npy"))
|
| 543 |
+
|
| 544 |
+
# resize_layers: 0=ConvTranspose, 1=ConvTranspose, 2=Identity, 3=Conv
|
| 545 |
+
sd["reassemble.resize_layers.0.weight"] = _conv_transpose_kernel_flax_to_torch(
|
| 546 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_0/kernel.npy"))
|
| 547 |
+
sd["reassemble.resize_layers.0.bias"] = _bias(
|
| 548 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_0/bias.npy"))
|
| 549 |
+
sd["reassemble.resize_layers.1.weight"] = _conv_transpose_kernel_flax_to_torch(
|
| 550 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_1/kernel.npy"))
|
| 551 |
+
sd["reassemble.resize_layers.1.bias"] = _bias(
|
| 552 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_1/bias.npy"))
|
| 553 |
+
# resize_layers_2 = Identity (no weights)
|
| 554 |
+
sd["reassemble.resize_layers.3.weight"] = _conv_kernel_flax_to_torch(
|
| 555 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_3/kernel.npy"))
|
| 556 |
+
sd["reassemble.resize_layers.3.bias"] = _bias(
|
| 557 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_3/bias.npy"))
|
| 558 |
+
|
| 559 |
+
# --- Convs (3×3, no bias) ---
|
| 560 |
+
for i in range(4):
|
| 561 |
+
sd[f"convs.{i}.weight"] = _conv_kernel_flax_to_torch(
|
| 562 |
+
npy(f"{prefix}convs_{i}/kernel.npy"))
|
| 563 |
+
|
| 564 |
+
# --- Fusion blocks ---
|
| 565 |
+
for i in range(4):
|
| 566 |
+
fb = f"{prefix}fusion_blocks_{i}/"
|
| 567 |
+
if i == 0:
|
| 568 |
+
# No residual unit, only 1 PreActResidualConvUnit
|
| 569 |
+
sd[f"fusion_blocks.{i}.main_unit.conv1.weight"] = _conv_kernel_flax_to_torch(
|
| 570 |
+
npy(f"{fb}PreActResidualConvUnit_0/conv1/kernel.npy"))
|
| 571 |
+
sd[f"fusion_blocks.{i}.main_unit.conv2.weight"] = _conv_kernel_flax_to_torch(
|
| 572 |
+
npy(f"{fb}PreActResidualConvUnit_0/conv2/kernel.npy"))
|
| 573 |
+
else:
|
| 574 |
+
# Residual unit (index 0) + main unit (index 1)
|
| 575 |
+
sd[f"fusion_blocks.{i}.residual_unit.conv1.weight"] = _conv_kernel_flax_to_torch(
|
| 576 |
+
npy(f"{fb}PreActResidualConvUnit_0/conv1/kernel.npy"))
|
| 577 |
+
sd[f"fusion_blocks.{i}.residual_unit.conv2.weight"] = _conv_kernel_flax_to_torch(
|
| 578 |
+
npy(f"{fb}PreActResidualConvUnit_0/conv2/kernel.npy"))
|
| 579 |
+
sd[f"fusion_blocks.{i}.main_unit.conv1.weight"] = _conv_kernel_flax_to_torch(
|
| 580 |
+
npy(f"{fb}PreActResidualConvUnit_1/conv1/kernel.npy"))
|
| 581 |
+
sd[f"fusion_blocks.{i}.main_unit.conv2.weight"] = _conv_kernel_flax_to_torch(
|
| 582 |
+
npy(f"{fb}PreActResidualConvUnit_1/conv2/kernel.npy"))
|
| 583 |
+
|
| 584 |
+
# out_conv (Conv2d 1×1)
|
| 585 |
+
sd[f"fusion_blocks.{i}.out_conv.weight"] = _conv_kernel_flax_to_torch(
|
| 586 |
+
npy(f"{fb}Conv_0/kernel.npy"))
|
| 587 |
+
sd[f"fusion_blocks.{i}.out_conv.bias"] = _bias(
|
| 588 |
+
npy(f"{fb}Conv_0/bias.npy"))
|
| 589 |
+
|
| 590 |
+
# --- Project ---
|
| 591 |
+
sd["project.weight"] = _conv_kernel_flax_to_torch(
|
| 592 |
+
npy(f"{prefix}project/kernel.npy"))
|
| 593 |
+
sd["project.bias"] = _bias(
|
| 594 |
+
npy(f"{prefix}project/bias.npy"))
|
| 595 |
+
|
| 596 |
+
# --- Normals head ---
|
| 597 |
+
sd["normals_head.weight"] = _linear_kernel_flax_to_torch(
|
| 598 |
+
npy("decoder/pixel_normals/kernel.npy"))
|
| 599 |
+
sd["normals_head.bias"] = _bias(
|
| 600 |
+
npy("decoder/pixel_normals/bias.npy"))
|
| 601 |
+
|
| 602 |
+
zf.close()
|
| 603 |
+
|
| 604 |
+
# Load into model
|
| 605 |
+
missing, unexpected = model.load_state_dict(sd, strict=True)
|
| 606 |
+
if missing:
|
| 607 |
+
print(f"WARNING: Missing keys: {missing}")
|
| 608 |
+
if unexpected:
|
| 609 |
+
print(f"WARNING: Unexpected keys: {unexpected}")
|
| 610 |
+
print(f"Loaded DPT normals head weights ({len(sd)} tensors)")
|
| 611 |
+
return model
|
| 612 |
+
|
| 613 |
+
|
| 614 |
+
def load_segmentation_weights(model: DPTSegmentationHead, zip_path: str):
|
| 615 |
+
"""Load Scenic/Flax DPT weights from a zip/npz file into PyTorch model."""
|
| 616 |
+
zf = zipfile.ZipFile(zip_path, "r")
|
| 617 |
+
npy = lambda name: _load_npy_from_zip(zf, name)
|
| 618 |
+
sd = {}
|
| 619 |
+
prefix = "decoder/dpt/"
|
| 620 |
+
|
| 621 |
+
# --- ReassembleBlocks ---
|
| 622 |
+
for i in range(4):
|
| 623 |
+
# out_projections (Conv2d 1×1)
|
| 624 |
+
sd[f"reassemble.out_projections.{i}.weight"] = _conv_kernel_flax_to_torch(
|
| 625 |
+
npy(f"{prefix}reassemble_blocks/out_projection_{i}/kernel.npy"))
|
| 626 |
+
sd[f"reassemble.out_projections.{i}.bias"] = _bias(
|
| 627 |
+
npy(f"{prefix}reassemble_blocks/out_projection_{i}/bias.npy"))
|
| 628 |
+
|
| 629 |
+
# readout_projects (Linear)
|
| 630 |
+
sd[f"reassemble.readout_projects.{i}.weight"] = _linear_kernel_flax_to_torch(
|
| 631 |
+
npy(f"{prefix}reassemble_blocks/readout_projects_{i}/kernel.npy"))
|
| 632 |
+
sd[f"reassemble.readout_projects.{i}.bias"] = _bias(
|
| 633 |
+
npy(f"{prefix}reassemble_blocks/readout_projects_{i}/bias.npy"))
|
| 634 |
+
|
| 635 |
+
# resize_layers: 0=ConvTranspose, 1=ConvTranspose, 2=Identity, 3=Conv
|
| 636 |
+
sd["reassemble.resize_layers.0.weight"] = _conv_transpose_kernel_flax_to_torch(
|
| 637 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_0/kernel.npy"))
|
| 638 |
+
sd["reassemble.resize_layers.0.bias"] = _bias(
|
| 639 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_0/bias.npy"))
|
| 640 |
+
sd["reassemble.resize_layers.1.weight"] = _conv_transpose_kernel_flax_to_torch(
|
| 641 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_1/kernel.npy"))
|
| 642 |
+
sd["reassemble.resize_layers.1.bias"] = _bias(
|
| 643 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_1/bias.npy"))
|
| 644 |
+
# resize_layers_2 = Identity (no weights)
|
| 645 |
+
sd["reassemble.resize_layers.3.weight"] = _conv_kernel_flax_to_torch(
|
| 646 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_3/kernel.npy"))
|
| 647 |
+
sd["reassemble.resize_layers.3.bias"] = _bias(
|
| 648 |
+
npy(f"{prefix}reassemble_blocks/resize_layers_3/bias.npy"))
|
| 649 |
+
|
| 650 |
+
# --- Convs (3×3, no bias) ---
|
| 651 |
+
for i in range(4):
|
| 652 |
+
sd[f"convs.{i}.weight"] = _conv_kernel_flax_to_torch(
|
| 653 |
+
npy(f"{prefix}convs_{i}/kernel.npy"))
|
| 654 |
+
|
| 655 |
+
# --- Fusion blocks ---
|
| 656 |
+
for i in range(4):
|
| 657 |
+
fb = f"{prefix}fusion_blocks_{i}/"
|
| 658 |
+
if i == 0:
|
| 659 |
+
# No residual unit, only 1 PreActResidualConvUnit
|
| 660 |
+
sd[f"fusion_blocks.{i}.main_unit.conv1.weight"] = _conv_kernel_flax_to_torch(
|
| 661 |
+
npy(f"{fb}PreActResidualConvUnit_0/conv1/kernel.npy"))
|
| 662 |
+
sd[f"fusion_blocks.{i}.main_unit.conv2.weight"] = _conv_kernel_flax_to_torch(
|
| 663 |
+
npy(f"{fb}PreActResidualConvUnit_0/conv2/kernel.npy"))
|
| 664 |
+
else:
|
| 665 |
+
# Residual unit (index 0) + main unit (index 1)
|
| 666 |
+
sd[f"fusion_blocks.{i}.residual_unit.conv1.weight"] = _conv_kernel_flax_to_torch(
|
| 667 |
+
npy(f"{fb}PreActResidualConvUnit_0/conv1/kernel.npy"))
|
| 668 |
+
sd[f"fusion_blocks.{i}.residual_unit.conv2.weight"] = _conv_kernel_flax_to_torch(
|
| 669 |
+
npy(f"{fb}PreActResidualConvUnit_0/conv2/kernel.npy"))
|
| 670 |
+
sd[f"fusion_blocks.{i}.main_unit.conv1.weight"] = _conv_kernel_flax_to_torch(
|
| 671 |
+
npy(f"{fb}PreActResidualConvUnit_1/conv1/kernel.npy"))
|
| 672 |
+
sd[f"fusion_blocks.{i}.main_unit.conv2.weight"] = _conv_kernel_flax_to_torch(
|
| 673 |
+
npy(f"{fb}PreActResidualConvUnit_1/conv2/kernel.npy"))
|
| 674 |
+
|
| 675 |
+
# out_conv (Conv2d 1×1)
|
| 676 |
+
sd[f"fusion_blocks.{i}.out_conv.weight"] = _conv_kernel_flax_to_torch(
|
| 677 |
+
npy(f"{fb}Conv_0/kernel.npy"))
|
| 678 |
+
sd[f"fusion_blocks.{i}.out_conv.bias"] = _bias(
|
| 679 |
+
npy(f"{fb}Conv_0/bias.npy"))
|
| 680 |
+
|
| 681 |
+
# --- Project ---
|
| 682 |
+
sd["project.weight"] = _conv_kernel_flax_to_torch(
|
| 683 |
+
npy(f"{prefix}project/kernel.npy"))
|
| 684 |
+
sd["project.bias"] = _bias(
|
| 685 |
+
npy(f"{prefix}project/bias.npy"))
|
| 686 |
+
|
| 687 |
+
# --- Segmentation head ---
|
| 688 |
+
sd["segmentation_head.weight"] = _linear_kernel_flax_to_torch(
|
| 689 |
+
npy("decoder/pixel_segmentation/kernel.npy"))
|
| 690 |
+
sd["segmentation_head.bias"] = _bias(
|
| 691 |
+
npy("decoder/pixel_segmentation/bias.npy"))
|
| 692 |
+
|
| 693 |
+
zf.close()
|
| 694 |
+
|
| 695 |
+
# Load into model
|
| 696 |
+
missing, unexpected = model.load_state_dict(sd, strict=True)
|
| 697 |
+
if missing:
|
| 698 |
+
print(f"WARNING: Missing keys: {missing}")
|
| 699 |
+
if unexpected:
|
| 700 |
+
print(f"WARNING: Unexpected keys: {unexpected}")
|
| 701 |
+
print(f"Loaded DPT segmentation head weights ({len(sd)} tensors)")
|
| 702 |
+
return model
|
model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:38362aae91092ca0a6f2fe7f7ed29ec2e7042e3b920b7217d9317ad4c13abdfa
|
| 3 |
+
size 1622839292
|
modeling_dpt.py
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""TIPSv2 DPT dense prediction model for HuggingFace."""
|
| 2 |
+
|
| 3 |
+
from dataclasses import dataclass
|
| 4 |
+
from typing import Optional
|
| 5 |
+
|
| 6 |
+
import torch
|
| 7 |
+
from transformers import AutoConfig, AutoModel, PreTrainedModel
|
| 8 |
+
|
| 9 |
+
from .configuration_dpt import TIPSv2DPTConfig
|
| 10 |
+
from .dpt_head import DPTDepthHead, DPTNormalsHead, DPTSegmentationHead
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
@dataclass
|
| 14 |
+
class TIPSv2DPTOutput:
|
| 15 |
+
depth: Optional[torch.Tensor] = None
|
| 16 |
+
normals: Optional[torch.Tensor] = None
|
| 17 |
+
segmentation: Optional[torch.Tensor] = None
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
class TIPSv2DPTModel(PreTrainedModel):
|
| 21 |
+
"""TIPSv2 DPT dense prediction model (depth, normals, segmentation).
|
| 22 |
+
|
| 23 |
+
The backbone is loaded automatically from the base TIPSv2 model repo.
|
| 24 |
+
|
| 25 |
+
Usage::
|
| 26 |
+
|
| 27 |
+
model = AutoModel.from_pretrained("google/tipsv2-l14-dpt", trust_remote_code=True)
|
| 28 |
+
model.eval().cuda()
|
| 29 |
+
|
| 30 |
+
outputs = model(pixel_values)
|
| 31 |
+
outputs.depth # (B, 1, H, W)
|
| 32 |
+
outputs.normals # (B, 3, H, W)
|
| 33 |
+
outputs.segmentation # (B, 150, H, W)
|
| 34 |
+
|
| 35 |
+
# Individual tasks
|
| 36 |
+
depth = model.predict_depth(pixel_values)
|
| 37 |
+
normals = model.predict_normals(pixel_values)
|
| 38 |
+
seg = model.predict_segmentation(pixel_values)
|
| 39 |
+
"""
|
| 40 |
+
|
| 41 |
+
config_class = TIPSv2DPTConfig
|
| 42 |
+
_no_split_modules = []
|
| 43 |
+
_supports_cache_class = False
|
| 44 |
+
_tied_weights_keys = []
|
| 45 |
+
|
| 46 |
+
@property
|
| 47 |
+
def all_tied_weights_keys(self):
|
| 48 |
+
return {}
|
| 49 |
+
|
| 50 |
+
def __init__(self, config: TIPSv2DPTConfig):
|
| 51 |
+
super().__init__(config)
|
| 52 |
+
|
| 53 |
+
ppc = tuple(config.post_process_channels)
|
| 54 |
+
|
| 55 |
+
backbone_config = AutoConfig.from_pretrained(config.backbone_repo, trust_remote_code=True)
|
| 56 |
+
backbone = AutoModel.from_config(backbone_config, trust_remote_code=True)
|
| 57 |
+
self.vision_encoder = backbone.vision_encoder
|
| 58 |
+
|
| 59 |
+
self.depth_head = DPTDepthHead(
|
| 60 |
+
input_embed_dim=config.embed_dim, channels=config.channels,
|
| 61 |
+
post_process_channels=ppc, readout_type=config.readout_type,
|
| 62 |
+
num_depth_bins=config.num_depth_bins,
|
| 63 |
+
min_depth=config.min_depth, max_depth=config.max_depth,
|
| 64 |
+
)
|
| 65 |
+
self.normals_head = DPTNormalsHead(
|
| 66 |
+
input_embed_dim=config.embed_dim, channels=config.channels,
|
| 67 |
+
post_process_channels=ppc, readout_type=config.readout_type,
|
| 68 |
+
)
|
| 69 |
+
self.segmentation_head = DPTSegmentationHead(
|
| 70 |
+
input_embed_dim=config.embed_dim, channels=config.channels,
|
| 71 |
+
post_process_channels=ppc, readout_type=config.readout_type,
|
| 72 |
+
num_classes=config.num_seg_classes,
|
| 73 |
+
)
|
| 74 |
+
|
| 75 |
+
def _extract_intermediate(self, pixel_values):
|
| 76 |
+
intermediate = self.vision_encoder.get_intermediate_layers(
|
| 77 |
+
pixel_values, n=self.config.block_indices,
|
| 78 |
+
reshape=True, return_class_token=True, norm=True,
|
| 79 |
+
)
|
| 80 |
+
return [(cls_tok, patch_feat) for patch_feat, cls_tok in intermediate]
|
| 81 |
+
|
| 82 |
+
@torch.no_grad()
|
| 83 |
+
def predict_depth(self, pixel_values: torch.Tensor) -> torch.Tensor:
|
| 84 |
+
"""Predict depth map. Returns (B, 1, H, W)."""
|
| 85 |
+
pixel_values = pixel_values.to(self.device)
|
| 86 |
+
h, w = pixel_values.shape[2:]
|
| 87 |
+
dpt_inputs = self._extract_intermediate(pixel_values)
|
| 88 |
+
return self.depth_head(dpt_inputs, image_size=(h, w))
|
| 89 |
+
|
| 90 |
+
@torch.no_grad()
|
| 91 |
+
def predict_normals(self, pixel_values: torch.Tensor) -> torch.Tensor:
|
| 92 |
+
"""Predict surface normals. Returns (B, 3, H, W)."""
|
| 93 |
+
pixel_values = pixel_values.to(self.device)
|
| 94 |
+
h, w = pixel_values.shape[2:]
|
| 95 |
+
dpt_inputs = self._extract_intermediate(pixel_values)
|
| 96 |
+
return self.normals_head(dpt_inputs, image_size=(h, w))
|
| 97 |
+
|
| 98 |
+
@torch.no_grad()
|
| 99 |
+
def predict_segmentation(self, pixel_values: torch.Tensor) -> torch.Tensor:
|
| 100 |
+
"""Predict semantic segmentation (ADE20K). Returns (B, 150, H, W)."""
|
| 101 |
+
pixel_values = pixel_values.to(self.device)
|
| 102 |
+
h, w = pixel_values.shape[2:]
|
| 103 |
+
dpt_inputs = self._extract_intermediate(pixel_values)
|
| 104 |
+
return self.segmentation_head(dpt_inputs, image_size=(h, w))
|
| 105 |
+
|
| 106 |
+
def forward(self, pixel_values: torch.Tensor) -> TIPSv2DPTOutput:
|
| 107 |
+
"""Run all three tasks. Returns TIPSv2DPTOutput."""
|
| 108 |
+
pixel_values = pixel_values.to(self.device)
|
| 109 |
+
h, w = pixel_values.shape[2:]
|
| 110 |
+
dpt_inputs = self._extract_intermediate(pixel_values)
|
| 111 |
+
return TIPSv2DPTOutput(
|
| 112 |
+
depth=self.depth_head(dpt_inputs, image_size=(h, w)),
|
| 113 |
+
normals=self.normals_head(dpt_inputs, image_size=(h, w)),
|
| 114 |
+
segmentation=self.segmentation_head(dpt_inputs, image_size=(h, w)),
|
| 115 |
+
)
|
preprocessor_config.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"do_convert_rgb": true,
|
| 3 |
+
"do_normalize": false,
|
| 4 |
+
"do_rescale": true,
|
| 5 |
+
"do_resize": true,
|
| 6 |
+
"image_processor_type": "Tipsv2DptImageProcessor",
|
| 7 |
+
"resample": 2,
|
| 8 |
+
"rescale_factor": 0.00392156862745098,
|
| 9 |
+
"size": {
|
| 10 |
+
"height": 448,
|
| 11 |
+
"width": 448
|
| 12 |
+
}
|
| 13 |
+
}
|