Apprendimento automatico industriale: 10 principi di progettazione

Apprendimento automatico industriale: 10 principi di progettazione

Oggigiorno nascono ogni giorno nuovi servizi, applicazioni e altri importanti programmi che consentono di creare cose incredibili: dal software per controllare un razzo SpaceX all'interazione con un bollitore nella stanza accanto tramite uno smartphone.

E, a volte, ogni programmatore alle prime armi, sia esso un appassionato startupper o un normale Full Stack o Data Scientist, prima o poi si rende conto che esistono alcune regole per programmare e creare software che semplificano notevolmente la vita.

In questo articolo descriverò brevemente 10 principi su come programmare il machine learning industriale in modo che possa essere facilmente integrato in un'applicazione/servizio, basandosi sulla metodologia App a 12 fattori. suggerito dal team di Heroku. La mia iniziativa è aumentare la consapevolezza di questa tecnica, che può aiutare molti sviluppatori e persone di data science.

Questo articolo è il prologo di una serie di articoli sul Machine Learning industriale. In essi parlerò ulteriormente di come realizzare effettivamente un modello e lanciarlo in produzione, creare un'API per esso, nonché esempi da varie aree e aziende che hanno ML integrato nei loro sistemi.

Principio 1: una base di codice

Alcuni programmatori nelle prime fasi, per pigrizia di capirlo (o per qualche motivo tutto loro), dimenticano Git. O dimenticano completamente la parola, cioè si lanciano file a vicenda nell'unità/semplicemente lanciano testo/inviano tramite piccioni, oppure non pensano al loro flusso di lavoro e si impegnano ciascuno nel proprio ramo, e poi nel maestro.

Questo principio afferma: avere una base di codice e molte distribuzioni.

Git può essere utilizzato sia in produzione che in ricerca e sviluppo (R&S), in cui non viene utilizzato così spesso.

Ad esempio, nella fase di ricerca e sviluppo puoi lasciare commit con diversi metodi e modelli di elaborazione dati, per poi selezionare quello migliore e continuare facilmente a lavorarci ulteriormente.

In secondo luogo, nella produzione questa è una cosa insostituibile: dovrai costantemente osservare come cambia il tuo codice e sapere quale modello ha prodotto i risultati migliori, quale codice ha funzionato alla fine e cosa è successo che lo ha fatto smettere di funzionare o iniziare a produrre risultati errati . Ecco a cosa servono i commit!

Puoi anche creare un pacchetto del tuo progetto, posizionandolo, ad esempio, su Gemfury, e poi semplicemente importando da esso funzioni per altri progetti, in modo da non riscriverli 1000 volte, ma ne parleremo più avanti.

Principio 2: dichiarare e isolare chiaramente le dipendenze

Ogni progetto ha librerie diverse che importi dall'esterno per applicarle da qualche parte. Che si tratti di librerie Python, librerie di altri linguaggi per vari scopi o strumenti di sistema, il tuo compito è:

  • Dichiara chiaramente le dipendenze, ovvero un file che conterrà tutte le librerie, gli strumenti e le relative versioni utilizzate nel tuo progetto e che devono essere installate (ad esempio, in Python questo può essere fatto utilizzando Pipfile o requisiti.txt. A link che permette bene di comprendere: realpython.com/pipenv-guide)
  • Isola le dipendenze specifiche per il tuo programma durante lo sviluppo. Non vuoi cambiare costantemente versioni e reinstallare, ad esempio, Tensorflow?

In questo modo, gli sviluppatori che si uniranno in futuro al tuo team, potranno prendere rapidamente dimestichezza con le librerie e le loro versioni utilizzate nel tuo progetto, inoltre avrai la possibilità di gestire le versioni e le librerie stesse installate per uno specifico periodo. project, che ti aiuterà a evitare l'incompatibilità delle librerie o delle loro versioni.

Inoltre, l'applicazione non deve fare affidamento su strumenti di sistema che potrebbero essere installati su un sistema operativo specifico. Questi strumenti devono essere dichiarati anche nel manifest delle dipendenze. Ciò è necessario per evitare situazioni in cui la versione degli strumenti (nonché la loro disponibilità) non corrisponde agli strumenti di sistema di un particolare sistema operativo.

Pertanto, anche se curl può essere utilizzato su quasi tutti i computer, dovresti comunque dichiararlo nelle dipendenze, poiché durante la migrazione su un'altra piattaforma potrebbe non essere presente o la versione non sarà quella di cui avevi originariamente bisogno.

Ad esempio, il file require.txt potrebbe assomigliare a questo:

# Model Building Requirements
numpy>=1.18.1,<1.19.0
pandas>=0.25.3,<0.26.0
scikit-learn>=0.22.1,<0.23.0
joblib>=0.14.1,<0.15.0

# testing requirements
pytest>=5.3.2,<6.0.0

# packaging
setuptools>=41.4.0,<42.0.0
wheel>=0.33.6,<0.34.0

