00:01 Introduzione
02:44 Sondaggio sui bisogni predittivi
05:57 Modelli vs. Modellazione
12:26 La storia finora
15:50 Un po’ di teoria e un po’ di pratica
17:41 Programmazione Differenziabile, SGD 1/6
24:56 Programmazione Differenziabile, autodiff 2/6
31:07 Programmazione Differenziabile, funzioni 3/6
35:35 Programmazione Differenziabile, meta-parametri 4/6
37:59 Programmazione Differenziabile, parametri 5/6
40:55 Programmazione Differenziabile, particolarità 6/6
43:41 Esempio, previsione della domanda al dettaglio
45:49 Esempio, adattamento dei parametri 1/6
53:14 Esempio, condivisione dei parametri 2/6
01:04:16 Esempio, mascheramento della perdita 3/6
01:09:34 Esempio, integrazione delle covariate 4/6
01:14:09 Esempio, decomposizione sparsa 5/6
01:21:17 Esempio, ridimensionamento libero 6/6
01:25:14 Whiteboxing
01:33:22 Ritorno all’ottimizzazione sperimentale
01:39:53 Conclusioni
01:44:40 Prossima lezione e domande del pubblico

Descrizione

La Programmazione Differenziabile (DP) è un paradigma generativo utilizzato per progettare una vasta classe di modelli statistici, che si rivelano eccellenti per le sfide predittive della supply chain. La DP supera quasi tutta la letteratura “classica” di previsione basata su modelli parametrici. La DP è anche superiore agli algoritmi “classici” di machine learning - fino alla fine degli anni 2010 - in praticamente ogni dimensione che conta per un utilizzo pratico a fini di supply chain, inclusa la facilità di adozione da parte degli operatori.

Trascrizione completa

Slide 1

Benvenuti a questa serie di lezioni sulla supply chain. Sono Joannes Vermorel e oggi presenterò “Modellazione Predittiva Strutturata con Programmazione Differenziabile nella Supply Chain”. Scegliere la corretta linea di azione richiede una dettagliata conoscenza quantitativa del futuro. Infatti, ogni decisione - acquistare di più, produrre di più - riflette una certa anticipazione del futuro. Inevitabilmente, la teoria dominante della supply chain enfatizza la previsione per affrontare questo problema. Tuttavia, la prospettiva della previsione, almeno nella sua forma classica, presenta due limiti.

In primo luogo, enfatizza una stretta prospettiva di previsione delle serie temporali, che purtroppo non riesce a affrontare la diversità delle sfide come si presentano nelle supply chain del mondo reale. In secondo luogo, enfatizza una stretta focalizzazione sull’accuratezza delle previsioni delle serie temporali che in gran parte perde il punto. Ottenere qualche punto percentuale in più di accuratezza non si traduce automaticamente nella generazione di ulteriori profitti per la tua supply chain.

L’obiettivo della presente lezione è scoprire un approccio alternativo alla previsione, che è in parte una tecnologia e in parte una metodologia. La tecnologia sarà la programmazione differenziabile e la metodologia sarà la modellazione predittiva strutturata. Alla fine di questa lezione, dovresti essere in grado di applicare questo approccio a una situazione di supply chain. Questo approccio non è teorico; è stato l’approccio predefinito di Lokad per un paio di anni. Inoltre, se non hai guardato le lezioni precedenti, la presente lezione non dovrebbe essere totalmente incomprensibile. Tuttavia, in questa serie di lezioni, stiamo raggiungendo un punto in cui sarà molto utile guardare effettivamente le lezioni in sequenza. Nella presente lezione, riprenderemo molti elementi che sono stati introdotti nelle lezioni precedenti.

Slide 2

La previsione della domanda futura è il candidato ovvio quando si tratta di soddisfare le esigenze predictive della nostra supply chain. Infatti, una migliore anticipazione della domanda è un ingrediente critico per decisioni molto basilari come acquistare di più e produrre di più. Tuttavia, attraverso i principi della supply chain che abbiamo introdotto nel corso del terzo capitolo di questa serie di lezioni, abbiamo visto che esiste un insieme piuttosto diversificato di aspettative che è possibile avere in termini di requisiti predittivi per guidare la propria supply chain.

In particolare, ad esempio, i tempi di consegna variano e i tempi di consegna mostrano pattern stagionali. Praticamente ogni singola decisione legata all’inventario richiede un’anticipazione della domanda futura ma anche un’anticipazione del tempo di consegna futuro. Pertanto, i tempi di consegna devono essere previsti. I resi rappresentano anche a volte fino alla metà del flusso. Questo è il caso, ad esempio, per l’e-commerce di moda in Germania. In queste situazioni, anticipare i resi diventa critico e questi resi variano molto da un prodotto all’altro. Pertanto, in queste situazioni, i resi devono essere previsti.

Sul lato dell’offerta, la produzione stessa può variare e non solo a causa dei ritardi aggiuntivi o dei tempi di consegna variabili. Ad esempio, la produzione può comportare un certo grado di incertezza. Questo accade in settori a bassa tecnologia come l’agricoltura, ma può accadere anche in settori ad alta tecnologia come l’industria farmaceutica. Pertanto, anche i rendimenti di produzione devono essere previsti. Infine, il comportamento del cliente conta molto. Ad esempio, guidare la domanda attraverso prodotti che generano acquisizioni è molto importante e, al contrario, affrontare le rotture di stock su prodotti che causano un grande turnover quando tali prodotti mancano proprio a causa delle rotture di stock conta molto. Pertanto, questi comportamenti richiedono analisi, previsione - in altre parole, devono essere previsti. Il punto chiave qui è che la previsione delle serie temporali è solo un pezzo del puzzle. Abbiamo bisogno di un approccio predittivo che possa abbracciare tutte queste situazioni e altre ancora, poiché è una necessità se vogliamo avere un approccio che abbia qualche possibilità di successo di fronte a tutte le situazioni che una supply chain del mondo reale ci presenterà.

Slide 3

L’approccio standard quando si tratta del problema predittivo è presentare un modello. Questo approccio ha guidato la letteratura sulla previsione delle serie temporali per decenni ed è ancora, oserei dire, l’approccio predominante nei circoli dell’apprendimento automatico al giorno d’oggi. Questo approccio centrato sul modello, è così pervasivo che potrebbe persino essere difficile fare un passo indietro per valutare cosa sta realmente accadendo con questa prospettiva centrata sul modello.

La mia proposta per questa lezione è che la supply chain richiede una tecnica di modellazione, una prospettiva centrata sulla modellazione e che una serie di modelli, per quanto estesi, non sarà mai sufficiente per affrontare tutte le nostre esigenze come si trovano nelle supply chain del mondo reale. Cerchiamo di chiarire questa distinzione tra l’approccio centrato sul modello e l’approccio centrato sulla modellazione.

L’approccio centrato sul modello enfatizza prima di tutto un modello. Il modello viene presentato come un pacchetto, un insieme di “ricette numeriche” che di solito si presentano sotto forma di “pezzo di software” che è possibile eseguire effettivamente. Anche quando non è disponibile alcun software del genere, l’aspettativa è tale che se si ha un modello ma non il software, allora ci si aspetta che il modello sia descritto con precisione matematica, consentendo una completa reimplementazione del modello. Questo pacchetto, il modello reso software, è destinato a essere il fine ultimo.

Da una prospettiva idealizzata, si suppone che questo modello si comporti esattamente come una funzione matematica: input in ingresso, risultati in uscita. Se rimane qualche configurabilità per il modello, allora quegli elementi configurabili vengono trattati come punti deboli, come problemi che devono ancora essere completamente risolti. Infatti, ogni opzione di configurazione indebolisce il caso del modello. Quando abbiamo configurabilità e troppe opzioni dalla prospettiva centrata sul modello, il modello tende a dissolversi in uno spazio di modelli e improvvisamente non possiamo più fare un vero e proprio benchmark perché non esiste un singolo modello.

L’approccio di modellazione adotta un approccio completamente invertito sull’angolo della configurabilità. Massimizzare l’espressività del modello diventa il fine ultimo. Questo non è un difetto; diventa una caratteristica. La situazione può essere piuttosto confusa quando guardiamo da una prospettiva centrata sulla modellazione, perché se stiamo guardando una presentazione di una prospettiva centrata sulla modellazione, ciò che vedremo è una presentazione di modelli. Tuttavia, quei modelli hanno un intento molto diverso.

Se adottiamo la prospettiva di modellazione, il modello che viene presentato è solo un’illustrazione. Non ha alcun intento di essere completo o di essere la soluzione finale al problema. È solo un passo nel percorso per illustrare la tecnica di modellazione stessa. La sfida principale con la tecnica di modellazione è che improvvisamente diventa molto difficile valutare l’approccio. Infatti, stiamo perdendo l’opzione di un benchmark ingenuo perché, con questa prospettiva centrata sulla modellazione, abbiamo potenzialità di modelli. Non ci concentriamo specificamente su un modello rispetto all’altro; questa non è nemmeno la mentalità giusta. Quello che abbiamo è un’opinione informata.

Tuttavia, vorrei sottolineare immediatamente che non è perché si ha un benchmark e numeri associati al proprio benchmark che automaticamente si qualifica come scienza. I numeri potrebbero essere solo senza senso e, al contrario, non è perché è solo un’opinione informata che è meno scientifica. In un certo senso, è solo un approccio diverso e la realtà è che tra le varie comunità, i due approcci coesistono.

Ad esempio, se guardiamo al paper “Forecasting at Scale”, pubblicato da un team di Facebook nel 2017, abbiamo qualcosa che è praticamente l’archetipo dell’approccio centrato sul modello. In questo paper, viene presentato il modello Facebook Prophet. E in un altro paper, “Tensor Comprehension”, pubblicato nel 2018 da un altro team di Facebook, abbiamo essenzialmente una tecnica di modellazione. Questo paper può essere considerato l’archetipo dell’approccio di modellazione. Quindi, si può vedere che anche i team di ricerca che lavorano nella stessa azienda, praticamente nello stesso periodo, possono affrontare il problema da un angolo all’altro, a seconda della situazione.

