def csoftmax_for_slice(input):
    """ It is a implementation of the constrained softmax (csoftmax) for slice.
        Based on the paper:
        https://andre-martins.github.io/docs/emnlp2017_final.pdf "Learning What's Easy: Fully Differentiable Neural Easy-First Taggers" (page 4)
    Args:
        input: A list of [input tensor, cumulative attention].
    Returns:
        output: A list of [csoftmax results, masks]
    """

    [ten, u] = input

    shape_t = ten.shape
    shape_u = u.shape

    ten -= tf.reduce_mean(ten)
    q = tf.exp(ten)
    active = tf.ones_like(u, dtype=tf.int32)
    mass = tf.constant(0, dtype=tf.float32)
    found = tf.constant(True, dtype=tf.bool)

    def loop(q_, mask, mass_, found_):
        q_list = tf.dynamic_partition(q_, mask, 2)
        condition_indices = tf.dynamic_partition(tf.range(tf.shape(q_)[0]), mask, 2)  # 0 element it False,
        #  1 element if true

        p = q_list[1] * (1.0 - mass_) / tf.reduce_sum(q_list[1])
        p_new = tf.dynamic_stitch(condition_indices, [q_list[0], p])

        # condition verification and mask modification
        less_mask = tf.cast(tf.less(u, p_new), tf.int32)  # 0 when u is bigger than p, 1 when u is less than p
        condition_indices = tf.dynamic_partition(tf.range(tf.shape(p_new)[0]), less_mask,
                                                 2)  # 0 when u is bigger than p, 1 when u is less than p

        split_p_new = tf.dynamic_partition(p_new, less_mask, 2)
        split_u = tf.dynamic_partition(u, less_mask, 2)

        alpha = tf.dynamic_stitch(condition_indices, [split_p_new[0], split_u[1]])
        mass_ += tf.reduce_sum(split_u[1])

        mask = mask * (tf.ones_like(less_mask) - less_mask)

        found_ = tf.cond(tf.equal(tf.reduce_sum(less_mask), 0),
                         lambda: False,
                         lambda: True)

        alpha = tf.reshape(alpha, q_.shape)

        return alpha, mask, mass_, found_

    (csoft, mask_, _, _) = tf.while_loop(cond=lambda _0, _1, _2, f: f,
                                         body=loop,
                                         loop_vars=(q, active, mass, found))

    return [csoft, mask_]
def csoftmax_for_slice(input):
    """ It is a implementation of the constrained softmax (csoftmax) for slice.
        Based on the paper:
        https://andre-martins.github.io/docs/emnlp2017_final.pdf "Learning What's Easy: Fully Differentiable Neural Easy-First Taggers" (page 4)
    Args:
        input: A list of [input tensor, cumulative attention].
    Returns:
        output: A list of [csoftmax results, masks]
    """

    [ten, u] = input

    shape_t = ten.shape
    shape_u = u.shape

    ten -= tf.reduce_mean(ten)
    q = tf.exp(ten)
    active = tf.ones_like(u, dtype=tf.int32)
    mass = tf.constant(0, dtype=tf.float32)
    found = tf.constant(True, dtype=tf.bool)

    def loop(q_, mask, mass_, found_):
        q_list = tf.dynamic_partition(q_, mask, 2)
        condition_indices = tf.dynamic_partition(tf.range(tf.shape(q_)[0]), mask, 2)  # 0 element it False,
        #  1 element if true

        p = q_list[1] * (1.0 - mass_) / tf.reduce_sum(q_list[1])
        p_new = tf.dynamic_stitch(condition_indices, [q_list[0], p])

        # condition verification and mask modification
        less_mask = tf.cast(tf.less(u, p_new), tf.int32)  # 0 when u is bigger than p, 1 when u is less than p
        condition_indices = tf.dynamic_partition(tf.range(tf.shape(p_new)[0]), less_mask,
                                                 2)  # 0 when u is bigger than p, 1 when u is less than p

        split_p_new = tf.dynamic_partition(p_new, less_mask, 2)
        split_u = tf.dynamic_partition(u, less_mask, 2)

        alpha = tf.dynamic_stitch(condition_indices, [split_p_new[0], split_u[1]])
        mass_ += tf.reduce_sum(split_u[1])

        mask = mask * (tf.ones_like(less_mask) - less_mask)

        found_ = tf.cond(tf.equal(tf.reduce_sum(less_mask), 0),
                         lambda: False,
                         lambda: True)

        alpha = tf.reshape(alpha, q_.shape)

        return alpha, mask, mass_, found_

    (csoft, mask_, _, _) = tf.while_loop(cond=lambda _0, _1, _2, f: f,
                                         body=loop,
                                         loop_vars=(q, active, mass, found))

    return [csoft, mask_]
def csoftmax_for_slice ( input ) : [ ten , u ] = input shape_t = ten . shape shape_u = u . shape ten -= tf . reduce_mean ( ten ) q = tf . exp ( ten ) active = tf . ones_like ( u , dtype = tf . int32 ) mass = tf . constant ( 0 , dtype = tf . float32 ) found = tf . constant ( True , dtype = tf . bool ) def loop ( q_ , mask , mass_ , found_ ) : q_list = tf . dynamic_partition ( q_ , mask , 2 ) condition_indices = tf . dynamic_partition ( tf . range ( tf . shape ( q_ ) [ 0 ] ) , mask , 2 ) # 0 element it False, #  1 element if true p = q_list [ 1 ] * ( 1.0 - mass_ ) / tf . reduce_sum ( q_list [ 1 ] ) p_new = tf . dynamic_stitch ( condition_indices , [ q_list [ 0 ] , p ] ) # condition verification and mask modification less_mask = tf . cast ( tf . less ( u , p_new ) , tf . int32 ) # 0 when u is bigger than p, 1 when u is less than p condition_indices = tf . dynamic_partition ( tf . range ( tf . shape ( p_new ) [ 0 ] ) , less_mask , 2 ) # 0 when u is bigger than p, 1 when u is less than p split_p_new = tf . dynamic_partition ( p_new , less_mask , 2 ) split_u = tf . dynamic_partition ( u , less_mask , 2 ) alpha = tf . dynamic_stitch ( condition_indices , [ split_p_new [ 0 ] , split_u [ 1 ] ] ) mass_ += tf . reduce_sum ( split_u [ 1 ] ) mask = mask * ( tf . ones_like ( less_mask ) - less_mask ) found_ = tf . cond ( tf . equal ( tf . reduce_sum ( less_mask ) , 0 ) , lambda : False , lambda : True ) alpha = tf . reshape ( alpha , q_ . shape ) return alpha , mask , mass_ , found_ ( csoft , mask_ , _ , _ ) = tf . while_loop ( cond = lambda _0 , _1 , _2 , f : f , body = loop , loop_vars = ( q , active , mass , found ) ) return [ csoft , mask_ ]
It is a implementation of the constrained softmax (csoftmax) for slice.
        Based on the paper:
        https://andre-martins.github.io/docs/emnlp2017_final.pdf "Learning What's Easy: Fully Differentiable Neural Easy-First Taggers" (page 4)
    Args:
        input: A list of [input tensor, cumulative attention].
    Returns:
        output: A list of [csoftmax results, masks]
It is a implementation of the constrained softmax ( csoftmax ) for slice . Based on the paper : https : // andre - martins . github . io / docs / emnlp2017_final . pdf Learning What s Easy : Fully Differentiable Neural Easy - First Taggers ( page 4 ) Args : input : A list of [ input tensor cumulative attention ] . Returns : output : A list of [ csoftmax results masks ]