Domanda

Di recente ho letto reti completamente convoluzionali per Semantic segmentazione da Jonathan Lungo, Evan Shelhamer, Trevor Darrell. Non capisco che cosa "strati deconvolutional" fare / come funzionano.

La parte rilevante è

3.3. Upsampling è indietro strided circonvoluzione

Un altro modo per uscite grossolane di connessione ai pixel densi è interpolazione. Ad esempio, semplice interpolazione bilineare calcola ogni uscita $ y_ {ij} $ dalle più vicine quattro ingressi di una mappa lineare che dipende solo dalla posizione relativa della celle di input e output.
In un certo senso, si aumenta la frequenza con fattore di $ f $ è convoluzione con un passo ingresso frazionata di 1 / f. Finché $ f $ è parte integrante, un modo naturale per upsample è quindi all'indietro convoluzione (A volte chiamato deconvoluzione) con un passo di uscita $ F $. Una tale operazione è banale da implementare, poiché semplicemente inverte i passi in avanti e indietro di convoluzione.
Così upsampling viene eseguita in rete per end-to-end apprendimento backpropagation dalla perdita pixelwise.
Si noti che il filtro di deconvoluzione in tale non necessità strato di un fissato (ad esempio, a upsampling bilineare), ma possono essere apprese. Una pila di strati di deconvoluzione e funzioni di attivazione può anche imparare un upsampling non lineare.
Nei nostri esperimenti, troviamo che sovracampionamento in rete è veloce ed efficace per l'apprendimento densa previsione. Il nostro meglio architettura segmentazione usa questi strati per imparare a upsample per la previsione raffinato nel paragrafo 4.2.

Non credo che ho veramente capito come strati convoluzionali sono addestrati.

Quello che penso che ho capito è che gli strati convoluzionali con una dimensione del kernel $ k $ imparano filtri di dimensioni $ k \ times k $. L'uscita di uno strato convoluzionale con la dimensione del kernel $ k $, stride $ s \ in \ mathbb {N} $ e $ n $ filtri è di dimensione $ \ frac {\ text {dim ingresso}} {s ^ 2} \ cdot n $. Comunque, io non so come l'apprendimento di strati convoluzionali funziona. (Capisco come semplice MLPs imparano con discesa pendenza, se questo aiuta).

Quindi, se la mia comprensione di strati convoluzionali è corretto, non ho idea di come questo può essere invertito.

Qualcuno potrebbe per favore aiutarmi a capire strati deconvolutional?

È stato utile?

Soluzione

strato Deconvoluzione è un nome molto sfortunato e dovrebbe piuttosto essere chiamato un < em> recepita convoluzionale strato .

visivamente, per una convoluzione trasposta con un passo e senza imbottitura, abbiamo appena rilievo l'ingresso originale (voci blu) con zeri (voci bianche) (Figura 1).

Figura 1

In caso di passo a due e imbottitura, la circonvoluzione trasposto sarebbe simile a questa (Figura 2):

Figura 2

È possibile trovare maggiori (grande) visualizzazioni di convoluzionale arithmetics qui .

Altri suggerimenti

Credo che un modo per ottenere un'intuizione livello davvero alla base di convoluzione è che si sta scorrevole filtri K, che si può pensare come stencil K, sopra le attivazioni immagine in ingresso e prodotti K - ognuna delle quali rappresenta un grado di corrispondenza con un particolare stencil. L'operazione inversa di che sarebbe di prendere attivazioni K e li espandersi in un preimage dell'operazione di convoluzione. La spiegazione intuitiva del funzionamento inversa è quindi, approssimativamente, ricostruzione dell'immagine date le matrici (filtri) e attivazioni (il grado di corrispondenza per ogni stencil) e quindi al livello intuitivo base vogliamo esplodere ogni attivazione maschera del stencil e aggiungere in su.

Un altro modo di affrontare deconv comprensione sarebbe quello di esaminare l'attuazione strato deconvoluzione in caffe, vedere i seguenti corrispondenti bit di codice:

