Как подобрать параметр функции tenorflow (python) - PullRequest
0 голосов
/ 27 июня 2018

https://github.com/davidsandberg/facenet/blob/master/src/align/detect_face.py

Пожалуйста, обратитесь к приведенному выше коду Python.

Я обнаружил, что прототип класса Network функция conv НЕ МОЖЕТ совпадать с вызывающей его частью, как

@layer
def conv(self,
         inp,
         k_h,
         k_w,
         c_o,
         s_h,
         s_w,
         name,
         relu=True,
         padding='SAME',
         group=1,
         biased=True):

и вызов абонента

class PNet(Network):
def setup(self):
    (self.feed('data') #pylint: disable=no-value-for-parameter, no-member
         .conv(3, 3, 10, 1, 1, padding='VALID', relu=False, name='conv1')
         .prelu(name='PReLU1')
         .max_pool(2, 2, 2, 2, name='pool1')
         .conv(3, 3, 16, 1, 1, padding='VALID', relu=False, name='conv2')
         .prelu(name='PReLU2')
         .conv(3, 3, 32, 1, 1, padding='VALID', relu=False, name='conv3')
         .prelu(name='PReLU3')
         .conv(1, 1, 2, 1, 1, relu=False, name='conv4-1')
         .softmax(3,name='prob1'))

    (self.feed('PReLU3') #pylint: disable=no-value-for-parameter
         .conv(1, 1, 4, 1, 1, relu=False, name='conv4-2'))

Обратите внимание, что

  1. самостоятельно
  2. inp -> откуда он взялся?
  3. ....

Я знаю, что себя можно игнорировать; вх, k_h, k_w, c_o, S_H, s_w, может совпадать с позицией, например: 3, 3, 10, 1, 1 а остальные параметры назначаются по имени.

Тем не менее, я не могу понять, откуда взялся ввод?

Это сильно противоречит моему знакомому языку программирования C & C ++ ..

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

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Вы действительно правы, заметив, что хотя сигнатура функции принимает в качестве первого аргумента входной слой inp, она не передается при вызове функции.

Этот трюк достигается с помощью функционального декоратора @layer, который помещается непосредственно перед определением функции. Вот определение layer декоратора:

def layer(op):
    """Decorator for composable network layers."""

    def layer_decorated(self, *args, **kwargs):
        # Automatically set a name if not provided.
        name = kwargs.setdefault('name', self.get_unique_name(op.__name__))
        # Figure out the layer inputs.
        if len(self.terminals) == 0:
            raise RuntimeError('No input variables found for layer %s.' % name)
        elif len(self.terminals) == 1:
            layer_input = self.terminals[0]
        else:
            layer_input = list(self.terminals)
        # Perform the operation and get the output.
        # [!] Here it passes the `inp` parameter, and all the other ones
        layer_output = op(self, layer_input, *args, **kwargs)
        # Add to layer LUT.
        self.layers[name] = layer_output
        # This output is now the input for the next layer.
        self.feed(layer_output)
        # Return self for chained calls.
        return self

return layer_decorated

Он принимает в качестве входных данных функцию / метод через параметр op и возвращает еще один, layer_decorated, который заменит исходное определение op. Итак PNet.conv = layer(Pnet.conv). Если вы посмотрите на определение layer_decorated, вы увидите, что оно по существу устанавливает первый аргумент функции op, а именно layer_input (строка с [!]). Он также ведет некоторую бухгалтерию, чтобы узнать, какой слой использовать в качестве входных данных, основываясь на его имени.

Для упрощения, это позволяет программисту использовать цепочечные вызовы методов без повторения. Это преобразует это:

 x = self.feed('data') #pylint: disable=no-value-for-parameter, no-member
 x = self.conv(x, 3, 3, 10, 1, 1, padding='VALID', relu=False, name='conv1')
 x = self.prelu(x, name='PReLU1')
 x = self.max_pool(x, 2, 2, 2, 2, name='pool1')

в это:

x = (self.feed('data') #pylint: disable=no-value-for-parameter, no-member
     .conv(3, 3, 10, 1, 1, padding='VALID', relu=False, name='conv1')
     .prelu(name='PReLU1')
     .max_pool(2, 2, 2, 2, name='pool1')
 )
0 голосов
/ 27 июня 2018

Pnet - это сеть, которая выполняет множество сверток. Вы можете передать изображение на входной слой, и оно выполнит много сверток с ним. Имя входного слоя - «данные». Входной слой - это тензор, который принимает изображение.

data = tf.placeholder(tf.float32, (None,None,None,3), 'input')
pnet = PNet({'data':data})

Рассмотрим

out = pnet(img_y)

img_y помещается на слой данных Pnet,

, который подается на слой свертки.

.conv(3, 3, 10, 1, 1, padding='VALID', relu=False, name='conv1')

k_h (высота ядра) = 3

k_w (ширина ядра) = 3

c_o (количество фильтров) = 10

s_h (высота шага) = 1

s_w (ширина шага) = 1

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

применяются prelu и max pool, затем выход подается как вход следующего слоя свертки.

.conv(3, 3, 16, 1, 1, padding='VALID', relu=False, name='conv2')

и т. Д.

Чтобы лучше понять сверточные нейронные сети, обратитесь к CNN

...