Skip to content

Repository files navigation

LEAST: Loss Ensemble Style Transfer against Arbitrary Style Transfer

Official code for the paper:

LEAST: Loss Ensemble Style Transfer against Arbitrary Style Transfer Sunghwan Park, Jongseong Kim, Byunghoon Oh, Yohan Hwang, Jaewoo Lee, Junho Hong Human-centric Computing and Information Sciences (HCIS), Vol. 16, 2026. DOI: 10.22967/HCIS.2026.16.059

LEAST is a proactive protection method that shields an artist's work from unauthorized arbitrary style transfer (AST). It adds an imperceptible adversarial perturbation to a style image so that any off-the-shelf AST model which tries to imitate it produces a garbled, stylistically broken result.

Its core idea is a loss ensemble that simultaneously attacks the three major mathematical definitions of "style" inside the shared VGG-19 feature space — feature statistics (mean/std), Gram-matrix correlations, and raw feature maps — optimized with a full-spectrum PGD attack that applies no frequency constraint. This lets LEAST disrupt both low-frequency style components (e.g. the feature mean that high-frequency-only attacks cannot touch) and high-frequency texture components at once, yielding strong protection and state-of-the-art robustness to JPEG compression (97.5% retention).

LEAST pipeline


Scope of this repository

This is a focused, lightweight reproduction of the LEAST method itself — not the full benchmark suite from the paper. The baseline protection methods (NSP, LAACA, SFA) that LEAST is compared against are intentionally not included.

Shipped here:

Component Included
Protection LEAST (the proposed method)
AST targets AdaIN, Gatys (VGG-based, no external repos)
Defenses JPEG compression, Gaussian blur
Metrics PSNR, SSIM, LPIPS
Experiments Protection Performance, Image Damage, Robustness, Ablations

The transformer-based targets from the paper (SANet, EFDM, StyTr², S2WAT) rely on third-party repositories and large weight files, so they are omitted to keep this release self-contained. Every experiment that is AdaIN/Gatys-based — including Table 1, Table 2, and Table 3 — is fully reproducible here.


Installation

# 1. Environment
conda create -n least python=3.12 -y
conda activate least

# 2. PyTorch (CUDA 12.1 build; experiments used torch 2.5.1 on an RTX 3090)
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121

# 3. Remaining dependencies
pip install -r requirements.txt

Download pretrained weights

LEAST and the AdaIN target share a normalised VGG-19 encoder; AdaIN also needs its decoder. Both are fetched from the official pytorch-AdaIN release:

bash scripts/download_weights.sh

This populates weights/ with vgg_normalised.pth and adain_decoder.pth (checksums are verified automatically). The Gatys target needs no weights.

Prepare the style dataset

The paper uses 160 style images — the 16 most frequent style classes of the huggan/wikiart dataset, 10 images each:

pip install datasets      # only needed for this step
python scripts/prepare_wikiart_dataset.py

This writes data/style/wikiart/style_<id>_<idx>.jpg (seed = 42). The two content images from the paper (lenna.jpg portrait, kbo.jpg landscape) are already included under data/content/.


Quick start

Protect a single target/dataset and measure protection performance:

python run_experiment.py \
    --experiment protection_performance \
    --nst AdaIN --protection LEAST \
    --style-dir data/style/wikiart

Or drive everything from a config file:

python run_experiment.py --config configs/protection_performance.yaml

--experiment all runs protection-performance, image-damage, and robustness in sequence. Use --device cpu or --image-size 256 if you hit GPU memory limits.


Reproducing the paper

All commands below use the 160-image WikiArt set (--style-dir data/style/wikiart) and the two paper content images.

Paper result Command
Table 1 — Image damage (Iₛ vs I_p) python run_experiment.py --experiment image_damage --protection LEAST --style-dir data/style/wikiart
Protection perf. (AdaIN, Fig 4/5) python run_experiment.py --experiment protection_performance --nst AdaIN --protection LEAST --style-dir data/style/wikiart
Robustness — JPEG (Fig 2) python run_experiment.py --experiment robustness --nst AdaIN --protection LEAST --robustness JPEG --style-dir data/style/wikiart
Robustness — Gaussian blur (Fig 2) python run_experiment.py --experiment robustness --nst AdaIN --protection LEAST --robustness GaussianBlur --style-dir data/style/wikiart
Table 2 — Loss-ensemble ablation python run_ablation_study.py --nst AdaIN --style-dir data/style/wikiart
Table 3 — Frequency ablation python run_freq_ablation.py --nst AdaIN --style-dir data/style/wikiart

