Come automatizzare facilmente la sorveglianza con il Deep Learning

Questo articolo è un breve tutorial per l'implementazione di un sistema di sorveglianza tramite il rilevamento degli oggetti basato sul Deep Learning. Confronta inoltre le prestazioni di diversi modelli di rilevamento oggetti utilizzando il multiprocessing GPU per inferenza, su Pedestrian Detection.

La sorveglianza è parte integrante della sicurezza e della pattuglia. Per la maggior parte, il lavoro comporta lunghi periodi di ricerca di qualcosa di indesiderabile che accada. È fondamentale che lo facciamo, ma è anche un compito molto banale.

La vita non sarebbe molto più semplice se ci fosse qualcosa che potrebbe fare il "guardare e aspettare" per noi? Bene, sei fortunato. Con i progressi della tecnologia nel corso degli ultimi anni, abbiamo potuto scrivere alcuni script per automatizzare le attività di cui sopra - e anche questo, piuttosto facilmente. Ma, prima di approfondire, chiediamoci:

Le macchine sono buone come gli umani?

Chiunque abbia familiarità con Deep Learning saprebbe che i classificatori di immagini hanno superato la precisione a livello umano.

Percentuale di errori nel set di dati ImageNet nel tempo, per esseri umani, visione artificiale tradizionale (CV) e apprendimento profondo. (Fonte immagine: collegamento)

Quindi sì, una macchina può tenere d'occhio gli oggetti allo stesso standard (o meglio) rispetto a un essere umano. Detto questo, l'uso della tecnologia per eseguire la sorveglianza è molto più efficiente.

  • La sorveglianza è un compito ripetitivo e banale. Ciò può causare cali delle prestazioni per noi esseri umani. Lasciando che la tecnologia faccia la sorveglianza, potremmo concentrarci sull'azione se qualcosa va storto.
  • Per sondare una grande striscia di terra, hai bisogno di molto personale. Le telecamere fisse hanno anche un campo visivo limitato. Con i robot di sorveglianza mobili (come i micro droni) questi problemi possono essere mitigati.

Inoltre, la stessa tecnologia può essere utilizzata per una varietà di applicazioni che non si limitano alla sicurezza, come baby monitor o consegna automatizzata del prodotto.

Giusto. Ma come lo automatizziamo?

Prima di escogitare teorie complicate, pensiamo a come funziona normalmente la sorveglianza. Guardiamo un feed video e se rileviamo qualcosa di anormale, prendiamo provvedimenti. Quindi, in sostanza, la nostra tecnologia dovrebbe esaminare ogni fotogramma del video, sperando di individuare qualcosa di anormale. Questo processo suona un campanello?

Come avrai intuito, questa è l'essenza del rilevamento di oggetti con la localizzazione. È leggermente diverso dalla classificazione che, dobbiamo conoscere la posizione esatta dell'oggetto. Inoltre, potremmo avere più oggetti in una singola immagine.

Per trovare la posizione esatta, il nostro algoritmo dovrebbe ispezionare ogni parte dell'immagine per trovare l'esistenza di una classe. È più difficile di quanto sembri. Ma dal 2014, la continua ricerca iterativa in Deep Learning ha introdotto reti neurali fortemente ingegnerizzate in grado di rilevare oggetti in tempo reale.

Guarda come sono aumentate le prestazioni nell'arco di 2 anni!

Esistono diverse architetture di Deep Learning che utilizzano internamente metodi diversi per eseguire la stessa attività. Le varianti più popolari sono le reti più veloci RCNN, YOLO e SSD.

Rapporto tra velocità e precisione. Un mAP più elevato e un tempo GPU inferiore sono ottimali.

Ogni modello dipende da un classificatore di base, che influenza notevolmente l'accuratezza finale e le dimensioni del modello. Inoltre, la scelta del rivelatore di oggetti può influenzare pesantemente la complessità computazionale e la precisione finale.

Quando si sceglie un algoritmo di rilevamento oggetto, c'è sempre un compromesso tra velocità e precisione e dimensione.

In questo post del blog, impareremo come creare un sistema di sorveglianza semplice ma efficace, utilizzando il rilevamento degli oggetti. Parliamo prima dei vincoli a cui siamo tenuti a causa della natura del compito di sorveglianza.

