Most advice on visual anomaly detection models is about chasing 99.9% AUROC on benchmarks like MVTecAD. Then the same model goes onto a production line and falls apart. Academic performance and production reliability are not the same target, and a model tuned for one is often weak at the other.
I have watched teams spend weeks rewriting their architecture when the bottleneck was how they fed the model its data. Image size, cropping logic and a leaky validation split will cost you more accuracy than the choice of backbone, and they are far cheaper to fix.
Picking the input size for visual anomaly detection models
Input resolution is where most of the surprises live. Research papers tend to train on small inputs because it is faster, but on an industrial part a defect can be under 0.2% of the image, and downscaling erases it. If your model keeps missing hairline cracks or welding drops, try a larger input before reaching for a heavier architecture.
The cost shows up in memory and inference speed. The MVTec AD 2 analysis records a sharp jump in inference time as inputs grow. Model choice matters here too: PatchCore copes with a range of defect sizes, while RD4AD can actually get worse on larger defects in a high resolution frame. Benchmark the model you picked against your own defect profile before you commit to a resolution.
If the assets themselves are the problem, I wrote up managing heavy image assets without killing performance separately.
Preprocessing: cropping and background noise
If the inspected part always sits in the middle of the frame, use a center crop. Fewer pixels to process is the smaller win. The bigger one is dropping the background that generates false positives. One client’s model kept flagging anomalies because of a flickering light in the corner of the camera’s field of view, and a center crop fixed what weeks of hyperparameter tuning had not.
Masking follows the same logic. If one region of the line never produces defects, mask it out. Just remember that anything you mask is something you can no longer detect. An area that is clean today can start showing defects tomorrow once a machine wears down.
Early stopping on the wrong split
Plenty of public repos have training loops that decide when to stop based on the test set. That quietly leaks the test set into training. The model looks excellent on your machine and then fails as soon as a fresh batch of normal parts arrives. Early stopping needs a validation set of its own.
# The Naive (Bad) Approach: Stopping based on Test Set
# results = trainer.test(model, test_dataloaders=test_dl) # WRONG
# The Correct Way: Use a Validation Set to monitor performance
from anomalib.utils.callbacks import EarlyStopping
early_stop_callback = EarlyStopping(
monitor="val_pixel_AUROC",
patience=3,
mode="max"
)
# Ship this to production with confidence
trainer = Trainer(callbacks=[early_stop_callback])
If you are calling one of these models from a WordPress or e-commerce backend, handle the response asynchronously. Holding a request open while a heavy computer vision model assembles its JSON is how you end up with 504 Gateway Timeout errors. There is more on that in my notes on optimizing API performance.
If visual anomaly detection work is eating your dev hours, I can take it on. I have been building WordPress sites and awkward integrations since the 4.x days.
What to check first
- Use larger inputs when the defects are small, and watch what that does to memory.
- Crop and mask the background hard, since it is the cheapest way to cut false positives.
- Keep early stopping on a clean validation split so you never fit the test set.
- Run evaluation through something like Anomalib so the metrics stay comparable between runs.