Cosa sono gli strati deconvoluzionali?


188

Di recente ho letto Reti pienamente convoluzionali per la segmentazione semantica di Jonathan Long, Evan Shelhamer, Trevor Darrell. Non capisco cosa fanno gli "strati deconvoluzionali" / come funzionano.

La parte rilevante è

3.3. Upsampling è una convoluzione guidata all'indietro

Un altro modo per collegare output grossolani a pixel densi è l'interpolazione. Ad esempio, l'interpolazione bilineare semplice calcola ogni uscita dai quattro ingressi più vicini da una mappa lineare che dipende solo dalle posizioni relative delle celle di ingresso e uscita. In un certo senso, il sovracampionamento con il fattore f è una convoluzione con un passo di input frazionario di 1 / f. Finché f è integrale, un modo naturale di ricampionare è quindi una convoluzione all'indietro (a volte chiamata deconvoluzione) con un passo di uscita di f . Tale operazione è banale da attuare, poiché inverte semplicemente i passaggi avanti e indietro della convoluzione.yij
fff
Pertanto l'upsampling viene eseguito in rete per l'apprendimento end-to-end mediante backpropagation dalla perdita pixel.
Si noti che il filtro di deconvoluzione in tale strato non deve essere riparato (ad es. Per il sovracampionamento bilineare), ma può essere appreso. Una pila di livelli di deconvoluzione e funzioni di attivazione possono persino imparare un upsampling non lineare.
Nei nostri esperimenti, scopriamo che l'upsampling in rete è veloce ed efficace per l'apprendimento della previsione densa. La nostra migliore architettura di segmentazione utilizza questi livelli per imparare a sottocampionare per una previsione raffinata nella Sezione 4.2.

Non credo di aver veramente capito come vengono formati gli strati convoluzionali.

Quello che penso di aver capito è che i livelli convoluzionali con una dimensione del kernel imparano i filtri di dimensione k × k . L'uscita di uno strato convoluzionale con dimensione del kernel k , passo s N e N filtri è di dimensione dim Inputkk×kksNn. Tuttavia, non so come funziona l'apprendimento degli strati convoluzionali. (Capisco come le MLP semplici imparano con la discesa gradiente, se questo aiuta).Input dims2n

Quindi, se la mia comprensione degli strati convoluzionali è corretta, non ho idea di come questo possa essere invertito.

Qualcuno potrebbe aiutarmi a capire gli strati deconvoluzionali?


3
Questa video lezione spiega la deconvoluzione / upsampling: youtu.be/ByjaPdWXKJ4?t=16m59s
user199309

6
Sperando che potesse essere utile a chiunque, ho realizzato un quaderno per esplorare come la convoluzione e la convoluzione trasposta possano essere utilizzate in TensorFlow (0.11). Forse avere alcuni esempi e figure pratiche potrebbe aiutare un po 'di più a capire come funzionano.
AkiRoss,

1
Per me, questa pagina mi ha dato una spiegazione migliore, spiegando anche la differenza tra deconvoluzione e trasposizione convoluzione: versodatascience.com/…
T.Antoni,

Il sovracampionamento non è più simile al pooling all'indietro che alla convoluzione a passi indietro, poiché non ha parametri?
Ken Fehling,

Nota: il nome "livello di deconvoluzione" è fuorviante poiché questo livello non esegue la deconvoluzione .
user76284

Risposte:


210

Lo strato di deconvoluzione è un nome molto sfortunato e dovrebbe piuttosto essere chiamato uno strato convoluzionale trasposto .

Visivamente, per una convoluzione trasposta con passo uno e nessuna imbottitura, riempiamo semplicemente l'ingresso originale (voci blu) con zero (voci bianche) (Figura 1).

Figura 1

Nel caso del passo due e dell'imbottitura, la convoluzione trasposta sarebbe simile a questa (Figura 2):

figura 2

Puoi trovare più (grandi) visualizzazioni di aritmetica convoluzionale qui .


