Skip to main content

tcn-ae

A temporal convolutional autoencoder for anomaly detection in multivariate time series.

This is a reference implementation of:

Markus Thill, Wolfgang Konen, Hao Wang, Thomas Bäck. Temporal convolutional autoencoder for unsupervised anomaly detection in time series. Applied Soft Computing 112 (2021), 107751.

[!WARNING] Not ready for use. The package currently contains no model implementation — it is packaging and infrastructure only, and installing it gives you nothing usable yet. The released versions exist to validate the release pipeline, not to be depended on. The TCN-AE implementation and a stable public API are still to come.

Installation

pip install tcn-ae

This installs Keras with the TensorFlow backend, matching the paper's original implementation.

Keras 3 is multi-backend, so PyTorch can be used instead:

pip install "tcn-ae[torch]"
KERAS_BACKEND=torch python your_script.py

TensorFlow is a required dependency rather than an extra, so tcn-ae[torch] installs both. To make the backend choice permanent, set "backend": "torch" in ~/.keras/keras.json.

There is one implementation, written against the Keras 3 API — the backend is chosen at install and run time, not by a separate code path.

Documentation

https://markusthill.github.io/tcn-ae/

Citing

If you use this software, please cite the paper above. GitHub reads CITATION.cff, so the "Cite this repository" button produces BibTeX for both the software and the paper.

Development

The project uses uv for environments and packaging. In a Codespace or devcontainer everything below is already provisioned by .devcontainer/post-create.sh.

uv sync                     # create .venv from uv.lock, incl. the dev group
uv run prek install --hook-type pre-commit --hook-type commit-msg

The dev interpreter is pinned to Python 3.13 (.python-version). The package supports Python 3.11+, which is what CI's matrix exercises — keep those two numbers distinct.

Everyday commands

Task Command
Run tests uv run pytest
Tests with coverage gate uv run pytest --cov
Lint uv run ruff check .
Format uv run ruff format .
Type check uv run pyrefly check
Workflow security lint uv run zizmor .github/workflows
Docs preview uv run --group docs zensical serve
Docs build uv run --group docs zensical build

Type checking

pyrefly is the authority and gates CI and commits. ty is also installed and can be run with uv run ty check, but it is experimental and advisory only — it never blocks a commit or a build, and where the two disagree, pyrefly wins.

Git hooks (prek)

Hooks are managed by prek, a drop-in replacement for pre-commit that reads the same .pre-commit-config.yaml.

uv run prek run --all-files   # run every hook against the whole repo
uv run prek auto-update       # bump pinned hook revisions

On commit this runs file hygiene checks, ruff check --fix, ruff format, pyrefly, nbstripout (strips notebook outputs), and zizmor. On commit-msg it validates the message with commitizen.

Commit messages (commitizen)

Commit messages follow Conventional Commits and are enforced by the commit-msg hook.

uv run cz commit            # interactive, guided commit message

The commit type determines the next version: fix: → patch, feat: → minor. With major_version_zero = true the project stays on 0.x until you deliberately go to 1.0.

cz bump writes the version to [project] version in pyproject.toml and to uv.lock (version_provider = "uv"); the package reads it back at runtime via importlib.metadata. Do not switch to a dynamic/hatch version, it would break cz bump.

Trusted Publishing configuration

Already configured on both registries — nothing to do for a normal release. This is the trust relationship that lets the workflows publish without any API token stored in the repo.

Field PyPI TestPyPI
PyPI project name tcn-ae tcn-ae
Owner MarkusThill MarkusThill
Repository tcn-ae tcn-ae
Workflow release.yml release-testpypi.yml
Environment pypi testpypi

Renaming the repository, the workflow file, or the GitHub environment breaks the match and publishing fails with an OIDC error — update the publisher on the registry to match. The same table applies when setting up a fork: before a project exists, it is added under PublishingAdd a pending publisher; afterwards it lives in the project's own Publishing settings.

Cutting a release to PyPI

