Automatický kodér obrázku s využitím dekonvoluce a zrušení zařazování

Obsah

Souhrn

image

Příklad Image\GettingStarted\07_Deconvolution_PY.py ukazuje, jak použít Deconvolution a Unpooling k vygenerování jednoduchého automatického kodéru obrázku (07_Deconvolution_BS.cntk je odpovídající verze BrainScriptu). Používá datovou sadu MNIST, která má rozlišení 28x28x1, kóduje ji do reprezentace 7x7x1 pomocí konvoluce a sdružování a dekóduje původní rozlišení. Trénovací kritérium je chyba root-mean-square (RMSE). Výše uvedený obrázek znázorňuje vizualizace původního obrázku, zakódovaného obrázku a dekódovaného obrázku pro prvních pět obrázků testovací sady MNIST.

Nastavení

Pokud chcete spustit příklad, potřebujete datnou sadu MNIST. Data můžete získat spuštěním následujícího příkazu ze Examples\Image\DataSets\MNIST složky:

python install_mnist.py

Spuštění ukázky

Příklad se nachází ve Examples\Image\GettingStarted složce. K spuštění tohoto příkladu použijte následující příkaz ke spuštění verze Pythonu (z prostředí CNTK Pythonu):

python 07_Deconvolution_PY.py

nebo tento příkaz pro verzi BrainScriptu:

cntk configFile=07_Deconvolution_BS.cntk

Hodnoty RMSE pro trénování a testování jsou 0.225 a 0.223 v uvedeném pořadí. Pokud chcete vizualizovat kódované a dekódované image, spusťte následující příkaz:

python 07_Deconvolution_Visualizer.py

Nastavte use_brain_script_model=True pro model BrainScript a False pro model Python. Vizualizace budou uloženy ve Output složce společně Examples\Image\GettingStarted s textovou reprezentací kodéru a výstupem dekodéru.

Technické podrobnosti

Níže je definice modelu pro jednoduchý automatický kodér obrázku v BrainScriptu (úplný konfigurační soubor viz Obrázek\GettingStarted\07_Deconvolution_BS.cntk)

    cMap = 1
    model = inputFeatures => {
        conv1   = ConvolutionalLayer {cMap, (5:5), pad = true, activation=ReLU}(inputFeatures)
        pool1   = MaxPoolingLayer    {(4:4), stride=(4:4)}(conv1)
        unpool1 = MaxUnpoolingLayer  {(4:4), stride=(4:4)}(pool1, conv1)
        deconv1 = DeconvLayer        {1, (5:5), cMap, lowerPad=(2:2:0), upperPad=(2:2:0), bias=false}(unpool1)
    }.deconv1

Odpovídající definice modelu v souboru 07_Deconvolution_PY.py je

    cMap = 1
    conv1   = cntk.layers.Convolution  ((5,5), cMap, pad=True, activation=cntk.ops.relu)(scaled_input)
    pool1   = cntk.layers.MaxPooling   ((4,4), (4,4))(conv1)
    unpool1 = cntk.layers.MaxUnpooling ((4,4), (4,4))(pool1, conv1)
    z       = cntk.layers.Deconvolution((5,5), num_channels, cMap, lower_pad=(0,2,2), upper_pad=(0,2,2), bias=False, init=cntk.glorot_uniform(0.001))(unpool1)
    

Tady popisujeme verzi BrainScriptu, verze Pythonu je analogická. Model nejprve použije ConvolutionalLayer s hloubkou cMap=1 vstupních funkcí následovaných aktivací ReLU a používá MaxPoolingLayer s tvarem filtru a stridem (4:4). Výsledkem je zakódovaný tensor velikosti 7x7x1. Potom použije MaxUnpoolingLayer a DeconvLayer s odpovídajícími obrazci filtru k dekódování zpět do původního rozlišení.