Vincoli per l'apprendimento profondo nella sorveglianza

Spesso vorremmo tenere d'occhio un ampio tratto di terra. Questo porta alla luce un paio di fattori che potremmo dover considerare prima di automatizzare la sorveglianza.

1. Feed video

Naturalmente, per tenere d'occhio una vasta area, potremmo aver bisogno di più telecamere. Inoltre, queste telecamere devono archiviare questi dati da qualche parte; a livello locale o remoto.

Telecamere di sorveglianza tipiche. (Foto di Scott Webb su Unsplash)

Un video di qualità superiore richiederà molta più memoria rispetto a uno di qualità inferiore. Inoltre, un flusso di input RGB è 3 volte più grande di un flusso di input BW. Poiché possiamo archiviare solo una quantità limitata del flusso di input, la qualità viene spesso ridotta per massimizzare lo spazio di archiviazione.

Pertanto, un sistema di sorveglianza scalabile dovrebbe essere in grado di interpretare immagini di bassa qualità. Quindi, il nostro algoritmo di Deep Learning deve essere addestrato anche su immagini di bassa qualità.

2. Potenza di elaborazione

Ora che abbiamo risolto il vincolo di input, possiamo rispondere a una domanda più grande. Dove trattiamo i dati ottenuti da fonti di telecamere? Esistono due metodi per farlo.

  • Elaborazione su un server centralizzato:

I flussi video dalle telecamere vengono elaborati fotogramma per fotogramma su un server remoto o un cluster. Questo metodo è robusto e ci consente di trarre vantaggio dai modelli complessi con elevata precisione. L'ovvio problema è la latenza; è necessaria una connessione Internet veloce per un ritardo limitato. Inoltre, se non si utilizza un'API commerciale, i costi di installazione e manutenzione del server possono essere elevati.

Consumo di memoria vs tempo GPU inferenza (millisecondi). La maggior parte dei modelli ad alte prestazioni consuma molta memoria. (Fonte)
  • Elaborazione sul bordo:

Collegando un piccolo microcontrollore, possiamo eseguire l'inferenza in tempo reale sulla fotocamera stessa. Non vi è alcun ritardo di trasmissione e le anomalie possono essere segnalate più rapidamente del metodo precedente. Inoltre, questo è un eccellente componente aggiuntivo per i robot mobili, in modo che non debbano essere limitati dalla gamma di WiFi / Bluetooth disponibili. (come i microdrones).

Funzionalità FPS di vari rilevatori di oggetti. (Fonte)

Lo svantaggio è che i microcontrollori non sono potenti come le GPU e quindi potresti essere costretto a utilizzare modelli con una precisione inferiore. Questo problema può essere aggirato utilizzando GPU integrate, ma è una soluzione costosa. Una soluzione interessante sarebbe quella di utilizzare software come TensorRT, che può ottimizzare il tuo programma per l'inferenza.

Addestramento di un sistema di sorveglianza

In questa sezione, verificheremo come identificare i pedoni usando il Rilevamento oggetti. Useremo l'API di rilevamento oggetti TensorFlow per creare il nostro modulo di rilevamento oggetti. Esploreremo in breve su come impostare l'API e addestrarla per il nostro compito di sorveglianza. Per una spiegazione più dettagliata, puoi consultare questo post sul blog.

L'intero processo può essere sintetizzato in tre fasi:

  1. Preparazione dei dati
  2. Addestramento del modello
  3. Inferenza
Il flusso di lavoro coinvolto nella formazione di un modello di rilevamento oggetti.

Se hai voglia di vedere i risultati ti motiverebbe di più a provarlo, scorri verso il basso fino alla Fase 3!

Fase 1: preparazione dei dati

Passaggio 1: ottenere il set di dati

Le riprese di sorveglianza scattate in passato sono probabilmente il set di dati più accurato che puoi ottenere. Ma è spesso difficile ottenere tali filmati di sorveglianza nella maggior parte dei casi. In tal caso, possiamo addestrare il nostro rilevatore di oggetti a riconoscere generalmente i nostri obiettivi da immagini normali.

Immagine annotata di esempio dal nostro set di dati.

