def test_lower_bound_raises_on_different_dtypes(self): """Make sure that lower_bound() raises when given different dtypes.""" value1 = 3.1 value2 = 2.7 expression1 = operations.wrap_rate( tf.constant(value1, dtype=tf.float32)) expression2 = operations.wrap_rate( tf.constant(value2, dtype=tf.float64)) # List elements have different dtypes. with self.assertRaises(TypeError): operations.lower_bound([expression1, expression2])
def test_wrap_rate_penalty_and_constraint(self): """Make sure that wrap_rate() works correctly when given two parameters.""" penalty_value = 3.1 constraint_value = 2.7 penalty_tensor = tf.constant(penalty_value, dtype=tf.float32) constraint_tensor = tf.constant(constraint_value, dtype=tf.float32) wrapped = operations.wrap_rate(penalty_tensor, constraint_tensor) wrapped = operations.wrap_rate(penalty_tensor) actual_penalty_value, actual_constraint_value = self._evaluate_expression( wrapped) # The penalty and constraint portions of the Expression were initialized to # penalty_tensor and constraint_tensor, respectively. self.assertNear(penalty_value, actual_penalty_value, err=1e-6) self.assertNear(penalty_value, actual_constraint_value, err=1e-6)
def test_keras_layer(self): """Tests the `KerasLayer` class.""" zero_placeholder = keras.KerasPlaceholder( lambda y_true, y_pred: tf.constant(0.0)) one_constant = lambda: tf.constant(1.0) two_placeholder = keras.KerasPlaceholder( lambda y_true, y_pred: tf.constant(0.2)) three_constant = lambda: tf.constant(0.03) four_placeholder = keras.KerasPlaceholder( lambda y_true, y_pred: tf.constant(0.004)) zero = operations.wrap_rate(zero_placeholder) one = operations.wrap_rate(one_constant) two = operations.wrap_rate(two_placeholder) three = operations.wrap_rate(three_constant) four = operations.wrap_rate(four_placeholder) objective = sum([one, two, three, four], zero) constraints = [zero <= one] # Trying to create a KerasLayer without including the input placeholders # should raise. with self.assertRaises(ValueError): _ = keras.KerasLayer(objective=objective, constraints=constraints) placeholders = [zero_placeholder, two_placeholder, four_placeholder] layer = MockKerasLayer(objective=objective, constraints=constraints, placeholders=placeholders) # Make sure that we created the variables we expected. expected_names = {"tfco_global_step", "tfco_lagrange_multipliers"} actual_names = set(layer.names) self.assertEqual(expected_names, actual_names) # and that the layer is aware of them. keras_names = [weight.name for weight in layer.weights] keras_names.sort() self.assertTrue(keras_names[0].startswith("tfco_global_step")) self.assertTrue(keras_names[1].startswith("tfco_lagrange_multipliers")) # Make sure that the loss evaluates to the correct value, including both the # constant and placeholder inputs. with self.wrapped_session() as session: result = session.run(layer.loss(-10.0, -100.0)) self.assertNear(1.234, result, err=1e-6)
def test_lower_bound_raises_on_tensor(self): """Make sure that lower_bound() raises when given a non-Expression.""" value1 = 3.1 value2 = 2.7 tensor1 = tf.constant(value1, dtype=tf.float32) expression2 = operations.wrap_rate(tf.constant(value2, dtype=tf.float64)) # List element is a Tensor, instead of an Expression. with self.assertRaises(TypeError): operations.lower_bound([tensor1, expression2])
def test_lower_bound_raises_on_minimization(self): """Make sure that lower_bound() raises if it's minimized.""" bounded = operations.lower_bound([operations.wrap_rate(1.0)]) # All three of "penalty_expression", "constraint_expression" and # "extra_constraints" should raise. with self.assertRaises(RuntimeError): _ = bounded.penalty_expression with self.assertRaises(RuntimeError): _ = bounded.constraint_expression with self.assertRaises(RuntimeError): _ = bounded.extra_constraints
def test_wrap_rate_penalty(self): """Make sure that wrap_rate() works correctly when given one parameter.""" penalty_value = 3.1 penalty_tensor = tf.constant(penalty_value, dtype=tf.float32) wrapped = operations.wrap_rate(penalty_tensor) actual_penalty_value, actual_constraint_value = self._evaluate_expression( wrapped) # Both the penalty and the constraint portions of the Expression were # initialized to penalty_tensor. self.assertNear(penalty_value, actual_penalty_value, err=1e-6) self.assertNear(penalty_value, actual_constraint_value, err=1e-6)
def test_wrap_rate_raises(self): """Make sure that wrap_rate() raises if given an `Expression`.""" penalty_value = 3.1 constraint_value = 2.7 wrapped = operations.wrap_rate(penalty_value, constraint_value) # We should raise a TypeError if either or both of the parameters to # wrap_rate() are Expressions. with self.assertRaises(TypeError): operations.wrap_rate(penalty_value, wrapped) with self.assertRaises(TypeError): operations.wrap_rate(wrapped, constraint_value) with self.assertRaises(TypeError): operations.wrap_rate(wrapped, wrapped)
def test_lower_bound(self): """Make sure that lower_bound() creates the correct Expression.""" values = [0.8, 3.1, -1.6, 2.7] bound_value = 1.4 expressions = [operations.wrap_rate(value) for value in values] # We need to negate "bounded" since it's implicitly being minimized, and we # cannot minimize a lower bound. bounded = -operations.lower_bound(expressions) # Before evaluating any expressions, we'll assign "bound_value" to the slack # variable, so that we can make sure that the same slack variable is being # used for all of the constraints. def update_ops_fn(memoizer, variables): lower_bound_tensor = None for variable in variables: tensor = variable(memoizer) if tensor.name.startswith("tfco_lower_bound"): self.assertIsNone(lower_bound_tensor) lower_bound_tensor = tensor self.assertIsNotNone(lower_bound_tensor) return [lower_bound_tensor.assign(bound_value)] # Extract the set of constraints, and make sure that there is one for each # quantity that is being bounded. self.assertEqual(len(values), len(bounded.extra_constraints)) constraints = list(bounded.extra_constraints) # Evaluate the constraint expressions. actual_values = [] for constraint in constraints: actual_penalty_value, actual_constraint_value = self._evaluate_expression( constraint.expression, update_ops_fn) self.assertEqual(actual_penalty_value, actual_constraint_value) actual_values.append(actual_penalty_value) # Constraints take the form expression <= 0, and these are lower-bound # constraints, so we're expecting: # bound_value - value1 <= 0 # bound_value - value2 <= 0 # .... # We sort the constraint expression values since they occur in no particular # order. actual_values = sorted(actual_values) expected_values = sorted(bound_value - value for value in values) self.assertAllClose(expected_values, actual_values, rtol=0, atol=1e-6)
def test_wrap_rate_raises(self): """Make sure that wrap_rate() raises if given an `Expression`.""" penalty_value = 3.1 constraint_value = 2.7 penalty_tensor = tf.constant(penalty_value, dtype=tf.float32) constraint_tensor = tf.constant(constraint_value, dtype=tf.float32) wrapped = operations.wrap_rate(penalty_tensor, constraint_tensor) # We should raise a TypeError if either or both of the parameters to # wrap_rate() are Expressions. with self.assertRaises(TypeError): operations.wrap_rate(penalty_tensor, wrapped) with self.assertRaises(TypeError): operations.wrap_rate(wrapped, constraint_tensor) with self.assertRaises(TypeError): operations.wrap_rate(wrapped, wrapped)
def test_lower_bound(self): """Make sure that lower_bound() creates the correct Expression.""" values = [0.8, 3.1, -1.6, 2.7] bound_value = 1.4 tensors = [tf.constant(value, dtype=tf.float32) for value in values] expressions = [operations.wrap_rate(tt) for tt in tensors] bounded = operations.lower_bound(expressions) # Before evaluating any expressions, we'll assign "bound_value" to the slack # variable, so that we can make sure that the same slack variable is being # used for all of the constraints. bound_tensor = bounded.penalty_expression.tensor self.assertEqual(tf.float32, bound_tensor.dtype.base_dtype) pre_train_ops = [tf.assign(bound_tensor, bound_value)] # Extract the set of constraints, and make sure that there is one for each # quantity that is being bounded. self.assertEqual(len(values), len(bounded.extra_constraints)) constraints = list(bounded.extra_constraints) # Evaluate the constraint expressions. actual_values = [] for constraint in constraints: actual_penalty_value, actual_constraint_value = self._evaluate_expression( constraint.expression, pre_train_ops) self.assertEqual(actual_penalty_value, actual_constraint_value) actual_values.append(actual_penalty_value) # Constraints take the form expression <= 0, and these are lower-bound # constraints, so we're expecting: # bound_value - value1 <= 0 # bound_value - value2 <= 0 # .... # We sort the constraint expression values since they occur in no particular # order. actual_values = sorted(actual_values) expected_values = sorted(bound_value - value for value in values) self.assertAllClose(expected_values, actual_values, rtol=0, atol=1e-6)