ArtRECONon-Relational Recommendation via Contrastive Optimization

Part I — Embedding Model
Each artwork and caption is embedded with CLIP. Pretrained CLIP was trained on web image–caption pairs rather than curated museum art, so there’s a domain shift. Full fine-tuning of ViT-B/16 risks overfitting on roughly 58k examples; LoRA trains under 1% of parameters, regularizes implicitly, and fits on a consumer GPU.
For a frozen projection , LoRA learns a low-rank update
is Gaussian-initialized and is zero, so training starts exactly at the pretrained model and gradually learns a domain-specific perturbation.
Config: . Adapters target , , , and in both the vision and text towers — ~600k trainable parameters out of ~150M (under 0.4%).
Contrastive Training Objective
Symmetric CLIP contrastive loss. For a batch of normalized image embeddings and text embeddings , let . The image→text and text→image losses are
The final objective is . Temperature is learned via , clamped at to prevent collapse. Base CLIP weights stay frozen otherwise.
Optimization
- AdamW, lr , weight decay 0.01.
- Cosine schedule, 500 warmup steps.
- Batch size 64, 5 epochs.
- Mixed-precision fp16 with gradient scaling.
- Held-out 5% split, recall@5 reported each epoch.
Embedding Results
Recall@5 before and after LoRA tuning:
| Model | Image → Text | Text → Image | Average |
|---|---|---|---|
| Baseline CLIP | 0.1659 | 0.1418 | 0.1539 |
| LoRA-tuned CLIP | 0.4152 | 0.4019 | 0.4086 |
Table 1 — Recall@5 before and after LoRA tuning.
A side-by-side top-5 retrieval — baseline vs. LoRA on the same query — is the clearest qualitative view of the gain.
Limitations: captions are synthesized from metadata, the dataset is modest for contrastive learning, and training uses in-batch negatives rather than hard-negative mining.
Part II — Recommendation Algorithm
The recommendation layer uses the CLIP–LoRA embedding space to update preference state from clicks and split future feed slots between learned taste components and random exploration.
State
The user state is a set of weighted components with . Each component is either a taste component with a unit-norm vector , or the single random component, which has no vector and represents exploration mass.
Click Update
Let be the unit-norm embedding of the clicked artwork. Find the closest existing taste vector by cosine similarity,. If , merge the click into that component with mixing rate :
Otherwise spawn a new taste component . All other weights are scaled by , which keeps the total mass at one.
Pruning
After the update, drop any component with weight below and renormalize the survivors so the weights still sum to one.
Feed Allocation
Let be the total weight on the random component. For a feed of length , give slots to personalized items and the remaining to random exploration. Personalized slots are divided across taste components in proportion to their relative weight:
The personalized and random items are then interleaved into the final feed.
Decay of Random Exploration
Clicks only merge with taste components, so the random weight decays geometrically: . It drops below once . For and , that’s about 19 clicks — after which the feed is fully personalized.
Conclusion
The update rule removes the cold-start setup stage: the system starts with random exploration and learns taste directly from clicks, so every interaction shapes the state immediately.
Spawning new taste components when a click is far from existing ones lets the model carry multiple interests instead of collapsing into one profile. The random component keeps early recommendations exploratory, then decays as taste signal accumulates.