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_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_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_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_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)
def test_lower_bound_raises_on_empty_list(self): """Make sure that lower_bound() raises for an empty expressions list.""" with self.assertRaises(ValueError): operations.lower_bound([])