Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
needs: lint
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10']
python-version: ['3.10', '3.11']

steps:
- uses: actions/checkout@v4
Expand Down
115 changes: 71 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,9 +381,6 @@ python ev_run_render.py config/train_config.yml
G-PCC is the industry-standard point cloud codec from MPEG. Compare your results:

```bash
# Run G-PCC on the same data
python mp_run.py config/train_config.yml --num_parallel 8

# Generate a final comparison report
python mp_report.py \
results/metrics/evaluation_report.json \
Expand Down Expand Up @@ -552,69 +549,99 @@ print(f"Peak memory: {mem.peak_mb:.1f} MB")

| Software | Version | Purpose |
|----------|---------|---------|
| Python | 3.8+ | Programming language |
| TensorFlow | ≥ 2.11.0 | Neural network framework |
| Python | 3.10+ | Programming language |
| TensorFlow | ~=2.15 | Neural network framework |
| TensorFlow Probability | ~=0.23 | Probability distributions for entropy modeling |
| MPEG G-PCC | Latest | Industry-standard codec for comparison |
| MPEG PCC Metrics | v0.12.3 | Standard evaluation metrics |

### Python Dependencies

Install these with `pip install -r requirements.txt`:

| Package | Purpose |
|---------|---------|
| tensorflow | Neural network operations |
| tensorflow-probability | Probability distributions for entropy modeling |
| numpy | Numerical computations |
| matplotlib | Visualization |
| pandas | Data analysis |
| pyyaml | Configuration file parsing |
| scipy | Scientific computing |
| numba | JIT compilation for speed |
| Package | Version | Purpose |
|---------|---------|---------|
| tensorflow | ~=2.15 | Neural network operations |
| tensorflow-probability | ~=0.23 | Probability distributions for entropy modeling |
| numpy | ~=1.26 | Numerical computations |
| matplotlib | ~=3.8 | Visualization |
| pandas | ~=2.1 | Data analysis |
| pyyaml | ~=6.0 | Configuration file parsing |
| scipy | ~=1.11 | Scientific computing |
| tqdm | ~=4.66 | Progress bars |
| numba | ~=0.58 | JIT compilation for speed |
| keras-tuner | ~=1.4 | Hyperparameter tuning (for cli_train.py) |
| pytest | ~=8.0 | Test framework |
| ruff | >=0.4 | Linter (configured in pyproject.toml) |

---

## Project Structure

```
deepcompress/
├── src/ # Source code
├── src/ # Source code
│ ├── Model Components
│ │ ├── model_transforms.py # Main encoder/decoder architecture
│ │ ├── entropy_model.py # Entropy coding (converts to bits)
│ │ ├── entropy_parameters.py # Hyperprior parameter prediction
│ │ ├── context_model.py # Spatial autoregressive context
│ │ ├── channel_context.py # Channel-wise context
│ │ └── attention_context.py # Attention-based context
│ │ ├── model_transforms.py # Main encoder/decoder (V1 + V2) architecture
│ │ ├── entropy_model.py # Gaussian conditional, hyperprior entropy models
│ │ ├── entropy_parameters.py # Hyperprior mean/scale prediction network
│ │ ├── context_model.py # MaskedConv3D, autoregressive spatial context
│ │ ├── channel_context.py # Channel-wise context model
│ │ └── attention_context.py # Windowed attention context model
│ │
│ ├── Performance
│ │ ├── constants.py # Pre-computed math constants
│ │ ├── precision_config.py # Mixed precision settings
│ │ ├── benchmarks.py # Performance measurement
│ │ └── quick_benchmark.py # Quick testing tool
│ │ ├── constants.py # Pre-computed math constants (LOG_2, EPSILON)
│ │ ├── precision_config.py # Mixed precision (float16) settings
│ │ ├── benchmarks.py # Performance measurement
│ │ └── quick_benchmark.py # Quick synthetic smoke test
│ │
│ ├── Data Processing
│ │ ├── ds_mesh_to_pc.py # Convert meshes to point clouds
│ │ ├── ds_pc_octree_blocks.py# Split into octree blocks
│ │ ├── compress_octree.py # Compression pipeline
│ │ └── decompress_octree.py # Decompression pipeline
│ │ ├── data_loader.py # Unified data loader (ModelNet40 / 8iVFB)
│ │ ├── ds_mesh_to_pc.py # Convert .off meshes to point clouds
│ │ ├── ds_pc_octree_blocks.py # Split point clouds into octree blocks
│ │ ├── ds_select_largest.py # Select N largest blocks by point count
│ │ ├── octree_coding.py # Octree encode/decode for voxel grids
│ │ ├── compress_octree.py # Compression entry point
│ │ └── map_color.py # Transfer colors between point clouds
│ │
│ ├── Training & Evaluation
│ │ ├── training_pipeline.py # End-to-end training loop
│ │ ├── evaluation_pipeline.py # Model evaluation pipeline
│ │ ├── cli_train.py # Training CLI with hyperparameter tuning
│ │ └── experiment.py # Experiment runner
│ │
│ └── Training & Evaluation
│ ├── training_pipeline.py # End-to-end training
│ ├── evaluation_pipeline.py# Model evaluation
│ └── cli_train.py # Command-line interface
│ └── Evaluation & Comparison
│ ├── ev_compare.py # Point cloud quality metrics (PSNR, Chamfer)
│ ├── ev_run_render.py # Visualization / rendering
│ ├── point_cloud_metrics.py # D1/D2 point-to-point metrics
│ ├── mp_report.py # MPEG G-PCC comparison reports
│ ├── colorbar.py # Colorbar visualization utility
│ └── parallel_process.py # Parallel processing utility
├── tests/ # Automated tests
│ ├── test_entropy_model.py
│ ├── test_context_model.py
│ ├── test_performance.py # Performance regression tests
│ └── ...
├── tests/ # Automated tests (pytest + tf.test.TestCase)
│ ├── conftest.py # Session-scoped fixtures (tf_config, file factories)
│ ├── test_utils.py # Shared test utilities (mock grids, configs)
│ ├── test_model_transforms.py # V1 + V2 model tests
│ ├── test_entropy_model.py # Entropy model tests
│ ├── test_context_model.py # Context model tests
│ ├── test_channel_context.py # Channel context tests
│ ├── test_attention_context.py # Attention context tests
│ ├── test_performance.py # Performance regression + optimization tests
│ ├── test_training_pipeline.py # Training loop tests
│ ├── test_evaluation_pipeline.py # Evaluation pipeline tests
│ ├── test_data_loader.py # Data loading tests
│ ├── test_compress_octree.py # Compression pipeline tests
│ ├── test_octree_coding.py # Octree codec tests
│ └── ... # + 10 more module-level test files
├── config/ # Configuration files
├── data/ # Datasets (not in git)
├── results/ # Output files (not in git)
├── README.md # This file
└── requirements.txt # Python dependencies
├── data/ # Datasets (not in git)
├── results/ # Output files (not in git)
├── CLAUDE.md # AI agent coding standards
├── pyproject.toml # Ruff linter configuration
├── pytest.ini # Pytest configuration and markers
├── setup.py # Package setup
├── requirements.txt # Python dependencies
└── README.md # This file
```

---
Expand Down
20 changes: 10 additions & 10 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
matplotlib~=3.5.0
pyntcloud~=0.1.2
numpy~=1.23.0
pandas~=1.4.0
tqdm~=4.64.0
tensorflow~=2.11.0
tensorflow~=2.15.0
tensorflow-probability~=0.23.0
numpy~=1.26.0
matplotlib~=3.8.0
pandas~=2.1.0
tqdm~=4.66.0
pyyaml~=6.0
pytest~=7.1.0
scipy~=1.8.1
numba~=0.56.0
tensorflow-probability~=0.19.0
pytest~=8.0.0
scipy~=1.11.0
numba~=0.58.0
keras-tuner~=1.4.0
ruff>=0.4.0
2 changes: 1 addition & 1 deletion src/evaluation_pipeline.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
from dataclasses import asdict, dataclass
from pathlib import Path
from typing import Any, Dict, List
from typing import Any, Dict

import tensorflow as tf

Expand Down
2 changes: 1 addition & 1 deletion src/model_transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import tensorflow as tf

from constants import LOG_2_RECIPROCAL, EPSILON
from constants import EPSILON, LOG_2_RECIPROCAL


@dataclass
Expand Down
6 changes: 4 additions & 2 deletions src/training_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
class TrainingPipeline:
def __init__(self, config_path: str):
import yaml

from data_loader import DataLoader
from model_transforms import DeepCompressModel, TransformConfig
from entropy_model import EntropyModel
from model_transforms import DeepCompressModel, TransformConfig

self.config_path = config_path
with open(config_path, 'r') as f:
Expand Down Expand Up @@ -50,7 +51,8 @@ def __init__(self, config_path: str):
def _train_step(self, batch: tf.Tensor, training: bool = True) -> Dict[str, tf.Tensor]:
"""Run a single training step."""
with tf.GradientTape(persistent=True) as tape:
x_hat, y, y_hat, z = self.model(batch[..., tf.newaxis] if len(batch.shape) == 4 else batch, training=training)
inputs = batch[..., tf.newaxis] if len(batch.shape) == 4 else batch
x_hat, y, y_hat, z = self.model(inputs, training=training)

# Compute focal loss on reconstruction
focal_loss = self.compute_focal_loss(
Expand Down
1 change: 0 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import tensorflow as tf



def pytest_collection_modifyitems(items):
"""Filter out tf.test.TestCase.test_session, which is a deprecated
context manager that pytest mistakenly collects as a test."""
Expand Down
3 changes: 1 addition & 2 deletions tests/test_colorbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@

sys.path.insert(0, str(Path(__file__).parent.parent / 'src'))

import json

import matplotlib.pyplot as plt
import numpy as np
import pytest

from colorbar import ColorbarConfig, get_colorbar
from colorbar import get_colorbar


class TestColorbar:
Expand Down
1 change: 0 additions & 1 deletion tests/test_entropy_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from entropy_model import EntropyModel, PatchedGaussianConditional



class TestEntropyModel(tf.test.TestCase):
def setUp(self):
tf.random.set_seed(42)
Expand Down
1 change: 0 additions & 1 deletion tests/test_evaluation_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import sys
from pathlib import Path

import numpy as np
import pytest
import tensorflow as tf
import yaml
Expand Down
2 changes: 1 addition & 1 deletion tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from data_loader import DataLoader
from evaluation_pipeline import EvaluationPipeline
from model_transforms import DeepCompressModel, DeepCompressModelV2, TransformConfig
from test_utils import create_mock_point_cloud, create_mock_voxel_grid, create_test_dataset, setup_test_environment
from test_utils import create_mock_point_cloud, create_mock_voxel_grid, setup_test_environment
from training_pipeline import TrainingPipeline


Expand Down
11 changes: 6 additions & 5 deletions tests/test_performance.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,25 +95,25 @@ def test_f16_constants_accuracy(self, tf_setup):

def test_get_log2_constant_f32(self, tf_setup):
"""Verify get_log2_constant returns LOG_2 for default dtype."""
from constants import get_log2_constant, LOG_2
from constants import LOG_2, get_log2_constant
result = get_log2_constant()
assert result is LOG_2

def test_get_log2_constant_f16(self, tf_setup):
"""Verify get_log2_constant returns LOG_2_F16 for float16."""
from constants import get_log2_constant, LOG_2_F16
from constants import LOG_2_F16, get_log2_constant
result = get_log2_constant(tf.float16)
assert result is LOG_2_F16

def test_get_log2_reciprocal_f32(self, tf_setup):
"""Verify get_log2_reciprocal returns LOG_2_RECIPROCAL for default dtype."""
from constants import get_log2_reciprocal, LOG_2_RECIPROCAL
from constants import LOG_2_RECIPROCAL, get_log2_reciprocal
result = get_log2_reciprocal()
assert result is LOG_2_RECIPROCAL

def test_get_log2_reciprocal_f16(self, tf_setup):
"""Verify get_log2_reciprocal returns LOG_2_RECIPROCAL_F16 for float16."""
from constants import get_log2_reciprocal, LOG_2_RECIPROCAL_F16
from constants import LOG_2_RECIPROCAL_F16, get_log2_reciprocal
result = get_log2_reciprocal(tf.float16)
assert result is LOG_2_RECIPROCAL_F16

Expand Down Expand Up @@ -363,9 +363,10 @@ def test_configure_invalid_policy(self, tf_setup):

def test_configure_mixed_float16_warns_on_cpu(self, tf_setup):
"""Verify UserWarning when enabling float16 on CPU."""
from precision_config import PrecisionManager
import warnings as w

from precision_config import PrecisionManager

gpus = tf.config.list_physical_devices('GPU')
if gpus:
pytest.skip("Test requires CPU-only environment")
Expand Down