Results are written as JSON to results/. Each file ends with an "average" summary entry containing the mean ± std of every metric.

Expected LEAST numbers (from the paper)

Result LPIPS PSNR (dB) SSIM
Image damage — Iₛ vs I_p (Table 1) 0.476 ± 0.150 25.21 ± 0.35 0.611 ± 0.113
Loss ensemble F+G+S on AdaIN (Table 2) 0.583 ± 0.054 12.82 ± 0.92 0.331 ± 0.041
Full-spectrum on AdaIN (Table 3) 0.583 ± 0.054 12.82 ± 0.92 0.331 ± 0.041

Small deviations are expected across GPU/driver/PyTorch versions.


Method summary

LEAST maximizes a composite loss over the frozen VGG-19 features at layer ReLU4_1, Φ(I):

L_total = λ₁ · L_stats + λ₂ · L_gram + λ₃ · L_feat
  • L_stats — pushes the channel-wise mean/std of Φ(I_p) away from Φ(I_s) (attacks AdaIN / EFDM / LAACA, the low-frequency "mean" component).
  • L_gram — maximizes the distance between Gram matrices (attacks the Gatys texture/correlation definition of style).
  • L_feat — maximizes MSE while minimizing cosine similarity of the raw feature maps (general disruption, inspired by NSP).

The perturbation δ (with ‖δ‖_∞ ≤ ε) is optimized by full-spectrum PGD — the entire sign gradient is used with no frequency filtering:

δ_{t+1} = Clip_ε( δ_t + α · sign( ∇_δ L_total(δ_t) ) )

Default hyperparameters (see models/protection/least.py): ε = 16/255, T = 100 steps, α = ε/10. The per-loss weights default to values that balance the three gradient magnitudes during PGD, consistent with the paper's equal-weighting rationale.

The ablation flags (use_feature, use_gram, use_stats, freq_mode) exposed by the LEAST class are what run_ablation_study.py and run_freq_ablation.py sweep to produce Tables 2 and 3.


Repository layout

LEAST/
├── run_experiment.py            # main entry: protection_performance / image_damage / robustness / all
├── run_ablation_study.py        # loss-ensemble ablation (Table 2)
├── run_freq_ablation.py         # frequency ablation (Table 3)
├── run_wikiart_experiments.py   # batch driver over the WikiArt set
├── configs/                     # ready-to-run YAML configs
├── scripts/
│   ├── download_weights.sh      # fetch vgg_normalised.pth + adain_decoder.pth
│   └── prepare_wikiart_dataset.py
├── models/
│   ├── nst/                     # AST targets: AdaIN, Gatys
│   ├── protection/least.py      # >>> LEAST <<<
│   └── robustness/              # JPEG, Gaussian blur
├── metrics/                     # PSNR, SSIM, LPIPS
├── experiments/                 # experiment runners
├── utils/                       # registry, config, image + logging helpers
├── data/
│   ├── content/                 # lenna.jpg, kbo.jpg (included)
│   └── style/wikiart/           # filled by prepare_wikiart_dataset.py
└── weights/                     # filled by download_weights.sh

The framework uses a registry pattern: models self-register via decorators (@PROTECTION_REGISTRY.register("LEAST"), etc.) and are discovered on import. To add a new AST target, drop a NSTModel subclass in models/nst/, register it, and import it in models/nst/__init__.py.


Citation

@article{park2026least,
  title   = {LEAST: Loss Ensemble Style Transfer against Arbitrary Style Transfer},
  author  = {Park, Sunghwan and Kim, Jongseong and Oh, Byunghoon and
             Hwang, Yohan and Lee, Jaewoo and Hong, Junho},
  journal = {Human-centric Computing and Information Sciences},
  volume  = {16},
  year    = {2026},
  doi     = {10.22967/HCIS.2026.16.059}
}

Acknowledgements

The AdaIN target and the normalised VGG-19 weights are based on naoto0804/pytorch-AdaIN (MIT). The style images are sampled from the huggan/wikiart dataset.

License

Released under the MIT License.

About

LEAST reproduction code

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages