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)
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]
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 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])