Slide 4

Questa lezione fa parte di una serie di lezioni sulla supply chain. Nel primo capitolo, ho presentato il mio punto di vista sulla supply chain sia come campo di studio che come pratica. Fin dalla prima lezione, ho sostenuto che la teoria mainstream della supply chain non è all’altezza delle aspettative. Accade che la teoria mainstream della supply chain si basa pesantemente sull’approccio centrato sul modello e credo che questo singolo aspetto sia una delle principali cause di attrito tra la teoria mainstream della supply chain e le esigenze delle supply chain del mondo reale.

Nel secondo capitolo di questa serie di lezioni, ho introdotto una serie di metodologie. Infatti, le metodologie naive sono tipicamente sconfitte dalla natura episodica e spesso avversaria delle situazioni di supply chain. In particolare, la lezione intitolata “Ottimizzazione sperimentale empirica”, che faceva parte del secondo capitolo, è il tipo di prospettiva che adotto oggi in questa lezione.

Nel terzo capitolo, ho introdotto una serie di personae della supply chain. Le personae rappresentano un focus esclusivo sui problemi che stiamo cercando di affrontare, ignorando completamente qualsiasi soluzione candidata. Queste personae sono strumentali per comprendere la diversità delle sfide predictive affrontate dalle supply chain del mondo reale. Credo che queste personae siano essenziali per evitare di rimanere intrappolati nella stretta prospettiva delle serie temporali, che è un tratto distintivo di una teoria della supply chain che viene esercitata prestando poca attenzione ai dettagli concreti delle supply chain del mondo reale.

Nel quarto capitolo, ho introdotto una serie di scienze ausiliarie. Queste scienze sono distinte dalla supply chain, ma un comando di base di queste discipline è essenziale per la pratica moderna della supply chain. Abbiamo già affrontato brevemente l’argomento della programmazione differenziabile in questo quarto capitolo, ma lo reintrodurrò in modo molto più dettagliato tra qualche minuto.

Infine, nella prima lezione di questo quinto capitolo, abbiamo visto un modello semplice, alcuni direbbero anche semplicistico, che ha raggiunto un’accuratezza di previsione all’avanguardia in una competizione di previsione a livello mondiale che si è svolta nel 2020. Oggi, presenterò una serie di tecniche che possono essere utilizzate per apprendere i parametri coinvolti con questo modello che ho presentato nella lezione precedente.

Slide 5

Il resto di questa lezione si dividerà in due blocchi, seguiti da alcune considerazioni finali. Il primo blocco è dedicato alla programmazione differenziabile. Abbiamo già affrontato questo argomento nel quarto capitolo; tuttavia, oggi lo esamineremo più da vicino. Alla fine di questa lezione, dovresti essere quasi in grado di creare la tua implementazione di programmazione differenziabile. Dico “quasi” perché potrebbe variare a seconda della tecnologia che stai utilizzando. Inoltre, la programmazione differenziabile è una piccola arte a sé stante; richiede un po’ di esperienza per farla funzionare correttamente nella pratica.

Il secondo blocco di questa lezione è una panoramica di una situazione di previsione della domanda al dettaglio. Questa panoramica è un seguito della lezione precedente, in cui abbiamo presentato il modello che ha ottenuto il primo posto nella competizione di previsione M5 nel 2020. Tuttavia, nella presentazione precedente, non abbiamo dettagliato come i parametri del modello siano stati effettivamente calcolati. Questa panoramica fornirà esattamente ciò e affronteremo anche elementi importanti come le scorte esaurite e le promozioni che non sono state affrontate nella lezione precedente. Infine, basandomi su tutti questi elementi, discuterò la mia opinione sulla idoneità della programmazione differenziabile per scopi legati alla supply chain.

Slide 6

La discesa del gradiente stocastico (SGD) è uno dei due pilastri della programmazione differenziabile. L’SGD è ingannevolmente semplice eppure non è ancora del tutto chiaro perché funzioni così bene. È assolutamente chiaro perché funziona; ciò che non è molto chiaro è perché funzioni così bene.

La storia della discesa del gradiente stocastico risale agli anni ‘50, quindi ha una storia piuttosto lunga. Tuttavia, questa tecnica è diventata riconosciuta a livello mainstream solo nell’ultimo decennio con l’avvento del deep learning. La discesa del gradiente stocastico è profondamente radicata nella prospettiva dell’ottimizzazione matematica. Abbiamo una funzione di perdita Q che vogliamo minimizzare e abbiamo un insieme di parametri reali, indicati con W, che rappresentano tutte le possibili soluzioni. Quello che vogliamo trovare è la combinazione di parametri W che minimizza la funzione di perdita Q.

La funzione di perdita Q dovrebbe rispettare una proprietà fondamentale: può essere decomposta in modo additivo in una serie di termini. L’esistenza di questa decomposizione additiva fa sì che la discesa del gradiente stocastico funzioni. Se la tua funzione di perdita non può essere decomposta in modo additivo in questo modo, allora la discesa del gradiente stocastico non si applica come tecnica. In questa prospettiva, X rappresenta l’insieme di tutti i termini che contribuiscono alla funzione di perdita e Qx rappresenta una perdita parziale che rappresenta la perdita per uno dei termini in questa prospettiva di avere la funzione di perdita come somma di termini parziali.

Sebbene la discesa del gradiente stocastico non sia specifica per situazioni di apprendimento, si adatta molto bene a tutti i casi di apprendimento e quando dico apprendimento, intendo apprendimento come nei casi di machine learning. Infatti, se abbiamo un set di dati di addestramento, questo set di dati assumerà la forma di un elenco di osservazioni, con ogni osservazione che è una coppia di caratteristiche che rappresentano l’input del modello e etichette che rappresentano gli output. Fondamentalmente, quello che vogliamo da una prospettiva di apprendimento è progettare un modello che si comporti al meglio sull’errore empirico e su altre cose osservate da questo set di dati di addestramento. Da una prospettiva di apprendimento, X sarebbe effettivamente l’elenco delle osservazioni e i parametri sarebbero i parametri di un modello di machine learning che cerchiamo di ottimizzare per adattarsi al meglio a questo set di dati.

La discesa del gradiente stocastico è fondamentalmente un processo iterativo che itera casualmente attraverso le osservazioni, una osservazione alla volta. Prendiamo una osservazione, una piccola X, alla volta e per questa osservazione calcoliamo un gradiente locale, rappresentato come nabla di Qx. È solo un gradiente locale che si applica solo a un termine della funzione di perdita. Questo non è il gradiente della funzione di perdita completa, ma un gradiente locale che si applica solo a un termine della funzione di perdita - puoi vederlo come un gradiente parziale.

Un passo della discesa del gradiente stocastico consiste nel prendere questo gradiente locale e spostare leggermente i parametri W in base a questa osservazione parziale del gradiente. Questo è esattamente ciò che sta accadendo qui, con W che viene aggiornato con W meno eta volte nabla QxW. Questo sta semplicemente dicendo, in forma molto concisa, di spostare il parametro W nella direzione del gradiente locale ottenuto con X, dove X è solo una delle osservazioni del tuo set di dati, se stiamo affrontando un problema da una prospettiva di apprendimento. Quindi, procediamo casualmente, applicando questo gradiente locale e iterando.

Intuitivamente, la discesa del gradiente stocastico funziona molto bene perché mostra un compromesso tra iterazioni più veloci e gradienti più rumorosi, fino ad arrivare a iterazioni più granulari e quindi più veloci. L’essenza della discesa del gradiente stocastico è che non ci interessa avere misurazioni molto imperfette per i nostri gradienti purché possiamo ottenere quelle misurazioni imperfette molto velocemente. Se possiamo spostare il compromesso fino a ottenere iterazioni più veloci, anche a scapito di gradienti più rumorosi, facciamolo. Ecco perché la discesa del gradiente stocastico è così efficace nel ridurre la quantità di risorse di calcolo necessarie per ottenere una certa qualità di soluzione per il parametro W.

Infine, abbiamo la variabile eta, che viene definita tasso di apprendimento. In pratica, il tasso di apprendimento non è una costante; questa variabile varia mentre la discesa del gradiente stocastico è in corso. Presso Lokad, utilizziamo l’algoritmo Adam per controllare l’evoluzione di questo parametro eta per il tasso di apprendimento. Adam è un metodo pubblicato nel 2014 ed è molto popolare nei circoli di machine learning quando è coinvolta la discesa del gradiente stocastico.

Slide 7

Il secondo pilastro della programmazione differenziabile è la differenziazione automatica. Abbiamo già visto questo concetto in una lezione precedente. Rivisitiamo questo concetto guardando un pezzo di codice. Questo codice è scritto in Envision, un linguaggio di programmazione specifico del dominio sviluppato da Lokad per scopi di ottimizzazione predittiva delle catene di approvvigionamento. Sto scegliendo Envision perché, come vedrete, gli esempi sono molto più concisi e sperabilmente anche molto più chiari rispetto alle presentazioni alternative se dovessi usare Python, Java o C#. Tuttavia, vorrei sottolineare che anche se sto usando Envision, non c’è nessuna formula magica coinvolta. Potresti reimplementare completamente tutti questi esempi in altri linguaggi di programmazione. Molto probabilmente moltiplicherebbe il numero di righe di codice per un fattore di 10, ma nel grande schema delle cose, questo è un dettaglio. Qui, per una lezione, Envision ci offre una presentazione molto chiara e concisa.