Dekodér komprimuje původní 784 (28x28) čísla na 49 (7x7), faktoru 16. Použití pouze hloubky 1 pro ConvolutionalLayer má výhodu, že výsledky kodéru lze vizualizovat smysluplným způsobem (viz obrázek v horní části této stránky). Jeden může zvýšit počet konvolučních filtrů, např. cMap=3 aby měl menší kompresi a snad lepší dekódování výsledků. V tomto příkladu se RMSE pro trénování i testování sníží na 0.196. Dalším způsobem, jak mít menší kompresi, je použít menší tvar filtru a krok pro vrstvu sdružování. Použití (2:2) pro sdružování i odřazování přináší kódovaný tensor velikosti 14x14x1 a zmenšuje rmsE v tomto příkladu na 0.136 trénování a 0.131 testování. Následující obrázek znázorňuje vizualizaci původního obrázku a dekódovaného obrázku pro prvních pět obrázků testovací sady MNIST pro tři diskutovaná nastavení.

image

Dekonvoluce a zrušení zařazování

Pojďme se trochu blíže podívat na MaxUnpoolingLayer a DeconvLayer.

MaxUnpoolingLayer {(4:4), stride=(4:4)}(pool1, conv1)

MaxPoolingLayer vyžaduje dva vstupy, což jsou výstup odpovídající vrstvy sdružování (pool1 v tomto případě) a vstup odpovídající vrstvy sdružování (conv1 v tomto případě). conv1je vyžadován v CNTK k určení cíle operace Zrušení zařazování, protože CNTK neukládá tzv. proměnné přepínače (podrobnosti najdete tady).

DeconvLayer {1, (5:5), cMap, lowerPad=(2:2:0), upperPad=(2:2:0)}

První parametr DeconvLayer je hloubka výstupního svazku, druhý je tvar jádra (width:height) a třetí je hloubka vstupního svazku. Parametry odsazení musí být nastaveny v souladu s tvarem jádra, aby bylo dosaženo požadované šířky a výšky výstupního tensoru (v tomto případě 28x28). Další podrobnosti o DeconvLayer najdete na stránce s referenčními informacemi o vrstvě.

Automatický kodér s více vrstvami

Pro složitější automatický kodér můžete naskládat více vrstev conv/Deconv a pool/Unpool. Následuje příklad se dvěma vrstvami každého typu, ve 07_Deconvolution_BS.cntk které můžete použít (jednoduše nahraďte model v souboru):

    inputDim = 1
    cMap1 = 5
    cMap2 = 1
    model = inputFeatures => {
        conv_A   = ConvolutionalLayer {cMap1, (5:5), pad = true, activation=ReLU}(inputFeatures)
        pool_A   = MaxPoolingLayer    {(2:2), stride=(2:2)}(conv_A)
        conv_B   = ConvolutionalLayer {cMap2, (5:5), pad = true, activation=ReLU}(pool_A)
        pool_B   = MaxPoolingLayer    {(2:2), stride=(2:2)}(conv_B)
        unpool_B = MaxUnpoolingLayer  {(2:2), stride=(2:2)}(pool_B, conv_B)
        deconv_B = DeconvLayer        {cMap1, (5:5), cMap2, lowerPad=(2:2:0), upperPad=(2:2:0)}(unpool_B)
        unpool_A = MaxUnpoolingLayer  {(2:2), stride=(2:2)}(deconv_B, conv_A)
        deconv_A = DeconvLayer        {inputDim, (5:5), cMap1, lowerPad=(2:2:0), upperPad=(2:2:0)}(unpool_A)
    }.deconv_A

Pokud chcete vizualizovat výsledky, které je potřeba nahradit z.pool1 před jeho spuštěním z.pool_B07_Deconvolution_Visualizer.py , aby se vyřešil správný název uzlu pro výstup kodéru. Pokud chcete prozkoumat všechny názvy uzlů v modelu, jednoduše odkomentujte print_all_node_names(model_file) skript Pythonu.