6

私はこのデザインでニューラル(ish)ネットをkerasに実装しようとしています: http://nlp.cs.rpi.edu/paper/AAAI15.pdf

このアルゴリズムには、基本的に 3 つの入力があります。入力 2 と入力 3 に同じ重み行列 W1 が乗算され、O2 と O3 が生成されます。入力 1 に W2 を乗算して O1 を生成します。次に、O1 * O2 と O1 * O3 の内積を取る必要があります。

これをkerasで実装しようとしています。

最初に考えたのは、kerasGraphクラスを使用して、W1 を 2 つの入力と 2 つの出力を持つ共有ノード レイヤーにすることでした。ここまでは順調です。

次に、これらの 2 つの出力の内積を O1 でどのように取得するかという問題が発生します。

カスタム関数を定義しようとしました:

   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"])

コンパイル時に発生する問題は、keras が Lambda レイヤーに 1 つの入力のみを与えたいということです。

   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)

別の方法として、許可されたマージのタイプとしてMergeクラスを使用することも考えられました。dotただし、Mergeクラスの入力レイヤーはコンストラクターに渡す必要があります。Mergeしたがって、出力を共有ノードから に取得してに追加するMerge方法はないようですGraph

コンテナを使用していた場合はSequential、それらをMerge. Sequentialただし、2 つのレイヤーが同じ重み行列を共有する必要があることを実装する方法はありません。

O1、O2、および O3 を出力層として単一のベクトルに連結し、目的関数内で乗算を実行しようと考えました。しかし、それには目的関数がその入力を分割する必要があり、これは keras では可能ではないようです (関連する Theano 関数は keras API にパススルーされません)。

解決策を知っていますか?

編集:

shared_node実装されていることがわかったのでdot(ドキュメントに記載されていなくても)、 ある程度進歩したと思いました。

だから私はしなければなりません:

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")

そして今、エラーは次のとおりです。

>>> 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')))
4

2 に答える 2

0

私は同様の問題に直面しています。解決策を考えていますが、まだ試していません。

  1. Input2 と Input3 の両方を入力として受け取る Sequential モデル A に畳み込み層を使用します。このようにして、同じ畳み込みカーネルが Input2 と Input3、つまり同じ重み W1 に適用されます。

  2. Input1 を別の Sequential モデル B の入力として取得します。

  3. マージ レイヤーを使用して、A と B の出力をマージします。また、マージ レイヤーのカスタム関数を介してドットを実行することもできます。

于 2016-05-07T06:42:44.660 に答える