Delen via


Automatisch coderingsprogramma voor afbeeldingen met behulp van deconvolution en unpooling

Inhoudsopgave

Samenvatting

image

In het voorbeeld Image\GettingStarted\07_Deconvolution_PY.py ziet u hoe u Deconvolution en Unpooling gebruikt om een eenvoudige automatische coderingsprogramma voor afbeeldingen te genereren (07_Deconvolution_BS.cntk is de bijbehorende BrainScript-versie). Er wordt gebruikgemaakt van de MNIST-gegevensset, die een resolutie van 28x28x1 heeft, codeert deze in een 7x7x1-weergave met behulp van convolutie en pooling en decoderen naar de oorspronkelijke resolutie. Het trainingscriterium is root-mean-square error (RMSE). In de bovenstaande afbeelding ziet u visualisaties van de oorspronkelijke afbeelding, de gecodeerde afbeelding en de gedecodeerde afbeelding voor de eerste vijf afbeeldingen van de MNIST-testset.

Instellen

Als u het voorbeeld wilt uitvoeren, hebt u de MNIST-gegevensset nodig. U kunt de gegevens ophalen door de volgende opdracht uit te voeren vanuit de Examples\Image\DataSets\MNIST map:

python install_mnist.py

Het voorbeeld uitvoeren

Het voorbeeld bevindt zich in de Examples\Image\GettingStarted map. Als u dit voorbeeld wilt uitvoeren, gebruikt u de volgende opdracht om de Python-versie uit te voeren (vanuit een Python CNTK-omgeving):

python 07_Deconvolution_PY.py

of deze opdracht voor de BrainScript-versie:

cntk configFile=07_Deconvolution_BS.cntk

De RMSE-waarden voor training en testen zijn respectievelijk 0,225 en 0,223. Voer de volgende opdracht uit om de gecodeerde en gedecodeerde installatiekopieën te visualiseren:

python 07_Deconvolution_Visualizer.py

Ingesteld use_brain_script_model=True voor het BrainScript-model en False voor het Python-model. De visualisaties worden samen met een tekstweergave van de encoder en de decoderuitvoer opgeslagen in Output de map Examples\Image\GettingStarted .

Technische details

Hieronder vindt u de modeldefinitie voor de eenvoudige coderingsprogramma voor afbeeldingen in BrainScript (zie Image\GettingStarted\07_Deconvolution_BS.cntk) voor het volledige configuratiebestand.

    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

De bijbehorende modeldefinitie in 07_Deconvolution_PY.py is

    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)
    

We beschrijven hier de BrainScript-versie, de Python versie is vergelijkbaar. Het model past eerst een ConvolutionalLayer toe met een diepte van cMap=1 op de invoerfuncties, gevolgd door een ReLU-activering en het gebruik van een MaxPoolingLayer met een filtershape en stride van (4:4). Dit resulteert in een gecodeerde tensor van grootte 7x7x1. Vervolgens wordt een MaxUnpoolingLayer en een DeconvLayer met de bijbehorende filtershapes gebruikt om deze terug te decoderen naar de oorspronkelijke resolutie.

Het decoderonderdeel comprimeert de oorspronkelijke 784 (28x28) getallen tot 49 (7x7), een factor van 16. Het gebruik van alleen een diepte voor 1 de ConvolutionalLayer heeft het voordeel dat de encoderresultaten op een zinvolle manier kunnen worden gevisualiseerd (zie afbeelding bovenaan deze pagina). Men kan het aantal convolutionele filters verhogen, bijvoorbeeld om cMap=3 minder compressie te hebben en, hopelijk, betere decoderingsresultaten. In dit voorbeeld wordt de RMSE voor zowel training als testen verminderd tot 0.196. Een andere manier om minder compressie te hebben, is het gebruik van een kleinere filtervorm en -stride voor de poollaag. Het gebruik (2:2) van zowel pooling als unpooling levert een gecodeerde tensor van grootte 14x14x1 op en vermindert de RMSE in dit voorbeeld voor 0.136 training en 0.131 testen. In de onderstaande afbeelding ziet u een visualisatie van de oorspronkelijke afbeelding en de gedecodeerde afbeelding voor de eerste vijf afbeeldingen van de MNIST-testset voor de drie besproken instellingen.

image

Deconvolution en Unpooling

Laten we een beetje dichter bij de MaxUnpoolingLayer en de DeconvLayer kijken.

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

De MaxPoolingLayer vereist twee invoerwaarden, die de uitvoer zijn van de bijbehorende poollaag (pool1 in dit geval) en de invoer van de bijbehorende poollaag (conv1 in dit geval). conv1is vereist in CNTK om het doel van de unpooling-bewerking te bepalen, omdat CNTK geen zogenaamde switchvariabelen opslaat (zie hier voor meer informatie).

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

De eerste parameter van de DeconvLayer is de diepte van het uitvoervolume, de tweede is de kernelshape (breedte:hoogte) en de derde is de diepte van het invoervolume. De opvullingsparameters moeten worden ingesteld volgens de kernelshape om de gewenste breedte en hoogte van de uitvoertenor (in dit geval 28x28) te bereiken. Zie de pagina Laagreferentie voor meer informatie over de DeconvLayer.

Automatische coderingsprogramma met meerdere lagen

U kunt meer lagen van Conv/Deconv en Pool/Unpool stapelen voor een complexere automatische encoder. Hier volgt een voorbeeld met twee lagen van elk type waarin u kunt gebruiken 07_Deconvolution_BS.cntk (vervang het model in het bestand):

    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

Als u de resultaten wilt visualiseren die u moet vervangen z.pool1z.pool_B07_Deconvolution_Visualizer.py voordat u deze uitvoert om de juiste knooppuntnaam voor de encoder-uitvoer te adresseren. Als u alle knooppuntnamen in het model wilt onderzoeken, hoeft u alleen de opmerkingen print_all_node_names(model_file) in het script Python uit te schakelen.