Vediamo come la programmazione differenziabile può essere utilizzata per affrontare una regressione lineare. Questo è un problema giocattolo; non abbiamo bisogno della programmazione differenziabile per fare una regressione lineare. L’obiettivo è semplicemente acquisire familiarità con la sintassi della programmazione differenziabile. Dalle righe 1 alla 6, stiamo dichiarando la tabella T, che rappresenta la tabella delle osservazioni. Quando dico tabella delle osservazioni, ricorda semplicemente l’insieme di discesa del gradiente stocastico che è stato chiamato X. È esattamente la stessa cosa. Questa tabella ha due colonne, una caratteristica indicata con X e un’etichetta indicata con Y. Quello che vogliamo è prendere X come input e essere in grado di prevedere Y con un modello lineare, o più precisamente, un modello affine. Ovviamente, abbiamo solo quattro punti dati in questa tabella T. Questo è un dataset ridicolmente piccolo; è solo per la chiarezza dell’esposizione.

Alla riga 8, introduciamo il blocco autodiff. Il blocco autodiff può essere visto come un ciclo in Envision. È un ciclo che itera su una tabella, in questo caso, la tabella T. Queste iterazioni riflettono i passaggi della discesa del gradiente stocastico. Quindi, ciò che accade quando l’esecuzione di Envision entra in questo blocco autodiff è che abbiamo una serie di esecuzioni ripetute in cui prendiamo righe dalla tabella delle osservazioni e quindi applichiamo passaggi della discesa del gradiente stocastico. Per fare ciò, abbiamo bisogno dei gradienti.

Da dove vengono i gradienti? Qui, abbiamo scritto un programma, una piccola espressione del nostro modello, Ax + B. Introduciamo la funzione di perdita, che è l’errore quadratico medio. Vogliamo avere il gradiente. Per una situazione così semplice come questa, potremmo scrivere il gradiente manualmente. Tuttavia, la differenziazione automatica è una tecnica che consente di compilare un programma in due forme: la prima forma è l’esecuzione in avanti del programma e la seconda forma è la forma di esecuzione inversa che calcola i gradienti associati a tutti i parametri presenti nel programma.

Alle righe 9 e 10, abbiamo la dichiarazione di due parametri, A e B, con la parola chiave “auto” che dice a Envision di fare una inizializzazione automatica per i valori di questi due parametri. A e B sono valori scalari. La differenziazione automatica avviene per tutti i programmi contenuti in questo blocco autodiff. Fondamentalmente, è una tecnica a livello di compilatore per compilare questo programma due volte: una volta per il passaggio in avanti e una seconda volta per un programma che fornirà i valori dei gradienti. La bellezza della tecnica di differenziazione automatica è che garantisce che la quantità di CPU necessaria per calcolare il programma regolare sia allineata con la quantità di CPU necessaria per calcolare il gradiente quando si esegue il passaggio inverso. Questa è una proprietà molto importante. Infine, alla riga 14, stampiamo i parametri che abbiamo appena appreso con il blocco autodiff sopra.

Slide 8

La programmazione differenziabile brilla davvero come paradigma di programmazione. È possibile comporre un programma arbitrariamente complesso e ottenere la differenziazione automatica di questo programma. Questo programma può includere rami e chiamate di funzioni, ad esempio. Questo esempio di codice riprende la funzione di perdita pinball che abbiamo introdotto nella precedente lezione. La funzione di perdita pinball può essere utilizzata per derivare stime dei quantili quando osserviamo deviazioni da una distribuzione di probabilità empirica. Se si minimizza l’errore quadratico medio con la propria stima, si ottiene una stima della media della distribuzione empirica. Se si minimizza la funzione di perdita pinball, si ottiene una stima di un obiettivo di quantile. Se si punta a un quantile del 90°, significa che è il valore nella propria distribuzione di probabilità in cui il valore futuro da osservare ha una probabilità del 90% di essere inferiore alla propria stima se si ha un obiettivo del 90° o una probabilità del 10% di essere superiore. Questo ricorda l’analisi dei livelli di servizio che esiste nella supply chain.

Alle righe 1 e 2, stiamo introducendo una tabella di osservazioni popolata con deviazioni campionate casualmente da una distribuzione di Poisson. I valori della distribuzione di Poisson sono campionati con una media di 3 e otteniamo 10.000 deviazioni. Alle righe 4 e 5, implementiamo la nostra implementazione personalizzata della funzione di perdita pinball. Questa implementazione è quasi identica al codice che ho introdotto nella lezione precedente. Tuttavia, la parola chiave “autodiff” è ora aggiunta alla dichiarazione della funzione. Questa parola chiave, quando collegata alla dichiarazione della funzione, garantisce che il compilatore Envision possa differenziare automaticamente questa funzione. Sebbene, in teoria, la differenziazione automatica possa essere applicata a qualsiasi programma, in pratica ci sono molti programmi che non hanno senso essere differenziati o molte funzioni in cui non avrebbe senso. Ad esempio, considera una funzione che prende due valori di testo e li concatena. Dal punto di vista della differenziazione automatica, non ha senso applicare la differenziazione automatica a questo tipo di operazione. La differenziazione automatica richiede che i numeri siano presenti in input e in output per le funzioni che si sta cercando di differenziare.

Alle righe 7-9, abbiamo il blocco autodiff, che calcola la stima del quantile target per la distribuzione empirica ricevuta attraverso la tabella di osservazioni. Sotto il cofano, è effettivamente una distribuzione di Poisson. La stima del quantile è dichiarata come un parametro chiamato “quantile” alla riga 8 e alla riga 9 facciamo una chiamata di funzione alla nostra implementazione della funzione di perdita pinball. L’obiettivo del quantile è impostato su 0,5, quindi stiamo effettivamente cercando una stima mediana della distribuzione. Infine, alla riga 11, stampiamo i risultati per il valore che abbiamo appreso attraverso l’esecuzione del blocco autodiff. Questo pezzo di codice illustra come un programma che andremo a differenziare automaticamente possa includere sia una chiamata di funzione che un ramo, e tutto ciò può accadere completamente automaticamente.

Slide 9

Ho detto che i blocchi autodiff possono essere interpretati come un ciclo che esegue una serie di passi di discesa del gradiente stocastico (SGD) sulla tabella di osservazioni, prendendo una riga da questa tabella di osservazioni alla volta. Tuttavia, sono rimasto abbastanza elusivo sulla condizione di arresto per questa situazione. Quando si ferma la discesa del gradiente stocastico in Envision? Per impostazione predefinita, la discesa del gradiente stocastico si ferma dopo 10 epoche. Un’epoca, in termini di apprendimento automatico, rappresenta un passaggio completo attraverso la tabella di osservazioni. Alla riga 7, un attributo chiamato “epoche” può essere allegato ai blocchi autodiff. Questo attributo è opzionale; per impostazione predefinita, il valore è 10, ma se si specifica questo attributo, è possibile scegliere un conteggio diverso. Qui stiamo specificando 100 epoche. Tieni presente che il tempo totale per il calcolo è quasi strettamente lineare al numero di epoche. Pertanto, se hai il doppio delle epoche, il tempo di calcolo durerà il doppio.

Tuttavia, alla riga 7, stiamo anche introducendo un secondo attributo chiamato “learning_rate”. Anche questo attributo è opzionale e per impostazione predefinita ha il valore 0,01, allegato al blocco autodiff. Questo tasso di apprendimento è un fattore utilizzato per inizializzare l’algoritmo Adam che controlla l’evoluzione del tasso di apprendimento. Questo è il parametro eta che abbiamo visto nel passaggio della discesa del gradiente stocastico. Controlla l’algoritmo Adam. Fondamentalmente, questo è un parametro che non è necessario regolare frequentemente, ma a volte regolando questo parametro è possibile risparmiare una parte significativa della potenza di elaborazione. Non è inaspettato che regolando questo tasso di apprendimento, è possibile risparmiare circa il 20% del tempo di calcolo totale per la discesa del gradiente stocastico.

Slide 10

L’inizializzazione dei parametri appresi nel blocco autodiff richiede anche un’analisi più approfondita. Finora abbiamo usato la parola chiave “auto” e in Envision, questo significa semplicemente che Envision inizializzerà il parametro estrarre casualmente un valore da una distribuzione gaussiana di media 1 e deviazione standard 0,1. Questa inizializzazione si discosta dalla pratica usuale nell’apprendimento profondo, in cui i parametri vengono inizializzati casualmente con gaussiane centrate intorno a zero. Il motivo per cui Lokad ha adottato questo approccio diverso diventerà più chiaro più avanti in questa lezione quando procederemo con una situazione di previsione della domanda di vendita al dettaglio effettiva.

In Envision, è possibile sovrascrivere e controllare l’inizializzazione dei parametri. Il parametro “quantile”, ad esempio, viene dichiarato alla riga 9 ma non ha bisogno di essere inizializzato. Infatti, alla riga 7, appena sopra il blocco autodiff, abbiamo una variabile “quantile” a cui viene assegnato il valore 4,2 e quindi la variabile è già inizializzata con un valore dato. Non c’è più bisogno di inizializzazione automatica. È anche possibile imporre un intervallo di valori consentiti per i parametri, e ciò viene fatto con la parola chiave “in” alla riga 9. Fondamentalmente, stiamo definendo che “quantile” dovrebbe essere compreso tra 1 e 10, inclusi. Con questi limiti, se c’è un aggiornamento ottenuto dall’algoritmo Adam che sposterebbe il valore del parametro al di fuori dell’intervallo accettabile, limitiamo il cambiamento da Adam in modo che rimanga all’interno di questo intervallo. Inoltre, impostiamo anche a zero i valori di momento che sono tipicamente allegati all’algoritmo Adam sotto il cofano. L’imposizione dei limiti dei parametri si discosta dalla pratica classica dell’apprendimento profondo; tuttavia, i vantaggi di questa funzionalità diventeranno evidenti una volta che inizieremo a discutere un esempio effettivo di previsione della domanda di vendita al dettaglio.

Slide 11

