DocsUnderstand3 min read

The deep table#

A linear table adds one score per word, so "not good" can never mean the opposite of "good". The deep table keeps the same lookups but turns each row into a small hidden vector, then applies a ReLU and one dense layer. It learns negation and word pairs, and still answers in microseconds.

TL;DR: you don't have to do anything. With student = "auto" (the default) training builds both and keeps the deep table only when it certifies more held-out rows. It made sentiment, the classic weak spot, work.

What changed, measured#

Measured through the full pipeline at α = 5% (labels as the teacher):

task linear table: certified deep table: certified disagreement on served deep table C p50 / p99
SST-2 sentiment (32k rows) 0% 74% 4.3% H = 32, 2.7 MB 1 / 5 µs
AG News topics (29k rows) 81% 83% 4.5% H = 32, 5.7 MB 6 / 13 µs
BANKING77 intents (77 options) 81% 87% 3.0% H = 128, 3.1 MB 4 / 13 µs
prompt-injection set (LLM labels) 97.0% 98.1% 3.3% auto kept linear

How it works#

Each word or n-gram of the input is hashed to a row, exactly as before. In a linear table a row holds one score per option and the rows are added. In a deep table a row holds H numbers (32 to 128, chosen from the number of options); they are added, passed through a ReLU, and one small dense layer turns them into option scores. That one non-linearity is what lets "not" change the meaning of "good".

It is file format 2. The C core, numpy and JavaScript read it and compute the same scores bit for bit: deep tables are summed in the C core's order everywhere. Only the final exp is each platform's own, so a probability can differ in its last bit; answers and certified flags match.

Choosing#

student What you get
"auto" (default) Both are trained; the held-out fitting slice is split in two, one half tunes, the other judges which certifies more. The certificate records the choice.
"linear" Always the additive table, with its exact robustness radius
"deep" Always the deep table
intent = shad0w.decision("sentiment", options=["positive", "negative"], llm="openai/gpt-6-luna", student="auto")
shad0w train --dir shad0w --question sentiment --student deep --hidden 64

What it costs#

Also new in 0.4#

See also: Decision Bench, where shad0w-auto chose the deep table on three of six tasks (AG News, BANKING77, CLINC150).