> For the complete documentation index, see [llms.txt](https://docs.roboflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.roboflow.com/models/supported-models/patchcore.md).

# PatchCore

Train PatchCore anomaly detection models on normal images in Roboflow and run them through the Serverless Cloud API

PatchCore finds defects without needing pictures of them. It learns what a normal part looks like from normal images only, then flags any image that departs from it. It stores features of small image patches from your normal images (from a WideResNet50 backbone) and scores a new image by its most unusual patch. Each prediction returns a "normal" or "anomalous" verdict, a raw anomaly score, and a heatmap of where the image differs. At the default 224×224, scoring is light, so PatchCore runs well on CPU.

<figure><img src="https://3448603185-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fcmo9mhfIjYrvFFy1U7dk%2Fuploads%2Fgit-blob-e23341d273e9ec2b2d93ce2f30b9698bac0ae737%2Fpatchcore-egg-anomaly-heatmap.webp?alt=media" alt="PatchCore results on a normal egg, a cracked egg, and a stained egg: the normal egg is framed in green, the cracked and stained eggs are framed in red with a heatmap on each defect"><figcaption><p>A PatchCore model trained on normal eggs passes the clean egg and flags the cracked and stained eggs. The heatmap marks where each image is above the anomaly threshold, from green at the edge to red at the strongest point.</p></figcaption></figure>

Try [FoundAD](/models/supported-models/foundad.md) if PatchCore misses subtle defects or you only have a few normal images. It uses a larger DINOv3 encoder and runs best on a GPU. See [Choosing an anomaly detection model](/models/supported-tasks/anomaly-detection.md#choosing-an-anomaly-detection-model) to compare the two.

## Train PatchCore

{% stepper %}
{% step %}

### Label normal and anomalous images

Create an Anomaly Detection [Project](https://docs.roboflow.com/datasets/create-and-upload/create-a-project), upload images, and label each one "normal" or "anomalous". Most of your images should be normal. The model trains on normal images only. Anomalous images set the decision threshold and measure accuracy, so they go to the valid and test splits only.
{% endstep %}

{% step %}

### Generate a version

Use only the auto-orient and "Stretch to" resize preprocessing steps, and no augmentation. The image size must be square, from 32 to 1024 pixels. PatchCore defaults to 224×224.

{% hint style="info" %}
Keep 224×224 unless your defects are too small to see at that size. Larger images make PatchCore much slower (see [Inference speed](#inference-speed)).
{% endhint %}
{% endstep %}

{% step %}

### Start a training

[Train a model](/models/train/train-a-model.md) and pick PatchCore. When training finishes, Roboflow reports precision, recall, and F1 on the test set, using the threshold it saved during training.
{% endstep %}
{% endstepper %}

## Inference speed

PatchCore compares each patch of an image with a memory bank of patches from your normal training images. More training images make the memory bank bigger. A larger image size makes both the number of patches and the memory bank bigger, so image size matters most. At large image sizes with a few hundred training images or more, [FoundAD](/models/supported-models/foundad.md) can be faster.

<figure><img src="https://3448603185-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fcmo9mhfIjYrvFFy1U7dk%2Fuploads%2Fgit-blob-d22306601283dce5f374e3a4146b39a6950cc2ad%2Fpatchcore-inference-time-by-resolution.webp?alt=media" alt="PatchCore inference time per image by number of training images, one line per image size from 224×224 to 640×640, with FoundAD as a flat reference line"><figcaption><p>The memory bank is 10% of all training patches. The dashed line is FoundAD at 512×512, which stays the same at any training set size.</p></figcaption></figure>

{% hint style="info" %}
The chart shows one benchmark on an Apple M4 Max CPU with Roboflow Inference 1.8. It times the PatchCore backbone and memory bank search, using memory banks of the size training builds. Times on your hardware differ, but the trend holds.
{% endhint %}

## PatchCore API

{% stepper %}
{% step %}

### Get your API Key

Find your key on the [Roboflow API settings page](https://app.roboflow.com/settings/api) and make it available to your shell:

```bash
export ROBOFLOW_API_KEY="your-key-here"
```

{% endstep %}

{% step %}

### Install the dependencies

Install the [Inference SDK](https://docs.roboflow.com/deployment/self-hosted/self-hosted):

```bash
pip install -U inference-sdk
```

{% endstep %}

{% step %}

### Run the model

Call your trained model by its ID (see [Versions, Trainings, and Models](/models/versions-trainings-and-models.md)).

```python
import os
from inference_sdk import InferenceHTTPClient, InferenceConfiguration

client = InferenceHTTPClient(
    api_url="https://serverless.roboflow.com",
    api_key=os.environ["ROBOFLOW_API_KEY"],
).configure(InferenceConfiguration(api_key_transport="header", include_anomaly_map=True))

# Replace "your-project/1" with your model ID.
result = client.infer("my-image.jpg", model_id="your-project/1")

print(result["top"])  # "normal" or "anomalous"
print(result["anomaly_score"], result["anomaly_threshold"])
heatmap = result["anomaly_map"]  # NumPy array, larger values are more anomalous
```

{% endstep %}
{% endstepper %}

The response has these fields:

* `top`: the verdict, "normal" or "anomalous".
* `anomaly_score`: the raw score. Larger means more anomalous. The score has no fixed range.
* `anomaly_threshold`: the score at which an image becomes anomalous, saved during training.
* `confidence` and `predictions`: the confidence of the verdict, and of each class. The "anomalous" confidence grows with the score and is exactly 0.5 at the threshold, so it is not a defect probability.
* `anomaly_map`: the heatmap, returned only when you set `include_anomaly_map=True`. It is a square array at the model's input size, so stretch it to your image's width and height to overlay it.

{% hint style="info" %}
Set `api_url` to match your deployment target:

* `https://serverless.roboflow.com` for the Serverless Cloud API.
* `http://localhost:9001` for a local [Inference](https://docs.roboflow.com/deployment/self-hosted/self-hosted) server, version 1.7.4 or later.
* Your [Dedicated Deployment](https://docs.roboflow.com/deployment/roboflow-cloud/dedicated-deployments) URL for a private endpoint.
  {% endhint %}

## Use PatchCore in a Workflow

Add the [Anomaly Detection Model](https://docs.roboflow.com/workflows/blocks/blocks/run-a-model/anomaly-detection-model) block to a [Workflow](https://docs.roboflow.com/workflows) to score images, then connect its `anomaly_map` output to the [Anomaly Heatmap Visualization](https://docs.roboflow.com/workflows/blocks/blocks/visualize-predictions/anomaly-heatmap-visualization) block to draw the heatmap. Self-hosted Workflows need Inference 1.8.2 or later for these blocks. Change the block's `confidence` to trade missed defects for false alarms without retraining: lower it to flag more images as anomalous.

## License

PatchCore follows [amazon-science/patchcore-inspection](https://github.com/amazon-science/patchcore-inspection) and is licensed under Apache 2.0. See [Model Licenses](/models/model-licenses.md).
