Skip to main content

NCET

NCET (Neural-network Constraint Embedding Toolkit) converts supported PyTorch neural networks into exact mixed-integer linear constraints. It preserves graph connectivity, including branches and residual/skip connections, rather than restricting models to sequential structures.

NCET is partly supported by Engineering and Physical Sciences Research Council grant number [EP/Y025946/1].

Documentation: https://xuwkk.github.io/ncet/

Installation

Install NCET from PyPI:

pip install ncet

For a local editable installation, run from the repository root:

pip install -e .

Quick start

This example exactly encodes a small residual network and maximizes its first output over a bounded input box:

import cvxpy as cp
import numpy as np
import torch
from torch import nn

from ncet import Bounds, form_milp


class ResidualMLP(nn.Module):
    def __init__(self) -> None:
        super().__init__()
        self.linear = nn.Linear(2, 2)
        with torch.no_grad():
            self.linear.weight.copy_(
                torch.tensor([[1.0, -1.0], [0.5, 1.0]])
            )
            self.linear.bias.copy_(torch.tensor([0.0, -0.25]))

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        return torch.relu(self.linear(x)) + x


model = ResidualMLP().eval()
# Bounds describe one sample; do not include a batch dimension.
bounds = Bounds(
    lower=np.array([-1.0, -1.0]),
    upper=np.array([1.0, 1.0]),
)

encoding = form_milp(model, bounds, relu_binary_mode="reduced")

x = encoding.inputs["x"]
y = encoding.outputs[0]
problem = cp.Problem(cp.Maximize(y[0]), encoding.constraints)
problem.solve(solver=cp.SCIPY)

print(problem.status, problem.value)  # optimal 3.0
print(x.value)                        # [ 1. -1.]

See the complete form_milp() user interface for all arguments, accepted bound forms, return fields, and public exceptions.

Modeling scope

NCET captures static PyTorch FX graphs and normalizes the supported operations into a canonical graph intermediate representation (IR). The current operator set is Linear, Conv2d, AvgPool2d, MaxPool2d, ReLU, Add, Sub, Concat, Flatten, Reshape/View, Permute, Transpose, and static GetItem/Slice. Graph-based interval bound propagation and the CVXPY/MILP encoder support this operator set. See the current operator boundary for the accepted semantics and restrictions of each operator.

  • Input bounds use a single sample's shape, such as (features,) or (channels, height, width), without a batch dimension.
  • lower and upper define elementwise box bounds $\mathrm{lower} \leq x \leq \mathrm{upper}$. The symmetric box $[x_0-\epsilon, x_0+\epsilon]$ is an $L_\infty$ ball. Coupled $L_1$, $L_2$, and other norm bounds are not currently accepted.
  • relu_binary_mode="reduced" (the default) introduces binaries only for unstable ReLU elements. "full" introduces one binary per ReLU element. Both modes are exact; see ReLU binary handling.
  • MaxPool2d uses the full exact formulation, with one binary selector for every valid candidate in each pooling window.

Requirements

NCET requires Python 3.10+, CVXPY 1.7.5+, NumPy 1.26+, SciPy 1.13+, and PyTorch 2.2+. See pyproject.toml for the supported upper bounds.

Examples

Notebook Description
Representative operator test Compares PyTorch and NCET outputs for a branched CNN using representative supported operators.
MNIST adversarial attack Trains a small CNN and solves targeted and worst-case adversarial attacks with NCET.
Common failures and exceptions Demonstrates common invalid inputs and models, their public exceptions, and supported fixes.

License

NCET is licensed under the Apache License 2.0.

Citation

If you use NCET in your research, please cite:

@ARTICLE{xu2026learning,
  author={Xu, Wangkun and Chu, Zhongda and Teng, Fei},
  journal={IEEE Transactions on Power Systems}, 
  title={Learning-Augmented Power System Operations: A Unified Optimization View}, 
  year={2026},
  volume={},
  number={},
  pages={1-21},
  doi={10.1109/TPWRS.2026.3726363}}

Metadata

Release files for ncet 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ncet 0.1.0
File Size Uploaded
ncet-0.1.0.tar.gz 39.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ncet 0.1.0
File Interpreter ABI Platform
ncet-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 74.4 kB

Release files / ncet-0.1.0.tar.gz

Download URL ncet-0.1.0.tar.gz
Size 39.6 kB
Tags Source
SHA-256 checksum
How to use checksums
f960e5d5f0ae4524709646e7bf5bee046cc4077d64ba80c372b8e9d1ab37a715
BLAKE2b-256 checksum
How to use checksums
19979e3daab72b59cd9727452da4181da6aa647c7a008cc9521f0c62d05f7279
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.11

Release files / ncet-0.1.0-py3-none-any.whl

Download URL ncet-0.1.0-py3-none-any.whl
Size 34.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
77d6f7a8f2b61985c85a96679396c6edfb4d478bed5bb40228c8b8b7eb36f7e7
BLAKE2b-256 checksum
How to use checksums
7e4ed6556b5a97ea9b718d885f8f2b14c6777265dbd9c040a8d6e02a2a6b4041
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.11

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page