Come discusso in precedenza, le immagini nella videocamera potrebbero essere di qualità inferiore. Quindi devi addestrare il tuo modello a lavorare in tali condizioni. Un modo molto elegante per farlo è quello di eseguire l'aumento dei dati, che è spiegato in dettaglio qui. In sostanza, dobbiamo aggiungere del rumore per degradare la qualità dell'immagine del set di dati. Potremmo anche sperimentare effetti di sfocatura ed erosione.

Utilizzeremo il set di dati TownCentre per la nostra attività di rilevamento degli oggetti. Utilizzeremo i primi 3600 frame del video per la formazione e la convalida e i restanti 900 per i test. È possibile utilizzare gli script nel mio repository GitHub per estrarre il set di dati.

Passaggio 2: annotare il set di dati

È possibile utilizzare uno strumento come LabelImg per eseguire le annotazioni. Questo è un compito noioso, ma importante lo stesso. Le annotazioni vengono salvate come file XML.

Fortunatamente, i proprietari del set di dati TownCentre hanno fornito annotazioni in formato CSV. Ho scritto uno script rapido per convertire le annotazioni nel formato XML richiesto, che puoi trovare nel mio repository GitHub.

Passaggio 3: clonare il repository

Clona il repository. Eseguire i seguenti comandi per installare i requisiti, compilare alcune librerie Protobuf e impostare le variabili del percorso

pip install -r Requisiti.txt
sudo apt-get install protobuf-compilatore
protoc object_detection / protos / *. proto --python_out =.
export PYTHONPATH = $ PYTHONPATH: `pwd`:` pwd` / slim

Passaggio 4: preparare gli ingressi di supporto

Dobbiamo assegnare un ID al nostro target. Definiamo l'ID nel file chiamato label_map.pbtxt come segue

articolo {
 id: 1
 nome: "target"
}

Successivamente, è necessario creare un file di testo con i nomi dei file XML e di immagine. Ad esempio, se nel tuo set di dati hai img1.jpg, img2.jpg e img1.xml, img2.xml, il file trainval.txt dovrebbe apparire così:

img1
img2

Separare il set di dati in due cartelle, ovvero immagini e annotazioni. Inserisci label_map.pbtxt e trainval.txt nella cartella delle annotazioni. Crea una cartella denominata xmls nella cartella delle annotazioni e posiziona tutti i tuoi XML all'interno. La gerarchia di directory dovrebbe essere simile a questa:

-base_directory
| -immagini
| -annotations
|| -xmls
|| -label_map.pbtxt
|| -trainval.txt

Passaggio 5: creare record TF

L'API accetta input nel formato file TFRecords. Utilizzare il file create_tf_record.py fornito nel mio repository per convertire il set di dati in TFRecords. È necessario eseguire il comando seguente nella directory di base:

python create_tf_record.py \
    --data_dir = `pwd` \
    --output_dir = `pwd`

Troverai due file, train.record e val.record, al termine della sua esecuzione.

Fase 2: addestramento del modello

Passaggio 1: selezione del modello

Come accennato in precedenza, c'è un compromesso tra velocità e precisione. Inoltre, costruire e addestrare un rilevatore di oggetti da zero richiederebbe molto tempo. Pertanto, l'API TensorFlow Object Detection fornisce una serie di modelli pre-addestrati, che è possibile ottimizzare con il proprio caso d'uso. Questo processo è noto come Transfer Learning e accelera il processo di allenamento di una quantità enorme.

Un gruppo di modelli pre-addestrati sul set di dati MS COCO

Scarica uno di questi modelli ed estrai il contenuto nella directory di base. Riceverai i checkpoint del modello, un grafico di inferenza congelato e un file pipeline.config.

Passaggio 2: definizione del lavoro di formazione

Devi definire il "lavoro di addestramento" nel file pipeline.config. Posiziona il file nella directory di base. Ciò che conta davvero sono le ultime righe del file: devi solo impostare i valori evidenziati nelle rispettive posizioni dei file.

