{"id":943,"date":"2019-09-20T14:08:40","date_gmt":"2019-09-20T12:08:40","guid":{"rendered":"https:\/\/blog.besharp.it\/?p=943"},"modified":"2021-03-17T12:53:12","modified_gmt":"2021-03-17T11:53:12","slug":"machine-learning-su-aws-come-creare-e-deployare-un-servizio-con-aws-sagemaker","status":"publish","type":"post","link":"https:\/\/blog.besharp.it\/it\/machine-learning-su-aws-come-creare-e-deployare-un-servizio-con-aws-sagemaker\/","title":{"rendered":"Machine Learning su AWS: come creare e deployare un servizio con AWS SageMaker"},"content":{"rendered":"
Nell\u2019ultimo decennio l\u2019approccio alla gestione del dato \u00e8 drasticamente cambiato: da un lato, grazie al diffondersi di servizi di public Cloud, il costo di storage \u00e8 sensibilmente diminuito.<\/strong> Dall\u2019altro, con l\u2019utilizzo sempre pi\u00f9 diffuso di ERPs, CRM, piattaforme IoT e altri software di monitoring e profilazione, la raccolta di dati \u00e8 diventata estremamente pi\u00f9 semplice; \u00e8 possibile avere a disposizione enormi quantit\u00e0 di dati<\/strong> sia sui processi aziendali interni, che sulle preferenze e i comportamenti dei clienti. In altre parole, oggi abbiamo l\u2019opportunit\u00e0 di sfruttare quantit\u00e0 di informazioni sempre pi\u00f9 grandi e di qualit\u00e0 sempre migliore<\/strong> ad un costo infinitamente ridotto.<\/span><\/p>\n \u00a0<\/span>Negli ultimi anni la facilit\u00e0 crescente di costruzione di dataset di grandi dimensioni su cui poter effettuare analisi ha fatto aumentare enormemente l\u2019interesse verso temi come Intelligenza Artificiale e Machine Learning (ML),<\/strong> che consentono di creare modelli predittivi a partire dai dataset.<\/span><\/p>\n \u00a0<\/span>La diffusione di dispositivi interconnessi e dell\u2019IoT in generale ha aumentato le opportunit\u00e0 di generare e collezionare molti dati a basso costo. Da qui, grazie all\u2019applicazione di tecniche di Machine Learning hanno preso vita innumerevoli possibilit\u00e0, fino a qualche anno fa inimmaginabili. Si pensi ad esempio alla profilazione dei clienti: di loro oggi possiamo sapere praticamente tutto: quali prodotti usano, come li usano, quali azioni inizialmente non pensate dalle aziende compiono ogni giorno, quali aspetti di ciascun prodotto sono realmente rilevanti nella loro vita quotidiana e molto altro. Spostandosi dal quotidiano all’industria, poi, \u00e8 facile ottenere informazioni rispetto ad esempio a quali componenti industriali siano pi\u00f9 soggetti all\u2019usura per agire quindi di conseguenza (manutenzione predittiva), sulla base di una semplice raccolta di immagini sapere in anticipo se le componenti meccaniche prodotte siano difettose oppure no, e cos\u00ec via.<\/span><\/p>\n \u00a0<\/span>La capacit\u00e0 di capire quali dati estrarre, di interpretarli correttamente e di sfruttarli al massimo per farne un uso il pi\u00f9 possibile utile<\/strong> \u00e8 ci\u00f2 che fa realmente la differenza nell\u2019applicazione di questo nuovo approccio e ci\u00f2 che pu\u00f2 davvero attribuire un vantaggio competitivo ad un\u2019azienda rispetto ad un\u2019azienda competitor.<\/span><\/p>\n \u00a0<\/span>I principali provider Cloud come Amazon Web Services<\/strong> oggi offrono gi\u00e0 una vasta gamma di servizi gestiti dedicati al Machine Learning, utili a soddisfare la stragrande maggioranza dei casi d\u2019uso richiesti dagli utenti.<\/span><\/p>\n \u00a0<\/span>Prima di entrare nel merito di AWS SageMaker quindi facciamo una veloce carrellata dei principali servizi offerti da AWS e delle loro potenzialit\u00e0:<\/span><\/p>\n \u00a0<\/span>Si tratta per\u00f2 di servizi <\/span>completamente gestiti<\/span><\/i>; per chi invece \u00e8 in cerca di una soluzione pi\u00f9 personalizzabile e flessibile<\/strong> con cui divertirsi ad esplorare le infinite potenzialit\u00e0 del Machine Learning, ecco AWS SageMaker.<\/strong><\/span><\/p>\n Entriamo quindi nel dettaglio di questo servizio per poi analizzare, nella seconda parte dell\u2019articolo, la struttura di un progetto basato su AWS SageMaker, come creare un semplice modello di previsione e come effettuare il deploy di un servizio HTTP basato su un modello di Machine Learning.<\/strong><\/span><\/p>\n \u00a0<\/span>Dalla console di AWS SageMaker possiamo subito notare nella sidebar la lista di tutti i componenti di SageMaker con le loro configurazioni.<\/strong><\/span><\/p>\n Il servizio AWS SageMaker \u00e8 composto da <\/span>sottoservizi:<\/span><\/i><\/p>\n \u00a0<\/span>\u00c8 possibile anche deployare progetti completi di SageMaker direttamente dall\u2019 AWS Marketplace per soddisfare tasks specifici.<\/span><\/p>\n \u00a0<\/span>I progetti di ML offerti su Marketplace sono affidabili e trattano un ampio insieme di casistiche; per questo \u00e8 importante scegliere il progetto che pi\u00f9 si addice alle proprie esigenze prima di procedere con lo sviluppo del progetto.<\/span><\/i><\/p>\n Quando si sviluppa un servizio basato su ML, il primo passo consiste nella creazione di una Notebook instance<\/strong> tramite la console AWS. Come mostrato nello screenshot, saranno richiesti un nome per l\u2019istanza, la definizione dell\u2019IAM Role che l\u2019istanza utilizzer\u00e0 e dovremo decidere se vogliamo o meno che la Notebook instance sia inserita in una VPC (In questo caso sar\u00e0 possibile definire anche Security Group e Subnet)<\/span><\/p>\n Anche se decidiamo di non inserire l\u2019istanza in una VPC, lo Jupiter notebook potr\u00e0 essere raggiunto esclusivamente un pre-sign URL, generato dalle nostre credenziali AWS.<\/strong> Una volta aperta la Jupiter notebook, ci troveremo di fronte all\u2019interfaccia standard Jupiter Nootebook:<\/span><\/p>\n Nella \u201cExample tab\u201d, AWS fornisce una lista di esempi per aiutare i data scientists a prendere confidenza con SageMaker.<\/span><\/p>\n Noi abbiamo scelto di seguire l\u2019esempio di Image Classification utilizzando il dataset Caltech 256.<\/strong><\/span><\/p>\n Clicchiamo su Use Image-classification-fulltraining.ipynb e cominciamo.<\/strong><\/em><\/span><\/p>\n Verr\u00e0 mostrato un normale Jupiter Notebook. Andiamo semplicemente a seguire le istruzioni fornite:<\/span><\/p>\n Il primo passo sar\u00e0 creare un bucket S3.<\/strong> Assicuriamoci quindi che il ruolo che abbiamo assegnato alla Notebook instance abbia i permessi di lettura e scrittura<\/strong> su quel bucket. <\/span><\/p>\n Avviato il template, scaricheremo il dataset Caltech 256<\/strong> e prepareremo il training job per l’algoritmo di image classification. L\u2019algoritmo utilizzato in questo esempio \u00e8 l\u2019algoritmo AWS Image Classification<\/strong> il quale si basa su una rete neurale convoluzionale (ResNet). AWS fornisce un ampio array di algoritmi generali ottimizzati per SageMaker (Per pi\u00f9 info, leggi la documentazione di AWS<\/a><\/span>). In ogni caso sar\u00e0 comunque possibile deployare un modello custom da trainare all\u2019interno di un docker container.<\/span><\/p>\n \u00c8 importante comprendere come splittare il dataset in due parti: una parte per il training<\/strong> e una parte di validazione<\/strong>. In questo esempio ogni classe dell\u2019immagine (ball, bathtub, Mars, riffle, ecc) verr\u00e0 divisa in due set: 60 immagini di training e le restanti per la validazione.<\/span><\/p>\n Prima di iniziare col training, \u00e8 fondamentale scegliere con cura gli Hyperparameters sensibili:<\/strong> una scelta non accurata avr\u00e0 come risultato un algoritmo non performante. La scelta di questi parametri \u00e8 spesso una questione di \u201cprove ed errori\u201d; per questa particolare applicazione, i parametri pi\u00f9 rilevanti saranno learning rate ed epochs number.<\/span><\/p>\n Il Learning Rate<\/strong> non \u00e8 altro che la lunghezza del vettore dell\u2019algoritmo di Steepest Descent: se troppo alta, avremo oltrepassato l\u2019optimum, se troppo bassa il training andr\u00e0 avanti all\u2019infinito e non otterremo mai un risultato stabile. L\u2019epochs number<\/strong> \u00e8 invece il valore che indica quante volte l\u2019intero dataset \u00e8 passato avanti e indietro attraverso la rete neurale. Un epoch number troppo basso significher\u00e0 che il modello non avr\u00e0 appreso abbastanza e otterremo quindi cattivi risultati ma il tempo di training sar\u00e0 breve. Al contrario, un epoch numer alto porter\u00e0 ad un overfitting dei dati e perci\u00f2 di nuovo a risultati poco accurati e a un tempo di apprendimento molto lungo. Sia l\u2019overfitting, che l\u2019underfitting sono negativi<\/strong> in quanto causeranno una cattiva performance del modello trainato durante la validazione dei dati.<\/span><\/p>\n Ad esempio, utilizzando i valori di default forniti da AWS, in questo caso il tempo di training \u00e8 molto basso (una manciata di minuti), ma il modello classificher\u00e0 ogni immagine vagamente rossiccia o appena rotondeggiante come\u2026 Marte \ud83d\ude42\u00a0<\/span><\/p>\n Una volta che il training sar\u00e0 completato, sar\u00e0 ora di deployare il modello che \u00e8 stato trainato meglio.<\/strong> Possiamo creare il modello utilizzando il risultato del training:<\/span><\/p>\n A questo punto, procediamo scegliendo la parte di dataset da utilizzare per il testing:<\/strong> in questo caso la scelta \u00e8 ricaduta su bathtubs:<\/strong><\/p>\n Creiamo ora un batch job<\/strong> per mandare tutte le immagini di test al modello per classificarle.<\/p>\n La creazione di un batch job accender\u00e0 una istanza EC2<\/strong> (del taglio prescelto) per procedere con la classificazione delle immagini. Una volta che il processo sar\u00e0 concluso, potremo controllare il risultato: se saranno stati utilizzati solo due epochs durante il training, pochissime immagini saranno classificate correttamente.<\/p>\n Quando saremo soddisfatti del risultato, potremo procedere con la creazione di un endpoint e, successivamente, a deployare il modello:<\/strong><\/p>\n Una volta creato l\u2019endpoint, possiamo inviargli le immagini tramite HTTP utilizzando gli AWS SDKs,<\/strong> ad esempio utilizzando Python boto3.<\/p>\n Il comando sar\u00e0:<\/strong><\/p>\n Dove<\/p>\n \u00e8 l’immagine.<\/p>\n L\u2019endpoint pu\u00f2 essere utilizzato sia da applicazioni deployate su AWS – a condizione che il loro IAM Role permetta di invocare gli endpoints di AWS SageMaker (es. Lambda functions, Microservizi docker che funzionano su Fargate, applicazioni deployate su istanze EC2), sia da applicazioni on-premise o addirittura direttamente su Client a condizione che esse riescano ad autenticare le loro API calls utilizzando le credenziali AWS.<\/span><\/p>\n In questo articolo abbiamo visto insieme come deployare una semplice applicazione di Machine Learning con AWS SageMaker.<\/strong> Divertente vero? Il Machine Learning vi affascina? Allora restate sintonizzati: presto molti altri articoli! E se avete curiosit\u00e0 contattateci!<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":" Nell\u2019ultimo decennio l\u2019approccio alla gestione del dato \u00e8 drasticamente cambiato: da un lato, grazie al diffondersi di servizi di public […]<\/p>\n","protected":false},"author":9,"featured_media":961,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[247],"tags":[321,299,323],"class_list":["post-943","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai-ml","tag-ai","tag-how-to","tag-ml"],"yoast_head":"\n\n
\u00a0<\/span>SageMaker: un Building Block<\/span><\/h2>\n
\n
\u00a0<\/span><\/i>Un esempio di progetto Machine Learning<\/span><\/h2>\n
<\/p>\n
<\/p>\n
<\/p>\n
<\/p>\n
<\/p>\n
<\/p>\n
model_name=\"DEMO-full-image-classification-model\" + time.strftime('-%Y-%m-%d-%H-%M-%S', time.gmtime())\r\nprint(model_name)\r\ninfo = sage.describe_training_job(TrainingJobName=job_name)\r\nmodel_data = info['ModelArtifacts']['S3ModelArtifacts']\r\nprint(model_data)\r\n\r\nhosting_image = get_image_uri(boto3.Session().region_name, 'image-classification')\r\n\r\nprimary_container = {\r\n 'Image': hosting_image,\r\n 'ModelDataUrl': model_data,\r\n}\r\n\r\ncreate_model_response = sage.create_model(\r\n ModelName = model_name,\r\n ExecutionRoleArn = role,\r\n PrimaryContainer = primary_container)\r\n\r\nprint(create_model_response['ModelArn'])\r\n<\/pre>\n
batch_input = 's3:\/\/{}\/image-classification-full-training\/test\/'.format(bucket)\r\ntest_images = '\/tmp\/images\/008.bathtub'\r\n\r\n!aws s3 cp $test_images $batch_input --recursive --quiet\r\n<\/pre>\n
timestamp = time.strftime('-%Y-%m-%d-%H-%M-%S', time.gmtime())\r\nbatch_job_name = \"image-classification-model\" + timestamp\r\nrequest = \\\r\n{\r\n \"TransformJobName\": batch_job_name,\r\n \"ModelName\": model_name,\r\n \"MaxConcurrentTransforms\": 16,\r\n \"MaxPayloadInMB\": 6,\r\n \"BatchStrategy\": \"SingleRecord\",\r\n \"TransformOutput\": {\r\n \"S3OutputPath\": 's3:\/\/{}\/{}\/output'.format(bucket, batch_job_name)\r\n },\r\n \"TransformInput\": {\r\n \"DataSource\": {\r\n \"S3DataSource\": {\r\n \"S3DataType\": \"S3Prefix\",\r\n \"S3Uri\": batch_input\r\n }\r\n },\r\n \"ContentType\": \"application\/x-image\",\r\n \"SplitType\": \"None\",\r\n \"CompressionType\": \"None\"\r\n },\r\n \"TransformResources\": {\r\n \"InstanceType\": \"ml.p2.xlarge\",\r\n \"InstanceCount\": 1\r\n }\r\n}\r\n\r\nsagemaker = boto3.client('sagemaker')\r\nsagemaker.create_transform_job(**request)\r\n\r\nprint(\"Created Transform job with name: \", batch_job_name)\r\n\r\nwhile(True):\r\n response = sagemaker.describe_transform_job(TransformJobName=batch_job_name)\r\n status = response['TransformJobStatus']\r\n if status == 'Completed':\r\n print(\"Transform job ended with status: \" + status)\r\n break\r\n if status == 'Failed':\r\n message = response['FailureReason']\r\n print('Transform failed with the following error: {}'.format(message))\r\n raise Exception('Transform job failed') \r\n time.sleep(30)\r\n<\/pre>\n
from time import gmtime, strftime\r\njob_name_prefix = \"test\"\r\n\r\ntimestamp = time.strftime('-%Y-%m-%d-%H-%M-%S', time.gmtime())\r\nendpoint_config_name = job_name_prefix + '-epc-' + timestamp\r\nendpoint_config_response = sage.create_endpoint_config(\r\n EndpointConfigName = endpoint_config_name,\r\n ProductionVariants=[{\r\n 'InstanceType':'ml.m4.xlarge',\r\n 'InitialInstanceCount':1,\r\n 'ModelName':model_name,\r\n 'VariantName':'AllTraffic'}])\r\n\r\ntimestamp = time.strftime('-%Y-%m-%d-%H-%M-%S', time.gmtime())\r\nendpoint_name = job_name_prefix + '-ep-' + timestamp\r\nprint('Endpoint name: {}'.format(endpoint_name))\r\n\r\nendpoint_params = {\r\n 'EndpointName': endpoint_name,\r\n 'EndpointConfigName': endpoint_config_name,\r\n}\r\nendpoint_response = sagemaker.create_endpoint(**endpoint_params)\r\n<\/pre>\n
runtime.invoke_endpoint(EndpointName=endpoint_name, \r\n ContentType='application\/x-image', \r\n Body=payload)\r\n<\/pre>\n
payload<\/pre>\n