La programmazione differenziabile si basa molto sulla discesa del gradiente stocastico. L’aspetto stocastico è ciò che rende la discesa molto veloce. È una spada a doppio taglio; il rumore ottenuto attraverso le perdite parziali non è solo un difetto, ma anche una caratteristica. Avendo un po’ di rumore, la discesa può evitare di rimanere bloccata in zone con gradienti molto piatti. Quindi, avere questo gradiente rumoroso non solo rende l’iterazione molto più veloce, ma aiuta anche a spingere l’iterazione a uscire dalle aree in cui il gradiente è molto piatto e causa una rallentamento della discesa. Tuttavia, una cosa da tenere presente è che quando si utilizza la discesa del gradiente stocastico, la somma del gradiente non è il gradiente della somma. Di conseguenza, la discesa del gradiente stocastico presenta piccoli bias statistici, soprattutto quando si considerano le code delle distribuzioni. Tuttavia, quando sorgono tali preoccupazioni, è relativamente semplice applicare correzioni numeriche, anche se la teoria rimane un po’ confusa.

La programmazione differenziabile (DP) non deve essere confusa con un risolutore di ottimizzazione matematica arbitrario. Il gradiente deve fluire attraverso il programma affinché la programmazione differenziabile funzioni. La programmazione differenziabile può funzionare con programmi arbitrariamente complessi, ma tali programmi devono essere progettati tenendo presente la programmazione differenziabile. Inoltre, la programmazione differenziabile è una cultura; è un insieme di consigli e trucchi che si adattano bene alla discesa del gradiente stocastico. Tutto considerato, la programmazione differenziabile si trova sul lato facile dello spettro dell’apprendimento automatico. È molto accessibile come tecnica. Tuttavia, è necessaria un po’ di abilità per padroneggiare questo paradigma e utilizzarlo senza intoppi in produzione.

Slide 12

Siamo ora pronti per intraprendere il secondo blocco di questa lezione: la panoramica. Faremo una panoramica del nostro compito di previsione della domanda al dettaglio. Questo esercizio di modellazione è allineato alla sfida di previsione che abbiamo presentato nella lezione precedente. In breve, vogliamo prevedere la domanda giornaliera a livello di SKU in una rete di vendita al dettaglio. Un SKU, o unità di mantenimento delle scorte, è tecnicamente il prodotto cartesiano tra prodotti e negozi, filtrato lungo le voci dell’assortimento. Ad esempio, se abbiamo 100 negozi e 10.000 prodotti, e se ogni singolo prodotto è presente in ogni negozio, otteniamo 1 milione di SKU.

Ci sono strumenti per trasformare una stima deterministica in una stima probabilistica. Abbiamo visto uno di questi strumenti nella lezione precedente attraverso la tecnica ESSM. Riaffronteremo questa specifica problematica, ovvero trasformare le stime in stime probabilistiche, in maggior dettaglio nella prossima lezione. Tuttavia, oggi siamo interessati solo a stimare le medie, e tutti gli altri tipi di stime (quantili, probabilistiche) verranno successivamente come estensioni naturali dell’esempio principale che presenterò oggi. In questa panoramica, impareremo i parametri di un semplice modello di previsione della domanda. La semplicità di questo modello è ingannevole perché questa classe di modelli raggiunge previsioni all’avanguardia, come illustrato nella competizione di previsione M5 nel 2020.

Slide 13

Per il nostro modello di domanda parametrico, introduciamo un singolo parametro per ogni singolo SKU. Si tratta di una forma assolutamente semplicistica di modello; la domanda è modellata come una costante per ogni SKU. Tuttavia, non è la stessa costante per ogni SKU. Una volta ottenuta questa media giornaliera costante, avrà lo stesso valore per tutti i giorni dell’intero ciclo di vita dello SKU.

Diamo un’occhiata a come viene fatto con la programmazione differenziabile. Dalle righe da 1 a 4, stiamo introducendo il blocco dei dati di prova. In pratica, questo modello e tutte le sue varianti dipenderebbero da input ottenuti dai sistemi aziendali: l’ERP, WMS, TMS, ecc. Presentare una lezione in cui inserirei un modello matematico in una rappresentazione realistica dei dati, come si ottiene dall’ERP, introdurrebbe tonnellate di complicazioni accidentali che sono irrilevanti per l’argomento attuale della lezione. Quindi, quello che sto facendo qui è introdurre un blocco di dati di prova che non sta nemmeno cercando di essere realistico in alcun modo, o il tipo di dati che si può osservare in una situazione di vendita al dettaglio effettiva. L’unico obiettivo di questi dati di prova è introdurre le tabelle e le relazioni all’interno delle tabelle, e assicurarsi che l’esempio di codice fornito sia completo, possa essere compilato e possa essere eseguito. Tutti gli esempi di codice che hai visto finora sono completamente autonomi; non ci sono parti nascoste prima o dopo. Lo scopo unico del blocco dei dati di prova è assicurarsi di avere un pezzo di codice autonomo.

In ogni esempio in questa panoramica, partiamo da questo blocco di dati di prova. Alla riga 1, introduciamo la tabella delle date con “dates” come chiave primaria. Qui, abbiamo un intervallo di date che è fondamentalmente di due anni e un mese. Quindi, alla riga 2, introduciamo la tabella degli SKU, che è l’elenco degli SKU. In questo esempio minimalista, abbiamo solo tre SKU. In una situazione di vendita al dettaglio reale per una rete di vendita al dettaglio di dimensioni considerevoli, avremmo milioni, se non decine di milioni, di SKU. Ma qui, per il bene dell’esempio, prendo un numero molto piccolo. Alla riga 3, abbiamo la tabella “T”, che è un prodotto cartesiano tra gli SKU e la data. Fondamentalmente, ciò che ottieni attraverso questa tabella “T” è una matrice in cui hai ogni singolo SKU e ogni singolo giorno. Ha due dimensioni.

Alla riga 6, introduciamo il nostro vero blocco di autodiff. La tabella delle osservazioni è la tabella degli SKU, e la discesa del gradiente stocastico qui prenderà un SKU alla volta. Alla riga 7, introduciamo il “level”, che sarà il nostro unico parametro. È un parametro vettoriale, e finora, nei nostri blocchi di autodiff, abbiamo introdotto solo parametri scalari. I parametri precedenti erano solo un numero; qui, “SKU.level” è effettivamente un vettore. È un vettore che ha un valore per SKU, ed è letteralmente la nostra domanda costante modellata a livello di SKU. Specifichiamo un intervallo, e vedremo perché è importante tra un minuto. Deve essere almeno 0,01, e mettiamo 1.000 come limite superiore della domanda media giornaliera per questo parametro. Questo parametro viene inizializzato automaticamente con un valore vicino a uno, che è un punto di partenza ragionevole. In questo modello, abbiamo solo un grado di libertà per SKU. Infine, alle righe 8 e 9, stiamo effettivamente implementando il modello in sé. Alla riga 8, stiamo calcolando “dot.delta”, che è la domanda prevista dal modello meno l’osservata, che è “T.sold”. Il modello è solo un singolo termine, una costante, e poi abbiamo l’osservazione, che è “T.sold”.

Per capire cosa sta succedendo qui, abbiamo alcuni comportamenti di trasmissione. La tabella “T” è una tabella incrociata tra SKU e data. Il blocco autodiff è un’iterazione che scorre le righe della tabella delle osservazioni. Alla riga 9, siamo all’interno del blocco autodiff, quindi abbiamo selezionato una riga per la tabella SKU. Il valore “SKUs.level” non è un vettore qui; è solo uno scalare, un solo valore perché abbiamo selezionato solo una riga della tabella delle osservazioni. Quindi “T.sold” non è più una matrice perché abbiamo già selezionato un SKU. Quello che rimane è che “T.sold” è effettivamente un vettore, un vettore che ha la dimensione uguale alla data. Quando facciamo questa sottrazione, “SKUs.level - T.sold,” otteniamo un vettore allineato con la tabella delle date e lo assegniamo a “D.delta,” che è un vettore con una riga al giorno, due anni e un mese. Infine, alla riga 9, stiamo calcolando la funzione di perdita, che è solo l’errore quadratico medio. Questo modello è super semplicistico. Vediamo cosa si può fare per i modelli di calendario.

Slide 14

La condivisione dei parametri è probabilmente una delle tecniche di programmazione differenziabile più semplici e utili. Un parametro si dice condiviso se contribuisce a più righe di osservazione. Condividendo i parametri tra le osservazioni, possiamo stabilizzare la discesa del gradiente e mitigare i problemi di sovradattamento. Consideriamo il modello del giorno della settimana. Potremmo introdurre sette parametri che rappresentano i vari pesi per ogni singolo SKU. Finora, un SKU ha solo un parametro, che è solo la domanda costante. Se vogliamo arricchire questa percezione della domanda, potremmo dire che ogni singolo giorno della settimana ha il suo peso e poiché abbiamo sette giorni della settimana, possiamo avere sette pesi e applicare questi pesi moltiplicativamente.

Tuttavia, è improbabile che ogni singolo SKU abbia il proprio modello unico del giorno della settimana. La realtà è che è molto più ragionevole assumere che esista una categoria o qualche tipo di gerarchia, come una famiglia di prodotti, una categoria di prodotti, una sottocategoria di prodotti o addirittura un reparto nel negozio che cattura correttamente questo modello del giorno della settimana. L’idea è che non vogliamo introdurre sette parametri per SKU; quello che vogliamo è introdurre sette parametri per categoria, il livello di raggruppamento in cui assumiamo che ci sia un comportamento omogeneo in termini di modelli del giorno della settimana.

Se decidiamo di introdurre quei sette parametri con un effetto moltiplicativo sul livello, questo è esattamente l’approccio che è stato adottato nella precedente lezione per questo modello, che si è classificato al primo posto a livello di SKU nella competizione M5. Abbiamo un livello e un effetto moltiplicativo con il modello del giorno della settimana.