# fetching datasets
kaggle>=1.5.6,<1.6.0

Principio 3: configurazioni

Molti hanno sentito storie di vari sviluppatori che caricano accidentalmente codice su GitHub in repository pubblici con password e altre chiavi di AWS, svegliandosi il giorno successivo con un debito di $ 6000 o addirittura $ 50000.

Apprendimento automatico industriale: 10 principi di progettazione

Naturalmente, questi casi sono estremi, ma molto significativi. Se memorizzi le tue credenziali o altri dati necessari alla configurazione all'interno del codice, stai commettendo un errore, e credo non ci sia bisogno di spiegare il perché.

Un'alternativa a questo è memorizzare le configurazioni nelle variabili di ambiente. Puoi leggere ulteriori informazioni sulle variabili di ambiente qui.

Esempi di dati che in genere vengono archiviati in variabili di ambiente:

  • Nomi di dominio
  • URL/URI API
  • Chiavi pubbliche e private
  • Contatti (posta, telefoni, ecc.)

In questo modo non devi modificare costantemente il codice se le variabili di configurazione cambiano. Ciò ti aiuterà a risparmiare tempo, fatica e denaro.

Ad esempio, se utilizzi l'API Kaggle per condurre test (ad esempio, scarichi il software ed esegui il modello attraverso di esso per verificare durante l'esecuzione che il modello funzioni bene), le chiavi private di Kaggle, come KAGGLE_USERNAME e KAGGLE_KEY, dovrebbero essere memorizzati nelle variabili di ambiente.

Principio 4: Servizi di terzi

L'idea qui è quella di creare il programma in modo tale che non vi sia alcuna differenza tra risorse locali e di terze parti in termini di codice. Ad esempio, puoi connettere sia MySQL locale che quelli di terze parti. Lo stesso vale per varie API come Google Maps o Twitter API.

Per disattivare un servizio di terze parti o collegarne un altro è sufficiente modificare le chiavi nella configurazione delle variabili d'ambiente, di cui ho parlato nel paragrafo precedente.

Quindi, ad esempio, invece di specificare ogni volta il percorso dei file con set di dati all'interno del codice, è meglio usare la libreria pathlib e dichiarare il percorso dei set di dati in config.py, in modo che non importa quale servizio usi (per ad esempio CircleCI), il programma è stato in grado di scoprire il percorso dei set di dati tenendo conto della struttura del nuovo file system nel nuovo servizio.

Principio 5. Costruisci, rilascia, esegui

Molte persone nel campo della scienza dei dati trovano utile migliorare le proprie capacità di scrittura di software. Se vogliamo che il nostro programma vada in crash il più raramente possibile e funzioni senza problemi il più a lungo possibile, dobbiamo dividere il processo di rilascio di una nuova versione in 3 fasi:

  1. Palcoscenico сборки. Trasformi il tuo codice nudo con risorse individuali in un cosiddetto pacchetto che contiene tutto il codice e i dati necessari. Questo pacchetto è chiamato assembly.
  2. Palcoscenico rilascio — qui colleghiamo la nostra configurazione all'assembly, senza il quale non potremmo rilasciare il nostro programma. Ora questa è una versione completamente pronta per il lancio.
  3. Poi arriva il palco compimento. Qui rilasciamo l'applicazione eseguendo i processi necessari dalla nostra versione.

Un tale sistema per il rilascio di nuove versioni di un modello o dell'intera pipeline consente di separare i ruoli tra amministratori e sviluppatori, consente di tenere traccia delle versioni e previene arresti indesiderati del programma.

Per l'attività di rilascio, sono stati creati molti servizi diversi in cui è possibile scrivere processi da eseguire autonomamente in un file .yml (ad esempio, in CircleCI questo è config.yml per supportare il processo stesso). Wheely è bravissimo nel creare pacchetti per progetti.

Puoi creare pacchetti con diverse versioni del tuo modello di machine learning, quindi assemblarli e fare riferimento ai pacchetti necessari e alle relative versioni per utilizzare le funzioni che hai scritto da lì. Questo ti aiuterà a creare un'API per il tuo modello e il tuo pacchetto potrà essere ospitato su Gemfury, ad esempio.

Principio 6. Esegui il tuo modello come uno o più processi

Inoltre, i processi non dovrebbero avere dati condivisi. Cioè, i processi devono esistere separatamente e tutti i tipi di dati devono esistere separatamente, ad esempio, su servizi di terze parti come MySQL o altri, a seconda di ciò di cui hai bisogno.

Cioè, sicuramente non vale la pena memorizzare i dati all'interno del file system del processo, altrimenti ciò potrebbe portare alla cancellazione di questi dati al prossimo rilascio/modifica delle configurazioni o trasferimento del sistema su cui viene eseguito il programma.

