Понимание формы вывода keras Conv2DTranspose - PullRequest
0 голосов
/ 18 февраля 2019

Мне трудно понять форму вывода keras.layers.Conv2DTranspose

Вот прототип:

keras.layers.Conv2DTranspose(
    filters,
    kernel_size,
    strides=(1, 1),
    padding='valid',
    output_padding=None,
    data_format=None,
    dilation_rate=(1, 1),
    activation=None,
    use_bias=True,
    kernel_initializer='glorot_uniform',
    bias_initializer='zeros',
    kernel_regularizer=None,
    bias_regularizer=None,
    activity_regularizer=None,
    kernel_constraint=None,
    bias_constraint=None
)

В документации (https://keras.io/layers/convolutional/), Iчитать:

If output_padding is set to None (default), the output shape is inferred.

В коде (https://github.com/keras-team/keras/blob/master/keras/layers/convolutional.py), Я читал:

out_height = conv_utils.deconv_length(height,
                                      stride_h, kernel_h,
                                      self.padding,
                                      out_pad_h,
                                      self.dilation_rate[0])
out_width = conv_utils.deconv_length(width,
                                     stride_w, kernel_w,
                                     self.padding,
                                     out_pad_w,
                                     self.dilation_rate[1])
if self.data_format == 'channels_first':
    output_shape = (batch_size, self.filters, out_height, out_width)
else:
    output_shape = (batch_size, out_height, out_width, self.filters)

и (https://github.com/keras-team/keras/blob/master/keras/utils/conv_utils.py):

def deconv_length(dim_size, stride_size, kernel_size, padding, output_padding, dilation=1):

    """Determines output length of a transposed convolution given input length.
    # Arguments
        dim_size: Integer, the input length.
        stride_size: Integer, the stride along the dimension of `dim_size`.
        kernel_size: Integer, the kernel size along the dimension of `dim_size`.
        padding: One of `"same"`, `"valid"`, `"full"`.
        output_padding: Integer, amount of padding along the output dimension, can be set to `None` in which case the output length is inferred.
        dilation: dilation rate, integer.
    # Returns
        The output length (integer).
    """

    assert padding in {'same', 'valid', 'full'}
    if dim_size is None:
        return None

    # Get the dilated kernel size
    kernel_size = kernel_size + (kernel_size - 1) * (dilation - 1)

    # Infer length if output padding is None, else compute the exact length
    if output_padding is None:
        if padding == 'valid':
            dim_size = dim_size * stride_size + max(kernel_size - stride_size, 0)
        elif padding == 'full':
            dim_size = dim_size * stride_size - (stride_size + kernel_size - 2)
        elif padding == 'same':
            dim_size = dim_size * stride_size
    else:
        if padding == 'same':
            pad = kernel_size // 2
        elif padding == 'valid':
            pad = 0
        elif padding == 'full':
            pad = kernel_size - 1

        dim_size = ((dim_size - 1) * stride_size + kernel_size - 2 * pad + output_padding)

    return dim_size

Я понимаю, чтоConv2DTranspose является своего рода Conv2D, но в обратном порядке.

Поскольку применение Conv2D с kernel_size = (3, 3), шагами = (10, 10) и padding = "same" к изображению 200x200 приведет к 20x20image, я предполагаю, что применение Conv2DTranspose с kernel_size = (3, 3), strides = (10, 10) и padding = "same" к изображению 20x20 приведет к выводу изображения 200x200.

Кроме того, применениеConv2D с kernel_size = (3, 3), strides = (10, 10) и padding = "same" для изображения 195x195 также выведет изображение 20x20.

Итак, я понимаю, чтоНеоднозначность выходной формы при применении Conv2DTranspose с kernel_size = (3, 3), strides = (10, 10) и padding = "same«(пользователь может захотеть, чтобы выходные данные были 195x195, или 200x200, или многими другими совместимыми формами.)

Я предполагаю, что« выходная форма выведена. »означает, что выходная форма по умолчанию вычисляется в соответствии с параметрамислой, и я предполагаю, что есть механизм для задания формы вывода, отличной от значения по умолчанию, если необходимо.

При этом я не очень понимаю

  • значение параметра "output_padding"

  • взаимодействия между параметрами "padding" и "output_padding"

  • различные формулы в функцииkeras.conv_utils.deconv_length

Может кто-нибудь объяснить это?

Большое спасибо,

Julien

Ответы [ 2 ]

0 голосов
/ 08 июня 2019

Outpadding в Conv2DTranspose - это то, что меня беспокоит при разработке автоэнкодера.

Предположим, что шаг всегда равен 1. Вдоль пути кодера для каждого слоя свертки я выбрал padding = 'valid', что означает, что если мое входное изображение имеет формат HXW, а фильтр имеет размер mXn, выходнойуровень будет (H- (m-1)) X (W- (n-1)).

В соответствующем слое Con2DTranspose вдоль пути декодера, если я использую Theano, чтобы возобновитьразмер входного файла соответствующего ему Con2D, я должен выбрать padding = 'full' и out_padding = None или 0 (без разницы), что означает, что размер входного сигнала будет увеличен на [m-1, n-1] вокруг него, чтоесть, (m-1) / 2 для верха и низа и (n-1) / 2 для левого и правого.

Если я использую tenorflow, мне нужно будет выбрать padding = 'same' и out_padding = 2 * ((filter_size-1) // 2), я думаю, что это предполагаемое поведение Keras.

Если значение шага не равно 1, вам придется тщательно рассчитать, сколько выходных отступов нужно добавить.

В Conv2D out_size = floor (in_size + 2 * padding_size-filter_size) / stride + 1)

Если мы выберем padding = 'same', Keras автоматически установит padding = (filter_size-1) / 2;в то время как если мы выберем 'valid', padding_size будет установлен в 0, что является условием любых сверток ND.

И наоборот, в Con2DTranspose out_size = (in_size-1) * stride + filter_size-2 * padding_size

где padding_size относится к тому, сколько пикселей будет фактически дополнено, вызванных опцией 'padding' и out_padding вместе.Исходя из вышеизложенного, в тензорном потоке нет «полной» опции, нам придется использовать out_padding для возобновления размера ввода соответствующего ему Con2D.

Не могли бы вы попробовать и посмотреть, работает ли он правильно, и позвольте мнезнаете, пожалуйста?

Итак, в общем, я думаю, что out_padding используется для поддержки различных бэкэндов.

0 голосов
/ 26 февраля 2019

Возможно, я нашел (частичный) ответ.

Я нашел его в документации по Pytorch, которая мне кажется намного более понятной, чем документация Keras по этой теме.

При применении Conv2Dс шагом больше 1 к изображениям, размеры которых близки, мы получаем выходные изображения с такими же размерами.

Например, когда применяется Conv2D с размером ядра 3x3, шагом 7x7 и отступом "то же самое",следующие размеры изображения

22x22, 23x23, ..., 28x28, 22x28, 28x22, 27x24 и т. д. (7x7 = 49 комбинаций)

будет ALL дает выходное измерение 4x4.

Это потому, что output_dimension = потолок (input_dimension / stride).

Как следствие, при применении Conv2DTranspose с размером ядра 3x3, шага7x7 и заполнение «то же самое», есть неоднозначность в отношении выходного измерения.

Любой из 49 возможных выходных измерений будет правильным.

Параметр output_paddinbg является способомразрешить неоднозначность, явно выбрав выходное измерение.

В моем примере минимальный размер вывода составляет 22x22, а output_padding предоставляет количество строк (от 0 до 6), которые нужно добавить в нижней части выходного изображения.и количество столбцов (от 0 до 6), добавляемых справа от выходного изображения.

Таким образом, я могу получить output_dimensions = 24x25, если я использую outout_padding = (2, 3)

Однако я все еще не понимаю, какую логику использует keras для выбора определенного размера выходного изображения, если не указан output_padding (когда он «выводит» форму вывода)

Несколько указателей:

https://pytorch.org/docs/stable/nn.html#torch.nn.ConvTranspose2d https://discuss.pytorch.org/t/the-output-size-of-convtranspose2d-differs-from-the-expected-output-size/1876/5 https://discuss.pytorch.org/t/question-about-the-output-padding-in-nn-convtrasnpose2d/19740 https://discuss.pytorch.org/t/what-does-output-padding-exactly-do-in-convtranspose2d/2688

Итак, чтобы ответить на мои собственные вопросы:

  • значениеПараметр «output_padding»: см. выше
  • взаимодействия между параметрами «padding» и «output_padding»: эти параметры не зависят
  • от различных формул в функции keras.conv_utils.deconv_length
    • На данный момент я не понимаю часть, когда output_padding имеет значение None;
    • Я игнорирую случай, когда заполнение == 'full' (не поддерживается Conv2DTranspose);
    • Формула для заполнения == 'valid' кажется правильной (может быть вычислена путем обращения формулы Conv2D)
    • Формула для заполнения == 'same' мне кажется неверной, если kernel_size является четным.(На самом деле, keras дает сбой при попытке создать слой Conv2DTranspose с input_dimension = 5x5, kernel_size = 2x2, stride = 7x7 и padding = 'same'. Мне кажется, что в keras есть ошибка, я начнудругая тема для этой темы ...)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...