Nel codice, dalle righe 1 alla 5, abbiamo il blocco di dati di esempio come in precedenza e introduciamo una tabella aggiuntiva chiamata “category” (categoria). Questa tabella è una tabella di raggruppamento degli SKU e concettualmente, per ogni singola riga nella tabella SKU, c’è una e una sola riga che corrisponde nella tabella delle categorie. Nel linguaggio Envision, diciamo che la categoria è a monte della tabella SKU. Alla riga 7 viene introdotta la tabella del giorno della settimana. Questa tabella è strumentale e la introduciamo con una forma specifica che riflette il modello ciclico che vogliamo catturare. Alla riga 7, creiamo la tabella del giorno della settimana aggregando le date in base al loro valore modulo sette. Stiamo creando una tabella che avrà esattamente sette righe e quelle sette righe rappresenteranno ciascuno dei sette giorni della settimana. Per ogni singola riga nella tabella delle date, ogni riga nel database ha una e una sola controparte nella tabella del giorno della settimana. Quindi, seguendo il linguaggio Envision, la tabella del giorno della settimana è a monte della tabella “date”.

Ora abbiamo la tabella “CD,” che è un prodotto cartesiano tra categoria e giorno della settimana. In termini di numero di righe, questa tabella avrà tante righe quante sono le categorie volte sette perché il giorno della settimana ha sette righe. Alla riga 12, introduciamo un nuovo parametro chiamato “CD.DOW” (DOW sta per giorno della settimana), che è un altro parametro vettoriale appartenente alla tabella CD. In termini di gradi di libertà, avremo esattamente sette valori dei parametri volte il numero di categorie, che è ciò che cerchiamo. Vogliamo un modello in grado di catturare questo modello del giorno della settimana ma con un solo modello per categoria, non un modello per SKU.

Dichiariamo questo parametro e utilizziamo la parola chiave “in” per specificare che il valore per “CD.DOW” dovrebbe essere compreso tra 0,1 e 100. Alla riga 13, scriviamo la domanda come espressa dal modello. La domanda è “SKUs.level * CD.DOW,” che rappresenta la domanda. Abbiamo la domanda meno l’osservato “T.sold,” e questo ci dà un delta. Quindi calcoliamo l’errore quadratico medio.

Alla riga 13, abbiamo un po’ di magia di broadcasting in corso. “CD.DOW” è una tabella incrociata tra categoria e giorno della settimana. Poiché siamo all’interno del blocco autodiff, la tabella CD è una tabella incrociata tra categoria e giorno della settimana. Poiché siamo all’interno del blocco autodiff, il blocco sta iterando sulla tabella SKUs. Fondamentalmente, quando scegliamo un SKU, abbiamo effettivamente scelto una categoria, poiché la tabella delle categorie è a monte. Ciò significa che CD.DOW non è più una matrice, ma piuttosto un vettore di dimensione sette. Tuttavia, è a monte della tabella “date,” quindi quelle sette righe possono essere trasmesse nella tabella delle date. C’è solo un modo per fare questa trasmissione perché ogni riga della tabella del giorno della settimana ha un’affinità con righe specifiche della tabella delle date. Abbiamo un doppio broadcasting in corso e alla fine otteniamo una domanda che è una serie di valori ciclici al livello del giorno della settimana per lo SKU. Questo è il nostro modello in questo momento e il resto della funzione di perdita rimane invariato.

Vediamo un modo molto elegante per affrontare le ciclicità combinando i comportamenti di broadcasting ottenuti dalla natura relazionale di Envision con le sue capacità di programmazione differenziabile. Possiamo esprimere le ciclicità del calendario in soli tre righe di codice. Questo approccio funziona bene anche se stiamo lavorando con dati molto sparsi. Funzionerebbe bene anche se stessimo guardando prodotti che vendono solo un’unità al mese in media. In tali casi, l’approccio saggio sarebbe avere una categoria che include decine, se non centinaia di prodotti. Questa tecnica può anche essere utilizzata per riflettere altri modelli ciclici, come il mese dell’anno o il giorno del mese.

Il modello presentato nella precedente lezione, che ha ottenuto risultati all’avanguardia nella competizione M5, era una combinazione moltiplicativa di tre ciclicità: giorno della settimana, mese dell’anno e giorno del mese. Tutti questi modelli erano concatenati come una moltiplicazione. Implementare le altre due varianti è lasciato all’attenzione del pubblico attento, ma è solo una questione di un paio di righe di codice per modello ciclico, rendendolo molto conciso.

Slide 15

Nella precedente lezione, abbiamo introdotto un modello di previsione delle vendite. Tuttavia, non sono le vendite che ci interessano, ma la domanda. Non dovremmo confondere le vendite nulle con la domanda nulla. Se non fosse rimasto alcun stock per il cliente da acquistare nel negozio in un determinato giorno, la tecnica di mascheramento delle perdite viene utilizzata presso Lokad per far fronte alle mancanze di stock. Questa è la tecnica più semplice utilizzata per far fronte alle mancanze di stock, ma non è l’unica. Per quanto ne so, abbiamo almeno altre due tecniche che vengono utilizzate in produzione, ognuna con i suoi pro e contro. Queste altre tecniche non saranno trattate oggi, ma saranno affrontate in lezioni successive.

Tornando all’esempio di codice, le righe da 1 a 3 rimangono intatte. Esaminiamo cosa segue. Alla riga 6, stiamo arricchendo i dati di esempio con il flag booleano “in-stock”. Per ogni singolo SKU e per ogni singolo giorno, abbiamo un valore booleano che indica se c’è stata una mancanza di stock alla fine della giornata per il negozio. Alla riga 15, stiamo modificando la funzione di perdita per escludere, azzerandoli, i giorni in cui è stata osservata una mancanza di stock alla fine della giornata. Azzerando quei giorni, ci assicuriamo che nessun gradiente venga propagato all’indietro in situazioni che presentano un bias dovuto all’occorrenza della mancanza di stock.

L’aspetto più sorprendente della tecnica di mascheramento della perdita è che non cambia nemmeno il modello. Infatti, se guardiamo il modello espresso alla riga 14, è esattamente lo stesso; non è stato modificato. È solo la funzione di perdita stessa che viene modificata. Questa tecnica può essere semplice, ma si discosta profondamente da una prospettiva incentrata sul modello. È, nel suo nucleo, una tecnica incentrata sulla modellazione. Miglioriamo la situazione riconoscendo il bias causato dalle mancanze di stock, riflettendo questo nei nostri sforzi di modellazione. Tuttavia, facciamo questo cambiando la metrica di accuratezza, non il modello stesso. In altre parole, stiamo cambiando la perdita che ottimizziamo, rendendo questo modello non confrontabile con altri modelli in termini di errore numerico puro.

Per una situazione come Walmart, come discusso nella precedente lezione, la tecnica di mascheramento della perdita è adeguata per la maggior parte dei prodotti. Come regola generale, questa tecnica funziona bene se la domanda non è così scarsa da avere solo un’unità in magazzino la maggior parte del tempo. Inoltre, si dovrebbero evitare i prodotti in cui le mancanze di stock sono molto frequenti perché è la strategia esplicita del rivenditore finire con una mancanza di stock alla fine della giornata. Questo accade tipicamente per alcuni prodotti ultra-freschi in cui il rivenditore mira a una situazione di esaurimento scorte entro la fine della giornata. Tecniche alternative rimediano a queste limitazioni, ma non abbiamo tempo per trattarle oggi.

Slide 16

Le promozioni sono un aspetto importante del settore della vendita al dettaglio. Più in generale, ci sono molti modi per il rivenditore di influenzare e plasmare la domanda, come la determinazione dei prezzi o lo spostamento delle merci su una gondola. Le variabili che forniscono informazioni aggiuntive a fini predittivi sono tipicamente indicate come covariate nei circoli della supply chain. C’è molta illusione riguardo a covariate complesse come i dati meteorologici o i dati dei social media. Tuttavia, prima di approfondire argomenti avanzati, dobbiamo affrontare l’elefante nella stanza, come ad esempio le informazioni sui prezzi, che ovviamente hanno un impatto significativo sulla domanda che sarà osservata. Pertanto, alla riga 7 in questo esempio di codice, introduciamo per ogni singolo giorno alla riga 14, “category.ed”, dove “ed” sta per elasticità della domanda. Questo è un parametro vettoriale condiviso con un grado di libertà per categoria, inteso come rappresentazione dell’elasticità della domanda. Alla riga 16, introduciamo una forma esponenziale di elasticità del prezzo come esponenziale di (-category.ed * t.price). Intuitivamente, con questa forma, quando il prezzo aumenta, la domanda converge rapidamente a zero a causa della presenza della funzione esponenziale. Al contrario, quando il prezzo converge a zero, la domanda aumenta in modo esplosivo.

Questa forma esponenziale di risposta ai prezzi è semplicistica e la condivisione dei parametri garantisce un elevato grado di stabilità numerica anche con questa funzione esponenziale nel modello. In contesti reali, specialmente per situazioni come Walmart, avremmo diverse informazioni sui prezzi, come sconti, la differenza rispetto al prezzo normale, covariate che rappresentano spinte di marketing eseguite dal fornitore o variabili categoriche che introducono elementi come le gondole. Con la programmazione differenziabile, è facile creare risposte ai prezzi arbitrariamente complesse che si adattano strettamente alla situazione. L’integrazione di covariate di quasi ogni tipo è molto semplice con la programmazione differenziabile.

Slide 17

I prodotti a lenta rotazione sono una realtà nella vendita al dettaglio e in molti altri settori. Il modello finora introdotto ha un parametro, un grado di libertà per SKU, con più se si contano i parametri condivisi. Tuttavia, questo potrebbe già essere troppo, soprattutto per gli SKU che ruotano solo una volta all’anno o solo poche volte all’anno. In tali situazioni, non possiamo nemmeno permetterci un grado di libertà per SKU, quindi la soluzione è fare affidamento esclusivamente su parametri condivisi e rimuovere tutti i parametri con gradi di libertà a livello di SKU.

Alle righe 2 e 4, introduciamo due tabelle chiamate “prodotti” e “negozi”, e la tabella “SKU” viene costruita come una sotto-tabella filtrata del prodotto cartesiano tra prodotti e negozi, che è la stessa definizione di assortimento. Alle righe 15 e 16, abbiamo introdotto due parametri vettoriali condivisi: un livello con affinità alla tabella dei prodotti e un altro livello con affinità alle tabelle dei negozi. Anche questi parametri sono definiti entro un determinato intervallo, da 0,01 a 100, che è il valore massimo.

