def __init__(self, num_class, node, points, node_units, edge_units, mixture, train_rate, infer_rate, mvn, mw, ent, t=10, potential='nn', dtype=tf.float64): super(CompleteMrf, self).__init__(name='mrf', dtype=dtype) self.optimizer = tf.keras.optimizers.Adam(learning_rate=train_rate) self.marginal = GMMComplete(c=num_class, n=node, l=mixture, k=points, lr=infer_rate, dtype=dtype) self.potential = NeuralNetPotential(node_units=node_units, edge_units=edge_units) if potential == 'nn' \ else PolynomialPotential(order=2, name='order2_polynomial', dtype=dtype) self.logZ = tf.zeros(num_class, dtype=dtype) self.belief_pool = [ tf.tile(v, [1, 1, t, 1]) for v in self.marginal.trainable_variables ] self.entropy_pool = tf.tile(tf.expand_dims(self.marginal.entropy(), 1), [1, t]) # self.Wijk, self.qp = self.quad3(mvn=mvn, k=31, dtype=dtype) self.mw = tf.reshape(mw, [1, 1, -1, 1]) self.mvn_entropy = ent
def __init__(self, num_class, img_width, points, node_units, edge_units, mixture, train_rate, infer_rate, batch_size, potential='nn', dtype=tf.float64): super(TreeMrf, self).__init__(name='tree_mrf', dtype=dtype) self.optimizer = tf.keras.optimizers.Adam(learning_rate=train_rate) self.marginal = GMMHidden(c=num_class, m=img_width, l=mixture, bs=batch_size, k=points, lr=infer_rate) self.potential = NeuralNetPotential(node_units=node_units, edge_units=edge_units) if potential == 'nn' \ else PolynomialPotential(c=num_class, m=img_width, n=img_width, order=2, name='order2_polynomial') self.logZ = tf.zeros((num_class, 1 + batch_size), dtype=dtype)
def __init__(self, num_class, height, width, points, node_units, edge_units, mixture, train_rate, infer_rate, potential='nn', dtype=tf.float64): super(GridMrf, self).__init__(name='mrf', dtype=dtype) self.optimizer = tf.keras.optimizers.Adam(learning_rate=train_rate) self.marginal = GMMGrid0(c=num_class, m=height, n=width, l=mixture, k=points, lr=infer_rate, dtype=dtype) self.potential = NeuralNetPotential(node_units=node_units, edge_units=edge_units) if potential == 'nn' \ else PolynomialPotential(order=2, name='order2_polynomial', dtype=dtype) self.logZ = tf.zeros((num_class, ), dtype=dtype)
dsigma2 = tf.transpose( tf.reduce_sum( fe * (self.xi2axj2 - self.xi2mxj2 / sqrtq), -1, keepdims=True) / o2, [1, 0, 2, 3]) drou = tf.reduce_sum( fe * (2 * self.xij - self.rou * self.xi2axj2), -1, keepdims=True) / q dmu += tf.transpose( tf.concat([tf.math.segment_sum(dmu1, self.id1), self.zeros], 0) + tf.math.unsorted_segment_sum(dmu2, self.id2, self.N), [1, 0, 2, 3]) dsigma += tf.transpose( tf.concat([tf.math.segment_sum(dsigma1, self.id1), self.zeros], 0) + tf.math.unsorted_segment_sum(dsigma2, self.id2, self.N), [1, 0, 2, 3]) dalpha = (tf.reduce_sum(fn_, [1, -1], keepdims=True) + tf.reduce_sum(fe_, [1, -1], keepdims=True)) dw = alpha * (dalpha - tf.reduce_sum(dalpha * alpha, 2, keepdims=True)) energy = -(tf.reduce_sum(fn, [1, 2, 3]) + tf.reduce_sum(fe, [1, 2, 3])) return (-dmu, -dsigma, -drou, -dw), energy if __name__ == '__main__': from core.potential.dnn import NeuralNetPotential import timeit gmm = GMMComplete(c=10, n=10, l=1, k=11) pot = NeuralNetPotential(node_units=(4, 5, 5, 4), edge_units=(5, 7, 7, 5)) print(timeit.timeit(lambda: gmm.infer(pot, 50), number=1))
def testGradient(self): """test if close form gradient consistent with tensorflow's auto-gradient result""" tf.random.set_seed(7) c = 4 l = 4 bs = 2 gmm = GMMHidden(c=c, m=27, l=l, k=51, bs=bs, dtype=tf.float64) # u = tf.random.uniform([c, m, n, 1, 1, 1], -3, 3, dtype=gmm.dtype) # o = tf.random.uniform([c, m, n, 1, 1, 1], 0.001, 10, dtype=gmm.dtype) # p = tf.random.uniform((c, m, n, 2, 1, 1), -0.999, 0.999, dtype=gmm.dtype) # gmm.mu.assign(tf.tile(u, [1, 1, 1, 1, l, 1])) # gmm.sigma.assign(tf.tile(o, [1, 1, 1, 1, l, 1])) # gmm.rou.assign(tf.tile(p, [1, 1, 1, 1, l, 1])) gmm.mu.assign( tf.random.uniform(gmm.mu.get_shape(), 0, 1, dtype=gmm.dtype)) gmm.sigma.assign( tf.random.uniform(gmm.sigma.get_shape(), 0.8, 1, dtype=gmm.dtype)) # gmm.rou.assign(tf.random.uniform(gmm.rou.get_shape(), -0.99, 0.99, dtype=gmm.dtype)) gmm.w.assign( tf.random.uniform(gmm.w.get_shape(), -7, 7, dtype=gmm.dtype)) # pot = PolynomialPotential(c=c, m=27, n=27, order=2, dtype=tf.float64) pot = NeuralNetPotential(node_units=(3, 4, 4, 3), edge_units=(4, 5, 5, 4), dtype=tf.float64) x0 = tf.random.uniform([c, bs, 729, 1, 1], 0, 1, dtype=gmm.dtype) x0 = tf.tile(x0, [1, 1, 1, l, 1]) gmm.mu[:, 1:, :729, ...].assign(x0) gmm.sigma[:, 1:, :729, ...].assign(tf.zeros_like(x0)) with tf.GradientTape(watch_accessed_variables=False) as tape: tape.watch(gmm.trainable_variables) bfe = gmm.bethe_free_energy(pot) grd = tape.gradient(bfe, gmm.trainable_variables) grd = [ tf.where(tf.math.is_nan(grd[i]), tf.zeros_like(grd[i]), grd[i]) for i in range(len(grd)) ] # grd, bfe = gmm.gradient_cf(pot) # --------------------below are close form gradient calculating--------------------- gmm2 = GMMHidden(c=c, m=27, l=l, k=17, bs=bs, dtype=tf.float64) gmm2.mu.assign(gmm.mu.read_value()) gmm2.sigma.assign(gmm.sigma.read_value()) # gmm2.rou.assign(gmm.rou.read_value()) gmm2.w.assign(gmm.w.read_value()) # with tf.GradientTape(watch_accessed_variables=False) as tape: # tape.watch(gmm2.trainable_variables) # bfe2 = gmm2.bethe_free_energy(pot) # grd2 = tape.gradient(bfe2, gmm2.trainable_variables) grd2, bfe2 = gmm2.gradient_cf(pot) tolerance = 1e-6 # self.assertAllClose(bfe, bfe2, tolerance, tolerance) self.assertAllClose(grd[:-1], grd2[:-1], rtol=tolerance, atol=tolerance) print(f'max grd{[tf.reduce_max(i).numpy() for i in grd]}') print(f'max grd2{[tf.reduce_max(i).numpy() for i in grd2]}') print(f'min grd{[tf.reduce_min(i).numpy() for i in grd]}') print(f'min grd2{[tf.reduce_min(i).numpy() for i in grd2]}')