2017-01-21 3 views
0

У меня есть Layer, который вычисляет среднее значение timesteps и поддерживает маскировку. Моя проблема в том, что может быть так, что маска пуста (без добавленных временных меток), но я не знаю, как проверить нули при работе с тензорами.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) становится равным нулю. Чтобы обойти это, я увеличил длину ввода, поэтому он охватывает все мои учебные примеры, но это не решение. Также я попытался добавить try/except, но это также не сработало.

ответ

0

try/except не работает, потому что вся эта часть кода создает символический тензорный график, который не имеет никакого исключения .. оценка, следовательно, деление на 0 происходит в функции fit/evaluation/pred. Вам нужно включить логику/решение в символический граф.

Вы можете использовать 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) 
Смежные вопросы