% ============================================================================ % TikZ: Robust tabular neural network architecture % ============================================================================ \begin{tikzpicture}[ font=\small, >=Latex, node distance=6mm and 6mm, box/.style={rounded corners=2pt, draw=black!55, align=center, minimum height=8mm, inner sep=3pt, text width=24mm}, cat/.style={box, fill=NavyBlue!8}, num/.style={box, fill=OliveGreen!10, text width=30mm}, emb/.style={box, fill=BurntOrange!14, text width=22mm}, op/.style={box, fill=black!5}, spine/.style={box, fill=black!6, text width=52mm}, res/.style={box, fill=Plum!10, text width=52mm, minimum height=11mm}, outb/.style={box, fill=NavyBlue!16, text width=34mm, font=\bfseries}, detail/.style={rounded corners=2pt, draw=black!40, dashed, fill=Plum!5, align=left, text width=40mm, inner sep=4pt, font=\footnotesize}, ar/.style={->, thick, black!65} ] % ---- inputs ---- \node[cat] (city) {City index\\{\footnotesize (195 cats)}}; \node[cat, right=of city] (type) {Type index}; \node[cat, right=of type] (src) {Source index}; \node[num, right=10mm of src] (numin) {Numeric features\\{\footnotesize $\approx$45: area, lot, beds,\\baths, age, amenities,\\rooms, GPT specs}}; % ---- embeddings / bn ---- \node[emb, below=of city] (ecity) {Embedding\\{\footnotesize dim 29}}; \node[emb, below=of type] (etype) {Embedding\\{\footnotesize dim 4}}; \node[emb, below=of src] (esrc) {Embedding\\{\footnotesize dim 2}}; \node[op, below=of numin, text width=30mm] (bn) {BatchNorm\\{\footnotesize + missingness flags}}; \draw[ar] (city)--(ecity); \draw[ar] (type)--(etype); \draw[ar] (src)--(esrc); \draw[ar] (numin)--(bn); % ---- concat ---- \node[spine, below=12mm of etype.south, xshift=8mm] (concat) {Concatenate \;$\rightarrow$\; $\mathbb{R}^{\,\text{emb}+\text{num}}$}; \draw[ar] (ecity) |- (concat.west); \draw[ar] (etype) -- (concat); \draw[ar] (esrc) -- (concat); \draw[ar] (bn) -| (concat.east); % ---- projection ---- \node[spine, below=of concat] (proj) {Linear $\rightarrow$ 256\;\; (trunk)}; \draw[ar] (concat)--(proj); % ---- residual blocks ---- \node[res, below=of proj] (resb) {Residual block \;$\times\,3$\\{\footnotesize BN $\to$ GELU $\to$ Lin$_{512}$ $\to$ Dropout $\to$ Lin$_{256}$ \;$\oplus$\; skip}}; \draw[ar] (proj)--(resb); % ---- head ---- \node[spine, below=of resb] (head) {Head:\; BatchNorm $\to$ GELU $\to$ Linear$_{1}$}; \draw[ar] (resb)--(head); % ---- output ---- \node[outb, below=of head] (out) {$\widehat{\ln(\text{Price})}$}; \draw[ar] (head)--(out); % ---- residual detail callout ---- \node[detail, right=10mm of resb] (dtl) {\textbf{Res block:} $x \mapsto x + f(x)$\\ $f=$ Drop$\circ$Lin$_{256}\!\circ$Drop$\circ$GELU\\ $\circ$Lin$_{512}\!\circ$BN}; \draw[->, dashed, black!45] (resb.east)--(dtl.west); % ---- training / ensemble annotation ---- \node[detail, right=10mm of head, text width=42mm, fill=OliveGreen!6, draw=black!40] (train) {\textbf{Training (robust):}\\ Huber loss $\cdot$ AdamW $\cdot$ cosine LR\\ grad-clip 5 $\cdot$ dropout $\cdot$ early stop}; % ---- ensemble + blend ---- \node[op, below=8mm of out, text width=64mm, fill=NavyBlue!7] (ens) {Ensemble of 3 seeds (average) \;$\Rightarrow$\; blend 50/50 with gradient boosting}; \draw[ar] (out)--(ens); \end{tikzpicture}