16
Giusto per essere sicuro di averlo capito: "Deconvoluzione" è praticamente la stessa cosa della convoluzione, ma aggiungi qualche imbottitura? (Intorno all'immagine / quando s> 1 anche attorno a ciascun pixel)?
Martin Thoma,

17
Sì, un livello di deconvoluzione esegue anche la convoluzione! Ecco perché la convoluzione trasposta si adatta molto meglio come nome e il termine deconvoluzione è in realtà fuorviante.
David Dao,

11
Perché dici "nessuna imbottitura" nella Figura 1, se in realtà l'input è a zero?
Stas S

8
A proposito: ora si chiama convoluzione trasposta in TensorFlow: tensorflow.org/versions/r0.10/api_docs/python/…
Martin Thoma

9
Grazie per questa risposta molto intuitiva, ma sono confuso sul perché il secondo è il caso dei due passi, si comporta esattamente come il primo quando il kernel si sposta.
Demonedge

49

Penso che un modo per ottenere un'intuizione di livello davvero basilare dietro la convoluzione sia che stai facendo scorrere i filtri K, che puoi pensare come stencil K, sull'immagine di input e produrre attivazioni K - ognuno che rappresenta un grado di corrispondenza con un particolare stencil . L'operazione inversa di ciò sarebbe prendere le attivazioni K ed espanderle in una pre-immagine dell'operazione di convoluzione. La spiegazione intuitiva dell'operazione inversa è quindi, approssimativamente, la ricostruzione dell'immagine data gli stencil (filtri) e le attivazioni (il grado della corrispondenza per ogni stencil) e quindi al livello intuitivo di base vogliamo far esplodere ogni attivazione dalla maschera dello stencil e aggiungili.

Un altro modo per avvicinarsi alla comprensione del deconv sarebbe quello di esaminare l'implementazione del livello di deconvoluzione in Caffe, vedere i seguenti bit di codice rilevanti:

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

Puoi vedere che è implementato in Caffe esattamente come backprop per un normale livello convoluzionale in avanti (per me è stato più ovvio dopo aver confrontato l'implementazione di backprop in cuDNN conv layer vs ConvolutionLayer :: Backward_gpu implementato usando GEMM). Quindi, se lavori attraverso il modo in cui viene eseguita la backpropagation per una convoluzione regolare, capirai cosa succede a livello di calcolo meccanico. Il modo in cui funziona questo calcolo corrisponde all'intuizione descritta nel primo paragrafo di questo blurb.

Tuttavia, non so come funziona l'apprendimento degli strati convoluzionali. (Capisco come le MLP semplici imparano con la discesa gradiente, se questo aiuta).

Per rispondere alla tua altra domanda all'interno della tua prima domanda, ci sono due differenze principali tra backpropagation MLP (layer completamente connesso) e reti convoluzionali:

1) l'influenza dei pesi è localizzata, quindi prima di tutto capire come fare il backprop, diciamo un filtro 3x3 contorto con una piccola area 3x3 di un'immagine di input, mappando su un singolo punto dell'immagine di risultato.

2) i pesi dei filtri convoluzionali sono condivisi per l'invarianza spaziale. Ciò significa in pratica che nel passaggio in avanti lo stesso filtro 3x3 con gli stessi pesi viene trascinato attraverso l'intera immagine con gli stessi pesi per il calcolo in avanti per produrre l'immagine in uscita (per quel particolare filtro). Ciò che ciò significa per il backprop è che i gradienti del backprop per ogni punto nell'immagine sorgente sono sommati sull'intero intervallo che abbiamo trascinato quel filtro durante il passaggio in avanti. Si noti che esistono anche diversi gradienti di perdita rispetto a x, w e bias poiché dLoss / dx deve essere riprogrammato e dLoss / dw è il modo in cui aggiorniamo i pesi. w e bias sono input indipendenti nel DAG di calcolo (non ci sono input precedenti), quindi non è necessario eseguire backpropagation su quelli.

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

7
Penso che questa sia la migliore risposta a questa domanda.
kli_nlpr il

8
Sono d'accordo che questa è la risposta migliore. La risposta in alto ha delle animazioni graziose, ma fino a quando non ho letto questa risposta mi sono sembrate delle normali circonvoluzioni con qualche imbottitura arbitraria per me. Oh, come le persone sono influenzate dalla gioia degli occhi.
Reii Nakano,

1
D'accordo, la risposta accettata non ha spiegato nulla. È molto meglio
Bjorn,

Grazie per la tua grande spiegazione. Al momento non riesco a capire come eseguire correttamente il backprop. Potresti darmi un suggerimento per favore?
Bastian,

33

