2017-01-21 7 views
0

私はタイムステップの平均を計算し、マスキングをサポートするLayerを持っています。 私の問題は、マスクが空である(パディングされたタイムステップはない)場合がありますが、テンソルを扱うときにゼロをチェックする方法がわからないことです。Keras - Theano - ゼロ除算のテスト

私はマスクが空であるため、NaNの損失があり、プログラムがクラッシュするいくつかのトレーニング例があります。

これは私のレイヤです:

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

    def call(self, x, mask=None): 
     if mask is not None: 
      return K.cast(x.sum(axis=1)/mask.sum(axis=1, keepdims=True), K.floatx()) # this may result to division by zero 
     else: 
      return K.mean(x, axis=1) 

    def get_output_shape_for(self, input_shape): 
     return input_shape[0], input_shape[-1] 

    def compute_mask(self, input, input_mask=None): 
     return None 

このmask.sum(axis=1, keepdims=True)はゼロとなります。これを回避するためにinput_lengthを増やして、すべてのトレーニングの例をカバーしていますが、これは解決策ではありません。また、try/exceptを追加しようとしましたが、これもうまくいきませんでした。

答えて

0

try/exceptこのコードはすべて例外ではないシンボリックテンソルグラフを作成するため、機能しません。したがって、評価は0でフィット/評価/予測関数で行われます。シンボリックグラフにロジック/決定を含める必要があります。

次の場合、他含めるswitch(condition, then_expression, else_expression)を使用することができます。

def call(self, x, mask=None): 
    if mask is not None: 
     sum = mask.sum(axis=1, keepdims=True) 
     cond = K.equal(sum,0) 
     _the_other_tensor_ = .... 
     div = K.switch(cond, _the_other_tensor_ ,sum) 
     return K.cast(x.sum(axis=1)/div, K.floatx()) # this may result to division by zero 
    else: 
     return K.mean(x, axis=1) 

それとも分裂が数値的に安定させるために、ごく少数のイプシロンにクリップするclip(x, min_value, max_value)を使用しています。

def call(self, x, mask=None): 
    if mask is not None: 
     sum = mask.sum(axis=1, keepdims=True) 
     div = K.clip(sum, K.epsilon, 1) 
     return K.cast(x.sum(axis=1)/div, K.floatx()) # this may result to division by zero 
    else: 
     return K.mean(x, axis=1)