|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| """Optimizers mostly for value estimate.
|
|
|
| Gradient Descent optimizer
|
| LBFGS optimizer
|
| Best Fit optimizer
|
|
|
| """
|
|
|
| from __future__ import absolute_import
|
| from __future__ import division
|
| from __future__ import print_function
|
|
|
| from six.moves import xrange
|
| import tensorflow as tf
|
| import numpy as np
|
| import scipy.optimize
|
|
|
|
|
| def var_size(v):
|
| return int(np.prod([int(d) for d in v.shape]))
|
|
|
|
|
| def gradients(loss, var_list):
|
| grads = tf.gradients(loss, var_list)
|
| return [g if g is not None else tf.zeros(v.shape)
|
| for g, v in zip(grads, var_list)]
|
|
|
| def flatgrad(loss, var_list):
|
| grads = gradients(loss, var_list)
|
| return tf.concat([tf.reshape(grad, [-1])
|
| for (v, grad) in zip(var_list, grads)
|
| if grad is not None], 0)
|
|
|
|
|
| def get_flat(var_list):
|
| return tf.concat([tf.reshape(v, [-1]) for v in var_list], 0)
|
|
|
|
|
| def set_from_flat(var_list, flat_theta):
|
| assigns = []
|
| shapes = [v.shape for v in var_list]
|
| sizes = [var_size(v) for v in var_list]
|
|
|
| start = 0
|
| assigns = []
|
| for (shape, size, v) in zip(shapes, sizes, var_list):
|
| assigns.append(v.assign(
|
| tf.reshape(flat_theta[start:start + size], shape)))
|
| start += size
|
| assert start == sum(sizes)
|
|
|
| return tf.group(*assigns)
|
|
|
|
|
| class LbfgsOptimization(object):
|
|
|
| def __init__(self, max_iter=25, mix_frac=1.0):
|
| self.max_iter = max_iter
|
| self.mix_frac = mix_frac
|
|
|
| def setup_placeholders(self):
|
| self.flat_theta = tf.placeholder(tf.float32, [None], 'flat_theta')
|
| self.intended_values = tf.placeholder(tf.float32, [None], 'intended_values')
|
|
|
| def setup(self, var_list, values, targets, pads,
|
| inputs, regression_weight):
|
| self.setup_placeholders()
|
| self.values = values
|
| self.targets = targets
|
|
|
| self.raw_loss = (tf.reduce_sum((1 - pads) * tf.square(values - self.intended_values))
|
| / tf.reduce_sum(1 - pads))
|
| self.loss_flat_gradient = flatgrad(self.raw_loss, var_list)
|
|
|
| self.flat_vars = get_flat(var_list)
|
| self.set_vars = set_from_flat(var_list, self.flat_theta)
|
|
|
| def optimize(self, sess, feed_dict):
|
| old_theta = sess.run(self.flat_vars)
|
|
|
| old_values, targets = sess.run([self.values, self.targets], feed_dict=feed_dict)
|
| intended_values = targets * self.mix_frac + old_values * (1 - self.mix_frac)
|
| feed_dict = dict(feed_dict)
|
| feed_dict[self.intended_values] = intended_values
|
|
|
| def calc_loss_and_grad(theta):
|
| sess.run(self.set_vars, feed_dict={self.flat_theta: theta})
|
| loss, grad = sess.run([self.raw_loss, self.loss_flat_gradient],
|
| feed_dict=feed_dict)
|
| grad = grad.astype('float64')
|
| return loss, grad
|
|
|
| theta, _, _ = scipy.optimize.fmin_l_bfgs_b(
|
| calc_loss_and_grad, old_theta, maxiter=self.max_iter)
|
| sess.run(self.set_vars, feed_dict={self.flat_theta: theta})
|
|
|
|
|
| class GradOptimization(object):
|
|
|
| def __init__(self, learning_rate=0.001, max_iter=25, mix_frac=1.0):
|
| self.learning_rate = learning_rate
|
| self.max_iter = max_iter
|
| self.mix_frac = mix_frac
|
|
|
| def get_optimizer(self):
|
| return tf.train.AdamOptimizer(learning_rate=self.learning_rate,
|
| epsilon=2e-4)
|
|
|
| def setup_placeholders(self):
|
| self.flat_theta = tf.placeholder(tf.float32, [None], 'flat_theta')
|
| self.intended_values = tf.placeholder(tf.float32, [None], 'intended_values')
|
|
|
| def setup(self, var_list, values, targets, pads,
|
| inputs, regression_weight):
|
| self.setup_placeholders()
|
| self.values = values
|
| self.targets = targets
|
|
|
| self.raw_loss = (tf.reduce_sum((1 - pads) * tf.square(values - self.intended_values))
|
| / tf.reduce_sum(1 - pads))
|
|
|
| opt = self.get_optimizer()
|
| params = var_list
|
| grads = tf.gradients(self.raw_loss, params)
|
| self.gradient_ops = opt.apply_gradients(zip(grads, params))
|
|
|
| def optimize(self, sess, feed_dict):
|
| old_values, targets = sess.run([self.values, self.targets], feed_dict=feed_dict)
|
| intended_values = targets * self.mix_frac + old_values * (1 - self.mix_frac)
|
|
|
| feed_dict = dict(feed_dict)
|
| feed_dict[self.intended_values] = intended_values
|
|
|
| for _ in xrange(self.max_iter):
|
| sess.run(self.gradient_ops, feed_dict=feed_dict)
|
|
|
|
|
| class BestFitOptimization(object):
|
|
|
| def __init__(self, mix_frac=1.0):
|
| self.mix_frac = mix_frac
|
|
|
| def setup_placeholders(self):
|
| self.new_regression_weight = tf.placeholder(
|
| tf.float32, self.regression_weight.shape)
|
|
|
| def setup(self, var_list, values, targets, pads,
|
| inputs, regression_weight):
|
| self.values = values
|
| self.targets = targets
|
|
|
| self.inputs = inputs
|
| self.regression_weight = regression_weight
|
|
|
| self.setup_placeholders()
|
|
|
| self.update_regression_weight = tf.assign(
|
| self.regression_weight, self.new_regression_weight)
|
|
|
| def optimize(self, sess, feed_dict):
|
| reg_input, reg_weight, old_values, targets = sess.run(
|
| [self.inputs, self.regression_weight, self.values, self.targets],
|
| feed_dict=feed_dict)
|
|
|
| intended_values = targets * self.mix_frac + old_values * (1 - self.mix_frac)
|
|
|
|
|
| reg_coeff = 1e-5
|
| for _ in range(5):
|
| best_fit_weight = np.linalg.lstsq(
|
| reg_input.T.dot(reg_input) +
|
| reg_coeff * np.identity(reg_input.shape[1]),
|
| reg_input.T.dot(intended_values))[0]
|
| if not np.any(np.isnan(best_fit_weight)):
|
| break
|
| reg_coeff *= 10
|
|
|
| if len(best_fit_weight.shape) == 1:
|
| best_fit_weight = np.expand_dims(best_fit_weight, -1)
|
|
|
| sess.run(self.update_regression_weight,
|
| feed_dict={self.new_regression_weight: best_fit_weight})
|
|
|