{"id":730,"date":"2019-06-14T12:11:04","date_gmt":"2019-06-14T10:11:04","guid":{"rendered":"https:\/\/blog.besharp.it\/?p=730"},"modified":"2021-03-17T12:39:37","modified_gmt":"2021-03-17T11:39:37","slug":"deepracer-our-journey-to-the-top-ten","status":"publish","type":"post","link":"https:\/\/blog.besharp.it\/it\/deepracer-our-journey-to-the-top-ten\/","title":{"rendered":"DeepRacer: our journey to the top ten!"},"content":{"rendered":"

\"\"<\/p>\n

Las Vegas<\/strong> \u00e8 diventata in questi anni il punto di riferimento per gli eventi legati al Cloud di AWS: abbiamo visto in prima persona il re:Invent crescere dai 6.000 partecipanti del 2012 agli oltre 40.000 dell\u2019anno scorso. Una manifestazione oceanica, nella quale \u00e8 diventato difficile anche semplicemente orientarsi nello scegliere le session a cui partecipare! Deve essere anche per questo che AWS, da quest\u2019anno, ha deciso di affiancare al loro main event alcune conferenze con un focus pi\u00f9 specifico, la prima delle quali, l\u2019AWS re:MARS,<\/strong> \u00e8 stata realizzata intorno ai topic pi\u00f9 hot del momento: <\/span>M<\/b>achine Learning, <\/span>A<\/b>utomazione, <\/span>R<\/b>obotica e <\/span>S<\/b>pazio.<\/span><\/p>\n

beSharp – ovviamente – non poteva mancare.<\/strong><\/p>\n

Tanti grandi nomi per i keynote: Jeff Bezos, Werner Vogels,<\/strong> il cofondatore di Coursera Andrew Ng,<\/strong> il CEO e fondatore di IRobot Colin M. Angle<\/strong> e\u2026 Robert Downey Jr!<\/strong> Chi meglio \u00a0di \u201cIron Man\u201d per parlare delle meraviglie tecnologiche che cambieranno radicalmente la nostra vita gi\u00e0 dai prossimi anni? Lo stesso Robert \u00e8, tra le altre cose, il co-finanziatore di Footprint Coalition, un\u2019organizzazione privata creata con lo scopo di ripulire il nostro pianeta mediante robotica e tecnologie all\u2019avanguardia.<\/span><\/p>\n

Moltissime le sessioni<\/strong> curate da aziende disruptive che hanno presentato innovazioni rese possibili dall\u2019intelligenza artificiale: compagnie oil&gas, enti spaziali privati per il lancio di satelliti artificiali e, soprattutto, l\u2019incredibile Amazon GO, la catena di negozi Amazon in cui \u00e8 possibile fare la spesa ed uscire senza passare dalle casse. Come dice il motto, \u201cno lines, no checkout. NO seriously!\u201d<\/strong>: grazie a tecniche di machine learning e simulazioni in ambienti 3D, chiunque entri in uno store viene etichettato all\u2019ingresso, cos\u00ec da tenere traccia delle azioni e degli articoli prelevati dagli scaffali: all\u2019uscita dal negozio, il sistema di Amazon GO<\/strong> elabora il \u201ccarrello\u201d ed invia la fattura direttamente sul profilo Amazon personale dell\u2019utente. Un\u2019esperienza incredibile!<\/span><\/p>\n

Mentre le sessioni ufficiali sarebbero iniziate solo il 5 giugno, gi\u00e0 dal primo giorno era possibile seguire dei workshop<\/strong> su alcune tematiche specifiche; noi ne abbiamo individuata subito una che stuzzicava in modo particolare le nostre fantasie di nerd: un deep-dive su AWS DeepRacer!<\/strong><\/span><\/p>\n

Il workshop ci ha veramente colpiti: introdotto al keynote del re:Invent 2018 da Andy Jassy, questo modellino 4WD<\/strong> con asse da monster truck \u00e8 in grado di imparare mediante Reinforcement Learning<\/strong> come muoversi autonomamente su percorsi prestabiliti. Descritta da AWS come il modo pi\u00f9 semplice per imparare il Machine Learning, AWS DeepRacer mantiene tutte le promesse: la serie di passaggi per scendere in pista e veder correre la propria macchinina \u00e8 davvero minima. \u00c8 possibile avere un modello trainizzato per la guida in poco meno di un\u2019ora,<\/strong> anche se – ovviamente – per ottenere buoni risultati sono necessari pi\u00f9 esperimenti e molto pi\u00f9 tempo.<\/span><\/p>\n

Noi abbiamo subito sperimentato quante pi\u00f9 opzioni possibili per migliorare di volta in volta il nostro tempo in pista. Tra le altre cose, il re:MARS \u00e8 una delle tappe della DeepRacer League,<\/strong> una competizione che si svolge in concomitanza con i principali eventi di AWS.<\/span><\/p>\n

Quale migliore occasione per imparare direttamente sul campo?<\/span><\/p>\n

\f<\/b>Come funzionano l\u2019AWS DeepRacer e il Reinforcement Learning<\/span><\/h2>\n

Prima di iniziare a parlare di corse e tempi da record \u00e8 bene dare uno sguardo all\u2019interfaccia del servizio DeepRacer di AWS,<\/strong> che \u00e8 lo strumento per il training del modello. Ci sembra inutile specificarlo, ma \u00e8 indispensabile possedere un account AWS! \ud83d\ude42<\/span><\/p>\n

Appena entrati nella vostra console, cliccate sulla barra dei servizi e cercate \u201cDeepRacer\u201d<\/span><\/p>\n

\"\"<\/p>\n

Dalla schermata iniziale \u00e8 possibile vedere i nostri modelli, verificarne lo stato del training e crearne di nuovi.<\/span><\/p>\n

\"\"<\/p>\n

Per cominciare, creiamo un nuovo modello cliccando su \u201cCreate model\u201d.<\/strong><\/span><\/p>\n

Questa schermata ci presenta le caratteristiche del modello, oltre a verificare se abbiamo tutti i permessi sull\u2019account per poterlo salvare correttamente.<\/span><\/p>\n

\"\"<\/p>\n

Nel caso ci fosse qualcosa da sistemare, AWS provveder\u00e0 a segnalarvelo e ad aiutarvi nel correggerlo.<\/span><\/p>\n

Inseriamo un nome e una descrizione:<\/strong> scegliete un nome facile da ricordare e soprattutto univoco perch\u00e9, se vorrete competere in una gara ufficiale, vi verr\u00e0 richiesto di trasferire il vostro modello su una macchina attraverso una chiavetta USB, e quindi di richiamarlo tra quelli caricati attraverso una app dall\u2019iPad del marshall di pista.<\/span><\/p>\n

Scegliamo una pista dove trainizzare il modello:<\/strong> noi abbiamo selezionato la prima, che \u00e8 il circuito ufficiale per la DeepRacer League, \u201cre:Invent 2018\u201d. Potete provare con qualsiasi percorso a disposizione.<\/span><\/p>\n

\"\"<\/p>\n

Una volta selezionata la pista per il training, \u00e8 il momento di creare la funzione di reward<\/strong> con cui addestreremo il modello. Questo passo \u00e8 fondamentale per ottenere un macchina performante e ottenere buoni punteggi nelle gare.<\/span><\/p>\n

Prima di raccontarvi la nostra esperienza, \u00e8 utile ricordare brevemente come funziona il Reinforcement Learning.<\/strong><\/span><\/p>\n

Il Reinforcement Learning \u00e8 un sistema di training di reti neurali unsupervised,<\/strong> ovvero che non necessitano di una ground truth iniziale con la quale adattare i propri pesi. Il Reinforcement Learning effettua invece diverse misurazioni dell\u2019ambiente circostante per massimizzare la propria funzione di reward. Durante questo processo, che viene ripetuto ad oltranza fino al raggiungimento di una soglia di cutoff, i pesi della rete vengono aggiornati volta per volta, andando cos\u00ec ad ottimizzare la rete stessa.<\/span><\/p>\n

Nel caso della DeepRacer Car abbiamo cominciato con una funzione di reward molto semplice, il cui obiettivo \u00e8 quello di insegnare alla macchina a rimanere in mezzo alla pista; questo significa far ritornare un valore di reward pi\u00f9 alto se, al momento della misurazione, la distanza dal centro della carreggiata \u00e8 meno della met\u00e0 della larghezza della strada. In tutti gli altri casi la reward viene ridotta.<\/span><\/p>\n

Di seguito un esempio di come costruire la funzione.<\/span><\/p>\n

import<\/b><\/span> math<\/b><\/span>\r\n\r\ndef<\/b><\/span> reward_function<\/b><\/span>(params):<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span>'''<\/span><\/span>\r\n\r\n\u00a0 \u00a0Use square root for center line<\/span>\r\n\r\n \u00a0\u00a0\u00a0'''<\/span>\r\n\r\n \u00a0\u00a0\u00a0track_width = params[<\/span>'track_width'<\/span>]<\/span>\r\n\r\n \u00a0\u00a0\u00a0distance_from_center = params[<\/span>'distance_from_center'<\/span>]<\/span>\r\n\r\n \u00a0\u00a0\u00a0reward = <\/span>1<\/b><\/span> - math.sqrt(distance_from_center \/ (track_width\/<\/span>2<\/b><\/span>))<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span>if<\/b><\/span> reward < <\/span>0<\/b><\/span>:<\/span>\r\n\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0reward = <\/span>0<\/b><\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span>return<\/b> float<\/span><\/span>(reward)<\/span><\/pre>\n

Scegliamo i gradi di libert\u00e0 della nostra 4WD: velocit\u00e0 massima, angolo di sterzata e livelli di velocit\u00e0 possibili.<\/strong> La combinazione lineare di queste informazioni definisce quante variazioni la macchina \u00e8 in grado di gestire, sia nel caso di sterzate che di cambi di velocit\u00e0.<\/span><\/p>\n

\"\"<\/p>\n

Questa operazione \u00e8 fortemente dipendente dalla funzione di training e viceversa: spesso alterazioni nei gradi di libert\u00e0 sulla funzione di reward producono risultati molto diversi tra di loro.<\/span><\/p>\n

\"\"<\/p>\n

Inserite queste informazioni, \u00e8 possibile decidere per quante ore addestrare il modello, fino ad un massimo di 8 ore per singola operazione. <\/span><\/p>\n

\u00c8 utile sapere che \u00e8 possibile ri-addestrare ulteriormente lo stesso modello<\/strong> per aumentare il grado di confidenza: quello che abbiamo verificato \u00e8 che, con un tempo di training di circa 8 – 10 ore, \u00e8 possibile dare alla macchina una certa confidenza sulla pista, a patto di mantenere un modello semplice. <\/span><\/p>\n

Effettuiamo alcuni test di confidenza sulla funzione descritta precedentemente: dalla schermata principale del modello clicchiamo su \u201cStart new evaluation\u201d<\/strong> e scegliamo il numero di \u201ctrial\u201d sulla pista; con tre prove il risultato \u00e8 il seguente:<\/span><\/p>\n

\"\"<\/p>\n

Niente male come primo risultato ma non potevamo certo fermarci a 23 secondi! Ecco quindi che entrano in gioco le diverse variabili che DeepRacer fornisce per manipolare la propria funzione di reward.<\/span><\/p>\n

{<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span><\/span>\"all_wheels_on_track\"<\/span>: <\/span><\/span>Boolean<\/span>, \u00a0\u00a0\u00a0<\/span># flag to indicate if the vehicle is on the track<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span><\/span>\"x\"<\/span>: <\/span>float<\/span>, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span># vehicle's x-coordinate in meters<\/span>\r\n\r\n \u00a0\u00a0\u00a0\"y\"<\/span>: <\/span>float<\/span>, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span># vehicle's y-coordinate in meters<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span><\/span>\"distance_from_center\"<\/span>: <\/span>float<\/span>, \u00a0\u00a0\u00a0\u00a0<\/span># distance in m<\/span>eters from the track center <\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span>\"is_left_of_center\"<\/span>: <\/span>Boolean<\/span>, \u00a0\u00a0\u00a0\u00a0\u00a0<\/span># Flag to indicate if the vehicle is on the left side to the track <\/span>center or not. <\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span>\"heading\"<\/span>: <\/span>float<\/span>, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\u00a0# vehicle's yaw in degrees<\/span>\r\n\r\n \u00a0\u00a0\u00a0\"progress\"<\/span>: <\/span>float<\/span>, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span># percentage of track completed<\/span>\r\n\r\n \u00a0\u00a0\u00a0\"steps\"<\/span>: <\/span>int<\/span>, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span># number steps completed<\/span>\r\n\r\n \u00a0\u00a0\u00a0\"speed\"<\/span>: <\/span>float<\/span>, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span># vehicle's speed in meters per second (m\/s)<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span><\/span>\"steering_angle\"<\/span>: <\/span>float<\/span>, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span># vehicle's steering angle in degrees<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span>\"track_width\"<\/span>: <\/span>float<\/span>, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span># width of the track<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span>\"waypoints\"<\/span>: [[<\/span>float<\/span>, <\/span>float<\/span><\/span>], <\/span>\u2026<\/span> ], <\/span># <\/span>list of [x,y] as milestones along the track center<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span>\"closest_waypoints\"<\/span>: [<\/span>int<\/span>, <\/span>int<\/span><\/span>] \u00a0\u00a0\u00a0<\/span># <\/span>indices of the two nearest waypoints.<\/span>\r\n\r\n}<\/span><\/pre>\n

Proviamo ad aggiungere alcune di queste informazioni alla nostra funzione di reward:<\/span><\/p>\n

import<\/span> math<\/span>\r\n\r\ndef<\/span> reward_function<\/span>(params):<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span>'''<\/span>\r\n\r\n \u00a0\u00a0\u00a0Use square root for center line<\/span>\r\n\r\n \u00a0\u00a0\u00a0'''<\/span>\r\n\r\n \u00a0\u00a0\u00a0track_width = params[<\/span>'track_width'<\/span>]<\/span>\r\n\r\n \u00a0\u00a0\u00a0distance_from_center = params[<\/span>'distance_from_center'<\/span>]<\/span>\r\n\r\n \u00a0\u00a0\u00a0steering = <\/span>abs<\/span>(params[<\/span>'steering_angle'<\/span>])<\/span>\r\n\r\n \u00a0\u00a0\u00a0speed = params[<\/span>'speed'<\/span>]<\/span>\r\n\r\n \u00a0\u00a0\u00a0all_wheels_on_track = params[<\/span>'all_wheels_on_track'<\/span>]<\/span>\r\n\r\n \u00a0\u00a0\u00a0ABS_STEERING_THRESHOLD = <\/span>15<\/span>\r\n\r\n\r\n\r\n\r\n \u00a0\u00a0\u00a0reward = <\/span>1<\/span> - (distance_from_center \/ (track_width\/<\/span>2<\/span>))**(<\/span>4<\/span>)<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span>if<\/span> reward < <\/span>0<\/span>:<\/span>\r\n\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0reward = <\/span>0<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span>if<\/span> steering > ABS_STEERING_THRESHOLD:<\/span>\r\n\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0reward *= <\/span>0.8<\/span>\r\n\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span><\/span>if<\/span> not<\/span><\/span> (all_wheels_on_track):<\/span>\r\n\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0reward = <\/span>0<\/span>\r\n\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\r\n\r\n \u00a0\u00a0\u00a0<\/span>return<\/span> float<\/span>(reward)<\/span><\/pre>\n

In particolare, abbiamo aggiunto lo \u201csteering_angle\u201d, la \u201cspeed\u201d e la variabile Booleana \u201call_wheels_on_track\u201d che ci indica se in un determinato momento la macchinina ha tutte le ruote fuori dal tracciato.<\/span><\/p>\n

Se osserviamo il codice, vediamo che la funzione di reward, dopo essere stata calcolata rispetto alla posizione relativa al centro della pista, viene modificata come segue:<\/span><\/p>\n