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

请参考上面的python代码。

我发现类网络函数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'))


注意



inp->它从哪里来?
....


我知道自我可以忽略。 inp,
         k_h,
         k_w,
         c_o,
         s_h,
         s_w,
可以与位置匹配,例如:3、3、10、1、1
其他参数按名称分配。

但是,我不知道inp的来源吗?

它与我熟悉的编程语言C&C ++矛盾很多。

有人可以帮忙解释一下吗?

提前致谢。

最佳答案

您确实应该注意到,尽管函数签名将输入层inp作为其第一个参数,但是在调用函数时不会传递它。

此技巧是通过将function decorator @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')
 )

关于python - 如何匹配tensorflow(python)函数的参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51061685/

10-12 21:26