2015-12-10 30 views
6

iki katmandan çıkışını keras ediyorum çarpımı. Giriş 2 ve Giriş 3, O2 ve O3 üretmek için aynı ağırlık matrisi W1 ile çarpılır. Giriş 1, O1 üretmek için W2 ile çarpılır. Daha sonra O1 * O2 ve O1 * O3'ün nokta ürününü almalıyız.Bu tasarıma sahip bir sinirsel (imsi) net içinde uygulamaya çalıştığını keras

Bunu keras'ta uygulamaya çalışıyorum.

İlk düşüncem keras Graph sınıfını kullanmak ve W1'i iki girişli ve iki çıkışlı bir paylaşımlı düğüm katmanı yapmaktı. Şimdiye kadar iyi. O zaman, bu iki çıkışın nokta ürünlerini O1 ile nasıl alacağınız sorusundan kaynaklanır. Daha sonra

def layer_mult(X, Y): 
     return K.dot(X * K.transpose(Y)) 

:

ntm.add_node(Lambda(layer_mult, output_shape = (1,1)), name = "ls_pos", inputs = ["O1", "O2"]) 
ntm.add_node(Lambda(layer_mult, output_shape = (1,1)), name = "ls_neg", inputs = ["O1", "O3"]) 

derleme ile ortaya çıkan sorun, sadece lambda katman bir giriş vermek için istediği keras olup:

Özel bir fonksiyonu belirlemeye çalıştık
1045   func = types.FunctionType(func, globals()) 
    1046   if hasattr(self, 'previous'): 
-> 1047    return func(self.previous.get_output(train)) 
    1048   else: 
    1049    return func(self.input) 

TypeError: layer_mult() takes exactly 2 arguments (1 given) 

Bir alternatifinsınıfını kullanabileceğini düşündüm.izin verilen birleştirme türü olarak. Ancak, Merge sınıfı için giriş katmanları yapıcıya iletilmelidir. Bu nedenle, 'u Graph'a eklemek için paylaşılan düğümünden çıktıları Merge'a almanın bir yolu görünmemektedir.

Sequential kapsayıcılarımı kullanıyorum, bunları Merge içine besleyebilirim. Ancak, iki Sequential katmanının aynı ağırlık matrisini paylaşması gerektiğinin uygulanmasının bir yolu olmazdı.

O1, O2 ve O3'ü bir çıkış katmanı olarak tek bir vektörde birleştirmeyi denedim ve sonra çarpımı bir amaç işlevi içinde gerçekleştirmeyi düşündüm. Ancak, bu, kerasında mümkün görünmeyen girdiyi bölmek için objektif fonksiyon gerektirecektir (ilgili Theano fonksiyonları keras API'sine geçemez).

Herhangi bir çözümü biliyor musunuz?

DÜZENLEME: shared_node uyguladığını ettiğini tespit ettiği

Ben bazı ilerlemeler kaydetmiştir sanıyordum dot (bile onun değil belgelerinde).

Yani lazım:

ntm = Graph() 
ntm.add_input(name='g', input_shape=(300,)) # Vector of 300 units, normally distributed around zero 
ntm.add_node([pretrained bit], name = "lt", input = "g") # 300 * 128, output = (,128) 
n_docs = 1000 
ntm.add_input("d_pos", input_shape = (n_docs,)) # (,n_docs) 
ntm.add_input("d_neg", input_shape = (n_docs,)) # (,n_docs) 

ntm.add_shared_node(Dense(128, activation = "softmax", 
#      weights = pretrained_W1, 
         W_constraint = unitnorm(), 
         W_regularizer = l2(0.001) 
        ), name = "ld", 
        inputs = ["d_pos", "d_neg"], 
        outputs = ["ld_pos", "ld_neg"], 
        merge_mode=None) # n_docs * 128, output = (,128) * 2 
ntm.add_shared_node(ActivityRegularization(0,0), #ActivityRegularization is being used as a passthrough - the function of the node is to dot* its inputs 
        name = "ls_pos", 
        inputs = ["lt", "d_pos"], 
        merge_mode = 'dot') # output = (,1) 
ntm.add_shared_node(ActivityRegularization(0,0), 
        name = "ls_neg", 
        inputs = ["lt", "d_neg"], 
        merge_mode = 'dot') # output = (,1) 
