Udostępnij za pośrednictwem


Automatyczne kodowanie obrazów przy użyciu deconvolution i unpooling

Spis treści

Podsumowanie

image

W przykładzie Image\GettingStarted\07_Deconvolution_PY.py pokazano , jak używać funkcji Deconvolution i Unpooling w celu wygenerowania prostego kodera automatycznego obrazu (07_Deconvolution_BS.cntk jest odpowiednią wersją języka BrainScript). Używa zestawu danych MNIST, który ma rozdzielczość 28x28x1, koduje go do reprezentacji 7x7x1 przy użyciu konwolucji i buforowania i dekodowania do oryginalnej rozdzielczości. Kryterium trenowania to błąd główny średniokwadratowy (RMSE). Na powyższej ilustracji przedstawiono wizualizacje oryginalnego obrazu, zakodowanego obrazu i zdekodowanego obrazu dla pierwszych pięciu obrazów zestawu testowego MNIST.

Konfigurowanie

Aby uruchomić przykład, potrzebny jest zestaw danych MNIST. Dane można pobrać, uruchamiając następujące polecenie z Examples\Image\DataSets\MNIST folderu :

python install_mnist.py

Uruchamianie przykładu

Przykład znajduje się w folderze Examples\Image\GettingStarted . Aby uruchomić ten przykład, użyj następującego polecenia, aby uruchomić wersję języka Python (ze środowiska CNTK języka Python):

python 07_Deconvolution_PY.py

lub to polecenie dla wersji BrainScript:

cntk configFile=07_Deconvolution_BS.cntk

Wartości RMSE do trenowania i testowania to odpowiednio 0,225 i 0,223. Aby zwizualizować zakodowane i zdekodowane obrazy, uruchom następujące polecenie:

python 07_Deconvolution_Visualizer.py

Ustaw use_brain_script_model=True dla modelu BrainScript i False dla modelu języka Python. Wizualizacje będą przechowywane w folderze Output w obszarze Examples\Image\GettingStarted wraz z tekstową reprezentacją kodera i danymi wyjściowymi dekodera.

Szczegóły techniczne

Poniżej znajduje się definicja modelu prostego kodera automatycznego obrazu w języku BrainScript (w przypadku pełnego pliku konfiguracji zobacz 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

Odpowiadająca definicja modelu w pliku 07_Deconvolution_PY.py to

    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)
    

W tym miejscu opisano wersję języka BrainScript. Wersja języka Python jest analogiczna. Model najpierw stosuje element ConvolutionalLayer z głębokością cMap=1 funkcji wejściowych, a następnie aktywacją reLU, a następnie używa elementu MaxPoolingLayer z kształtem filtru (4:4)i krokiem . Powoduje to zakodowany tensor o rozmiarze 7x7x1. Następnie używa elementu MaxUnpoolingLayer i deconvLayer z odpowiednimi kształtami filtru, aby zdekodować go z powrotem do oryginalnej rozdzielczości.

Część dekodera kompresuje oryginalne 784 liczby (28x28) do 49 (7x7), współczynnik .16 Korzystanie tylko z 1 głębokości elementu ConvolutionalLayer ma przewagę nad tym, że wyniki kodera można wizualizować w zrozumiały sposób (zobacz rysunek w górnej części tej strony). Można zwiększyć liczbę filtrów splotowych, np. aby cMap=3 mieć mniej kompresji i, miejmy nadzieję, lepsze wyniki dekodowania. W tym przykładzie elementy RMSE do trenowania i testowania są ograniczone do wartości 0.196. Innym sposobem zmniejszenia kompresji jest użycie mniejszego kształtu filtru i kroku dla warstwy buforowania. Użycie (2:2) zarówno w przypadku buforowania, jak i buforowania daje zakodowany tensor rozmiaru 14x14x1 i zmniejsza w tym przykładzie elementy RMSE do 0.136 trenowania i 0.131 testowania. Na poniższej ilustracji przedstawiono wizualizację oryginalnego obrazu i zdekodowanego obrazu dla pierwszych pięciu obrazów zestawu testowego MNIST dla trzech omówionych ustawień.

image

Dekonwolucja i anulowanie buforowania

Przyjrzyjmy się nieco bliżej maxUnpoolingLayer i DeconvLayer.

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

Element MaxPoolingLayer wymaga dwóch danych wejściowych, które są danymi wyjściowymi odpowiedniej warstwy buforowania (pool1 w tym przypadku) i danymi wejściowymi odpowiedniej warstwy buforowania (conv1 w tym przypadku). conv1program jest wymagany w CNTK w celu określenia celu operacji unpooling, ponieważ CNTK nie przechowuje tak zwanych zmiennych przełącznika (zobacz tutaj, aby uzyskać szczegółowe informacje).

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

Pierwszy parametr deconvLayer to głębokość woluminu wyjściowego, drugi to kształt jądra (width:height), a trzeci to głębokość woluminu wejściowego. Parametry wypełnienia muszą być ustawione zgodnie z kształtem jądra, aby osiągnąć żądaną szerokość i wysokość tensor wyjściowy (28x28 w tym przypadku). Aby uzyskać więcej informacji na temat elementu DeconvLayer, zobacz stronę Informacje o warstwie.

Koder automatyczny wielowarstwowy

W celu uzyskania bardziej złożonego kodera automatycznego można stosować więcej warstw conv/Deconv i Pool/Unpool. Poniżej przedstawiono przykład z dwoma warstwami każdego typu, których można użyć w 07_Deconvolution_BS.cntk programie (po prostu zastąp model w pliku):

    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

Aby zwizualizować wyniki, które należy zastąpić z.pool1z.pool_B07_Deconvolution_Visualizer.py , przed uruchomieniem go, aby adresował poprawną nazwę węzła dla danych wyjściowych kodera. Aby zbadać wszystkie nazwy węzłów w modelu, po prostu usuń znaczniki print_all_node_names(model_file) komentarza w skryscie języka Python.