mojtaba/amini
Home/Writing/RNN · Production
Mar 2025·8 min read·RNN · Production

An RNN that learned the rhythm of an Italian factory

Predicting which phase a job is in, and what it will cost by the time it ships, from telemetry no one had ever bothered to keep.

A production order at Dekali passes through six to twelve named phases — cutting, bending, welding, finishing, inspection — depending on the product. The factory had a system that recorded when each phase officially started and ended, but nobody used it consistently. Operators logged a phase when they remembered. The "data" was a slurry of timestamps with twenty percent missing and another twenty percent obviously wrong (phase 6 starts before phase 5 ends, that kind of thing).

The ask from management was disarmingly simple: tell me, for a job currently on the floor, what phase it is really in, and how many euros it will have consumed by the time it ships. Two questions. One model. We chose an RNN — specifically a small bidirectional GRU — because the input is naturally a sequence: every recorded event, in time order, with the operator and the machine ID attached. The model output was two heads: a softmax over phases (one of eight possible labels) and a regression on remaining cost in euros.

The training data was the dirty timestamp log, but we did one preprocessing pass that made the whole thing work. For every order, we built two parallel sequences: the official "what was logged" and the inferred "what actually happened" using the simple invariant that you cannot weld a part before you cut it. Disagreements between the two sequences became a third input feature: a confidence indicator on every event. The model learned to weight the confident events and ignore the contradictory ones, without anyone hand-curating the dataset.

The phase head reached 92% accuracy on a held-out month. The cost head was within ±6% on average. Neither number is impressive on the leaderboard. Both numbers are revolutionary on the factory floor, because the previous tool — a spreadsheet maintained by the office manager — had no concept of uncertainty at all. The shipped feature was a single panel in the existing ERP: phase, confidence, projected cost, projected delivery, all updating in real-time as new events landed.

The lesson from this project is the one no machine-learning curriculum teaches well: in industrial work, the gap between "data we have" and "data we need" is bridged by domain priors, not bigger models. A bidirectional GRU with three layers and 64 hidden units, given the right priors, beat a much bigger transformer we briefly tried. The transformer had more capacity. The GRU had the priors baked in via feature engineering. The priors won.