Downloads · 30 days
0
alganet/wordpalette
wordpalette is a machine learning model from alganet. Use it for the machine learning task on the model card, and read the license before you ship it in a product. It is set up for onnx. The card lists the license as cc-by-4.0.
A ~710k-parameter character-level model that predicts the colours a word evokes. You give it a word; it returns up to three CIELab colours with proportions, and decides for itself how many a word has (blood → one red,…
Downloads · 30 days
0
Access
Public
Updated Jul 2, 2026
Repo size
2.9 MB
Likes
0
Public
Click a slice to open those files.
.onnx2.9 MB · 100%
From the Hugging Face model README
A ~710k-parameter character-level model that predicts the colours a word
evokes. You give it a word; it returns up to three CIELab colours with
proportions, and decides for itself how many a word has (blood → one red,
france → a blue/white/red tricolour). Trained entirely on free, human-made
colour data — no large language model was used at any point, for labels or
distillation.
Generative/affective colour: pick a theme colour from a tag, colour a word
cloud, seed a palette from a brand or a mood, or just explore how spelling maps
to colour. Because the encoder is character-level, it colours words it has
never seen — arborious → green, crimsonish → red — from morphology alone.
Inference needs only numpy + onnxruntime (no PyTorch):
import wordpalette # pip install wordpalette
wp = wordpalette.load()
[(s.hex, round(s.proportion, 2)) for s in wp.palette("brazil")]
# [('#30a432', 0.69), ('#ffd641', 0.25)]
Or drive the ONNX file directly:
import json, numpy as np, onnxruntime as ort
vocab = json.load(open("vocab.json"))
sess = ort.InferenceSession("wordpalette.onnx")
def encode(w):
ids = np.zeros(vocab["max_len"], dtype=np.int64) # PAD = 0
for i, c in enumerate(w.lower()[:vocab["max_len"]]):
j = vocab["chars"].find(c)
ids[i] = (j + 2) if j >= 0 else vocab["unk"]
return ids
lab_scaled, props = sess.run(None, {"chars": encode("ocean")[None]})
lab = lab_scaled[0] * np.array(vocab["scale"]) # [K, 3] real CIELab
I/O. Input chars: int64 [batch, 24], characters mapped as
a–z + #→2.., others→UNK(1), zero-padded (PAD 0). Outputs lab_scaled
[batch, 3, 3] (multiply by scale = [100, 110, 110] for real Lab) and props
[batch, 3] (softmax proportions). A slot is "on" when its proportion ≥ 0.15;
always keep at least the dominant slot.
Ten free colour sources — Simple Icons, Company Colors, color-names (meodai),
XKCD, CSS, GitHub label colours, emoji dominant-colour, flag palettes, WordNet
glosses, and Wikipedia first sentences — are normalised to word → CIELab with
a trust weight, then coalesced into one belief per word (aggregate GitHub
duplicates, denoise over-segmented palettes, drop cross-source outliers,
demote logo colours that contradict a word's everyday sense). A causal GRU is
then trained per-prefix in scaled Lab with:
The full, runnable pipeline (and the reasoning behind each choice) is in the GitHub repo. Reproduction is a short CPU/GPU job from the committed data.
Evaluated during development against the NRC/Mohammad word–colour association lexicon (held out, never trained on) plus flag-palette accuracy and behavioural probes. It is a small model over noisy, partial supervision: it captures volume and patterns (thousands of natural kinds, morphology, flags) but not isolated facts (a handful of planets or trademark-only brands may be approximate). Colours are associative and sometimes contestable — treat outputs as evocative, not authoritative.
Weights derive from the sources listed above; please credit them (see the repo README for per-source licences). Notably the WordNet License (Princeton) and CC-BY-SA text from Wikipedia contribute; no source trained an LLM.
@software{wordpalette,
author = {Gomes Gaigalas, Alexandre},
title = {wordpalette: a tiny character-level word-to-colour model},
year = {2026},
url = {https://github.com/alganet/wordpalette}
}