La matematica passo dopo passo spiega come trasvolgere la convoluzione fa 2x upsampling con filtro 3x3 e passo di 2:

inserisci qui la descrizione dell'immagine

Lo snippet TensorFlow più semplice per 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()

Penso che il tuo calcolo sia sbagliato qui. L'output intermedio dovrebbe essere 3+ 2 * 2 = 7, quindi per un kernel 3x3 l'output finale dovrebbe essere 7-3 + 1 = 5x5
Alex

Spiacente, @Alex, ma non riesco a capire perché l'output intermedio sia 7. Puoi per favore elaborare?
andriys,

2
@andriys Nell'immagine che hai mostrato, perché il risultato finale viene ritagliato?
James Bond,

28

Le note che accompagnano la classe CS231n di Stanford CS : Convolutional Neural Networks for Visual Recognition, di Andrej Karpathy , fanno un ottimo lavoro nel spiegare le reti neurali convoluzionali.

Leggere questo documento dovrebbe darti un'idea approssimativa di:

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

Queste diapositive sono ottime per le reti deconvoluzionali.


29
È possibile riassumere il contenuto di uno di questi link in un breve paragrafo? I collegamenti potrebbero essere utili per ulteriori ricerche, ma idealmente una risposta di scambio di stack dovrebbe avere abbastanza testo per rispondere alla domanda di base senza dover andare fuori dal sito.
Neil Slater,

Mi dispiace ma il contenuto di queste pagine è troppo grande per essere riassunto in un breve paragrafo.
Azrael,

12
Non è richiesto un riepilogo completo, ma solo un titolo, ad esempio "Una rete neurale deconvoluzionale è simile a una CNN, ma è addestrata in modo tale che le funzionalità di qualsiasi livello nascosto possano essere utilizzate per ricostruire il livello precedente (e ripetendo i livelli, alla fine il l'input potrebbe essere ricostruito dall'output). Ciò consente di addestrarlo senza supervisione al fine di apprendere funzionalità generiche di alto livello in un dominio problematico - in genere l'elaborazione delle immagini "(nota che non sono nemmeno sicuro che sia corretto, quindi non scrivo il mio propria risposta).
Neil Slater,

6
Sebbene i collegamenti siano buoni, un breve riassunto del modello con parole tue sarebbe stato meglio.
SmallChess,

11

Ho appena trovato un ottimo articolo dal sito web del theaon su questo argomento [1]:

La necessità di convoluzioni trasposte deriva generalmente dal desiderio di usare una trasformazione che va nella direzione opposta a una convoluzione normale, [...] per proiettare mappe caratteristiche su uno spazio di dimensione superiore. [...] cioè, mappa da uno spazio a 4 dimensioni a uno spazio a 16 dimensioni, mantenendo il modello di connettività della convoluzione.

Le convoluzioni trasposte - chiamate anche convoluzioni a gradazioni frazionate - funzionano scambiando i passaggi avanti e indietro di una convoluzione. Un modo per dirlo è notare che il kernel definisce una convoluzione, ma se si tratta di una convoluzione diretta o di una convoluzione trasposta è determinato dal modo in cui vengono calcolati i passaggi avanti e indietro.

L'operazione di convoluzione trasposta può essere pensata come il gradiente di qualche convoluzione rispetto al suo input, che è di solito il modo in cui le convoluzioni trasposte vengono implementate nella pratica.

Si noti infine che è sempre possibile implementare una convoluzione trasposta con una convoluzione diretta. Lo svantaggio è che di solito comporta l'aggiunta di molte colonne e righe di zeri all'input, con conseguente implementazione molto meno efficiente.

Quindi, in parole semplici, una "convoluzione trasposta" è un'operazione matematica che utilizza matrici (proprio come la convoluzione) ma è più efficiente della normale operazione di convoluzione nel caso in cui si desideri tornare dai valori contorti all'originale (direzione opposta). Questo è il motivo per cui nelle implementazioni si preferisce la convoluzione quando si calcola la direzione opposta (cioè per evitare molte moltiplicazioni 0 non necessarie causate dalla matrice sparsa che risulta dall'imbottitura dell'ingresso).

Image ---> convolution ---> Result

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

A volte si salvano alcuni valori lungo il percorso di convoluzione e si riutilizzano tali informazioni quando "si torna indietro":

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

