def test_foldr(self): # This test aims to make sure that we walk the array from right to left # and checks it in the following way: multiplying left to right 1e-40 # cannot be held into a float32 so it causes an underflow while from # right to left we have no such problem and the result is larger x = np.array([1e-20, 1e-20, 10, 10, 10], dtype=np.float32) for K in [KTF, KTH]: p1 = K.eval(K.foldl(lambda a, b: a * b, x)) p2 = K.eval(K.foldr(lambda a, b: a * b, x)) assert p1 < p2 assert 9e-38 < p2 <= 1e-37
def integral(y_true, y_pred): dx = K.constant(0.05 / 100, dtype='float32') Acc_L2R_t = K.foldl(lambda acc, x: x * 0, K.transpose(y_true)) Acc_L2R_p = K.foldl(lambda acc, x: x * 0, K.transpose(y_pred)) Acc_R2L_t = K.foldr(lambda acc, x: x * 0, K.transpose(y_true)) Acc_R2L_p = K.foldr(lambda acc, x: x * 0, K.transpose(y_pred)) for i in range(2, 50): Acc_L2R_t += K.foldl(lambda acc, x: acc + x, K.transpose(y_true)[0:int(i - 1)]) Acc_L2R_t += K.foldl(lambda acc, x: acc + x, K.transpose(y_true)[1:i]) Acc_L2R_p += K.foldl(lambda acc, x: acc + x, K.transpose(y_pred)[0:int(i - 1)]) Acc_L2R_p += K.foldl(lambda acc, x: acc + x, K.transpose(y_pred)[1:i]) Acc_R2L_t += K.foldr(lambda acc, x: acc + x, K.transpose(y_true)[0:int(i - 1)]) Acc_R2L_t += K.foldr(lambda acc, x: acc + x, K.transpose(y_true)[1:i]) Acc_R2L_p += K.foldr(lambda acc, x: acc + x, K.transpose(y_pred)[0:int(i - 1)]) Acc_R2L_p += K.foldr(lambda acc, x: acc + x, K.transpose(y_pred)[1:i]) return K.mean(K.square(y_pred - y_true), axis=-1) + K.mean( K.square(Acc_L2R_t * dx - Acc_L2R_p * dx) + K.mean(K.square(Acc_R2L_t * dx - Acc_R2L_p * dx)), axis=-1)