gradient_clipping_by_norm: 10.0
  fine_tune_checkpoint: "model.ckpt"
  from_detection_checkpoint: true
  num_steps: 200000
}
train_input_reader {
  label_map_path: "annotations / label_map.pbtxt"
  tf_record_input_reader {
    input_path: "train.record"
  }
}
eval_config {
  num_examples: 8000
  max_evals: 10
  use_moving_averages: false
}
eval_input_reader {
  label_map_path: "annotations / label_map.pbtxt"
  shuffle: false
  num_epochs: 1
  num_readers: 1
  tf_record_input_reader {
    input_path: "val.record"
  }
}

Passaggio 3: iniziare l'addestramento

Eseguire il comando seguente per iniziare il lavoro di formazione. Si consiglia di utilizzare una macchina con una GPU abbastanza grande (a condizione che tu abbia installato la versione gpu di tensorflow) per accelerare il processo di allenamento.

python object_detection / train.py \
--logtostderr \
--pipeline_config_path = pipeline.config \
--train_dir = treno

Fase 3: inferenza

Passaggio 1: esportare il modello addestrato

Prima di poter utilizzare il modello, è necessario esportare i file di checkpoint addestrati in un grafico di inferenza congelato. In realtà è più facile di quanto detto: esegui semplicemente il codice seguente (sostituisci "xxxxx" con il numero del checkpoint):

python object_detection / export_inference_graph.py \
--input_type = image_tensor \
--pipeline_config_path = pipeline.config \
--trained_checkpoint_prefix = train / model.ckpt-xxxxx \
--output_directory = uscita

Otterrai un file chiamato frozen_inference_graph.pb, insieme a un mucchio di file di checkpoint.

Passaggio 2: utilizzalo su uno streaming video

Dobbiamo estrarre i singoli fotogrammi dalla nostra fonte video. Può farlo usando il metodo VideoCapture di OpenCV, come segue:

cap = cv2.VideoCapture ()
flag = True
while (bandiera):
    flag, frame = cap.read ()
    ## - Codice di rilevamento oggetti -

Il codice di estrazione dei dati utilizzato nella Fase 1 crea automaticamente una cartella "test_images" con le immagini del nostro set di test. Possiamo eseguire il nostro modello sul set di test eseguendo quanto segue:

python object_detection / inference.py \
--input_dir = {PATH} \
--output_dir = {PATH} \
--label_map = {PATH} \
--frozen_graph = {PATH} \
--num_output_classes = 1 \
--n_jobs = 1 \
--delay = 0

esperimenti

Come accennato in precedenza, esiste un compromesso tra velocità e precisione durante la scelta di un modello di rilevamento degli oggetti. Ho condotto alcuni esperimenti per misurare l'FPS e contare l'accuratezza delle persone rilevate utilizzando tre diversi modelli. Inoltre, gli esperimenti sono stati condotti su diversi vincoli di risorse (vincoli di parallelismo GPU). Il risultato di questi esperimenti può darti alcune informazioni preziose durante la selezione di un modello di rilevamento di oggetti.

Impostare

I seguenti modelli sono stati selezionati per il nostro esperimento. Questi sono disponibili nello zoo modello dell'API di rilevamento oggetti TensorFlow.

  • RCNN più veloce con ResNet 50
  • SSD con MobileNet v1
  • SSD con InceptionNet v2

Tutti i modelli sono stati addestrati su Google Colab per 10k passaggi (o fino a quando la loro perdita si è saturata). Per deduzione, è stata utilizzata un'istanza AWS p2.8xlarge. La precisione del conteggio è stata misurata confrontando il numero di persone rilevate dal modello e la verità di base. La velocità di inferenza in frame per secondo (FPS) è stata testata con i seguenti vincoli:

  • GPU singola
  • Due GPU in parallelo
  • Quattro GPU in parallelo
  • Otto GPU in parallelo

risultati

Ecco un estratto dell'output prodotto utilizzando FasterRCNN sul nostro set di test. Ho anche allegato un video che confronta l'output prodotto da ciascun modello verso la fine di questo blog. Sentiti libero di scorrere verso il basso e provalo!

Tempo di allenamento

Il diagramma seguente mostra il tempo necessario per addestrare ciascun modello per 10k passi (in ore). Ciò esclude il tempo richiesto per una ricerca dell'iperparametro.

