2016-11-08 46 views
0

我看到一個Python函數調用方式Keras'教程這樣的:在Python中調用函數的意義?

from keras.layers import Input, Dense 
from keras.models import Model 

# this returns a tensor 
inputs = Input(shape=(784,)) 

# a layer instance is callable on a tensor, and returns a tensor 
x = Dense(64, activation='relu')(inputs) 

但是,我不知道的功能是什麼意思調用形式:

x = Dense(64, activation='relu')(inputs) 

爲什麼會出現「(輸入)」在功能「密集」的參數列表的括號之外?

+1

的[?什麼是「柯里」]可能的複製(http://stackoverflow.com/questions/36314/what-is- currying) –

回答

5

因爲Dense(...)返回一個可調用函數(基本上是一個函數),因此可以依次調用它。這裏有一個簡單的例子:

def make_adder(a): 
    def the_adder(b): 
     return a + b 
    return the_adder 

add_three = make_adder(3) 
add_three(5) 
# => 8 

make_adder(3)(5) 
# => 8 

這裏,make_adder(3)返回被定義爲

def the_adder(b) 
    return 3 + b 

然後參數調用5回報8該函數的功能。如果您跳過將返回值make_adder(3)分配給單獨變量的步驟,則會得到您詢問的表單:make_adder(3)(5)與您的問題中的Dense(64, activation='relu')(inputs)是一樣的。

編輯:從技術上講,Dense沒有被分類爲Python中的函數,而是作爲一個類; Dense(...)因此是一個構造函數的調用。有問題的類定義了__call__方法,它使得這個類的對象「可調用」。可以通過用參數列表調用它們來調用函數和可調用對象,兩者之間的區別根本不會影響解釋。但是,這裏有一個簡單的調用,更接近平行Dense的例子:

class Adder: 
    def __init__(self, a): 
     self.a = a 
    def __call__(self, b): 
     return self.a + b 

adder_of_three = Adder(3) 
adder_of_three(5) 
# => 8 

Adder(3)(5) 
# => 8 
+0

這個例子可能會引起誤解,因爲在這種情況下[Dense](https://github.com/fchollet/keras/blob/master/keras/layers/core.py#L607)是一個定義'__call__ ',但示例顯示了一個工廠函數。 – SethMMorton

+1

@SethMMorton:在概念上,'Dense'是一個返回可調用的函數(作爲定義'__call__'方法的類的構造函數)。 'make_adder'也是一個返回可調用對象的函數(通過返回一個函數,這個函數根據定義可調用)。他們沒有那麼不同。從技術上講,肯定 - '密集'是一個類,'make_adder'是一個函數 - 在引擎蓋下有很多差異。嗯,我可以補充說,雖然... – Amadan

+0

是的,我同意這是一個類是如何建立在引擎蓋下。但對於新用戶來說,描述可能會讓人困惑,因爲如果他們將源代碼視爲「密集」,他們會將其定義爲類而不是函數。我想說的是,這個答案不會連接工廠函數和可調用類之間的點,如果建立連接,它可能會使其得到改進。雖然OP已經接受,所以也許這不值得。 – SethMMorton