Поделиться через


Автокодировщик изображений с помощью деконволюции и отмены вставки

Оглавление

Сводка

image

В примере Image\GettingStarted\07_Deconvolution_PY.py показано, как использовать deconvolution и unpooling для создания простого автокодировщика изображений (07_Deconvolution_BS.cntk — соответствующая версия BrainScript). Он использует набор данных MNIST, имеющий разрешение 28x28x1, кодирует его в представление 7x7x1 с использованием свертки и объединения в пул и декодирования исходного разрешения. Критерий обучения — это ошибка корневого среднего квадрата (RMSE). На рисунке выше показаны визуализации исходного изображения, закодированного изображения и декодированного изображения для первых пяти изображений тестового набора MNIST.

Настройка

Чтобы запустить пример, вам потребуется набор данных MNIST. Чтобы получить данные, выполните следующую команду из Examples\Image\DataSets\MNIST папки:

python install_mnist.py

Выполнение примера

Пример находится в папке Examples\Image\GettingStarted . Чтобы запустить этот пример, используйте следующую команду, чтобы запустить версию Python (из среды Python CNTK):

python 07_Deconvolution_PY.py

или эта команда для версии BrainScript:

cntk configFile=07_Deconvolution_BS.cntk

Значения RMSE для обучения и тестирования : 0,225 и 0,223 соответственно. Чтобы визуализировать закодированные и декодированные изображения, выполните следующую команду:

python 07_Deconvolution_Visualizer.py

Задайте use_brain_script_model=True для модели BrainScript и False для модели Python. Визуализации будут храниться в папке OutputExamples\Image\GettingStarted вместе с текстовым представлением кодировщика и выходными данными декодера.

Технические сведения

Ниже приведено определение модели для простого автокодировщика изображений в BrainScript (полный файл конфигурации см. в разделе 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

Соответствующее определение модели в файле 07_Deconvolution_PY.py

    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)
    

Здесь мы описываем версию BrainScript, Python версия аналогична. Модель сначала применяет convolutionalLayer с глубиной cMap=1 входных функций, за которым следует активация ReLU, и использует MaxPoolingLayer с фигурой фильтра и шагом (4:4). Это приводит к тензору закодированного размера 7x7x1. Затем он использует MaxUnpoolingLayer и DeconvLayer с соответствующими фигурами фильтра, чтобы декодировать его обратно в исходное разрешение.

Часть декодера сжимает исходные 784 числа (28x28) до 49 (7x7), коэффициент 16. Использование только глубины 1 для ConvolutionalLayer имеет преимущество, что результаты кодировщика можно визуализировать в понятном виде (см. рисунок в верхней части этой страницы). Можно увеличить количество сверточных фильтров, например, чтобы cMap=3 иметь меньше сжатия и, надеюсь, лучше декодировать результаты. В этом примере RMSE для обучения и тестирования сокращается до 0.196. Другим способом уменьшения сжатия является использование меньшей фигуры фильтра и шага для слоя пула. Использование (2:2) как для пула, так и для отмены пула дает закодированный тензор размера 14x14x1 и уменьшает RMSE в этом примере 0.136 для обучения и 0.131 тестирования. На рисунке ниже показана визуализация исходного изображения и декодированного изображения для первых пяти изображений тестового набора MNIST для трех рассмотренных параметров.

image

Деконволюция и отмена перепулирования

Давайте немного ближе рассмотрим MaxUnpoolingLayer и DeconvLayer.

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

MaxPoolingLayer требует двух входных данных, которые являются выходными данными соответствующего слоя пула (pool1 в данном случае) и входными данными соответствующего слоя пула (conv1 в данном случае). conv1требуется в CNTK для определения целевого объекта операции отмены переключения, так как CNTK не хранит так называемые переменные коммутатора (дополнительные сведения см. здесь).

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

Первый параметр DeconvLayer — глубина выходного тома, второй — фигура ядра (ширина:высота), а третья — глубина входного тома. Параметры заполнения должны быть заданы в соответствии с формой ядра для достижения требуемой ширины и высоты выходного тензора (в данном случае 28x28). Дополнительные сведения о DeconvLayer см. на странице "Справочник по слоям".

Многоуровневый автоматический кодировщик

Вы можете сложить больше слоев Conv/Deconv и Pool/Unpool для более сложного автоматического кодировщика. Ниже приведен пример с двумя слоями каждого типа, в которых можно использовать 07_Deconvolution_BS.cntk (просто замените модель в файле):

    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

Чтобы визуализировать результаты, которые необходимо заменить z.pool1z.pool_B07_Deconvolution_Visualizer.py , прежде чем запускать его, чтобы указать правильное имя узла для выходных данных кодировщика. Чтобы изучить все имена узлов в модели, просто раскомментируйте print_all_node_names(model_file) его в скрипте Python.