【问题标题】:How to match up tensorflow(python) function's parameter如何匹配张量流(python)函数的参数
【发布时间】:2018-06-27 11:29:46
【问题描述】:

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):

& 调用 conv by

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. ....

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

但是,我无法弄清楚 inp 的来源?

这和我熟悉的编程语言 C & C++ 有很大的矛盾..

谁能帮忙解释一下?

提前致谢。

【问题讨论】:

  • Inp 是从上一层输入的。

标签: python tensorflow convolutional-neural-network function-parameter


【解决方案1】:

您确实正确地注意到,虽然函数签名将输入层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')
 )

【讨论】:

  • @changjc 在 stackOverflow 上的问题在得到接受的答案时被认为已解决。这表明其他人都很好地解决了这个问题,并允许他们转向未回答的问题。因此,如果它解决了您的问题,请考虑将其标记为已接受的答案(勾选绿色标记)。也可以考虑为您以前的问题这样做
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-04
    相关资源
    最近更新 更多