Conversation
A DataFrame column named in `image_features_indices` holds one image per cell, as a base64 string or bytes. The transformer embeds each image with a frozen DINOv3 ViT-S/16 (CLS token), standardises and reduces the embeddings with a PCA fit on the training rows, and replaces the column by those components. Nothing is detected: an undeclared column is left alone and none of the optional dependencies is imported. Missing or undecodable cells are refused by column and row, at fit and at predict. The encoder is cached per process and never stored on the transformer, so saved estimators stay small. Requires the `tabpfn[image]` extra. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`TRANSFORM_IMAGE` is on by default and acts only on declared columns; off, declared columns are refused. `IMAGE_N_COMPONENTS` sets the number of PCA components per image column and `IMAGE_ENCODER_MODEL` the Hub id of the encoder, so an ungated model can stand in for DINOv3. Also adds the validator for `image_features_indices`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Images are expanded first, before dates and text, in `expand_images_dates_and_text`; declared categorical positions are shifted accordingly. Fitted estimators expose `image_transformer_`, which runs at every predict site, in `get_embeddings` and in the batched predictors, and follows the estimator's device on load. Tuning clones fit on the already-embedded array. Differentiable input rejects declared image columns. Tests use a stub encoder so CI downloads nothing, plus one slow test against the real encoder. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`examples/tabpfn_with_images.py` predicts an Amazon best seller's price from its photo and ratings by default; Glaucoma SMDG and Hateful Meme are selectable. It fits tabular-only, picture-only and combined models and prints each score. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
An unbounded direct dependency makes the lowest-direct resolution lock its oldest release: pillow 6.2.0 has no wheel for Python 3.10 and fails to build when matplotlib pulls it in. torchvision 0.20 pairs with the package's torch floor, pillow 10.4 ships wheels for every supported platform. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 795573a. Configure here.
| @@ -0,0 +1 @@ | |||
| `image_features_indices` declares DataFrame columns that hold one image per cell, as a base64 string or bytes. Each such column is replaced by up to `IMAGE_N_COMPONENTS` numeric features (30 by default): the CLS embedding of a frozen DINOv3 ViT-S/16, standardised and reduced by a PCA fit on the training rows. Nothing is detected: without a declaration nothing changes and none of the optional dependencies is imported. `TRANSFORM_IMAGE` is on by default; off, declared image columns are refused. A missing or undecodable cell is refused by column and row, at fit and at predict. Requires `pip install "tabpfn[image]"` and accepting the encoder's license on the Hugging Face Hub; `IMAGE_ENCODER_MODEL` swaps in another encoder. Fitted estimators expose `image_transformer_`, and `categorical_features_indices_` now gives the declared categorical positions after image, date and text expansion. Not run by the fine-tuning estimators. | |||
There was a problem hiding this comment.
Changelog fragment exceeds user-facing scope
Low Severity
The towncrier fragment is a long implementation write-up rather than a one- or two-sentence user note. It names fitted internals such as image_transformer_ and categorical_features_indices_, and retells encoder, PCA, refusal, extra, and fine-tuning details that belong in the PR body, not the concatenated user changelog.
Triggered by learned rule: Towncrier fragments: user-facing change only; keep concise
Reviewed by Cursor Bugbot for commit 795573a. Configure here.
|
We will reimplement this in TabPFN-Extensions |


What & why
People keep asking for TabPFN on images plus tabular fields, medical imaging in particular. This adds the recipe of the MulTaBench paper (https://arxiv.org/abs/2605.10616), where TabPFN on frozen DINOv3 embeddings beats the alternatives on image-tabular tasks: an image sits in a DataFrame cell as a base64 string (or bytes), the user names the column in
image_features_indices, and TabPFN swaps the column for a small block of numeric features before validation. Nothing is detected.How it works
preprocessing/images.py::ImageTransformermirrorsTextTransformer.base.expand_imagesruns first, thenexpand_datesandexpand_text, each returning the expanded input, its fitted transformer and the declared categorical positions in the expanded input. Each declared image column is decoded, embedded by a frozen DINOv3 ViT-S/16 (CLS token, 384 dims, batches of 64, no grad), standardised and reduced by a PCA fit on the training rows, tomin(IMAGE_N_COMPONENTS, n_rows, 384)features named<column>_img_<i>.save_fitted_tabpfn_modelfiles stay small;estimator_to_devicere-points the transformer's device on load.image_transformer_;categorical_features_indices_now gives the declared positions after image, date and text expansion; tuning clones fit on the already-embedded array. Differentiable input rejects declared image columns. The fine-tuning estimators do not run it.How to use
The default encoder's weights are gated: accept the license at https://huggingface.co/facebook/dinov3-vits16-pretrain-lvd1689m and run
hf auth loginonce, or pointinference_config={"IMAGE_ENCODER_MODEL": ...}at an ungated encoder.examples/tabpfn_with_images.pyruns three MulTaBench tasks (Amazon Bestseller by default, Glaucoma SMDG and Hateful Meme selectable) with tabular-only, picture-only and combined models. The default run takes about two minutes on an A100 and gives R2 0.164 / 0.569 / 0.633 for the three.Design decisions
TRANSFORM_IMAGEdefaults to True since it only acts on declared columns; off, declared columns are refused with a message naming the flag, like dates.torchvisionis in it because transformers ships DINOv3 with a fast image processor only.slowtest uses the real encoder and skips without the extra or a Hub token.Deferred follow-ups
🤖 Generated with Claude Code