From a clean main that is up to date with origin:

# 1. Preview the version derived from the commits since the last tag
uv run cz bump --dry-run

# 2. Bump: updates pyproject.toml, uv.lock and CHANGELOG.md, commits, creates the v* tag
uv run cz bump

# 3. Push the commit *and* the tag
git push --follow-tags

# 4. Confirm the tag actually arrived — this is where releases usually fail silently
git ls-remote --tags origin

# 5. Watch the release run
gh run watch

Step 3 is the one that catches people: a plain git push does not push tags. The bump commit lands, main looks correct, and nothing is ever released. If step 4 prints no tag, push it explicitly:

git push origin "v$(uv run cz version --project)"

The tag push triggers release.yml: build → twine check → publish to PyPI via Trusted Publishing (OIDC, no API token stored) → GitHub release with the artifacts attached.

[!WARNING] Do not remove annotated_tag = true from [tool.commitizen]. Git has two kinds of tags: annotated ones are real objects carrying a tagger, date and message, while lightweight ones are just a name pointing at a commit. git push --follow-tags pushes annotated tags only, and commitizen creates lightweight ones unless told otherwise — so without that setting cz bump produces a tag the push silently ignores, and no release ever runs.

If a release fails

A version number is consumed permanently on PyPI — a deleted release cannot be re-uploaded under the same version. If the run failed before anything was uploaded (a bad publisher config, a failing build), drop the tag, fix, and retag:

git push --delete origin v0.1.0
git tag -d v0.1.0

If the upload already succeeded, do not try to reuse the version — bump to a new one.

Rehearsing a release on TestPyPI

TestPyPI exists purely to prove the procedure works before it matters. Run release-testpypi.yml manually from the Actions tab; it exercises the same build → twine check → OIDC publish path as a real release.

It does not cover the tag trigger, cz bump, or GitHub release creation — those only run in release.yml.

Optional, if verifying the upload is installable: an extra index is required, because TestPyPI's own tensorflow stops at 1.0.0 and keras at 2.0.0.

pip install --index-url https://test.pypi.org/simple/ \
            --extra-index-url https://pypi.org/simple/ tcn-ae

Notebooks

Notebooks in notebooks/ are executed in CI with nbmake so the examples cannot silently rot:

uv run pytest --nbmake notebooks/

Outputs are stripped on commit by nbstripout, so keep notebooks free of large embedded results in git.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tcn_ae-0.0.3.tar.gz (151.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tcn_ae-0.0.3-py3-none-any.whl (6.1 kB view details)

Uploaded Python 3

File details

Details for the file tcn_ae-0.0.3.tar.gz.

File metadata

  • Download URL: tcn_ae-0.0.3.tar.gz
  • Upload date:
  • Size: 151.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for tcn_ae-0.0.3.tar.gz
Algorithm Hash digest
SHA256 07870f0419f600bc63746f11594068e4e360504adbc00d2728d03a88925f2097
MD5 d2b8cdcf868953d851b20162241815d0
BLAKE2b-256 c11e75be5ec50c83587d1dec51de5d0b8af8c89933b9b87fcae849aa4f0786d6

See more details on using hashes here.

Provenance

The following attestation bundles were made for tcn_ae-0.0.3.tar.gz:

Publisher: release.yml on MarkusThill/tcn-ae

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tcn_ae-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: tcn_ae-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 6.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for tcn_ae-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 89e7864920c993d7642b07aca4dda4d3fdb0e92e77bc1a6a5c1fe25e616edb8f
MD5 464e142ad5e7048ac7e6e42c072f5c63
BLAKE2b-256 35dc307ae807aed78cad933e670b8510f7ba3d118c3a00a4c63d0153430b796d

See more details on using hashes here.

Provenance

The following attestation bundles were made for tcn_ae-0.0.3-py3-none-any.whl:

Publisher: release.yml on MarkusThill/tcn-ae

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.0.3 This release

2 files

0.0.2

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page