Quando l'applicazione è molto diversa dal modello predefinito utilizzato per l'apprendimento del trasferimento, potrebbe essere necessario regolare fortemente gli iperparametri. Tuttavia, quando l'applicazione è simile, non è necessario eseguire una ricerca approfondita. Tuttavia, potrebbe essere necessario sperimentare parametri di allenamento come il tasso di apprendimento e la scelta dell'ottimizzatore.

Velocità (frame al secondo)

Questa è stata la parte più interessante del nostro esperimento. Come affermato in precedenza, abbiamo misurato le prestazioni FPS dei nostri tre modelli su cinque diversi vincoli di risorse. I risultati sono mostrati sotto:

Gli SSD sono estremamente veloci, battendo facilmente la velocità di RCNN più veloce quando utilizziamo una singola GPU. Tuttavia, Faster RCNN raggiunge rapidamente SSD quando aumentiamo il numero di GPU (lavorando in parallelo). Inutile dire che SSD con MobileNet è molto più veloce di SSD con InceptionNet in un ambiente con GPU basso.

Una caratteristica notevole del grafico sopra è che, l'FPS diminuisce leggermente quando aumentiamo il numero di GPU per SSD con MobileNet. In realtà c'è una semplice risposta a questo apparente paradosso. Si scopre che la nostra configurazione ha elaborato le immagini più velocemente di quanto non fossero fornite dalla funzione di lettura delle immagini!

La velocità del sistema di elaborazione video non può essere superiore alla velocità con cui le immagini vengono inviate al sistema.

Per dimostrare la mia ipotesi, ho dato alla funzione di lettura dell'immagine un vantaggio. Il diagramma seguente mostra il miglioramento dell'FPS per SSD con MobileNet quando è stato aggiunto un ritardo. La leggera riduzione degli FPS nel grafico precedente è dovuta al sovraccarico coinvolto a causa di più GPU che richiedono input.

Inutile dire che osserviamo un forte aumento degli FPS se introduciamo ritardi. La linea di fondo è che dobbiamo avere una pipeline di trasferimento delle immagini ottimizzata per evitare un collo di bottiglia per la velocità. Ma poiché il nostro caso d'uso previsto è la sorveglianza, abbiamo un collo di bottiglia aggiuntivo. L'FPS della telecamera di sorveglianza imposta il limite superiore per l'FPS del nostro sistema.

Accuratezza del conteggio

Definiamo l'accuratezza del conteggio come la percentuale di persone correttamente riconosciute dal nostro sistema di rilevamento degli oggetti. Mi è sembrato più adatto rispetto alla sorveglianza. Ecco come si sono comportati i nostri modelli:

Inutile dire che Faster RCNN è il modello più preciso. Anche sorprendentemente MobileNet ha prestazioni migliori di InceptionNet.

Sulla base degli esperimenti, è evidente che esiste davvero un compromesso tra velocità e precisione. Tuttavia, se disponiamo di risorse sufficienti, possiamo utilizzare un modello con elevata precisione a una buona velocità FPS. Osserviamo che RCNN più veloce con ResNet-50 offre la massima precisione e un ottimo punteggio FPS se distribuito su 4+ GPU in parallelo.

Sono stati molti i passaggi!

Beh ... non vorrei discutere. Sono davvero molti passaggi. Inoltre, impostare un'istanza cloud per far funzionare questo modello in tempo reale sarebbe oneroso e costoso.

Una soluzione migliore sarebbe quella di utilizzare un servizio API già distribuito sui server in modo da poterti preoccupare solo dello sviluppo del tuo prodotto. È qui che entrano in gioco le Nanonet. Hanno la loro API distribuita su hardware di qualità con GPU in modo tale da ottenere prestazioni folli senza nessuna seccatura!

Ho convertito le mie annotazioni XML esistenti in formato JSON e le ho inviate all'API Nanonets. È un dato di fatto, se non si desidera annotare manualmente il set di dati, è possibile richiedere loro di annotarlo per voi. Ecco il flusso di lavoro ridotto quando le nanonette si occupano del sollevamento pesante.

Flusso di lavoro ridotto con le nanonette

