Automatisk avkodare för bilder med delegering och avpoolning
Innehållsförteckning
Sammanfattning
Exemplet Image\GettingStarted\07_Deconvolution_PY.py visar hur du använder Deconvolution och Unpooling för att generera en enkel automatisk avbildningskodare (07_Deconvolution_BS.cntk är motsvarande BrainScript-version). Den använder MNIST-datauppsättningen, som har en upplösning på 28x28x1, kodar den till en 7x7x1-representation med hjälp av decentralisering och poolning och avkodning till den ursprungliga upplösningen. Träningskriteriet är RMSE (root-mean-square error). Bilden ovan visar visualiseringar av den ursprungliga bilden, den kodade bilden och den avkodade bilden för de fem första bilderna i MNIST-testuppsättningen.
Installation
Om du vill köra exemplet behöver du MNIST-datauppsättningen. Du kan hämta data genom att köra följande kommando från Examples\Image\DataSets\MNIST
mappen :
python install_mnist.py
Kör exemplet
Exemplet finns i Examples\Image\GettingStarted
mappen . Om du vill köra det här exemplet använder du följande kommando för att köra Python version (från en Python CNTK miljö):
python 07_Deconvolution_PY.py
eller det här kommandot för BrainScript-versionen:
cntk configFile=07_Deconvolution_BS.cntk
RMSE-värdena för träning och testning är 0,225 respektive 0,223. Om du vill visualisera de kodade och avkodade bilderna kör du följande kommando:
python 07_Deconvolution_Visualizer.py
Ange use_brain_script_model=True
för BrainScript-modellen och False
för den Python modellen.
Visualiseringarna lagras i Output
mappen under Examples\Image\GettingStarted
tillsammans med en textrepresentation av kodaren och avkodarens utdata.
Teknisk information
Nedan visas modelldefinitionen för den enkla autokodaren för bilder i BrainScript (för den fullständiga konfigurationsfilen se Image\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
Motsvarande modelldefinition i 07_Deconvolution_PY.py är
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)
Vi beskriver BrainScript-versionen här, den Python versionen är analog. Modellen tillämpar först en ConvolutionalLayer med djupet cMap=1
på indatafunktionerna följt av en ReLU-aktivering och använder en MaxPoolingLayer med en filterform och steg av (4:4)
. Detta resulterar i en kodad tensor av storleken 7x7x1
. Den använder sedan en MaxUnpoolingLayer och en DeconvLayer med motsvarande filterformer för att avkoda den tillbaka till den ursprungliga upplösningen.
Avkodardelen komprimerar de ursprungliga 784
(28x28) talen till 49
(7x7), en faktor av 16
. Om du bara använder djupet 1
för för ConvolutionalLayer kan kodarens resultat visualiseras på ett meningsfullt sätt (se bilden överst på den här sidan). Man kan öka antalet faltningsfilter, t.ex. för att cMap=3
få mindre komprimering och förhoppningsvis bättre avkodningsresultat. I det här exemplet reduceras RMSE för både träning och testning till 0.196
. Ett annat sätt att få mindre komprimering är att använda en mindre filterform och steg för poolningsskiktet. Användning för (2:2)
både poolning och avpoolning ger en kodad tensor av storlek 14x14x1
och minskar RMSE i det här exemplet till 0.136
för träning och 0.131
testning. Bilden nedan visar visualisering av den ursprungliga bilden och den avkodade bilden för de första fem bilderna i MNIST-testuppsättningen för de tre diskuterade inställningarna.
Decentralisering och avpoolning
Låt oss titta lite närmare på MaxUnpoolingLayer och DeconvLayer.
MaxUnpoolingLayer {(4:4), stride=(4:4)}(pool1, conv1)
MaxPoolingLayer kräver två indata, som är utdata från motsvarande poollager (pool1
i det här fallet) och indata för motsvarande poollager (conv1
i det här fallet). conv1
krävs i CNTK för att fastställa målet för avpoolningsåtgärden, eftersom CNTK inte lagrar så kallade växelvariabler (se här för mer information).
DeconvLayer {1, (5:5), cMap, lowerPad=(2:2:0), upperPad=(2:2:0)}
Den första parametern i DeconvLayer är djupet på utdatavolymen, den andra är kernelformen (width:height) och den tredje är djupet på indatavolymen. Utfyllnadsparametrarna måste anges i enlighet med kernelformen för att uppnå önskad bredd och höjd för utdata tensorn (i det här fallet 28x28). Mer information om DeconvLayer finns på sidan Lagerreferens.
Automatisk kodare med flera lager
Du kan stapla fler lager av Conv/Deconv och Pool/Unpool för en mer komplex automatisk kodare. Följande är ett exempel med två lager av varje typ som du kan använda i 07_Deconvolution_BS.cntk
(ersätt helt enkelt modellen i filen):
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
För att visualisera resultaten måste du ersätta z.pool1
med z.pool_B
i 07_Deconvolution_Visualizer.py
innan du kör det för att adressera rätt nodnamn för kodarens utdata. Om du vill undersöka alla nodnamn i modellen tar du helt enkelt bort kommentaren print_all_node_names(model_file)
i Python skriptet.