Questo è probabilmente il motivo per cui viene erroneamente definita una "deconvoluzione". Tuttavia, ha qualcosa a che fare con la trasposizione matriciale della convoluzione (C ^ T), da cui il nome più appropriato "convoluzione trasposta".

Quindi ha molto senso se si considera il costo di elaborazione. Pagheresti molto di più per amazon gpus se non utilizzassi la convoluzione trasposta.

Leggi e guarda attentamente le animazioni qui: http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#no-zero-padding-unit-strides-transposed

Qualche altra lettura pertinente:

La trasposizione (o più in generale, la trasposizione di Hermitian o coniugato) di un filtro è semplicemente il filtro abbinato [3]. Questo si trova invertendo il kernel e prendendo il coniugato di tutti i valori [2].

Sono anche nuovo a questo e sarei grato per qualsiasi feedback o correzione.

[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


1
Nit picking, ma il link dovrebbe essere: deeplearning.net/software/theano_versions/dev/tutorial/…
Herbert

1
Penso che questa sia la migliore risposta !!!
kli_nlpr

10

Potremmo usare PCA per analogia.

Quando si utilizza conv, il passaggio in avanti è quello di estrarre i coefficienti dei componenti principali dall'immagine di input e il passaggio all'indietro (che aggiorna l'input) è di usare (il gradiente di) i coefficienti per ricostruire una nuova immagine di input, in modo che il la nuova immagine di input ha coefficienti PC che corrispondono meglio ai coefficienti desiderati.

Quando si utilizza deconv, il passaggio in avanti e il passaggio all'indietro vengono invertiti. Il passaggio in avanti tenta di ricostruire un'immagine dai coefficienti del PC e il passaggio all'indietro aggiorna i coefficienti del PC dati (il gradiente di) dell'immagine.

Il deconv forward pass esegue esattamente il calcolo del gradiente conv fornito in questo post: http://andrew.gibiansky.com/blog/machine-learning/convolutional-neural-networks/

Ecco perché nell'implementazione del caffe di deconv (fare riferimento alla risposta di Andrei Pokrovsky), il deconv forward pass chiama backward_cpu_gemm () e il backward call chiama forward_cpu_gemm ().


6

Oltre alla risposta di David Dao: è anche possibile pensare al contrario. Invece di concentrarsi su quali pixel di input (a bassa risoluzione) vengono utilizzati per produrre un singolo pixel di output, è anche possibile concentrarsi su quali singoli pixel di input contribuiscono a quale regione di pixel di output.

Questo viene fatto in questa pubblicazione distillata , inclusa una serie di visualizzazioni molto intuitive e interattive. Un vantaggio nel pensare in questa direzione è che spiegare gli artefatti a scacchiera diventa facile.


5

Convoluzioni dal punto di vista DSP

Sono un po 'in ritardo, ma vorrei comunque condividere la mia prospettiva e intuizioni. Il mio background è la fisica teorica e l'elaborazione del segnale digitale. In particolare ho studiato le wavelet e le convoluzioni sono quasi nella mia spina dorsale;)

Anche il modo in cui le persone nella comunità dell'apprendimento profondo parlano di convoluzioni è stato confuso per me. Dal mio punto di vista, ciò che sembra mancare è una corretta separazione delle preoccupazioni. Spiegherò le convoluzioni del deep learning usando alcuni strumenti DSP.

Clausola di esclusione della responsabilità

Le mie spiegazioni saranno un po 'ondulate a mano e non matematicamente rigorose al fine di ottenere i punti principali.


definizioni

xn={xn}n=={,x1,x0,x1,}

ynxn

(yx)n=k=ynkxk

q=(q0,q1,q2)x=(x0,x1,x2,x3)T

qx=(q1q000q2q1q000q2q1q000q2q1)(x0x1x2x3)

kN

kxn=xnk

kk1

kxn={xn/kn/kZ0otherwise

k=3

3{,x0,x1,x2,x3,x4,x5,x6,}={,x0,x3,x6,}
3{,x0,x1,x2,}={x0,0,0,x1,0,0,x2,0,0,}

k=2

2x=(x0x2)=(10000010)(x0x1x2x3)

e

2x=(x00x10)=(10000100)(x0x1)

k=kT


Convoluzioni del deep learning per parti

qx

  • kk(qx)
  • k(kq)x
  • kq(kx)

q(kx)=q(kTx)=(k(q)T)Tx

(q)q

q(kx)=(q1q000q2q1q000q2q1q000q2q1)(10000100)(x0x1)=(q1q200q0q1q200q0q1q200q0q1)T(10000010)T(x0x1)=((10000010)(q1q200q0q1q200q0q1q200q0q1))T(x0x1)=(k(q)T)Tx

Come si vede, è l'operazione trasposta, quindi il nome.

Connessione al vicino Upsampling più vicino

2(11)xq2(11)qxq=(q0q1q2)

(11)q=(q0q0+q1q1+q2q2),

cioè possiamo sostituire un upsampler ripetuto con fattore 2 e una convoluzione con un kernel di dimensione 3 con una convoluzione trasposta con dimensione del kernel 4. Questa convoluzione trasposta ha la stessa "capacità di interpolazione" ma sarebbe in grado di apprendere interpolazioni di corrispondenza migliori.


Conclusioni e osservazioni finali

Spero di poter chiarire un po 'le convoluzioni comuni riscontrate nell'apprendimento profondo, smontandole nelle operazioni fondamentali.

Non ho coperto il pooling qui. Ma questo è solo un downsampler non lineare e può essere trattato anche in questa notazione.


Risposta eccellente. Prendere una prospettiva matematica / simbolica spesso chiarisce le cose. Sono corretto nel pensare che il termine "deconvoluzione" in questo contesto si scontri con la terminologia esistente ?
user76284,

Non si scontrano davvero, non ha senso. La deconvoluzione è solo una convoluzione con l'operatore upsample. Il termine deconvoluzione suona come se fosse una forma di operazione inversa. Parlare di un contrario qui ha senso solo nel contesto delle operazioni a matrice. Si sta moltiplicando con la matrice inversa non con l'operazione inversa di convoluzione (come divisione vs moltiplicazione).
André Bergner,

zθx=zzθz=x

θz=xz=(θ)+x

In breve, il cosiddetto "strato di deconvoluzione" dell'OP non sta effettivamente effettuando la deconvoluzione. Sta facendo qualcos'altro (quello che hai descritto nella tua risposta).
user76284

4

Ho avuto molti problemi a capire cosa è successo esattamente nel documento fino a quando non mi sono imbattuto in questo post del blog: http://warmspringwinds.github.io/tensorflow/tf-slim/2016/11/22/upsampling-and-image-segmentation -con-tensorflow-e-tf-slim /

Ecco un riassunto di come capisco cosa sta succedendo in un upsampling 2x:

Informazioni dalla carta

  • Che cos'è il upsampling?
  • Quali sono i parametri di quella convoluzione?
  • I pesi sono fissi o allenabili?
    • Il documento afferma "inizializziamo il 2x ricampionamento all'interpolazione bilineare, ma consentiamo di apprendere i parametri [...]".
    • Tuttavia, la pagina github corrispondente afferma "Nei nostri esperimenti originali gli strati di interpolazione sono stati inizializzati in kernel bilineari e quindi appresi. Negli esperimenti di follow-up e in questa implementazione di riferimento, i kernel bilineari sono fissi"
    • → pesi fissi

Semplice esempio

  1. immagina la seguente immagine di input:

Immagine di input

  1. Le convoluzioni a gradazioni frazionarie funzionano inserendo fattore-1 = 2-1 = 1 zeri tra questi valori e quindi assumendo passo = 1 in seguito. Pertanto, si riceve la seguente immagine imbottita 6x6

immagine imbottita

  1. Il filtro 4x4 bilineare è simile al seguente. I suoi valori sono scelti in modo tale che i pesi utilizzati (= tutti i pesi non moltiplicati per uno zero inserito) si sommino a 1. I suoi tre valori univoci 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. Applicando il filtro 4x4 sull'immagine imbottita (usando padding = 'same' e stride = 1) si ottiene la seguente immagine ricampionata 6x6:

Immagine ingrandita

  1. Questo tipo di upsampling viene eseguito individualmente per ciascun canale (vedere la riga 59 in https://github.com/shelhamer/fcn.berkeleyvision.org/blob/master/surgery.py ). Alla fine, l'upsampling 2x è davvero un ridimensionamento molto semplice usando interpolazione bilineare e convenzioni su come gestire i confini. Credo che l'upsampling 16x o 32x funzioni più o meno allo stesso modo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.