DeconvolutionLayer<Dtype>::Forward_gpu
ConvolutionLayer<Dtype>::Backward_gpu
CuDNNConvolutionLayer<Dtype>::Backward_gpu
BaseConvolutionLayer<Dtype>::backward_cpu_gemm

Si può vedere che è implementato in Caffe esattamente come backprop per un normale livello convoluzionale in avanti (per me era più evidente dopo che ho confrontato l'attuazione di backprop in cuDNN strato conv vs ConvolutionLayer :: Backward_gpu implementato utilizzando GEMM). Quindi, se si lavora attraverso il modo backpropagation è fatto per convoluzione regolare potrete capire cosa succede a livello di calcolo meccanico. Il modo in cui questo calcolo funziona corrisponde l'intuizione di cui al primo comma del presente Blurb.

Comunque, io non so come l'apprendimento di strati convoluzionali funziona. (Capisco come semplice MLPs imparano con discesa pendenza, se questo aiuta).

Per rispondere alla tua domanda di altri all'interno della vostra prima domanda, ci sono due differenze principali tra MLP backpropagation (strato completamente collegato) e reti convoluzionali:

1) l'influenza dei pesi è localizzato, quindi prima capire come fare backprop per, dire un filtro 3x3 convoluta con una piccola area 3x3 di un'immagine in ingresso, la mappatura di un singolo punto dell'immagine risultati.

2) il peso di filtri convoluzionali sono condivisi per invarianza spaziale. Ciò significa in pratica che in avanti passaggio lo stesso filtro 3x3 con gli stessi pesi viene trascinato attraverso l'intera immagine con gli stessi pesi per il calcolo in avanti per ottenere l'immagine di uscita (per quel particolare filtro). Ciò significa per backprop è che i gradienti backprop per ciascun punto nell'immagine sorgente vengono sommati sull'intera gamma che abbiamo trascinato tale filtro durante il passaggio in avanti. Nota che ci sono anche diversi gradienti di perdita rispetto ad x, w e la polarizzazione dal dLoss / dx bisogno di essere backpropagated, e dLoss / DW è il modo in cui aggiorniamo i pesi. w e polarizzazione sono ingressi indipendenti nel DAG calcolo (non ci sono ingressi precedenti), quindi non c'è bisogno di fare backpropagation su quelli.

(my notation here assumes that convolution is y = x*w+b where '*' is the convolution operation)

Passo dopo passo la matematica spiegando come trasporre circonvoluzione fa upsampling 2x con filtro 3x3 e passo di 2:

 entrare descrizione dell'immagine qui

Il più semplice tensorflow frammento di convalidare la matematica:

import tensorflow as tf
import numpy as np

def test_conv2d_transpose():
    # input batch shape = (1, 2, 2, 1) -> (batch_size, height, width, channels) - 2x2x1 image in batch of 1
    x = tf.constant(np.array([[
        [[1], [2]], 
        [[3], [4]]
    ]]), tf.float32)

    # shape = (3, 3, 1, 1) -> (height, width, input_channels, output_channels) - 3x3x1 filter
    f = tf.constant(np.array([
        [[[1]], [[1]], [[1]]], 
        [[[1]], [[1]], [[1]]], 
        [[[1]], [[1]], [[1]]]
    ]), tf.float32)

    conv = tf.nn.conv2d_transpose(x, f, output_shape=(1, 4, 4, 1), strides=[1, 2, 2, 1], padding='SAME')

    with tf.Session() as session:
        result = session.run(conv)

    assert (np.array([[
        [[1.0], [1.0],  [3.0], [2.0]],
        [[1.0], [1.0],  [3.0], [2.0]],
        [[4.0], [4.0], [10.0], [6.0]],
        [[3.0], [3.0],  [7.0], [4.0]]]]) == result).all()

note che accompagnano Stanford CS classe CS231n : convoluzionale Reti Neurali per Visual riconoscimento, da Andrej Karpathy , fanno un ottimo lavoro di spiegare reti neurali convoluzionali.

La lettura di questo documento dovrebbe darvi una vaga idea su:

  • Deconvolutional Networks Matthew D. Zeiler, Dilip Krishnan, Graham W. Taylor e Rob Fergus Dipartimento di Informatica, Courant Institute, New York University

