Metadata-Version: 2.4
Name: dvae
Version: 0.1.3
Summary: Denoising Variational Auto-Encoder (DVAE) for binary classification in extremely low-data regimes.
Author: Radim Nedbal
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/rdned/DVAE
Project-URL: Repository, https://github.com/rdned/DVAE
Requires-Python: <3.12,>=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: numpy<2
Requires-Dist: torch==2.2.2
Requires-Dist: pyro-ppl==1.9.1
Requires-Dist: scikit-learn==1.7.2
Provides-Extra: dev
Requires-Dist: pre-commit; extra == "dev"
Dynamic: license-file

# DVAE Classifier
[![Python](https://img.shields.io/badge/Python-≤3.11-blue)](https://www.python.org/)
[![NumPy](https://img.shields.io/badge/NumPy-<2.0-important)](https://numpy.org/)
[![PyTorch](https://img.shields.io/badge/PyTorch-2.2.2-red)](https://pytorch.org/)
[![Pyro](https://img.shields.io/badge/Pyro-1.9.1-orange)](https://pyro.ai/)
[![License](https://img.shields.io/badge/license-Apache%202.0-green)](LICENSE)

Pyro/PyTorch implementation of the **Denoising Variational Auto‑Encoder (DVAE)** for binary classification in extremely low‑data regimes, based on the paper:

> *Harnessing Variational Auto‑Encoder for Binary Classification in Extremely Low Data Regime*
> Radim Nedbal and Babak Mahdian (2025), submitted to *Progress in Artificial Intelligence*.

## Overview

DVAE is a neural network designed to classify binary data with very few labeled examples. It combines the power of Variational Auto-Encoders with denoising techniques to achieve robust classification in extremely low-data regimes.

The classifier implementation is centered on the `VAE` class in `dvae/vae.py`.

## Features

- **Denoising Variational Auto‑Encoder (DVAE)** optimized for extremely low‑data binary classification
- **Pyro/PyTorch implementation** with reproducible training and inference
- **Integrated classifier head** built on top of the learned latent space
- **Configurable corruption (noise) model** for robust latent representations
- **Deterministic, pinned dependency versions** ensuring reproducible experiments
- **Modular architecture** (`vae.py`, `classifier.py`, `utils/`, `config/`) for easy extension
- **Example datasets and scripts** included for manual validation and experimentation
- **Wheel‑based reproducible build workflow** for clean packaging and isolated testing

## Table of Contents

- [Installation](#installation)
- [Quick Start](#quick-start)
- [Usage Examples](#usage-examples)
- [Installation from Source](#installation-from-source)
- [Repository Structure](#repository-structure)
- [Contributing](#contributing)
- [Configuration](#configuration)
- [Dependencies](#dependencies)
- [Citation](#citation)
- [Attribution](#attribution)
- [License](#license)

---

## Installation

### Prerequisites

- Python 3.11.x (PyTorch does not yet provide wheels for Python 3.13+)
- `pyenv` (recommended for Python version management)

### Setup

Clone the repository:

```bash
git clone https://github.com/rdned/DVAE.git
cd DVAE
```

Create a virtual environment using `pyenv` and install dependencies:

```bash
pyenv install 3.11.3 --skip-existing
pyenv virtualenv 3.11.3 dvae-3.11.3
pyenv local dvae-3.11.3
```

Update packaging tools (recommended):

```bash
pip install --upgrade pip setuptools wheel
```

Install the package (editable mode):

```bash
pip install -e .
```

>This installs the dvae package and all runtime dependencies declared in pyproject.toml.

---

## Quick Start

After installing DVAE, you can verify that the package is working by importing it
and checking the version:

```bash
python -c "import dvae; print(dvae.__version__)"
```

>This confirms that the library and its runtime dependencies were installed correctly.
For end‑to‑end usage examples (including dataset loading and model training),
see the **Usage Examples** section. The example scripts and datasets are part of the repository but are not installed with the package.
To run them, clone the repo or download the source tarball.

---

## Usage Examples

### Data Formats

#### NPZ Format

* A .npz archive containing:
  * X: array-like, shape (N, D) - input features (e.g., flattened vectors or images)
  * labels: array-like, shape (N,) – binary labels (0 or 1)

#### JSON Format

```json
{
  "X": [[feature_vector_1], [feature_vector_2], ...],
  "labels": [0, 1, 0, ...]
}
```

### Running the Example

To train and test the DVAE classifier with a sample dataset:

```bash
python -m example.tests <dataset_name> --filetype <json|npz>
```

Example:

```bash
python -m example.tests dataset1 --filetype npz
```

This will:

1. Load the example dataset
2. Instantiate the DVAE model with default configuration
3. Run training and evaluation across multiple training set sizes
4. Print corresponding accuracies

### Python / pyenv environment (recommended)

DVAE supports only Python 3.10 and 3.11. Python 3.12 and above is explicitly unsupported due to known PyTorch 2.2.2 runtime issues.

Preferred setup:

```bash
pyenv install 3.11.3 --skip-existing
pyenv virtualenv 3.11.3 dvae-3.11.3
pyenv local dvae-3.11.3
pip install -e .
```

If you run these commands with 3.12 (for some reason), the package will now raise a runtime error at import, and `pyproject.toml` + README are explicit that this is not a supported target.

### Using Your Own Dataset

1. Prepare your data in JSON or NPZ format (see Data Format section above)
2. Ensure X and labels are aligned and labels are binary (0/1)
3. Run:

```bash
python -m example.tests your_dataset --filetype npz
```

### Scikit-learn-style API (`VAEClassifier`)

`VAEClassifier` in `dvae/classifier.py` follows the sklearn API (fit/predict/predict_proba/transform).

Example usage:

```python
import numpy as np
from dvae.classifier import VAEClassifier

# synthetic binary data
rng = np.random.RandomState(42)
X = rng.randn(100, 8).astype(np.float32)
y = (X[:, 0] + 0.5 * X[:, 1] > 0).astype(int)

clf = VAEClassifier(
    feature_dim=8,
    z_dim=2,
    hidden_dim=[16, 8],
    alpha1=1e-3,
    alpha2=1e-3,
    beta=1.0,
    corruption=0.0,
    seed=42,
)

clf.fit(X, y, num_epochs=2)
print("train accuracy:", (clf.predict(X) == y).mean())
print("proba shape:", clf.predict_proba(X).shape)

# convenience helpers
pred = clf.fit_predict(X, y, num_epochs=2)
proba = clf.fit_predict_proba_on(X, y, X[:10], num_epochs=2)

# save / load
from pathlib import Path
path = Path("/tmp/dvae_clf.pt")
clf.save(path)
clf2 = VAEClassifier.load(path)

assert np.array_equal(clf.predict(X), clf2.predict(X))
```

---

## Python version compatibility

DVAE currently supports Python 3.10 and 3.11 only. Python 3.12 and newer are not supported due to known PyTorch 2.2.2 compatibility issues.

## Installation from Source

This project uses a two-directory workflow:

- `DVAE/` — the source tree containing the Python package and build configuration
- `dvae_test/` — a clean environment used to install and test the built wheel

### 1. Build the wheel (inside `DVAE/`)

```bash
cd DVAE
pip install --upgrade build
python -m build
```

This produces:

```
DVAE/dist/dvae-0.1.0-py3-none-any.whl
```

All runtime dependencies (NumPy < 2, PyTorch 2.2.2, Pyro 1.9.1, scikit‑learn 1.7.2) are encoded in the wheel metadata.

### 2. Create a clean test environment using pyenv (inside `dvae_test/`)

```bash
cd ../dvae_test
pyenv virtualenv 3.11.3 dvae-test
pyenv local dvae-test
```

### 3. Install the wheel

```bash
pip install ../DVAE/dist/dvae-0.1.0-py3-none-any.whl
```

Pip will automatically install the correct versions of:

* NumPy (< 2)
* PyTorch 2.2.2 (CPU build from PyPI)
* Pyro 1.9.1
* scikit‑learn 1.7.2

The wheel installs the CPU build of PyTorch 2.2.2; GPU builds must be installed manually following PyTorch’s instructions.:
https://pytorch.org/

### 4. Provide the dataset path explicitly

The dataset is not bundled with the package. You must supply its location explicitly.

Option A — Pass the path directly:

```bash
python - << 'EOF'
from dvae.utils import get_dataset_path
path = get_dataset_path("/absolute/path/to/DVAE/example/data/dataset1.json")
print(path)
EOF
```

Option B — Use an environment variable:

```bash
export DATASET_PATH=/absolute/path/to/DVAE/example/data/dataset1.json
```

Then in Python:

```bash
python - << 'EOF'
from dvae.utils import get_dataset_path
print(get_dataset_path())
EOF
```

---

## Repository Structure

```
.
├── CHANGELOG.md                    # Version history following Keep a Changelog
├── CONTRIBUTING.md                 # Contribution guidelines and dev workflow
├── LICENSE                         # Project license (Apache-2.0 with your header)
├── NOTICE                          # Third‑party attribution (Uber custom_mlp.py)
├── README.md                       # Project overview and usage
├── pyproject.toml                  # Project metadata and runtime dependencies
│
├── docs/                           # Project documentation (source only)
│    └── usage.md                   # DVAE usage guide
│
├── example/                        # Usage demonstrations and manual validation scripts
│   ├── data/                       # Example datasets
│   │   ├── dataset1.json
│   │   ├── dataset1.npz
│   │   ├── dataset2.json
│   │   └── dataset2.npz
│   └── tests.py                    # Manual example script (not part of automated tests)
│
└── src/                            # Source layout root (contains only packages)
    └── dvae/                       # Main DVAE package (imported as `import dvae`)
        ├── __init__.py             # Package entry point
        ├── _version.py             # Version management
        ├── classifier.py           # Classifier built on top of the VAE
        ├── vae.py                  # Core VAE implementation
        │
        ├── config/                 # Configuration modules (internal)
        │   ├── __init__.py
        │   └── hyperparameters.py  # Default hyperparameter definitions
        │
        └── utils/                  # Utility functions (internal)
            ├── __init__.py
            ├── custom_mlp.py       # Custom MLP architecture (Uber, Apache-2.0)
            ├── logger.py           # Lightweight logging utilities
            └── utils.py            # Miscellaneous helpers
```

---

## Contributing

Contributions are welcome.
Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for guidelines, development workflow, and coding standards.

---

## Configuration

Training and model hyperparameters are controlled in `dvae/config/hyperparameters.py`.

### Key Configuration Sections

* Training: Learning rate, decay rates, batch size, number of epochs
* DVAE:
  * Objective function parameters (KL divergence weight, reconstruction loss weight, classification weight)
  * Bernoulli corruption rate (noise added during training)
  * Architectural parameters (hidden layer sizes, latent dimension)

For detailed configuration options, see `dvae/config/hyperparameters.py`.

---

## Dependencies

This project pins exact versions for reproducibility. Key dependencies include:

* numpy 1.26.4 – Numerical computing (**required: PyTorch 2.2.2 is not compatible with NumPy ≥ 2.0**)
* torch 2.2.2 – Deep learning framework
* pyro-ppl 1.9.1 – Probabilistic programming library
* scikit-learn 1.7.2 – Machine learning utilities

---

## Citation

If you use this code, please cite:

### APA Format:

Radim Nedbal and Babak Mahdian (2025).
Harnessing Variational Auto-Encoder for Binary Classification in Extremely Low Data Regime.
Progress in Artificial Intelligence (submitted).

### BibTeX:

```bibtex
@article{nedbal2025dvae,
  author       = {Nedbal, Radim and Mahdian, Babak},
  title        = {Harnessing Variational Auto-Encoder for Binary Classification in Extremely Low Data Regime},
  journal      = {Progress in Artificial Intelligence},
  year         = {2025},
  note         = {Submitted},
  url          = {https://github.com/rdned/DVAE}
}
```

---

## Attribution

DVAE includes code originally developed by Uber Technologies, Inc.
The file src/dvae/utils/custom_mlp.py is licensed under the Apache License 2.0
and is redistributed in accordance with its terms.
See the accompanying NOTICE file for details.

---

## License

This project is licensed under the Apache License 2.0 — see the [LICENSE](LICENSE) file for details.
