A Django application around four Keras convolutional networks: English digits, English alphanumerics across sixty-two classes, Arabic digits, and the twenty-eight letters of the Arabic alphabet. You draw on a canvas and the matching model returns a prediction.
Four models, four datasets, one interface. Each is a small convolutional stack — three convolution and pooling blocks into a dropout and dense head — trained in a notebook, exported, and loaded from disk at import so a request never pays training or loading cost.
Splitting the models by script and by class set rather than training one large classifier keeps each output space small and each confusion matrix readable, which matters more than raw parameter count at this scale.
The two Arabic models need their input rotated ninety degrees and mirrored horizontally before inference, because that is the orientation the source dataset stores its glyphs in. Miss it and the model still returns a confident prediction — just the wrong one, with no error anywhere to point at.
Each of the four models therefore has its own preprocessing path: its own target resolution, its own flattening, its own normalisation. They are kept as four separate functions rather than one parameterised one, because the differences between them are exactly the thing a reader needs to see.