2017-01-21 3 views
0

나는 타임 스텝의 평균을 계산하고 마스킹을 지원하는 레이어가 있습니다. 제 문제는 마스크가 비어있는 경우 (패딩 된 타임 스텝 없음)가있을 수 있지만 텐서로 작업 할 때 0을 확인하는 방법을 모른다는 것입니다.Keras - Theano - 0으로 나누기위한 테스트

마스크가 비어있는 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으로 나누기/평가/예측 함수에서 발생합니다. 논리 그래프/결정을 기호 그래프에 포함시켜야합니다.

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)를 사용

다음과 같은 경우와 다른 포함 switch(condition, then_expression, else_expression)를 사용할 수 있습니다.

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) 
관련 문제