diapositive sono grandi per Deconvolutional Networks.

Appena trovato un grande articolo dal sito web theaon su questo argomento [1]:

La necessità di circonvoluzioni trasposti nasce generalmente dalla volontà di utilizzare una trasformazione che va nella direzione opposta di una circonvoluzione normale, [...] per progetto di lungometraggio mappe ad uno spazio a più dimensioni. [...] cioè, la mappa da uno spazio a 4 dimensioni in uno spazio tridimensionale 16, mantenendo il modello connettività della circonvoluzione.

recepito circonvoluzioni - chiamato anche circonvoluzioni frazionata strided - lavoro scambiando i passi in avanti e all'indietro di una convoluzione. Un modo per mettere va notato che il kernel definisce una convoluzione, ma che si tratti di una convoluzione diretta o una convoluzione trasposta è determinato da come i passi in avanti e all'indietro sono calcolate.

L'operazione di convoluzione trasposto può essere pensato come la pendenza di alcuni convoluzione rispetto al suo ingresso, che è di solito come convoluzioni trasposti attuazione pratica.

Infine ricordiamo che è sempre possibile implementare una convoluzione recepita con una convoluzione diretta. Lo svantaggio è che di solito comporta l'aggiunta più colonne e righe di zeri all'ingresso, con conseguente un'implementazione molto meno efficiente.

Quindi, in simplespeak, una "convoluzione recepita" è un'operazione matematica utilizzando matrici (proprio come convoluzione), ma è più efficiente rispetto al funzionamento normale convoluzione nel caso in cui si vuole andare indietro dai valori convoluta a quello originale (direzione opposta ). Ecco perché è preferito nelle implementazioni a convoluzione quando si calcola la direzione opposta (cioè per evitare molte inutili moltiplicazioni 0 causati dalla matrice sparsa che risulta dalla imbottitura input).

Image ---> convolution ---> Result

Result ---> transposed convolution ---> "originalish Image"

A volte si salvare alcuni valori lungo il percorso convoluzione e il riutilizzo che le informazioni quando "tornare indietro":

Result ---> transposed convolution ---> Image

Questo è probabilmente il motivo per cui è erroneamente chiamato "deconvoluzione". Tuttavia, esso ha a che fare con la trasposta della matrice della spira (C ^ T), da cui il nome più appropriato "recepita circonvoluzione".

Quindi ha molto senso se si considera il costo di calcolo. Faresti paga molto di più per le GPU amazon, se non si usa la circonvoluzione recepita.

leggere e guardare le animazioni qui con attenzione: http://deeplearning.net /software/theano_versions/dev/tutorial/conv_arithmetic.html#no-zero-padding-unit-strides-transposed

Qualche altra lettura rilevanti:

La trasposta (o più in generale, la hermitiana o trasposta coniugata) di un filtro è semplicemente il filtro adattato [3]. Questo si trova dal tempo di inversione del kernel e prendendo il coniugato di tutti i valori [2].

Sono anche nuovi a questo e sarei grato per qualsiasi feedback o correzioni.

[1] http://deeplearning.net/software/theano_versions/dev /tutorial/conv_arithmetic.html

[2] http://deeplearning.net /software/theano_versions/dev/tutorial/conv_arithmetic.html#transposed-convolution-arithmetic

[3] https://en.wikipedia.org/wiki/Matched_filter

Potremmo usare PCA per analogia.

Quando si utilizza conv, il passo in avanti è quello di estrarre i coefficienti di componenti principali dall'immagine in ingresso, e il passaggio posteriore (che aggiorna l'ingresso) è di uso (il gradiente di) coefficienti di ricostruire una nuova immagine in ingresso, in modo che l'immagine in ingresso ha coefficienti PC che meglio corrispondere i coefficienti desiderati.

Quando si utilizza deconv, il passo in avanti e il passo a ritroso sono invertiti. I tentativi in ??avanti per ricostruire un'immagine da coefficienti PC, e il passaggio all'indietro aggiorna i coefficienti PC dato (il gradiente) dell'immagine.

