关于python:当调用类似于activation(“relu”)(x)的类时,它实际上是如何工作的?

When calling a class like Activation('relu')(X), how does it actually work?

当我学习keras时,我总是看到类似Activation('relu')(X)的语法。我查看了源代码,发现Activation是一个类,所以我不理解像Class(...)(...)这样的语法是如何工作的。

下面是它的一个示例和用例:A = Add()([A1, A2])


在喀拉斯岛,它比香草Python要复杂一些。我们来分析一下当您调用Activation('relu')(X)时会发生什么:

  • Activation('relu')通过调用类__init__方法来创建该类的新对象。这将创建以"relu"作为参数的对象。
  • 通过实现__call__,可以调用python中的所有对象,允许您像函数一样调用它。Activation('relu')(X)现在使用X作为参数调用该函数。
  • 但是等等,Activation并没有直接实现它,实际上它是调用Layer.__call__的基类,它做了一些检查,比如形状匹配等。
  • 然后Layer.__call__实际调用self.call(X),然后调用Activation.call方法,该方法将激活应用于张量并返回结果。
  • 希望这澄清了这一行代码,当创建其他层并用函数API调用它们时,会发生类似的过程。


    在Python中,类可能具有__call__方法,这意味着类实例是可调用的。

    所以,打电话给Activation(...)(...)完全可以。

    第一步创建Activation的实例,第二步使用一些参数调用该实例。

    这和做一样:

    1
    2
    activationLayer = Activation('relu')
    outputTensor = activationLayer(inputTensor) #where inputTensor == X in your example

    这样,您还可以用不同的输入张量重用相同的层:

    1
    2
    3
    4
    activationLayer = Activation('relu')

    out1 = activationLayer(X1)
    out2 = activationLayer(X2)

    这与标准的激活层没有很大的区别,但是对于某些经过训练的层,它开始变得非常有趣。

    示例:您希望使用经过标准培训的VGG16模型来处理两个图像,然后连接这些图像:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    vgg16 = keras.applications.vgg16(......)

    img1 = Input(imageShape1)
    img2 = Input(imageShape2)

    out1 = vgg16(img1) #a model is also a layer by inheritance
    out2 = vgg16(img2)

    ... continue the model ....


    是否需要new关键字?python不使用该关键字,而是使用"函数表示法":

    Class instantiation uses function notation. Just pretend that the class
    object is a parameterless function that returns a new instance of the
    class. For example (assuming the above class):

    1
    x = MyClass()