def __init__(self, input_layer, input_layer_size, num_classes, scope=None, **kwargs):
if not hasattr(num_classes, "__len__"):
num_classes = (num_classes, )
# All splits are done via half-spaces, so there are always 2^k-1 output
# nodes. We handle non-power-of-two nodes by keeping track of the buffer
# sizes vs. the actual multinomial dimensions.
self._num_classes = num_classes
self._dim_sizes = [2**(int(np.ceil(np.log2(c)))) for c in num_classes]
self._num_nodes = np.prod(self._dim_sizes) - 1 # flatten the density into a 1-d grid
self._split_labels, self._split_masks = self.multinomial_split_masks()
with tf.variable_scope(scope or type(self).__name__):
self._labels = tf.placeholder(tf.float32, shape=[None, np.prod(self._num_classes)])
W = weight_variable([input_layer_size, self._num_nodes])
b = bias_variable([self._num_nodes])
split_indices = tf.to_int32(tf.argmax(self._labels, 1))
splits, z = tf.gather(self._split_labels, split_indices), tf.gather(self._split_masks, split_indices)
# q is the value of the tree nodes
# m is the value of the multinomial bins
self._q = tf.reciprocal(1 + tf.exp(-(tf.matmul(input_layer,W) + b)))
r = splits * tf.log(tf.clip_by_value(self._q, 1e-10, 1.0))
s = (1 - splits) * tf.log(tf.clip_by_value(1 - self._q, 1e-10, 1.0))
self._loss_function = tf.reduce_mean(-tf.reduce_sum(z * (r+s),
axis=[1]))
# Convert from multiscale output to multinomial output
L, R = self.multiscale_splits_masks()
q_tiles = tf.constant([1, np.prod(self._num_classes)])
m = tf.map_fn(lambda q_i: self.multiscale_to_multinomial(q_i, L, R, q_tiles), self._q)
# Reshape to the original dimensions of the density
density_shape = tf.stack([tf.shape(self._q)[0]] + list(self._num_classes))
self._density = tf.reshape(m, density_shape)
self._cross_entropy = tf.reduce_mean(-tf.reduce_sum(self._labels * tf.log(tf.clip_by_value(m, 1e-10, 1.0))
+ (1 - self._labels) * tf.log(tf.clip_by_value(1 - m, 1e-10, 1.0)),
axis=[1]))
评论列表
文章目录