2015-06-22 14 views
13

Vedo molto questo tipo di sintassi in alcuni file sorgente Lua che stavo leggendo ultimamente, cosa significa, in particolare la seconda coppia di parentesi Un esempio, riga 8 in https://github.com/karpathy/char-rnn/blob/master/model/LSTM.luaC'è un significato speciale per la sintassi()() in Lua

local LSTM = {} 
function LSTM.lstm(input_size, rnn_size, n, dropout) 
    dropout = dropout or 0 

    -- there will be 2*n+1 inputs 
    local inputs = {} 
    table.insert(inputs, nn.Identity()()) -- line 8 
    -- ... 

Il codice sorgente di nn.Identity https://github.com/torch/nn/blob/master/Identity.lua

********** UPDATE **************

Il modello()() è usato in biblioteca torcia 'nn' molto. La prima coppia di parentesi crea un oggetto del contenitore/nodo e la seconda coppia di parentesi fa riferimento al nodo dipendente.

Ad esempio, y = nn.Lineare (2,4) (x) significa che x si connette a ye la trasformazione è lineare da 1 * 2 a 1 * 4. Capisco appena l'utilizzo, come viene cablato sembra essere risposta da una delle risposte qui sotto.

In ogni caso, l'utilizzo dell'interfaccia è ben documentato di seguito. https://github.com/torch/nngraph/blob/master/README.md

+0

Se c'è una domanda, allora un buon modo per risolvere questo problema è quello di tirare fuori l'espressione 'nn.Identity()' e dargli un nome significativo. Ad esempio (ma con un nome quasi privo di significato poiché non so come chiamarlo): 'identityProvider locale = nn.Identity()' –

risposta

10

In complemento alla risposta di Yu Hao Faccio alcune precisioni torcia correlati:

  • nn.Identity() crea un modulo di identità,
  • () invitato questo modulo attiva nn.Module__call__ (grazie a Torch class system che collega correttamente questo nel metatable),
  • di default questo metodo __call__ esegue un forward/backward,
  • ma qui viene utilizzato torch/nngraph e ngraph sostituisce questo metodo come si può vedere here.

Di conseguenza ogni nn.Identity()() chiamate ha qui per effetto di restituire un nodo nngraph.Node({module=self}) dove l'auto si riferisce alla corrente nn.Identity() istanza.

-

Aggiornamento: un esempio di questa sintassi nel contesto LSTM-s si possono trovare here:

local i2h = nn.Linear(input_size, 4 * rnn_size)(input) -- input to hidden 

Se si ha familiarità con nngraph probabilmente sembra strano che stiamo costruendo un modulo e lo stiamo già chiamando di nuovo con un nodo grafico.In realtà, la chiamata alla seconda chiamata converte lo in nngraph.gModule e l'argomento specifica che è padre nel grafico.

12

No, ()() non ha un significato speciale in Lua, è solo due operatori di call () insieme.

L'operando è probabilmente una funzione che restituisce una funzione (o una tabella che implementa metametodo call). Per esempio:

function foo() 
    return function() print(42) end 
end 

foo()() -- 42 
2
  • La prima() chiama la funzione init e la seconda() chiama la funzione di chiamata
  • Se la classe non possiede una di queste funzioni, allora le funzioni di genitore sono chiamati.
  • Nel caso di nn.Identity()() la nn.Identity ha né funzione init né una chiamata di funzione quindi le madri Identità init e call funzioni di nn.Module chiamate .Attaching un'illustrazione

    require 'torch' 
    
    -- define some dummy A class 
    local A = torch.class('A') 
    function A:__init(stuff) 
        self.stuff = stuff 
        print('inside __init of A') 
    end 
    
    function A:__call__(arg1) 
    print('inside __call__ of A') 
    end 
    
    -- define some dummy B class, inheriting from A 
    local B,parent = torch.class('B', 'A') 
    
    function B:__init(stuff) 
        self.stuff = stuff 
        print('inside __init of B') 
    end 
    
    function B:__call__(arg1) 
    print('inside __call__ of B') 
    end 
    a=A()() 
    b=B()() 
    

    uscita

    inside __init of A 
    inside __call__ of A 
    inside __init of B 
    inside __call__ of B 
    

Un altro esempio di codice

require 'torch' 

    -- define some dummy A class 
    local A = torch.class('A') 
    function A:__init(stuff) 
     self.stuff = stuff 
     print('inside __init of A') 
    end 

    function A:__call__(arg1) 
    print('inside __call__ of A') 
    end 

    -- define some dummy B class, inheriting from A 
    local B,parent = torch.class('B', 'A') 

    b=B()() 

uscita

inside __init of A 
    inside __call__ of A 
Problemi correlati