Il passaggio deconv avanti fa esattamente la conv gradiente calcolo proposta in questo post: http://andrew.gibiansky.com/blog/machine-learning/ convoluzionale-neurali-reti /

Ecco perché nella realizzazione di caffe deconv (fare riferimento alla risposta di Andrei Pokrovsky), il deconv in avanti passano chiamate backward_cpu_gemm (), e le chiamate lancio all'indietro forward_cpu_gemm ().

Oltre alla risposta di David Dao: E 'anche possibile pensare il contrario. Invece di concentrarsi su cui (bassa risoluzione) pixel di input vengono usati per produrre un singolo pixel di uscita, si può anche concentrarsi su cui i singoli pixel di ingresso contribuiscono alla quale regione di pixel di uscita.

Questo viene fatto in questo distilla pubblicazione , tra cui una serie di effetti grafici molto intuitiva e interattiva. Un vantaggio di pensare in questa direzione è che spiegare manufatti scacchiera diventa facile.

Convoluzioni dal punto di vista DSP

Sono un po 'tardi per questo, ma ancora vorrei condividere la mia prospettiva e intuizioni. Il mio background è fisica teorica e di elaborazione del segnale digitale. In particolare piccole onde e le circonvoluzioni ho studiato sono quasi nella mia spina dorsale;)

Il modo di nella comunità di apprendimento profondo parlare di circonvoluzioni è stato anche fonte di confusione per me. Dal mio punto di vista ciò che sembra mancare è una corretta separazione degli interessi. Spiegherò le circonvoluzioni di apprendimento profonde utilizzando alcuni strumenti DSP.

responsabilità

Le mie spiegazioni sarà un po 'a mano ondulato e non matematica rigorosa al fine di ottenere i punti principali in tutto.

Definizioni