Ma c'è un'eccezione: per i progetti di machine learning, puoi memorizzare una cache di librerie in modo da non reinstallarle ogni volta che avvii una nuova versione, se non sono state apportate librerie aggiuntive o modifiche alle loro versioni. In questo modo ridurrai il tempo necessario per lanciare il tuo modello nell’industria.

Per eseguire il modello come diversi processi, è possibile creare un file .yml in cui si specificano i processi necessari e la loro sequenza.

Principio 7: Riciclabilità

I processi eseguiti nell'applicazione modello dovrebbero essere facili da avviare e arrestare. Pertanto, ciò ti consentirà di implementare rapidamente modifiche al codice, modifiche alla configurazione, scalare in modo rapido e flessibile e prevenire possibili guasti della versione funzionante.

Cioè, il tuo processo con il modello dovrebbe:

  • Ridurre al minimo il tempo di avvio. Idealmente, il tempo di avvio (dal momento in cui è stato impartito il comando di avvio al momento in cui il processo entra in funzione) non dovrebbe essere superiore a pochi secondi. La memorizzazione nella cache della libreria, descritta sopra, è una tecnica per ridurre i tempi di avvio.
  • Termina correttamente. Cioè, l'ascolto sulla porta del servizio è effettivamente sospeso e le nuove richieste inviate a questa porta non verranno elaborate. Qui devi impostare una buona comunicazione con gli ingegneri DevOps o capire tu stesso come funziona (preferibilmente, ovviamente, quest'ultimo, ma la comunicazione dovrebbe essere sempre mantenuta, in qualsiasi progetto!)

Principio 8: distribuzione/integrazione continua

Molte aziende utilizzano una separazione tra i team di sviluppo e distribuzione dell'applicazione (rendendo l'applicazione disponibile agli utenti finali). Ciò può rallentare notevolmente lo sviluppo del software e i progressi nel migliorarlo. Rovina anche la cultura DevOps, in cui sviluppo e integrazione sono, grosso modo, combinati.

Pertanto, questo principio afferma che l'ambiente di sviluppo dovrebbe essere il più vicino possibile all'ambiente di produzione.

Ciò consentirà:

  1. Riduci i tempi di rilascio di decine di volte
  2. Ridurre il numero di errori dovuti all'incompatibilità del codice.
  3. Ciò riduce anche il carico di lavoro del personale, poiché gli sviluppatori e le persone che distribuiscono l'applicazione sono ora un unico team.

Gli strumenti che ti consentono di lavorare con questo sono CircleCI, Travis CI, GitLab CI e altri.

Potrai apportare velocemente delle aggiunte al modello, aggiornarlo e lanciarlo subito, mentre sarà facile, in caso di guasti, tornare molto velocemente alla versione funzionante, in modo che l'utente finale non se ne accorga nemmeno. Questo può essere fatto particolarmente facilmente e rapidamente se si dispone di buoni test.

Minimizzare le differenze!!!

Principio 9. I tuoi log

I log (o “Log”) sono eventi, solitamente registrati in formato testo, che si verificano all'interno dell'applicazione (flusso di eventi). Un semplice esempio: "2020-02-02 - livello di sistema - nome del processo". Sono progettati in modo che lo sviluppatore possa letteralmente vedere cosa sta succedendo quando il programma è in esecuzione. Vede l'avanzamento dei processi e capisce se è come previsto dallo sviluppatore stesso.

Questo principio afferma che non dovresti archiviare i tuoi log all'interno del tuo file system: dovresti semplicemente "emetterli" sullo schermo, ad esempio, farlo sull'output standard del sistema. E in questo modo sarà possibile monitorare i flussi nel terminal durante lo sviluppo.

Ciò significa che non è affatto necessario salvare i registri? Ovviamente no. La tua applicazione semplicemente non dovrebbe fare questo: lascialo fare a servizi di terze parti. La tua applicazione può inoltrare i log solo a un file o terminale specifico per la visualizzazione in tempo reale oppure a un sistema di archiviazione dati per uso generale (come Hadoop). La tua applicazione stessa non dovrebbe archiviare o interagire con i log.

Principio 10. Prova!

Per il machine learning industriale questa fase è estremamente importante, poiché devi capire che il modello funziona correttamente e produce ciò che volevi.

I test possono essere creati utilizzando pytest e testati utilizzando un piccolo set di dati se si dispone di un'attività di regressione/classificazione.

Non dimenticare di impostare lo stesso seed per i modelli di deep learning in modo che non producano costantemente risultati diversi.

Questa era una breve descrizione dei 10 principi e, ovviamente, è difficile usarli senza provare e vedere come funzionano, quindi questo articolo è solo il prologo di una serie di articoli interessanti in cui svelerò come creare modelli di machine learning industriale, come integrarli nei sistemi e come questi principi possono semplificare la vita a tutti noi.

Cercherò anche di utilizzare principi interessanti che chiunque può lasciare nei commenti se lo desidera.

Fonte: habr.com

Aggiungi un commento