Понимание tf.nn.depthwise_conv2d - PullRequest
0 голосов
/ 17 марта 2020

С https://www.tensorflow.org/api_docs/python/tf/nn/depthwise_conv2d

С учетом четырехмерного входного тензора (форматы данных «NHW C» или «NCHW») и тензора фильтра формы [filter_height, filter_width, in_channels, channel_multiplier], содержащий сверточные фильтры in_channels глубиной 1, deepwise_conv2d применяет разные фильтры к каждому входному каналу (расширяется от 1 канала до каналов channel_multiplier для каждого), затем объединяет результаты вместе. Выход имеет каналы in_channels * channel_multiplier

  1. Что означает "расширение от 1 канала до каналов channel_multiplier для каждого"?
  2. Возможно ли иметь out_channels
  3. Можно ли разделить входной тензор на группы, как в Pytorch https://pytorch.org/docs/stable/nn.html#conv2d?

Пример:

import tensorflow as tf
import numpy as np
import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '1'
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)

np.random.seed(2020)

print('tf.__version__', tf.__version__)

def get_data_batch():
    bs = 2
    h = 3
    w = 3
    c = 4

    x_np = np.random.rand(bs, h, w, c)
    x_np = x_np.astype(np.float32)
    print('x_np.shape', x_np.shape)

    return x_np


def run_conv_dw():
    print('='*60)
    x_np = get_data_batch()
    in_channels = x_np.shape[-1]
    kernel_size = 3
    channel_multiplier = 1
    with tf.Session() as sess:
        x_tf = tf.convert_to_tensor(x_np)
        filter = tf.get_variable('w1', [kernel_size, kernel_size, in_channels, channel_multiplier],
                                 initializer=tf.contrib.layers.xavier_initializer())
        z_tf = tf.nn.depthwise_conv2d(x_tf, filter=filter, strides=[1, 1, 1, 1], padding='SAME')

        sess.run(tf.global_variables_initializer())
        z_np = sess.run(fetches=[z_tf], feed_dict={x_tf: x_np})[0]
        print('z_np.shape', z_np.shape)


if '__main__' == __name__:
    run_conv_dw()

Множитель канала не может быть плавающим:

Если channel_multiplier = 1:

x_np.shape (2, 3, 3, 4)
z_np.shape (2, 3, 3, 4)

Если channel_multiplier = 2:

x_np.shape (2, 3, 3, 4)
z_np.shape (2, 3, 3, 8)

1 Ответ

1 голос
/ 17 марта 2020

В терминах pytorch:

  1. всегда один входной канал на группу, выходные каналы 'channel_multiplier' на группу;
  2. не за один шаг;
  3. см. 1

Я вижу способ эмулировать несколько входных каналов на группу. Для двоих сделайте depthwise_conv2d, затем разделите полученный Тензор как колоду карт пополам, а затем суммируйте полученные пополам пополам (перед relu et c.). Обратите внимание, что входной номер канала i будет сгруппирован с i+inputs/2 единица.


РЕДАКТИРОВАТЬ: уловка выше полезна для небольших групп, для больших просто разделить входной тензор для N частей, где N - счетчик групп, сделать conv2d с каждой независимо, затем объединить результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...