definiamo un paio di cose prima. Mi limiterò la mia discussione a unidimensionale (l'estensione a più dimensioni è dritto in avanti) infinita (quindi non abbiamo bisogno di pasticciare con i confini) sequenze di $ x_n = \ {x_n \} _ {n = - \ infty} ^ {\ infty} = \ {\ dots, x _ {- 1}, x_ {0}, x_ {1}, \ dots \}. $

A puro (discreto) convoluzione tra due sequenze $ y_n $ e $ x_n $ è definito come

$$ (y * x) _n = \ sum_ {k = - \ infty} ^ {\ infty} y_ {nk} x_k $$

Se scriviamo questo in termini di operazioni vettoriali matrici sembra che questo (assumendo un semplice kernel $ \ mathbf {q} = (Q_0, Q_1, Q_2) $ e il vettore $ \ mathbf {x} = (x_0, x_1, x_2, x_3) ^ T $ ):

$$ \ mathbf {q} * \ mathbf {x} = \ Left (\ begin {array} {} cccc Q_1 & Q_0 & 0 & 0 \\ Q_2 & Q_1 & Q_0 & 0 \\ 0 & Q_2 & Q_1 & Q_0 \\ 0 & 0 & Q_2 & Q_1 \\ \ End {array} \ right) \ Left (\ begin {array} {} cccc x_0 \\ x_1 \\ x_2 \\ x_3 \ End {array} \ right) $$

Diamo introducono il down-e gli operatori up-sampling, $ \ downarrow $ e $ \ uparrow $ , rispettivamente. Downsampling di un fattore $ k \ in \ mathbb {N} $ è la rimozione di tutti i campioni ad eccezione di tutti i k-esimo uno:

$$ \ downarrow_k \! X_n = x_ {nk} $$

E si aumenta la frequenza di un fattore $ k $ è interleaving $ k-1 $ zeri tra i campioni:

$$ \ uparrow_k \! X_n = \ left \ {\ begin {array} {} ll x_ {n / k} & n / k \ in \ mathbb {Z} \\ 0 & \ text {altrimenti} \ End {array} \ right. $$

es. abbiamo per $ k = 3 $

$$ \ downarrow_3 \! \ {\ Dots, x_0, x_1, x_2, x_3, x_4, x_5, x_6, \ dots \} = \ {\ dots, x_0, x_3, x_6, \ dots \} $$ $$ \ uparrow_3 \! \ {\ Dots, x_0, x_1, x_2, \ dots \} = \ {\ puntini x_0, 0, 0, x_1, 0, 0, x_2, 0, 0, \ dots \} $$

o scritti in termini di operazioni di matrice (qui $ k = 2 $ ):

$$ \ downarrow_2 \! X = \ Left (\ begin {array} {} cc x_0 \\ x_2 \ End {array} \ right) = \ Left (\ begin {array} {} cccc 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ \ End {array} \ right) \ Left (\ begin {array} {} cccc x_0 \\ x_1 \\ x_2 \\ x_3 \ End {array} \ right) $$

e

$$ \ uparrow_2 \! X = \ Left (\ begin {array} {} cccc x_0 \\ 0 \\ x_1 \\ 0 \ End {array} \ right) = \ Left (\ begin {array} {} cc 1 e 0 \\ 0 & 0 \\ 0 & 1 \\ 0 & 0 \\ \ End {array} \ right) \ Left (\ begin {array} {} cc x_0 \\ x_1 \ End {array} \ right) $$

Come si può già vedere, il down-operatori e up-campione sono reciprocamente trasposti, vale a dire $ \ uparrow_k = \ downarrow_k ^ T $ .

Deep Learning Convoluzioni da Parts

Diamo un'occhiata alle circonvoluzioni tipiche utilizzate per l'apprendimento profondo e come li scriviamo. Dato un kernel $ \ mathbf {q} $ e il vettore $ \ mathbf {x} $ abbiamo la seguenti:

  • un strided convoluzione con passo $ k $ $ \ downarrow_k \! (\ Mathbf {q} * \ mathbf {x}) $ ,
  • un dilatato convoluzione con fattore di $ k $ $ (\ uparrow_k \! \ Mathbf {q}) * \ mathbf {x} $ ,
  • un trasposto convoluzione con passo $ k $ $ \ mathbf {q} * (\ uparrow_k \! \ Mathbf {x}) $

Riorganizza di lasciare che il trasposto spira un po ': $$ \ Mathbf {q} * (\ uparrow_k \ \ mathbf {x}!) \; = \; \ Mathbf {q} * (\ downarrow_k ^ T \ \ mathbf {x}!) \; = \; (\ Uparrow_k \! (\ Mathbf {q} *) ^ T) ^ T \ mathbf {x} $$

In questa notazione $ (\ mathbf {q} *) $ deve essere letta come un operatore, vale a dire che astrae convolvendo qualcosa con kernel $ \ mathbf {q} $ . O scritta in operazioni di matrice (esempio):

$$ \ Begin {align} \ Mathbf {q} * (\ uparrow_k \! \ Mathbf {x}) & = \ Left (\ begin {array} {} cccc Q_1 & Q_0 & 0 & 0 \\ Q_2 & Q_1 & Q_0 & 0 \\ 0 & Q_2 & Q_1 & Q_0 \\ 0 & 0 & Q_2 & Q_1 \\ \ End {array} \ right) \ Left (\ begin {array} {} cc 1 e 0 \\ 0 & 0 \\ 0 & 1 \\ 0 & 0 \\ \ End {array} \ right) \ Left (\ begin {array} {c} x_0 \\ x_1 \\ \ End {array} \ right) \\ & = \ Left (\ begin {array} {} cccc Q_1 & Q_2 & 0 & 0 \\ Q_0 & Q_1 & Q_2 & 0 \\ 0 & Q_0 & Q_1 & Q_2 \\ 0 & 0 & Q_0 & Q_1 \\ \ End {array} \ right) ^ T \ Left (\ begin {array} {} cccc 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ \ End {array} \ right) ^ T \ Left (\ begin {array} {c} x_0 \\ x_1 \\ \ End {array} \ right) \\ & = \sinistra( \ Left (\ begin {array} {} cccc 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ \ End {array} \ right) \ Left (\ begin {array} {} cccc Q_1 & Q_2 & 0 & 0 \\ Q_0 & Q_1 & Q_2 & 0 \\ 0 & Q_0 & Q_1 & Q_2 \\ 0 & 0 & Q_0 & Q_1 \\ \ End {array} \ right) \ Right) ^ T \ Left (\ begin {array} {c} x_0 \\ x_1 \\ \ End {array} \ right) \\ & = (\ uparrow_k \! (\ Mathbf {q} *) ^ T) ^ T \ mathbf {x} \ End {align} $$

Come si può vedere la è l'operazione di trasposizione, in tal modo, il nome.

Connessione al vicino più vicino Upsampling

Un altro approccio comune trovato nelle reti convoluzionali è upsampling con un po 'built-in sotto forma di interpolazione. Prendiamo si aumenta la frequenza di un fattore 2 con una semplice interpolazione di ripetizione. Questo può essere scritto come $ \ uparrow_2 \ (1 \; 1) * \ mathbf {x} $ . Se aggiungiamo anche un kernel learnable $ \ mathbf {q} $ per questo dobbiamo $ \ uparrow_2 \! (1 \ ; 1) * \ mathbf {q} * \ mathbf {x} $ . Le spire possono essere combinati, ad esempio per $ \ mathbf {q} = (Q_0 \; Q_1 \; Q_2) $ , abbiamo $$ (1 \ ; 1) * \ mathbf {q} = (Q_0 \; \; Q_0 \ \ + \ Q_1 \;!!! \; Q_1 \ \ + \ Q_2 \;!!! \; Q_2), $$

vale a dire. siamo in grado di sostituire un upsampler ripetere con fattore di 2 e una convoluzione con un kernel di dimensione 3 da un trasposto convoluzione con kernel dimensione 4. Questa convoluzione trasposto ha la stessa "capacità di interpolazione", ma sarebbe in grado di imparare meglio interpolazioni di corrispondenza.

Conclusioni e finale Osservazioni

Spero di poter chiarire alcuni circonvoluzioni comuni che si trovano in profonda imparare un po 'prendendo loro a parte nelle operazioni fondamentali.

Non ho coprire il pool qui. Ma questo è solo un downsampler non lineare e può essere trattato all'interno di questa notazione pure.

Ho avuto un sacco di difficoltà a capire che cosa è accaduto esattamente nella carta fino a quando mi sono imbattuto in questo post del blog: http://warmspringwinds.github.io/tensorflow/tf-slim/2016/11/22/upsampling -e-image-segmentazione-con-tensorflow-e-tf-slim /

Ecco un riassunto di come ho capito ciò che sta accadendo in un upsampling 2x:

Informazioni da carta

Esempio semplice

  1. immaginare l'immagine in ingresso seguente:

immagine di ingresso

  1. circonvoluzioni in frazioni strided funzionano inserendo factor-1 = 2-1 = 1 zeri tra questi valori e quindi assumendo stride = 1 in seguito. Così, si riceve l'immagine imbottita seguente 6x6

image imbottito

  1. I bilineari aspetto filtro 4x4 come questo. I suoi valori sono scelti in modo che i pesi utilizzati (= tutti i pesi non essendo moltiplicati con inserito lo zero) si sommano a 1. Le sue tre valori unici sono 0,56, 0,19 e 0,06. Inoltre, il centro del filtro è per convenzione il pixel nella terza riga e terza colonna.

filtro

  1. L'applicazione del filtro 4x4 sull'immagine imbottita (usando padding = 'stesso' e stride = 1) produce la seguente immagine upsampled 6x6:

immagine in scala

  1. Questo tipo di upsampling viene eseguita per ciascun canale (vedi linea 59 in https://github.com/shelhamer/fcn.berkeleyvision.org/blob/master/surgery.py ). Alla fine, l'upsampling 2x è davvero molto semplice ridimensionamento mediante interpolazione bilineare e convenzioni su come gestire i confini. 16x o 32x upsampling funziona più o meno allo stesso modo, credo.

Il seguente articolo discute layers.Both deconvolutional dal punto di vista architetturale e formazione. reti Deconvolutional

Autorizzato sotto: CC-BY-SA insieme a attribuzione
scroll top