ntm.add_shared_node(ActivityRegularization(0,0), 
        name = "summed", 
        inputs = ["ls_pos", "ls_neg"], 
        merge_mode = 'sum') # output = (,1) 
ntm.add_node(ThresholdedReLU(0.5), 
      input = "summed", name = "loss") # output = (,1) 
ntm.add_output(name = "loss_out", 
       input= "loss") 
def obj(X, Y): 
    return K.sum(Y) 
ntm.compile(loss = {'loss_out' : obj}, optimizer = "sgd") 

Ve şimdi hata: Ben benzer bir sorun yüzleşiyorum

>>> ntm.compile(loss = {'loss_out' : obj}, optimizer = "sgd") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "build/bdist.macosx-10.5-x86_64/egg/keras/models.py", line 602, in compile 
    File "build/bdist.macosx-10.5-x86_64/egg/keras/layers/advanced_activations.py", line 149, in get_output 
    File "build/bdist.macosx-10.5-x86_64/egg/keras/layers/core.py", line 117, in get_input 
    File "build/bdist.macosx-10.5-x86_64/egg/keras/layers/core.py", line 1334, in get_output 
    File "build/bdist.macosx-10.5-x86_64/egg/keras/layers/core.py", line 1282, in get_output_sum 
    File "build/bdist.macosx-10.5-x86_64/egg/keras/layers/core.py", line 1266, in get_output_at 
    File "build/bdist.macosx-10.5-x86_64/egg/keras/layers/core.py", line 730, in get_output 
    File "build/bdist.macosx-10.5-x86_64/egg/keras/layers/core.py", line 117, in get_input 
    File "build/bdist.macosx-10.5-x86_64/egg/keras/layers/core.py", line 1340, in get_output 
    File "build/bdist.macosx-10.5-x86_64/egg/keras/layers/core.py", line 1312, in get_output_dot 
    File "/Volumes/home500/anaconda/envs/[-]/lib/python2.7/site-packages/theano/tensor/var.py", line 360, in dimshuffle 
    pattern) 
    File "/Volumes/home500/anaconda/envs/[-]/lib/python2.7/site-packages/theano/tensor/elemwise.py", line 164, in __init__ 
    (input_broadcastable, new_order)) 
ValueError: ('You cannot drop a non-broadcastable dimension.', ((False, False, False, False), (0, 'x'))) 
+0

, ben oluşturma öneririm Bunun için github sorunu (Keras geliştiricisi olmamasına rağmen). Dahası, (ab) bunun için Siamese tabakasını kullanarak, iki kere bir ortak ağırlık matrisi ile O1 üretiyor? –

+0

Merhaba, probleminize çözüm buldunuz mu? – Bharat

cevap

2

Bu

main_branch.add kullanabilirsiniz (Birleştirme ([branch_1, branch_2], mod = 'nokta'))

+0

Cevabı kabul ediyorum, bu yüzden bu konuda yorum yapmaya gerek yok. Çok kolay olduğu ortaya çıktı ve yanıtınız bunu yapmanın tek yolunun bir örneğidir. – Bob

+0

Benzer bir şey deniyorum [lütfen bir göz atın] (http://stackoverflow.com/questions/42297359/typeerror-output-tensors-to-a-model-must-be-keras-tensors) ancak basitçe iş. Tek yapmaya çalıştığım bir tensörü bir skaler ile çarpmak. – displayname

0

. Bir çözüm düşünüyorum ama henüz denemedim.

  1. Girdi Olarak Giriş2 ve Giriş3'ü alan Ardışık Model A için Evrişim Katmanlarını Kullanma.Bu şekilde, aynı evrişim çekirdeği, Giriş 2'ye, aynı ağırlık W1 olan bir Giriş3'e uygulanacaktır. A ve B ve nokta üzerinden çıkış birleştirmek için bir birleştirme katmanı kullanılarak bir ardışık modeli B

  2. giriş olarak Input 1 çıkarak

  3. da birleştirme katmanının özel bir işlev ile yapılabilir. Henüz varsa

+0

Şu anda bunu deniyorum (bkz. [Here] (http://stackoverflow.com/questions/42297359/typeerror-output-tensors-to-a-model-must-be-keras-tensors)) ancak aşağıdaki gibi çalışmıyor Çıkış tensörünün Keras tensörü olması gerektiğini söyleyen bir 'TypeError 'alıyorum. – displayname