In precedenza, ho menzionato come le unità di sorveglianza mobile come i micro droni possono migliorare notevolmente l'efficienza. Possiamo creare tali droni abbastanza facilmente usando micro controller come il Raspberry Pi, e possiamo usare le chiamate API per eseguire l'inferenza.

È abbastanza semplice iniziare con l'API Nanonets per il rilevamento di oggetti, ma per una guida ben spiegata, puoi dare un'occhiata a questo post del blog.

Risultati con nanoneti

Nanonets ha impiegato circa 2 ore per completare il processo di formazione. Ciò include il tempo richiesto per la ricerca dell'iperparametro. In termini di tempo impiegato per l'addestramento, Nanonets è il chiaro vincitore. Le nanonette hanno anche sconfitto FasterRCNN in termini di precisione del conteggio.

Precisione conteggio più veloce di RCNN = 88,77%
Precisione del conteggio delle nanonette = 89,66%

Ecco le prestazioni di tutti e quattro i modelli nel nostro set di dati di prova. È evidente che entrambi i modelli SSD sono un po 'instabili e hanno una precisione inferiore. Inoltre, anche se FasterRCNN e Nanonets hanno precisioni comparabili, quest'ultima ha delle scatole di delimitazione più stabili.

La sorveglianza automatizzata è responsabile?

L'apprendimento profondo è uno strumento straordinario che offre risultati esemplari con facilità. Ma fino a che punto possiamo fidarci del nostro sistema di sorveglianza per agire da solo? Ci sono alcuni casi in cui l'automazione è discutibile.

Aggiornamento: alla luce del GDPR e dei motivi indicati di seguito, è indispensabile ponderare la legalità e le questioni etiche relative all'automazione della sorveglianza. Questo blog è solo a scopo didattico e ha utilizzato un set di dati disponibile al pubblico. È tua responsabilità assicurarti che il tuo sistema automatizzato sia conforme alla legge della tua regione.

1. Conclusioni dubbie

Non sappiamo come un algoritmo di apprendimento profondo arriva a una conclusione. Anche se il processo di immissione dei dati è impeccabile, potrebbero esserci molti colpi spuri. Ad esempio, questo filtro volgare di intelligenza artificiale usato dagli sbirri britannici continuava a rimuovere le immagini delle dune di sabbia pensando che fossero immagini oscene. Tecniche come la backpropagation guidata possono spiegare le decisioni in una certa misura, ma abbiamo ancora molta strada da fare.

2. Attacchi avversari

I sistemi di apprendimento profondo sono fragili. Gli attacchi avversari sono simili alle illusioni ottiche per i classificatori di immagini. Ma la parte spaventosa è che una perturbazione calcolata impercettibile può costringere un modello di apprendimento profondo a classificare male. Utilizzando lo stesso principio, i ricercatori sono stati in grado di aggirare i sistemi di sorveglianza basati sull'apprendimento profondo usando "occhiali contraddittori".

3. Falsi positivi

Un altro problema è che cosa facciamo in caso di falsi positivi. La gravità del problema dipende dall'applicazione stessa. Ad esempio, un falso positivo su un sistema di pattugliamento delle frontiere può essere più significativo di un sistema di monitoraggio del giardino. Dovrebbe esserci una certa quantità di intervento umano per evitare incidenti.

4. Volti simili

Purtroppo, il tuo look non è unico come la tua impronta digitale. È possibile che due (o più) persone abbiano un aspetto molto simile. I gemelli identici sono uno dei primi esempi. È stato riferito che Apple Face ID non è riuscito a distinguere due colleghi cinesi indipendenti. Ciò potrebbe rendere più difficile la sorveglianza e l'identificazione delle persone.

5. Mancanza di diversità nei set di dati

Gli algoritmi di deep learning sono validi solo come i dati forniti. I set di dati più popolari di volti umani contengono solo campioni di bianchi. Mentre può sembrare ovvio a un bambino che gli esseri umani possono esistere in vari colori, gli algoritmi di Deep Learning sono una specie di stupido. In effetti, Google si è messa nei guai perché ha classificato erroneamente una persona di colore come gorilla.

Informazioni sulle nanonette: Nanonets sta creando API per semplificare il deep learning per gli sviluppatori. Visitate il nostro sito https://www.nanonets.com per ulteriori informazioni)