Possiamo "riprogrammare" una rete neurale?


Abbiamo già parlato in questo blog degli adversarial examples: esempi, spesso immagini, costruiti a tavolino per ingannare reti neurali (o altri modelli di machine learning) già allenati. Un preprint pubblicato a Giugno descrive una possibilità ancora più radicale: costruire degli input in grado di far eseguire ad una rete neurale un compito diverso da quello per cui è stata allenata in origine. Anche se l'esistenza di questi adversarial programs è per ora dimostrata solo per problemi di classificazione di immagini, essa apre un campo di indagine incredibilmente vasto, sia per quanto riguarda la sicurezza di una rete neurale in ambienti di produzione, sia per quanto riguarda la nostra conoscenza delle dinamiche interne di ciascuna rete. Vediamo più nel dettaglio di cosa si tratta.

Come ti riprogrammo una rete neurale

Supponiamo di avere a nostra disposizione una rete neurale già allenata: come nel preprint, come esempio pratico consideriamo una delle tantissime reti neurali pre-allenate per riconoscere immagini a partire dal dataset di ImageNet. Supponiamo inoltre di voler in realtà risolvere un altro problema: ad esempio, vogliamo contare il numero di quadrati in un'immagine. Notiamo subito che, pur rimanendo nel dominio delle immagini, i due problemi non sono immediatamente comparabili: le nostre immagini e quelle di ImageNet sono probabilmente di dimensioni diverse, potrebbero avere scale di colori differenti, ed inoltre le 1000 classi di ImageNet sono fondamentalmente inutili per il nostro nuovo task.

Nonostante questo, ci piace complicarci la vita, ed al posto di allenare una nuova rete neurale da zero, vogliamo sfruttare quella che già abbiamo a disposizione. E non solo: lo vogliamo fare senza modificarne nulla nell'architettura.

Quest'ultimo requisito è quello che distingue l'adversarial reprogramming dal transfer learning, nel quale l'obiettivo è risfruttare il più possibile quanto già appreso dalla rete neurale, aggiungendo però nuovi moduli se necessari. Se siete interessati, ne abbiamo parlato discutendo di PyTorch.

Parleremo più avanti delle motivazioni reali dietro un problema del genere; per ora, lasciamoci guidare solo dalla curiosità. Non potendo modificare i parametri della rete, ci rimangono in effetti due cose su cui possiamo intervenire a nostro piacimento: manipolare l'input della rete, e processarne l'output. Andiamo con ordine.

La seconda parte è la più facile, in quanto possiamo definire un mapping (arbitrario) tra gli output originari della rete e quelli da noi desiderati, es.:

Fig. 1a
Esempio di mapping da classi di ImageNet a classi custom (fonte: Adversarial Reprogramming of Neural Networks, Fig. 1a).

L'idea è intuitiva: se la rete predice un "goldfish", noi lo interpreteremo come "due quadrati nell'immagine". Se predice un "ostrich", lo interpreteremo come "10 quadrati". Tutte le altre classi le ignoreremo. Il mapping, come detto, è completamente arbitrario (possiamo associare le classi come preferiamo), e potremmo renderlo complesso a piacere (es., considerando combinazioni di classi).

Il primo punto è più interessante, ed è meglio descritto da un'altra immagine presa dall'articolo:

Fig. 1b
Costruzione dell'adversarial program (fonte: Adversarial Reprogramming of Neural Networks, Fig. 1b).

Da un lato, abbiamo l'input per cui vogliamo chiedere una predizione (il numero di quadrati bianchi). Nell'esempio, questi sono messi al centro di un'immagine più grande (che ha le dimensioni richieste da ImageNet). Tutto il resto dell'immagine è riempita da quello che sembra rumore, ma che in realtà è proprio il nostro adversarial program: un "programma" che vogliamo ottimizzare per modificare il comportamento della rete neurale.

Anche se l'analogia è probabilmente pessima, possiamo pensare all'adversarial program come ad una sorta di SQL injection: un input che porta la query a comportarsi diversamente da come programmato.

Anche qui, abbiamo libertà in come combiniamo i nostri dati (i quadrati bianchi) con il nostro adversarial program. Ad esempio, un blog post molto interessante (con implementazione PyTorch associata) ha eseguito ulteriori esperimenti semplicemente sommando i due (al posto di separarli nettamente come nel caso precedente):

Fig. 1b
(Fonte: Exploring Adversarial Reprogramming).

Ed eccoci arrivati al punto cruciale: tramite ottimizzazione, cerchiamo ora un adversarial program ($W$ nell'immagine sopra) che faccia sì che l'output della rete neurale (le classi di ImageNet) soddisfi il nostro nuovo task (contare i quadrati), seguendo il mapping che abbiamo definito in precedenza:

Fig. 1c
Schema generale dell'adversarial reprogramming (fonte: Adversarial Reprogramming of Neural Networks, Fig. 1c).

Questo è un problema relativamente semplice, non molto dissimile, ad esempio, dal famoso DeepDream.

Ma funziona?

Se ne stiamo parlando, ovviamente sì! Nonostante il fatto che stiamo semplicemente aggiungendo un offset all'input della rete neurale, la rete impara perfettamente a contare i quadrati, e gli adversarial program risultanti mostrano anche una struttura molto particolare:

Fig. 2

E questo non è tutto, in quanto è possibile riprogrammare la rete neurale ad eseguire anche task più complessi, come classificare immagini dal MNIST o dal CIFAR-10:

Tab. 1

Il preprint è pieno di dettagli aggiuntivi molto interessanti. Ad esempio, la riprogrammazione non riesce se la rete non è allenata, dimostrando che il nuovo "programma" deve sfruttare pattern appresi in precedenza.

Ed io che ci faccio?

Questa è la domanda più interessante di tutte. Per ora, con molta probabilità, nulla, e tutto dipenderà da quello che scopriremo in futuro. Ad esempio, possiamo riprogrammare reti neurali anche per altri task, es., text-to-speech? Quanto devono essere simili fra loro i task? Più concretamente, esistono modi efficienti di generare questi programmi?

Nell'ipotesi in cui la riprogrammazione si dimostri un rischio concreto, due sono gli scenari più plausibili descritti nell'articolo. Il primo, il più semplice, è il furto di risorse computazionali, con la possibilità di sfruttare reti neurali messe a disposizione per altri scopi in maniera indiretta. Più in generale, così come gli adversarial attack possono essere replicati nel mondo reale, possiamo immaginare scenari più inquietanti in cui un assistente virtuale venga riprogrammato a piacere mostrandogli uno o più esempi contraffatti.

Al di là di scenari malevoli, però, l'adversarial reprogramming è già ulteriore dimostrazione dell'incredibile flessibilità delle reti neurali che così spesso usiamo e, più in generale, è un monito a quanto lontani ancora siamo da una completa comprensione delle loro capacità computazionali e dinamiche.


Se questo articolo ti è piaciuto e vuoi tenerti aggiornato sulle nostre attività, ricordati che l'iscrizione all'Italian Association for Machine Learning è gratuita! Puoi seguirci anche su Facebook e su LinkedIn.

Previous Post Next Post