Ora, alla riga 18, il livello per SKU è composto dalla moltiplicazione del livello del prodotto e del livello del negozio. Il resto dello script rimane invariato. Quindi, come funziona? Alla riga 19, SKU.level è uno scalare. Abbiamo il blocco autodesk che itera sulla tabella degli SKU, che è la tabella di osservazione. Pertanto, SKU.level alla riga 18 è solo un valore scalare. Poi abbiamo products.level. Poiché la tabella dei prodotti è a monte della tabella degli SKU, per ogni singolo SKU c’è una e una sola tabella dei prodotti. Pertanto, products.level è solo un numero scalare. Lo stesso vale per la tabella dei negozi, che è anche a monte della tabella degli SKU. Alla riga 18, c’è solo un negozio collegato a questo specifico SKU. Quindi, quello che abbiamo è la moltiplicazione di due valori scalari, che ci dà SKU.level. Il resto del modello rimane invariato.

Queste tecniche mettono una luce completamente nuova sulla affermazione che a volte non ci sono dati sufficienti o che a volte i dati sono troppo sparsi. Infatti, dal punto di vista differenziabile, quelle affermazioni non hanno nemmeno senso. Non esiste una cosa come troppi pochi dati o dati troppo sparsi, almeno non in termini assoluti. Ci sono solo modelli che possono essere modificati verso la sparsità e possibilmente verso la sparsità estrema. La struttura imposta è come guide che rendono il processo di apprendimento non solo possibile ma anche numericamente stabile.

Rispetto ad altre tecniche di apprendimento automatico che cercano di far scoprire al modello di apprendimento automatico tutti i modelli ex nihilo, questo approccio strutturato stabilisce la stessa struttura che dobbiamo imparare. Pertanto, il meccanismo statistico in gioco qui ha una libertà limitata in ciò che deve imparare. Di conseguenza, in termini di efficienza dei dati, può essere incredibilmente efficiente. Naturalmente, tutto ciò si basa sul fatto che abbiamo scelto la struttura giusta.

Come puoi vedere, fare esperimenti è molto semplice. Stiamo già facendo qualcosa di molto complicato e, in meno di 50 righe, potremmo gestire una situazione piuttosto complessa simile a quella di Walmart. Questo è un grande risultato. C’è un po’ di processo empirico, ma la realtà è che non è così tanto. Stiamo parlando di qualche dozzina di righe. Tieni presente che un ERP come quello che gestisce un’azienda, una grande rete di vendita al dettaglio, ha tipicamente mille tabelle e 100 campi per tabella. Quindi, chiaramente, la complessità dei sistemi aziendali è assolutamente gigantesca rispetto alla complessità di questo modello predittivo strutturato. Se dobbiamo dedicare un po’ di tempo all’iterazione, è quasi nulla.

Inoltre, come dimostrato nella competizione di previsione M5, la realtà è che i professionisti della supply chain conoscono già i modelli. Quando il team M5 ha utilizzato tre modelli di calendario, che erano il giorno della settimana, il mese dell’anno e il giorno del mese, tutti questi modelli erano evidenti per qualsiasi professionista esperto di supply chain. La realtà nella supply chain è che non stiamo cercando di scoprire qualche modello nascosto. Il fatto che, ad esempio, se si abbassa massivamente il prezzo, la domanda aumenta massicciamente, non sorprenderà nessuno. L’unica domanda che rimane è quale sia esattamente l’entità dell’effetto e quale sia la forma esatta della risposta. Questi sono dettagli relativamente tecnici e, se ti concedi l’opportunità di fare un po’ di esperimenti, puoi affrontare questi problemi in modo relativamente facile.

Slide 18

Come ultimo passo di questa panoramica, vorrei sottolineare una piccola particolarità della programmazione differenziabile. La programmazione differenziabile non deve essere confusa con un risolutore generico di ottimizzazione matematica. Dobbiamo tenere presente che c’è una discesa del gradiente in corso. Più specificamente, l’algoritmo utilizzato per ottimizzare e aggiornare i parametri ha una velocità massima di discesa pari al tasso di apprendimento fornito dall’algoritmo ADAM. In Envision, il tasso di apprendimento predefinito è 0,01.

Se guardiamo il codice, alla riga 4 abbiamo introdotto una inizializzazione in cui le quantità vendute vengono campionate da una distribuzione di Poisson con una media di 50. Se vogliamo apprendere un livello, tecnicamente avremmo bisogno di avere un livello che sia dell’ordine di 50. Tuttavia, quando facciamo un’inizializzazione automatica del parametro, partiamo con un valore che è intorno a uno, e possiamo solo andare in incrementi di 0,01. Ci vorrebbe circa 5.000 epoche per raggiungere effettivamente questo valore di 50. Poiché abbiamo un parametro non condiviso, SKU.level, questo parametro per epoca viene toccato solo una volta. Pertanto, avremmo bisogno di 5.000 epoche, che rallenterebbero inutilmente il calcolo.

Potremmo aumentare il tasso di apprendimento per accelerare la discesa, che sarebbe una soluzione. Tuttavia, sconsiglierei di aumentare eccessivamente il tasso di apprendimento, poiché questa non è tipicamente la giusta soluzione per affrontare il problema. In una situazione reale, avremmo parametri condivisi oltre a questo parametro non condiviso. Quei parametri condivisi verranno toccati dalla discesa del gradiente stocastico molte volte durante ogni epoca. Se aumenti notevolmente il tasso di apprendimento, rischi di creare instabilità numeriche per i tuoi parametri condivisi. Potresti aumentare la velocità di movimento del livello SKU ma creare problemi di stabilità numerica per gli altri parametri.

Una tecnica migliore sarebbe utilizzare un trucco di ridimensionamento e avvolgere il parametro in una funzione esponenziale, che è esattamente ciò che viene fatto alla riga 8. Con questo avvolgimento, ora possiamo raggiungere valori dei parametri per il livello che possono essere molto bassi o molto alti con un numero molto inferiore di epoche. Questa particolarità è fondamentalmente l’unica particolarità che dovrei introdurre per avere un esempio realistico per questa panoramica della situazione di previsione della domanda al dettaglio. Tutto considerato, è una piccola particolarità. Tuttavia, è un promemoria che la programmazione differenziabile richiede attenzione al flusso dei gradienti. La programmazione differenziabile offre nel complesso un’esperienza di progettazione fluida, ma non è magia.

Slide 19

Alcuni pensieri finali: i modelli strutturati raggiungono un’accuratezza di previsione all’avanguardia. Questo punto è stato ampiamente discusso nella precedente lezione. Tuttavia, basandoci sugli elementi presentati oggi, sostengo che l’accuratezza non sia nemmeno il fattore decisivo a favore della programmazione differenziabile con un modello parametrico strutturato. Quello che otteniamo è la comprensione; non otteniamo solo un pezzo di software in grado di fare previsioni, ma otteniamo anche una comprensione diretta dei modelli stessi che stiamo cercando di catturare. Ad esempio, il modello introdotto oggi ci fornirebbe direttamente una previsione della domanda che viene fornita con pesi espliciti per il giorno della settimana e un’elasticità esplicita della domanda. Se volessimo estendere questa domanda, ad esempio, per introdurre un aumento associato al Black Friday, un evento quasi stagionale che non accade allo stesso momento ogni anno, potremmo farlo. Aggiungeremmo semplicemente un fattore, e avremmo quindi una stima dell’aumento del Black Friday isolato da tutti gli altri modelli, come il modello del giorno della settimana. Questo è di primario interesse.

Quello che otteniamo attraverso l’approccio strutturato è la comprensione, ed è molto più di un semplice modello grezzo. Ad esempio, se otteniamo un’elasticità negativa, una situazione in cui il modello ti dice che aumentando il prezzo aumenti la domanda, in una situazione simile a Walmart, questo è un risultato molto dubbio. Molto probabilmente, riflette che l’implementazione del tuo modello è difettosa, o che ci sono problemi profondi in corso. Non importa cosa ti dica la metrica di accuratezza, se ti trovi in una situazione simile a Walmart con qualcosa che ti dice che rendendo un prodotto più costoso, le persone ne comprano di più, dovresti davvero mettere in discussione l’intero flusso dei tuoi dati perché molto probabilmente c’è qualcosa di molto sbagliato. Di questo si tratta la comprensione.

Inoltre, il modello è aperto al cambiamento. La programmazione differenziabile è incredibilmente espressiva. Il modello che abbiamo è solo una delle iterazioni di un percorso. Se il mercato si trasforma o se l’azienda stessa si trasforma, possiamo essere certi che il modello che abbiamo sarà in grado di catturare questa evoluzione in modo naturale. Non esiste una tale cosa come un’evoluzione automatica; richiederà l’impegno di un supply chain scientist per catturare questa evoluzione. Tuttavia, ci si può aspettare che questo sforzo sia relativamente minimo. Si riduce al fatto che se hai un modello molto piccolo e ordinato, quando devi rivedere questo modello in seguito per adattarne la struttura, sarà un compito relativamente piccolo rispetto a una situazione in cui il tuo modello sarebbe un mostro di ingegneria.

