Automatyczne kodowanie obrazów przy użyciu deconvolution i unpooling
Spis treści
Podsumowanie
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ń.
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). conv1
program 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.pool1
z.pool_B
07_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.