function_f()(variable_v) 的含义和工作原理(函数后跟 () 中的变量)

Meaning and working of a function_f()(variable_v) ( a function followed by variable in () )

我最近开始使用 Keras,在他们的文档中,只显示了几行代码

inp = Input(shape=(2,))

hl_x = Dense(4, activation='tanh', name= 'First_Hidden_Layer_Following_Input' )(inp)

哪里

type(Input)

>> function

type(inp)

>>>tensorflow.python.framework.ops.Tensor

Input 是一个函数,inp 是一个 tensor

类型的变量

这是什么意思,它是如何工作的?

Dense(....) returns一个对象,that can be __called__(),类似于参数化函数:

def print_multiple(k):
    """Returns a function that prints 'k' times whatever you give it."""
    return lambda x: print(*(x for _ in range(k)))

print_multiple(6)("Merry")  
print_multiple(4)("Christmas")  

打印

Merry Merry Merry Merry Merry Merry
Christmas Christmas Christmas Christmas 

keras.layers.dense 是一个可调用对象 - 所以沿着:

class PrintMult:
    """Object that prints 'how_often' times whatever you give it."""
    def __init__(self, how_often):
        self.how_often = how_often

    def __call__(self, what_ever):
        print(*(what_ever for _ in range(self.how_often)))

PrintMult(5)("Yeeha")    # Yeeha Yeeha Yeeha Yeeha Yeeha

我不是 Keras 的专家,但我会尽量强调它。

首先,Keras中的所有层都是可调用对象,例如他们定义了 __call__ 方法。这是什么意思?这样的 类 可能被用作一个函数:

x = np.random.randint(0, 10, (10,10))
functor = Layer()
res = functor(x)

它本身不是 Keras 的功能,只是一般的 Python 语法。由于与函数调用相比,您的对象可能具有更长的生命周期,因此您可能会在对象内部积累一些中间数据,例如一个层可以将所有相关的梯度保留在里面。

其次,我想,但我不确定,这种方法可以解决性能问题。当您定义模型时,不会发生很多事情。实际上,你只是 link 层之间的输入和输出到定向的 graph/network...仅此而已,这在计算资源方面非常便宜,你只需定义模型的结构通过在层之间传递 inph1_x,每一层都将其注册为自己的 input/output。所有神奇而沉重的事情都会在以后发生——在 model.compile() 和实际的 training/inference 阶段。