Quando progettati con cura, i modelli prodotti con la programmazione differenziabile sono molto stabili. La stabilità dipende dalla scelta della struttura. La stabilità non è garantita per qualsiasi programma che si ottimizza attraverso la programmazione differenziabile; è il tipo di cosa che si ottiene quando si ha una struttura molto chiara in cui i parametri hanno un significato specifico. Ad esempio, se hai un modello in cui, ogni volta che rialleni il tuo modello, ottieni pesi completamente diversi per il giorno della settimana, allora la realtà della tua attività non sta cambiando così velocemente. Se esegui il tuo modello due volte, dovresti ottenere valori per il giorno della settimana che sono abbastanza stabili. Se non è il caso, allora c’è qualcosa di molto sbagliato nel modo in cui hai modellato la tua domanda. Pertanto, se fai una scelta saggia per la struttura del tuo modello, puoi ottenere risultati numerici incredibilmente stabili. Facendo ciò, evitiamo le insidie che tendono a colpire i modelli di apprendimento automatico complessi quando cerchiamo di utilizzarli in un contesto di supply chain. Infatti, dal punto di vista della supply chain, le instabilità numeriche sono mortali perché abbiamo effetti di cricchetto ovunque. Se hai una stima della domanda che fluttua, significa che casualmente attiverai un ordine di acquisto o un ordine di produzione per nulla. Una volta che hai attivato il tuo ordine di produzione, non puoi decidere la settimana successiva che è stato un errore e che non avresti dovuto farlo. Se hai un estimatore della domanda futura che continua a fluttuare, finirai con riapprovvigionamenti gonfiati e ordini di produzione gonfiati. Questo problema può essere risolto garantendo la stabilità, che è una questione di progettazione.

Uno dei più grandi ostacoli per mettere in produzione l’apprendimento automatico è la fiducia. Quando si opera con milioni di euro o dollari, capire cosa sta succedendo nella propria ricetta numerica è fondamentale. Gli errori nella supply chain possono essere estremamente costosi e ci sono molti esempi di disastri nella supply chain causati da una cattiva applicazione di algoritmi poco compresi. Sebbene la programmazione differenziabile sia molto potente, i modelli che possono essere sviluppati sono incredibilmente semplici. Questi modelli potrebbero essere eseguiti in un foglio di calcolo Excel, in quanto sono tipicamente modelli moltiplicativi semplici con rami e funzioni. L’unico aspetto che non può essere eseguito in un foglio di calcolo Excel è la differenziazione automatica e, ovviamente, se si hanno milioni di SKU, non si dovrebbe tentare di farlo in un foglio di calcolo. Tuttavia, per quanto riguarda la semplicità, è molto compatibile con qualcosa che si inserirebbe in un foglio di calcolo. Questa semplicità contribuisce molto a instaurare fiducia e a portare l’apprendimento automatico in produzione, anziché mantenerlo come prototipi di lusso che le persone non riescono mai a fidarsi completamente.

Infine, mettendo insieme tutte queste proprietà, otteniamo un pezzo di tecnologia molto accurato. Questo punto è stato discusso nel primo capitolo di questa serie di lezioni. Vogliamo trasformare tutti gli sforzi investiti nella supply chain in investimenti capitalistici, invece di trattare gli esperti e i professionisti della supply chain come consumabili che devono fare sempre le stesse cose. Con questo approccio, possiamo considerare tutti questi sforzi come investimenti che genereranno e continueranno a generare un ritorno sull’investimento nel tempo. La programmazione differenziabile si adatta molto bene a questa prospettiva capitalista per la supply chain.

Slide 20

Nel secondo capitolo, abbiamo introdotto una lezione importante intitolata “Ottimizzazione sperimentale”, che ha fornito una possibile risposta alla semplice ma fondamentale domanda: Cosa significa effettivamente migliorare o fare meglio in una supply chain? La prospettiva della programmazione differenziabile fornisce una visione molto specifica delle molte difficoltà affrontate dagli operatori della supply chain. I fornitori di software aziendali spesso attribuiscono i fallimenti della supply chain a dati errati. Tuttavia, ritengo che questa sia semplicemente la prospettiva sbagliata per affrontare il problema. I dati sono semplicemente ciò che sono. Il vostro ERP non è mai stato progettato per la scienza dei dati, ma ha funzionato senza intoppi per anni, se non decenni, e le persone nell’azienda sono riuscite comunque a gestire la supply chain. Anche se il vostro ERP che registra i dati sulla vostra supply chain non è perfetto, va bene così. Se ci si aspetta che siano disponibili dati perfetti, questo è solo un desiderio. Stiamo parlando di supply chain; il mondo è molto complesso, quindi i sistemi sono imperfetti. Realisticamente, non si ha un solo sistema aziendale; se ne hanno almeno mezzo dozzina e non sono completamente coerenti tra loro. Questo è solo un fatto della vita. Tuttavia, quando i fornitori aziendali attribuiscono dati errati, la realtà è che viene utilizzato un modello di previsione molto specifico dal fornitore e questo modello è stato sviluppato con un insieme specifico di presupposti sull’azienda. Il problema è che se la vostra azienda viola uno qualsiasi di questi presupposti, la tecnologia si sgretola completamente. In questa situazione, si ha un modello di previsione che si basa su presupposti irragionevoli, si alimentano i dati, che non sono perfetti, e quindi la tecnologia si sgretola. È completamente irragionevole dire che la colpa è dell’azienda. La tecnologia colpevole è quella spinta dal fornitore che fa presupposti completamente irrealistici su quali dati possono essere presenti in un contesto di supply chain.

Oggi non ho presentato alcun benchmark per alcuna metrica di accuratezza. Tuttavia, la mia proposta è che tali metriche di accuratezza siano per lo più irrilevanti. Un modello predittivo è uno strumento per prendere decisioni. Quello che conta è se tali decisioni - cosa acquistare, cosa produrre, se aumentare o diminuire il prezzo - sono buone o cattive. Le decisioni sbagliate possono essere ricondotte al modello predittivo, è vero. Tuttavia, nella maggior parte dei casi, non si tratta di un problema di accuratezza. Ad esempio, avevamo un modello di previsione delle vendite e abbiamo risolto l’aspetto delle scorte che non veniva gestito correttamente. Tuttavia, quando abbiamo risolto l’aspetto delle scorte, abbiamo di fatto risolto la stessa metrica di accuratezza. Quindi, risolvere il modello predittivo non significa migliorare l’accuratezza; molto spesso significa letteralmente rivedere il problema stesso e la prospettiva in cui si opera, e quindi modificare la metrica di accuratezza o qualcosa di ancora più profondo. Il problema con la prospettiva classica è che si assume che la metrica di accuratezza sia un obiettivo valido. Questo non è del tutto vero.

Le catene di approvvigionamento operano nel mondo reale e ci sono molti eventi imprevisti e persino strani. Ad esempio, può verificarsi un’ostacolazione del Canale di Suez a causa di una nave; questo è un evento completamente strano. In una situazione del genere, invaliderebbe immediatamente tutti i modelli di previsione dei tempi di consegna esistenti che stavano guardando questa parte del mondo. Ovviamente, questo è qualcosa che non era mai successo prima, quindi non possiamo fare un backtest in una situazione del genere. Tuttavia, anche se abbiamo questa situazione completamente eccezionale con una nave che blocca il Canale di Suez, possiamo comunque risolvere il modello, almeno se abbiamo questo tipo di approccio white-box che sto proponendo oggi. Questa correzione comporterà un certo grado di congetture, il che va bene. È meglio essere approssimativamente corretti piuttosto che esattamente sbagliati. Ad esempio, se stiamo guardando al blocco del Canale di Suez, possiamo semplicemente dire: “aggiungiamo un mese al tempo di consegna per tutti i forniture che dovevano passare da questa rotta”. Questo è molto approssimativo, ma è meglio assumere che non ci sarà alcun ritardo, anche se hai già le informazioni. Inoltre, il cambiamento spesso proviene dall’interno. Ad esempio, consideriamo una rete di vendita al dettaglio che ha un vecchio centro di distribuzione e un nuovo centro di distribuzione che rifornisce alcune dozzine di negozi. Supponiamo che ci sia una migrazione in corso, in cui essenzialmente le forniture per i negozi vengono trasferite dal vecchio centro di distribuzione al nuovo. Questa situazione si verifica quasi una sola volta nella storia di questo specifico rivenditore e non può essere realmente testata. Tuttavia, con un approccio come la programmazione differenziabile, è completamente semplice implementare un modello che si adatti a questa migrazione graduale.

Slide 21

In conclusione, la programmazione differenziabile è una tecnologia che ci offre un approccio per strutturare le nostre intuizioni sul futuro. La programmazione differenziabile ci permette di modellare, letteralmente, il modo in cui guardiamo al futuro. La programmazione differenziabile si trova sul lato della percezione di questa immagine. Sulla base di questa percezione, possiamo prendere decisioni migliori per le catene di approvvigionamento e queste decisioni guidano le azioni che si trovano dall’altro lato dell’immagine. Uno dei più grandi fraintendimenti della teoria delle catene di approvvigionamento mainstream è che si può trattare la percezione e l’azione in modo isolato come componenti strettamente isolati. Questo assume la forma, ad esempio, di avere un team responsabile della pianificazione (che è la percezione) e un team indipendente responsabile del rifornimento (che è l’azione).

Tuttavia, il ciclo di feedback percezione-azione è molto importante; è di primaria importanza. Questo è letteralmente il meccanismo stesso che ti guida verso una corretta forma di percezione. Se non hai questo ciclo di feedback, non è nemmeno chiaro se stai guardando la cosa giusta o se la cosa che stai guardando è davvero ciò che pensi sia. Hai bisogno di questo meccanismo di feedback ed è attraverso questo ciclo di feedback che puoi effettivamente indirizzare i tuoi modelli verso una corretta valutazione quantitativa del futuro che è rilevante per il corso di azione della tua catena di approvvigionamento. Gli approcci delle catene di approvvigionamento mainstream stanno ignorando quasi completamente questo caso perché, fondamentalmente, credo che siano bloccati con una forma molto rigida di previsione. Questa forma di previsione centrata sul modello può essere un vecchio modello, come il modello di previsione di Holt-Winters, o uno recente come Facebook Prophet. La situazione è la stessa: se sei bloccato con un modello di previsione, allora tutto il feedback che puoi ottenere dal lato dell’azione dell’immagine è inutile perché non puoi fare nulla riguardo a questo feedback se non ignorarlo completamente.

