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/