def loss_function(y_true, y_pred): y_true = keras.flatten(y_true) y_pred = keras.flatten(y_pred) whites = keras.mean((y_true * (1.0 - y_pred))**2) blacks = keras.mean(((1.0 - y_true) * y_pred)**2) white_area = keras.foldl(lambda acc, x: acc + x, y_true) # TODO try keras.sum black_area = keras.foldl(lambda acc, x: acc + x, 1.0 - y_true) # TODO try keras.sum return (whites * black_area + blacks * white_area) / (white_area + black_area)
def test_foldl(self): x = np.random.rand(10, 3).astype(np.float32) for K in [KTF, KTH]: kx = K.eval(K.foldl(lambda a, b: a + b, K.variable(x))) assert (3,) == kx.shape assert_allclose(x.sum(axis=0), kx, atol=1e-05)
def test_foldl(self): x = np.random.rand(10, 3).astype(np.float32) for K in [KTF, KTH]: kx = K.eval(K.foldl(lambda a, b: a + b, K.variable(x))) assert (3, ) == kx.shape assert_allclose(x.sum(axis=0), kx, atol=1e-05)
def __call__(self, x): top = K.map_fn(lambda x: top_half(x), x) median = K.min(top, axis=0) mean = K.mean(x, axis=0) loss_mean = K.foldl(lambda acc, x: acc + kl_divergence(0.1, x), mean) loss_mean = 1.0 * loss_mean loss_median = K.foldl(lambda acc, x: acc + kl_divergence(0.06, x), median) loss_median = 1.0 * loss_median sparse = K.mean(x, axis=1) loss_se = K.foldl(lambda acc, x: acc + kl_divergence(0.1, x), sparse) loss_se = 1.0 * loss_se return loss_mean + loss_median + loss_se
def __call__(self, x): #x=tf.slice(z,[0,0],[200,50]) x = ((x - K.min(x, axis=0)) / (K.max(x, axis=0) - K.min(x, axis=0))) + 0.000001 top = K.map_fn(lambda x: top_half(x), x) median = K.min(top, axis=1) mean = K.mean(x, axis=1) loss_mean = K.foldl(lambda acc, x: acc + kl_divergence(0.05, x), mean) loss_mean = 1.0 * loss_mean loss_median = K.foldl(lambda acc, x: acc + kl_divergence(0.03, x), median) loss_median = 1.0 * loss_median sparse = K.mean(x, axis=0) loss_se = K.foldl(lambda acc, x: acc + kl_divergence(0.05, x), sparse) loss_se = 1.0 * loss_se return loss_mean + loss_median + loss_se
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 _sum_seg_embeddings(self, seg_indices, seg_embeddings): def __merge(ret, ele): _tmp_embedding, _tmp_cnt = ret _seg_ind, _seg_embedding = ele return _tmp_embedding + self._ungather( _seg_embedding, _seg_ind), _tmp_cnt + self._ungather( bk.ones_like(_seg_embedding), _seg_ind) tmp_embedding = bk.zeros_like(self.embedding) tmp_cnt = bk.zeros_like(self.embedding) return bk.foldl(__merge, (seg_indices, seg_embeddings), initializer=(tmp_embedding, tmp_cnt))
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)
def belief_propagation( S, ray_voxel_indices, ray_voxel_count, grid_shape, gamma=0.031, bp_iterations=3 ): """Run the sum product belief propagation on a batch of ray potentials Arguments --------- S: tensor (N, M) dtype=float32 The depth probability distribution for each one of the N rays ray_voxel_indices: tensor (N, M, 3), dtype=int32 The voxel indices in the voxel grid per ray ray_voxel_count: array(shape=(N,1), int) The number of voxels intersected by each ray grid_shape: tensor (3,) int32, The number of voxels for each axis gamma: float32, Prior probabilitiy that the ith voxel is occupied bp_iterations: int, Number of belief-propagation iterations """ # Extract the number of the rays as well as the maximum number of marched # voxels N, M, _ = K.int_shape(ray_voxel_indices) # Initialize the ray to occupancy messages to a uniform distribution (and # assume that they were accumulated) ray_to_occupancy_pon = K.zeros((N, M), dtype="float32") prior_pon = K.log(gamma) - K.log(np.float32(1) - gamma) #ray_to_occupancy_accumulated_pon_init = K.constant( # prior_pon, # shape=grid_shape #) ray_to_occupancy_accumulated_pon_init = K.tf.fill(grid_shape, prior_pon) ray_to_occupancy_accumulated_pon = ray_to_occupancy_accumulated_pon_init #ray_to_occupancy_accumulated_pon = K.variable( # ray_to_occupancy_accumulated_pon_init, # name="ray_to_occupancy_accumulated_pon" #) # Iterate over the rays for it in range(bp_iterations): # Compute the messages given the previous messages ray_to_occupancy_pon = K.map_fn( lambda i: single_ray_belief_propagation( S[i, :ray_voxel_count[i]], ray_voxel_indices[i, :ray_voxel_count[i]], ray_to_occupancy_accumulated_pon, ray_to_occupancy_pon[i, :ray_voxel_count[i]], M ), K.tf.range(0, N, dtype="int32"), dtype="float32" ) # Accumulate the messages to make the computation of the new messages # faster ray_to_occupancy_accumulated_pon = K.foldl( lambda acc, i: K.tf.sparse_add( acc, K.tf.SparseTensor( K.cast(ray_voxel_indices[i], dtype="int64"), ray_to_occupancy_pon[i], grid_shape ) ), K.tf.range(0, N, dtype="int32"), initializer=K.tf.zeros_like(ray_to_occupancy_accumulated_pon) ) ray_to_occupancy_accumulated_pon = ray_to_occupancy_accumulated_pon + ray_to_occupancy_accumulated_pon_init return ray_to_occupancy_accumulated_pon, ray_to_occupancy_pon