Se sei bloccato con un determinato modello di previsione, non puoi riformattare o ristrutturare il tuo modello mentre ottieni informazioni dal lato dell’azione. D’altra parte, la programmazione differenziabile, con il suo approccio di modellazione strutturata, ti offre un paradigma completamente diverso. Il modello predittivo è completamente eliminabile, tutto. Se il feedback che ricevi dalle tue azioni richiede cambiamenti radicali nella tua prospettiva predittiva, implementa semplicemente quei cambiamenti radicali. Non c’è un legame specifico con una determinata iterazione del modello. Mantenere il modello molto semplice è un modo per assicurarsi che una volta in produzione, si conservi l’opzione di continuare a cambiare questo modello. Perché, ancora una volta, se ciò che hai progettato è come una bestia, un mostro di ingegneria, diventa incredibilmente difficile cambiarlo una volta in produzione. Uno degli aspetti chiave è che se vuoi essere in grado di continuare a cambiare, devi avere un modello che sia molto parsimonioso in termini di righe di codice e complessità interna. Qui brilla la programmazione differenziabile. Non si tratta di raggiungere una maggiore precisione; si tratta di raggiungere una maggiore rilevanza. Senza rilevanza, tutte le metriche di precisione sono completamente inutili. La programmazione differenziabile e la modellazione strutturata ti offrono il percorso per raggiungere la rilevanza e mantenerla nel tempo.

Slide 22

Questo concluderà la lezione di oggi. La prossima volta, il 2 marzo, alla stessa ora, alle 15:00 ora di Parigi, presenterò la modellazione probabilistica per la catena di approvvigionamento. Daremo un’occhiata più da vicino alle implicazioni tecniche di guardare a tutti i futuri possibili anziché sceglierne uno solo e dichiararlo quello giusto. Infatti, guardare a tutti i futuri possibili è molto importante se vuoi che la tua catena di approvvigionamento sia efficacemente resiliente al rischio. Se scegli solo un futuro, è una ricetta per finire con qualcosa di incredibilmente fragile se la tua previsione non si rivela perfettamente corretta. E indovina un po’, la previsione non è mai completamente corretta. Ecco perché è molto importante abbracciare l’idea che è necessario guardare a tutti i futuri possibili e vedremo come farlo con ricette numeriche moderne.

Domanda: Viene aggiunto rumore stocastico per evitare minimi locali, ma come viene sfruttato o scalato per evitare grandi deviazioni in modo che la discesa del gradiente non venga allontanata dal suo obiettivo?

È una domanda molto interessante e ci sono due parti in questa risposta.

In primo luogo, è per questo che l’algoritmo Adam è molto conservativo in termini di ampiezza degli spostamenti. Il gradiente è fondamentalmente illimitato; può avere un valore di migliaia o milioni. Tuttavia, con Adam, il passo massimo è effettivamente limitato superiormente dal tasso di apprendimento. Quindi, in pratica, Adam viene fornito con una ricetta numerica che impone letteralmente un passo massimo e, si spera, evita instabilità numeriche massive.

Ora, se casualmente, nonostante il fatto che abbiamo questo tasso di apprendimento, potremmo dire che solo per pura fluttuazione ci muoveremo in modo iterativo, un passo alla volta, ma molte volte in una direzione che è scorretta, questa è una possibilità. Ecco perché dico che la discesa del gradiente stocastico non è ancora completamente compresa. Funziona incredibilmente bene in pratica, ma perché funziona così bene, e perché converge così velocemente, e perché non otteniamo più dei problemi che potrebbero verificarsi, non è ancora completamente compreso, specialmente se si considera che la discesa del gradiente stocastico avviene in dimensioni elevate. Di solito, hai letteralmente decine, se non centinaia, di parametri che vengono toccati ad ogni passo. Il tipo di intuizione che puoi avere in due o tre dimensioni è molto fuorviante; le cose si comportano molto diversamente quando si guardano dimensioni superiori.

Quindi, la conclusione per questa domanda: è molto rilevante. C’è una parte in cui c’è la magia di Adam nel essere molto conservativo con la scala dei passi del gradiente, e l’altra parte, che è poco compresa ma che funziona molto bene in pratica. A proposito, credo che il fatto che la discesa del gradiente stocastico non sia completamente intuitiva sia anche il motivo per cui per quasi 70 anni questa tecnica era conosciuta ma non riconosciuta come efficace. Per quasi 70 anni, le persone sapevano che esisteva, ma erano molto scettiche. Ci è voluto il grande successo del deep learning affinché la comunità riconoscesse e ammettesse che funziona molto bene, anche se non capiamo davvero perché.

Domanda: Come si capisce quando un certo pattern è debole e quindi dovrebbe essere rimosso dal modello?

Di nuovo, una domanda molto valida. Non ci sono criteri rigorosi; è letteralmente una valutazione da parte del supply chain scientist. Il motivo è che se il pattern che introduci ti dà benefici minimi, ma in termini di modellazione è solo due righe di codice e l’impatto in termini di tempo di calcolo è insignificante, e se mai vuoi rimuovere il pattern in seguito è semi-triviale, potresti dire: “Beh, posso tenerlo. Non sembra fare male, non fa molto bene. Posso immaginare situazioni in cui questo pattern che è debole ora potrebbe diventare forte.” In termini di manutenibilità, va bene.

Tuttavia, puoi anche vedere l’altro lato della medaglia in cui hai un pattern che non cattura molto e aggiunge molto calcolo al modello. Quindi non è gratuito; ogni volta che aggiungi un parametro o una logica, aumenti la quantità di risorse di calcolo necessarie per il tuo modello, rendendolo più lento e più difficile da gestire. Se pensi che questo pattern che è debole potrebbe diventare forte, ma in modo negativo, generando instabilità e creando caos nella tua modellazione predittiva, questa è tipicamente la situazione in cui penseresti: “No, probabilmente dovrei rimuoverlo.”

Vedi, è davvero una questione di valutazione. La programmazione differenziabile è una cultura; non sei da solo. Hai colleghi e pari che magari hanno provato cose diverse a Lokad. Questo è il tipo di cultura che cerchiamo di coltivare. So che potrebbe essere un po’ deludente rispetto alla prospettiva dell’intelligenza artificiale onnipotente, l’idea che potremmo avere un’intelligenza artificiale onnipotente che risolve tutti quei problemi per noi. Ma la realtà è che le supply chain sono così complesse e le nostre tecniche di intelligenza artificiale sono così rudimentali che non abbiamo alcun sostituto realistico per l’intelligenza umana. Quando dico valutazione, intendo solo che hai bisogno di una sana dose di intelligenza umana applicata al caso, perché tutti i trucchi algoritmici non sono nemmeno lontanamente in grado di fornire una risposta soddisfacente.

Tuttavia, ciò non significa che non si possa progettare qualche tipo di strumento. Questo sarebbe un altro argomento; vedrò se effettivamente coprirò il tipo di strumentazione che forniamo a Lokad per facilitare la progettazione. Un pattern tangenziale sarebbe, se dobbiamo prendere una decisione, cerchiamo di fornire tutta l’attrezzatura affinché questa decisione possa essere presa molto rapidamente, riducendo al minimo il dolore che deriva da questo tipo di indecisione in cui il supply chain scientist deve decidere qualcosa sul destino dello stato attuale del modello.

Domanda: Qual è la soglia di complessità di una supply chain dopo la quale l’apprendimento automatico e la programmazione differenziabile portano risultati considerevolmente migliori?

A Lokad, riusciamo tipicamente a ottenere risultati significativi per le aziende che hanno un fatturato di $10 milioni all’anno e oltre. Direi che inizia davvero a brillare se hai un’azienda con un fatturato annuo di $50 milioni e oltre.

Il motivo è che fondamentalmente è necessario stabilire un flusso di dati molto affidabile. È necessario essere in grado di estrarre tutti i dati rilevanti dall’ERP su base giornaliera. Non intendo dire che saranno dati buoni o cattivi, ma i dati che hai possono avere molti difetti. Tuttavia, ciò significa che c’è parecchia “idraulica” solo per essere in grado di estrarre le transazioni di base su base giornaliera. Se l’azienda è troppo piccola, di solito non ha nemmeno un reparto IT dedicato e non riesce a gestire un’estrazione giornaliera affidabile, compromettendo così i risultati.

Ora, in termini di settori o complessità, la cosa è che nella maggior parte delle aziende e delle supply chain, secondo me, non hanno nemmeno iniziato ad ottimizzare ancora. Come ho detto, la teoria mainstream della supply chain enfatizza che si dovrebbero cercare previsioni più accurate. Avere una percentuale ridotta di errore di previsione è un obiettivo e molte aziende, ad esempio, lo affrontano avendo un team di pianificazione o un team di previsione. Secondo me, tutto ciò non aggiunge nulla di valore all’azienda perché fornisce fondamentalmente risposte molto sofisticate al set di domande sbagliato.

Potrebbe sembrare sorprendente, ma la programmazione differenziabile brilla davvero non perché è fondamentalmente super potente - lo è - ma brilla perché è di solito la prima volta che viene messa in atto qualcosa che è veramente rilevante per l’azienda. Se vuoi solo un esempio, la maggior parte di ciò che viene implementato nella supply chain sono tipicamente modelli come il modello di scorta di sicurezza, che non hanno assolutamente alcuna rilevanza per qualsiasi supply chain del mondo reale. Ad esempio, nel modello di scorta di sicurezza, si assume che sia possibile avere un tempo di consegna negativo, il che significa che ordini adesso e ti viene consegnato ieri. Non ha senso, e di conseguenza, i risultati operativi per le scorte di sicurezza di solito sono insoddisfacenti.

La programmazione differenziabile brilla nel raggiungere la rilevanza, non nel raggiungere una sorta di grandiosa superiorità numerica o nel essere migliore di altre tecniche alternative di apprendimento automatico. Il punto è davvero raggiungere la rilevanza in un mondo che è molto complesso, caotico, avversario, in continua evoluzione e in cui devi affrontare un paesaggio applicativo semi-incubo che rappresenta i dati che devi elaborare.

Sembra che non ci siano altre domande. In tal caso, suppongo che ci rivedremo il mese prossimo per la lezione di modellazione probabilistica per la supply chain.