2016-09-15 79 views
3
... 
print('Build model...') 
model = Sequential() 
model.add(Embedding(max_features, 128)) 
model.add(LSTM(size, return_sequences=True, dropout_W=0.2 dropout_U=0.2)) 
model.add(GlobalAveragePooling1D()) 
model.add(Dense(1)) 
model.add(Activation('sigmoid')) 
.... 

をサポートマスキングとプール私は緻密層に、この平均値または最大ベクトルを与える前にLSTM層を形成した後、試料中のすべての時間ステップのためのベクトルの平均値や最大値を取ることができるようにする必要がありますケラスで平均または最大のKeras

私はtimedistributedmergeがこれを行うことができましたが、廃止されました。 return_sequences=Trueを使用すると、LSTM層の後のサンプル内のすべてのタイムステップのベクトルを取得できます。しかし、GlobalAveragePooling1D()はマスキングと互換性がなく、すべてのタイムステップを考慮しますが、マスクされていないタイムステップだけが必要です。

私はLambda層を推奨する投稿を見ましたが、これらもマスキングを考慮していません。どんな助けもありがとう。

答えて

1

平均的なプールは1軸で平均しているだけなので、損失マスキングはここではなく最後に処理されるため、平均の要素数を修正するだけで済みます。あなたがこれを行うことができ、xのマスクされた値がゼロに等しくなるようにするために

class GlobalAveragePooling1DMasked(GlobalAveragePooling1D): 
    def call(self, x, mask=None): 
     if mask != None: 
      return K.sum(x, axis=1)/K.sum(mask, axis=1) 
     else: 
      return super().call(x) 
+1

Kerasでは、 'x 'のマスクされた値がゼロに等しいとは限りません。したがって、この実装は間違った結果をもたらします。 – pir

+0

'Masking'と' Embedding'層によって導入されたマスク自体はバイナリです。もちろん、 'compute_mask'を実装するレイヤーはいつも異なっていても構いませんが、これは私が見る限りケラス自体では起こりません。 – nemo

+0

はい、マスクはバイナリです。それは私が言っていることではありません:) – pir

1

:あなたはこのようなもので、おそらくこれを行うことができます

class MeanPool(Layer): 
def __init__(self, **kwargs): 
    self.supports_masking = True 
    super(MeanPool, self).__init__(**kwargs) 

def compute_mask(self, input, input_mask=None): 
    # do not pass the mask to the next layers 
    return None 

def call(self, x, mask=None): 
    if mask is not None: 
     # mask (batch, time) 
     mask = K.cast(mask, K.floatx()) 
     # mask (batch, time, 'x') 
     mask = mask.dimshuffle(0, 1, 'x') 
     # to make the masked values in x be equal to zero 
     x = x * mask 
    return K.sum(x, axis=1)/K.sum(mask, axis=1) 

def get_output_shape_for(self, input_shape): 
    # remove temporal dimension 
    return input_shape[0], input_shape[2] 
1

Jacoxuの答えは正しいです。しかし、ケラスにテンソルフローバックエンドを使用している場合、Tensorタイプはダッシュシャープル機能をサポートしていません。代わりにこれを試してください。

def call(self, x, mask=None): 
    if mask is not None: 
     # mask (batch, time) 
     mask = K.cast(mask, K.floatx()) 
     # mask (batch, x_dim, time) 
     mask = K.repeat(mask, x.shape[-1]) 
     # mask (batch, time, x_dim) 
     mask = tf.transpose(mask, [0,2,1]) 
     x = x * mask 
    return K.sum(x, axis=1)/K.sum(mask, axis=1) 
関連する問題