Почему отделимая свертка, реализуемая тензорным потоком, медленнее, чем обычная свертка? - PullRequest
0 голосов
/ 18 января 2019

Я протестировал скорость separable_conv2d и normal conv2d, реализованную в TF, кажется, что depthwise_conv2d быстрее, чем normal conv2d, но производительность dw_conv2d, очевидно, плохая.

Сепарабельный_конв2д, упомянутый в MobileNet, его FLOPs составляет 1/9 от нормального конва, когда kernel_size=3, но, учитывая Memory Access Cost, сепарабельный не может быть в 9 раз быстрее обычного, но в моем эксперименте, отделяемый слишком медленный.

Я моделирую эксперимент следующим образом: separable_conv2d слишком медленный . В этом эксперименте separable_conv2d кажется более быстрым, чем нормальный, когда deep_multiply = 1, но когда я использую tf.nn, чтобы реализовать его следующим образом:

IMAGE_SIZE= 512
REPEAT = 100
KERNEL_SIZE = 3
data_format = 'NCHW'
#CHANNELS_BATCH_SIZE =  2048 # channe# ls * batch_size
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"

def normal_layers(inputs, nfilter, name=''):
    with tf.variable_scope(name, reuse=tf.AUTO_REUSE):
         shape = inputs.shape.as_list()
         in_channels = shape[1]
         filter = tf.get_variable(initializer=tf.initializers.random_normal,
                                  shape=[KERNEL_SIZE, KERNEL_SIZE, 
                                   in_channels, nfilter], name='weight')
         conv = tf.nn.conv2d(input= inputs, filter=filter, strides= 
                           [1,1,1,1],padding='SAME',data_format=data_format, 
                           name='conv')
    return conv
def sep_layers(inputs, nfilter, name=''):
    with tf.variable_scope(name, reuse=tf.AUTO_REUSE):
         shape= inputs.shape.as_list()
         in_channels = shape[1]
         dw_filter=
         tf.get_variable(initializer=tf.initializers.random_normal,
                         shape=[KERNEL_SIZE, KERNEL_SIZE, 
                         in_channels, 1], name='dw_weight')

         pw_filter = 
         tf.get_variable(initializer=tf.initializers.random_normal,
                                shape=[1,1,in_channels, nfilter], 
                         name='pw_weight')          
         conv = tf.nn.depthwise_conv2d_native(input=inputs,
                                              filter=dw_filter,
                                              strides=[1,1,1,1],
                                              padding='SAME',
                                              data_format=data_format)
         conv = tf.nn.conv2d(input=conv,
                             filter=pw_filter,
                             strides=[1,1,1,1],
                             padding='SAME',
                             data_format=data_format)
    return conv  

Каждый слой запускается в 100 times,
отличается от ссылки, я устанавливаю batch_size в качестве постоянной 10,
и channels is in [32, 64, 128],
входные данные - [batch_size, channel, img_size, img_size] и duration из них следующим образом:

Channels: 32
Normal Conv 0.7769527435302734s, Sep Conv 1.4197885990142822s
Channels: 64
Normal Conv 0.8963277339935303s, Sep Conv 1.5703468322753906s
Channels: 128
Normal Conv 0.9741833209991455s, Sep Conv 1.665834665298462s 

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

А при установке batch_size * channels в качестве постоянной
Форма входов: [CHANNELS_BATCH_SIZE // каналы, каналы, размер, размер]

Channels: 32
Normal Conv 0.871959924697876s, Sep Conv 1.569300651550293s
Channels: 64
Normal Conv 0.909860372543335s, Sep Conv 1.604109525680542s
Channels: 128
Normal Conv 0.9196009635925293s, Sep Conv 1.6144189834594727s

Что меня смущает, так это то, что результат отличается от результата по ссылке выше: временные затраты sep_conv2d не имеют очевидных изменений.

Мои вопросы:

  1. Что отличает мою ссылку от эксперимента выше?
  2. Я новичок , так что, в моем коде что-то не так для реализации separable_conv2d?
  3. Как реализовать separable_conv2d может быть быстрее обычного в TF или в Pytorch ?

Буду признателен за любую помощь. Спасибо заранее.

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