예제 #1
0
def weight_loss(neighb_count: np.array, labels: np.array,
                weights: list) -> float:
    """Calculates loss for given neighbors and weights.

    Parameters
    ----------
    neighb_count : numpy array
        describes for each point the number of neighbors with each label.
        Shape: (number of data points, number of labels)

    labels : numpy array
        label for each point. Shape: (number of data points, )

    weights : list
        weight of each label. Length: number of labels

    Returns
    -------
    float
        calculated loss
    """
    # reset graph before each run
    tf.reset_default_graph()

    num_data, num_labels = neighb_count.shape
    label_counts = np.zeros([num_labels])
    for label, count in Counter(labels).most_common():
        label_counts[label] = count

    # neighbors matrix
    neigh_matx = tf.constant(neighb_count, dtype=tf.float32)

    # label count vector
    label_cnts = tf.constant(label_counts, dtype=tf.float32)

    # weights
    w = tf.constant(weights, dtype=tf.float32)

    # weight lookup list
    w_list = tf.reduce_sum(tf.one_hot(labels, num_labels) * w, axis=1)

    # label counts lookup list
    label_cnts_list = tf.reduce_sum(tf.one_hot(labels, num_labels) * label_cnts,
                                    axis=1)
    nx = w * num_data

    ny = label_cnts_list / w_list * \
         tf.reduce_sum(neigh_matx * (w/label_cnts), axis=1)

    loss = (tf.reduce_sum(tf.digamma(nx) * w) \
          + tf.reduce_sum(tf.digamma(ny) * w_list / label_cnts_list))

    with tf.Session() as sess:
        return sess.run(loss)
예제 #2
0
    def outer_body(j, diffo, a, b, q):
        def body(i, diff, at, bt):
            bt1 = at * bgt
            at1 = tf.maximum(
                at +
                (tf.log(bt) + agt - tf.digamma(at)) / tf.polygamma(1.0, at),
                1e-5)
            diff1 = tf.reduce_mean(tf.abs(at/at1-1.0)) + \
                tf.reduce_mean(tf.abs(bt/bt1-1.0))
            return [i - 1, diff1, at1, bt1]

        def cond(i, diff, at, bt):
            return tf.logical_and(i > 0, diff > tol)

        vF = a * tf.log(b/sc) - (x+a) * tf.log(1+b/sc) - \
            log_beta(a, x) - tf.log(x+a)
        t = q + tf.concat([vF, tf.broadcast_to(vL_in, [1, K, G, C])], axis=0)
        eta = tf.reduce_logsumexp(t, axis=(0), keepdims=True)
        xi = rho + t - eta
        qt = tf.reduce_logsumexp(xi, axis=3, keepdims=True)  # sum over c
        qt1 = qt - tf.reduce_logsumexp(qt, axis=0, keepdims=True)  # sum over l
        xi_n = xi - tf.reduce_max(xi, axis=3, keepdims=True)
        p_n = tf.exp(xi_n[:L - 1, :, :, :])
        pt_n = tf.reduce_sum(p_n, axis=3, keepdims=True)
        bgt = pt_n / tf.reduce_sum(
            p_n * (a + x) / (b + sc), axis=3, keepdims=True)
        agt = tf.reduce_sum(
            p_n *
            (tf.digamma(x + a) - tf.log(sc + b)), axis=3, keepdims=True) / pt_n

        i, diff_in, at1, bt1 = tf.while_loop(cond, body,
                                             (n_inner_iter, 1.0, a, b))
        diffo1 = tf.reduce_mean(tf.abs(a/at1-1.0)) + \
            tf.reduce_mean(tf.abs(b/bt1-1.0))
        return [j - 1, diffo1, at1, bt1, qt1]
예제 #3
0
 def body(i, diff, at, bt):
     bt1 = at * bgt
     at1 = tf.maximum(
         at +
         (tf.log(bt) + agt - tf.digamma(at)) / tf.polygamma(1.0, at),
         1e-5)
     diff1 = tf.reduce_mean(tf.abs(at/at1-1.0)) + \
         tf.reduce_mean(tf.abs(bt/bt1-1.0))
     return [i - 1, diff1, at1, bt1]
예제 #4
0
def weight_optimizer(neighb_count, labels) -> (float, list):
    """Returns loss and optimized weights for given neighbors description.

    Parameters
    ----------
    neighb_count : numpy array of shape (# of data points, # of labels)
        describes for each point the number of neighbors with each label

    labels : numpy array of shape (# of data points, )
        label for each point

    Returns
    -------
    float
        loss
    list
        weight for each label
    """
    # reset graph before each run
    tf.reset_default_graph()

    num_data, num_labels = neighb_count.shape
    label_counts = np.zeros([num_labels])
    for label, count in Counter(labels).most_common():
        label_counts[label] = count

    # neighbors matrix
    neigh_matx = tf.constant(neighb_count, dtype=tf.float32)

    # label count vector
    label_cnts = tf.constant(label_counts, dtype=tf.float32)

    # logits -- to be optimized
    logits = tf.Variable(np.ones(num_labels), dtype=tf.float32)

    # weights
    w = tf.nn.softmax(logits)

    # weight lookup list
    w_list = tf.reduce_sum(tf.one_hot(labels, num_labels) * w, axis=1)

    # label cnts lookup list
    label_cnts_list = tf.reduce_sum(tf.one_hot(labels, num_labels) *
                                    label_cnts,
                                    axis=1)
    nx = w * num_data

    ny = label_cnts_list / w_list \
         * tf.reduce_sum(neigh_matx * (w/label_cnts), axis=1)

    loss = (tf.reduce_sum(tf.digamma(nx) * w) +
            tf.reduce_sum(tf.digamma(ny) * w_list / label_cnts_list))

    optimizer = tf.train.AdamOptimizer()
    train = optimizer.minimize(loss)

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        #print("Starting training...")
        for _ in range(5000):
            curr_loss, curr_w, __ = sess.run([loss, w, train])
            #if _ % 250 == 0:
            #    print("steps: %s, loss: %s, w: %s"
            #        % (_, curr_loss, curr_w))
        #print("Done.")
        return sess.run([loss, w])