Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Sviluppo di applicazioni AWS Panorama
È possibile utilizzare l'applicazione di esempio per imparare a conoscere la struttura dell'applicazione AWS Panorama e come punto di partenza per la tua applicazione.
Il seguente diagramma mostra i componenti principali dell'applicazione in esecuzione su AWS Panorama Appliance. Il codice dell'applicazione utilizza l'SDK dell'applicazione AWS Panorama per ottenere immagini e interagire con il modello, a cui non ha accesso diretto. L'applicazione invia video a uno schermo collegato ma non invia dati immagine al di fuori della rete locale.
In questo esempio, l'applicazione utilizza l'SDK dell'applicazione AWS Panorama per ottenere fotogrammi di video da una telecamera, preelaborare i dati video e inviare i dati a un modello di visione artificiale che rileva gli oggetti. L'applicazione visualizza il risultato su un display HDMI collegato all'apparecchio.
Sezioni
Manifest dell'applicazione
Il manifesto dell'applicazione è un file denominatograph.json
nellagraphs
folder. Il manifesto definisce i componenti dell'applicazione, che sono pacchetti, nodi e bordi.
I pacchetti sono codice, file di configurazione e binari per il codice dell'applicazione, i modelli, le fotocamere e i display. L'applicazione PHP PHP di esempio utilizza 4 pacchetti:
Esempio graphs/aws-panorama-sample/graph.json
— Pacchetti
"packages": [ { "name": "123456789012::SAMPLE_CODE", "version": "1.0" }, { "name": "123456789012::SQUEEZENET_PYTORCH_V1", "version": "1.0" }, { "name": "panorama::abstract_rtsp_media_source", "version": "1.0" }, { "name": "panorama::hdmi_data_sink", "version": "1.0" } ],
I primi due pacchetti sono definiti all'interno dell'applicazione, nellapackages
directory. Contengono il codice e il modello specifici di questa applicazione. I secondi due pacchetti sono pacchetti generici di telecamere e display forniti dal servizio AWS Panorama. Laabstract_rtsp_media_source
package è un segnaposto per una fotocamera che si sostituisce durante la distribuzione. Lahdmi_data_sink
package rappresenta il connettore di uscita HDMI sul dispositivo.
I nodi sono interfacce per i pacchetti, così come parametri non di pacchetto che possono avere valori predefiniti che vengono sovrascritti al momento della distribuzione. I pacchetti di codice e modello definiscono le interfacce inpackage.json
file che specificano ingressi e uscite, che possono essere flussi video o un tipo di dati di base come float, booleano o stringa.
Ad esempio, le ricettecode_node
node si riferisce a un'interfaccia dalSAMPLE_CODE
pacchetto.
"nodes": [ { "name": "code_node", "interface": "123456789012::SAMPLE_CODE.interface", "overridable": false, "launch": "onAppStart" },
Questa interfaccia è definita nel file di configurazione del pacchetto,package.json
. L'interfaccia specifica che il pacchetto è business logic e che richiede un flusso video denominatovideo_in
e un numero in virgola mobile denominatothreshold
come ingressi. L'interfaccia specifica inoltre che il codice richiede un buffer di flusso video denominatovideo_out
per trasmettere video su uno schermo
Esempio packages/123456789012-SAMPLE_CODE-1.0/package.json
{ "nodePackage": { "envelopeVersion": "2021-01-01", "name": "SAMPLE_CODE", "version": "1.0", "description": "Computer vision application code.", "assets": [], "interfaces": [ { "name": "interface", "category": "business_logic", "asset": "code_asset", "inputs": [ { "name": "video_in", "type": "media" }, { "name": "threshold", "type": "float32" } ], "outputs": [ { "description": "Video stream output", "name": "video_out", "type": "media" } ] } ] } }
Di nuovo nel manifesto dell'applicazione, ilcamera_node
node rappresenta un flusso video proveniente da una telecamera. Include un decoratore che appare nella console quando si distribuisce l'applicazione, che richiede di scegliere un flusso della telecamera.
Esempio graphs/aws-panorama-sample/graph.json
— Nodo Camera
{ "name": "camera_node", "interface": "panorama::abstract_rtsp_media_source.rtsp_v1_interface", "overridable": true, "launch": "onAppStart", "decorator": { "title": "Camera", "description": "Choose a camera stream." } },
Un nodo parametro,threshold_param
, definisce il parametro della soglia di confidenza utilizzato dal codice dell'applicazione. Il valore predefinito è 60 e può essere ignorato durante la distribuzione.
Esempio graphs/aws-panorama-sample/graph.json
— nodo Parametro
{ "name": "threshold_param", "interface": "float32", "value": 60.0, "overridable": true, "decorator": { "title": "Confidence threshold", "description": "The minimum confidence for a classification to be recorded." } }
La sezione finale del manifesto dell'applicazione,edges
, effettua connessioni tra i nodi. Il flusso video della telecamera e il parametro threshold si connettono all'ingresso del nodo di codice e l'uscita video dal nodo di codice si connette al display.
Esempio graphs/aws-panorama-sample/graph.json
— Bordi
"edges": [ { "producer": "camera_node.video_out", "consumer": "code_node.video_in" }, { "producer": "code_node.video_out", "consumer": "output_node.video_in" }, { "producer": "threshold_param", "consumer": "code_node.threshold" } ]
Creazione con l'applicazione di esempio
È possibile utilizzare l'applicazione di esempio come punto di partenza per la tua applicazione.
Il nome di ciascun pacchetto deve essere univoco nell'account. Se tu e un altro utente nel tuo account utilizzate entrambi un nome di pacchetto generico comecode
omodel
, potresti ottenere la versione sbagliata del pacchetto quando esegui la distribuzione. Modifica il nome del pacchetto di codice in uno che rappresenta la tua applicazione.
Per rinominare il pacchetto di codice
-
Rinominare la cartella dei pacchetti:
packages/123456789012-
.SAMPLE_CODE
-1.0/ -
Aggiorna il nome del pacchetto nelle seguenti posizioni.
-
Manifest dell'applicazione–
graphs/aws-panorama-sample/graph.json
-
Configurazione di Package–
packages/123456789012-SAMPLE_CODE-1.0/package.json
-
Script di compilazione–
3-build-container.sh
-
Per aggiornare il codice dell'applicazione
-
Modificare il codice dell'applicazione in
packages/123456789012-SAMPLE_CODE-1.0/src/application.py
. -
Per compilare il container, esegui
3-build-container.sh
.aws-panorama-sample$
./3-build-container.sh
TMPDIR=$(pwd) docker build -t code_asset packages/123456789012-SAMPLE_CODE-1.0 Sending build context to Docker daemon 61.44kB Step 1/2 : FROM public.ecr.aws/panorama/panorama-application ---> 9b197f256b48 Step 2/2 : COPY src /panorama ---> 55c35755e9d2 Successfully built 55c35755e9d2 Successfully tagged code_asset:latest docker export --output=code_asset.tar $(docker create code_asset:latest) gzip -9 code_asset.tar Updating an existing asset with the same name { "name": "code_asset", "implementations": [ { "type": "container", "assetUri": "98aaxmpl1c1ef64cde5ac13bd3be5394e5d17064beccee963b4095d83083c343.tar.gz", "descriptorUri": "1872xmpl129481ed053c52e66d6af8b030f9eb69b1168a29012f01c7034d7a8f.json" } ] } Container asset for the package has been succesfully built at ~/aws-panorama-sample-dev/assets/98aaxmpl1c1ef64cde5ac13bd3be5394e5d17064beccee963b4095d83083c343.tar.gzLa CLI elimina automaticamente la vecchia risorsa contenitore dal
assets
e aggiorna la configurazione del pacchetto. -
Per caricare i pacchetti, esegui
4-package-application.py
. Aprire la console AWS PanoramaPagina Applicazioni distribuite
. Scegliere un'applicazione.
-
Scegliere Replace (Sostituisci).
-
Completare i passaggi per implementare l'applicazione. Se necessario, è possibile apportare modifiche al manifesto dell'applicazione, ai flussi della telecamera o ai parametri.
Modifica del modello di visione artificiale
L'applicazione di esempio include un modello di visione artificiale. Per utilizzare il tuo modello, modifica la configurazione del nodo del modello e utilizza l'interfaccia a riga di comando dell'applicazione AWS Panorama per importarlo come risorsa.
L'esempio seguente utilizza un SSD MXNet ResNet50 modelli scaricabili da questa guida GitHub repo:ssd_512_resnet50_v1_voc.tar.gz
Per modificare il modello dell'applicazione di esempio
-
Rinominare la cartella dei pacchetti in base al modello. Ad esempio, per
packages/
.123456789012
-SSD_512_RESNET50_V1_VOC
-1.0/ -
Aggiorna il nome del pacchetto nelle seguenti posizioni.
-
Manifest dell'applicazione–
graphs/aws-panorama-sample/graph.json
-
Configurazione di Package–
packages/
123456789012
-SSD_512_RESNET50_V1_VOC
-1.0/package.json
-
-
Nel file di configurazione del pacchetto (
package.json
). Modifica il file.assets
valore a un array vuoto.{ "nodePackage": { "envelopeVersion": "2021-01-01", "name": "SSD_512_RESNET50_V1_VOC", "version": "1.0", "description": "Compact classification model", "assets":
[]
, -
Apri il file descrittore del pacchetto (
descriptor.json
). Aggiornamento diframework
eshape
valori corrispondenti al tuo modello.{ "mlModelDescriptor": { "envelopeVersion": "2021-01-01", "framework": "
MXNET
", "inputs": [ { "name": "data", "shape": [1, 3, 512, 512
] } ] } }Il valore performa,
1,3,512,512
, indica il numero di immagini che il modello prende come input (1), il numero di canali in ciascuna immagine (3: rosso, verde e blu) e le dimensioni dell'immagine (512 x 512). I valori e l'ordine dell'array variano a seconda dei modelli. -
Importa il modello con l'interfaccia a riga di comando dell'applicazione AWS Panorama. L'interfaccia a riga di comando dell'applicazione AWS Panorama copia i file del modello e del descrittore nel
assets
cartella con nomi univoci e aggiorna la configurazione del pacchetto.aws-panorama-sample$
panorama-cli add-raw-model --model-asset-name model-asset \ --model-local-path
{ "name": "model-asset", "implementations": [ { "type": "model", "assetUri": "b1a1589afe449b346ff47375c284a1998c3e1522b418a7be8910414911784ce1.tar.gz", "descriptorUri": "a6a9508953f393f182f05f8beaa86b83325f4a535a5928580273e7fe26f79e78.json" } ] }ssd_512_resnet50_v1_voc.tar.gz
\ --descriptor-path packages/123456789012-SSD_512_RESNET50_V1_VOC-1.0
/descriptor.json \ --packages-path packages/123456789012-SSD_512_RESNET50_V1_VOC-1.0
-
Per caricare il modello, esegui
panorama-cli package-application
.$
panorama-cli package-application
Uploading package SAMPLE_CODE Patch Version 1844d5a59150d33f6054b04bac527a1771fd2365e05f990ccd8444a5ab775809 already registered, ignoring upload Uploading package SSD_512_RESNET50_V1_VOC Patch version for the package 244a63c74d01e082ad012ebf21e67eef5d81ce0de4d6ad1ae2b69d0bc498c8fd upload: assets/b1a1589afe449b346ff47375c284a1998c3e1522b418a7be8910414911784ce1.tar.gz to s3://arn:aws:s3:us-west-2:454554846382:accesspoint/panorama-123456789012-wc66m5eishf4si4sz5jefhx 63a/123456789012/nodePackages/SSD_512_RESNET50_V1_VOC/binaries/b1a1589afe449b346ff47375c284a1998c3e1522b418a7be8910414911784ce1.tar.gz upload: assets/a6a9508953f393f182f05f8beaa86b83325f4a535a5928580273e7fe26f79e78.json to s3://arn:aws:s3:us-west-2:454554846382:accesspoint/panorama-123456789012-wc66m5eishf4si4sz5jefhx63 a/123456789012/nodePackages/SSD_512_RESNET50_V1_VOC/binaries/a6a9508953f393f182f05f8beaa86b83325f4a535a5928580273e7fe26f79e78.json { "ETag": "\"2381dabba34f4bc0100c478e67e9ab5e\"", "ServerSideEncryption": "AES256", "VersionId": "KbY5fpESdpYamjWZ0YyGqHo3.LQQWUC2" } Registered SSD_512_RESNET50_V1_VOC with patch version 244a63c74d01e082ad012ebf21e67eef5d81ce0de4d6ad1ae2b69d0bc498c8fd Uploading package SQUEEZENET_PYTORCH_V1 Patch Version 568138c430e0345061bb36f05a04a1458ac834cd6f93bf18fdacdffb62685530 already registered, ignoring upload
-
Aggiornamento del codice dell'applicazione. La maggior parte del codice può essere riutilizzata. Il codice specifico per la risposta del modello è nella
process_results
Metodo.def process_results(self, inference_results, stream): """Processes output tensors from a computer vision model and annotates a video frame.""" for class_tuple in inference_results: indexes = self.topk(class_tuple[0]) for j in range(2): label = 'Class [%s], with probability %.3f.'% (self.classes[indexes[j]], class_tuple[0][indexes[j]]) stream.add_label(label, 0.1, 0.25 + 0.1*j)
In base al modello in uso, potrebbe anche essere necessario aggiornare il
preprocess
Metodo.
Pre-elaborazione di immagini
Prima che l'applicazione invii un'immagine al modello, la prepara per l'inferenza ridimensionandola e normalizzando i dati colore. Il modello utilizzato dall'applicazione richiede un'immagine di 224 x 224 pixel con tre canali di colore, per corrispondere al numero di input nel suo primo livello. L'applicazione regola ogni valore di colore convertendolo in un numero compreso tra 0 e 1, sottraendo il valore medio per quel colore e dividendo per la deviazione standard. Infine, combina i canali di colore e li converte in un NumPy array che il modello può elaborare.
Esempio application.py — Pre-elaborazione
def preprocess(self, img, width): resized = cv2.resize(img, (width, width)) mean = [0.485, 0.456, 0.406] std = [0.229, 0.224, 0.225] img = resized.astype(np.float32) / 255. img_a = img[:, :, 0] img_b = img[:, :, 1] img_c = img[:, :, 2] # Normalize data in each channel img_a = (img_a - mean[0]) / std[0] img_b = (img_b - mean[1]) / std[1] img_c = (img_c - mean[2]) / std[2] # Put the channels back together x1 = [[[], [], []]] x1[0][0] = img_a x1[0][1] = img_b x1[0][2] = img_c return np.asarray(x1)
Questo processo fornisce i valori del modello in un intervallo prevedibile centrato attorno a 0. Corrisponde alla pre-elaborazione applicata alle immagini nel set di dati di addestramento, che è un approccio standard ma può variare in base al modello.
Caricamento di metriche con SDK per Python
L'applicazione PHP PHP PHP PHP di esempio utilizza SDK per Python per caricare le metriche su Amazon. CloudWatch.
Esempio application.py — SDK per Python
def process_streams(self): """Processes one frame of video from one or more video streams.""" ... logger.info('epoch length: {:.3f} s ({:.3f} FPS)'.format(epoch_time, epoch_fps)) logger.info('avg inference time: {:.3f} ms'.format(avg_inference_time)) logger.info('max inference time: {:.3f} ms'.format(max_inference_time)) logger.info('avg frame processing time: {:.3f} ms'.format(avg_frame_processing_time)) logger.info('max frame processing time: {:.3f} ms'.format(max_frame_processing_time)) self.inference_time_ms = 0 self.inference_time_max = 0 self.frame_time_ms = 0 self.frame_time_max = 0 self.epoch_start = time.time()
self.put_metric_data('AverageInferenceTime', avg_inference_time) self.put_metric_data('AverageFrameProcessingTime', avg_frame_processing_time)
def put_metric_data(self, metric_name, metric_value): """Sends a performance metric to CloudWatch.""" namespace = 'AWSPanoramaApplication' dimension_name = 'Application Name' dimension_value = 'aws-panorama-sample' try: metric = self.cloudwatch.Metric(namespace, metric_name) metric.put_data( Namespace=namespace, MetricData=[{ 'MetricName': metric_name, 'Value': metric_value, 'Unit': 'Milliseconds', 'Dimensions': [ { 'Name': dimension_name, 'Value': dimension_value }, { 'Name': 'Device ID', 'Value': self.device_id } ] }] ) logger.info("Put data for metric %s.%s", namespace, metric_name) except ClientError: logger.warning("Couldn't put data for metric %s.%s", namespace, metric_name) except AttributeError: logger.warning("CloudWatch client is not available.")
Ottiene l'autorizzazione da un ruolo di runtime assegnato durante la distribuzione. Il ruolo è definito nellaaws-panorama-sample.yml
AWS CloudFormationModello.
Esempio aws-panorama-sample.yml
Resources: runtimeRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - panorama.amazonaws.com Action: - sts:AssumeRole Policies: - PolicyName: cloudwatch-putmetrics PolicyDocument: Version: 2012-10-17 Statement:
- Effect: Allow Action: 'cloudwatch:PutMetricData' Resource: '*'
Path: /service-role/
L'applicazione di esempio installa l'SDK per Python e altre dipendenze con pip. Quando si crea il contenitore dell'applicazione, ilDockerfile
esegue comandi per installare le librerie in cima a ciò che viene fornito con l'immagine di base.
Esempio Dockerfile
FROM public.ecr.aws/panorama/panorama-application WORKDIR /panorama COPY . . RUN pip install --no-cache-dir --upgrade pip && \ pip install --no-cache-dir -r requirements.txt
Per utilizzare il pluginAWSSDK nel codice dell'applicazione, prima modifica il modello per aggiungere le autorizzazioni per tutte le azioni API utilizzate dall'applicazione. Aggiornamento diAWS CloudFormationstack eseguendo il1-create-role.sh
ogni volta che apporti una modifica. Quindi, implementa le modifiche al codice dell'applicazione.
Per le azioni che modificano o utilizzano risorse esistenti, è consigliabile ridurre al minimo l'ambito di questo criterio specificando un nome o un modello per la destinazione.Resource
in una dichiarazione separata. Per i dettagli sulle azioni e le risorse supportate da ciascun servizio, vedere.Operazioni, risorse e chiavi di condizionenella Service Authorization Reference
Fasi successive
Per istruzioni sull'utilizzo dell'interfaccia a riga di comando di AWS Panorama Application per creare applicazioni e creare pacchetti da zero, consulta il README dell'interfaccia della riga di comando.
Per ulteriori esempi di codice e un'utilità di test da utilizzare per convalidare il codice dell'applicazione prima della distribuzione, visita il repository di campioni di AWS Panorama.