def testNearZeroObjectivesAndDirectionCoordinates(self): multi_objectives = tf.constant([[3, 0, 0]], dtype=tf.float32) # direction with small non-zero coordinates. nonzero = 2 * multi_objective_scalarizer.HyperVolumeScalarizer.ALMOST_ZERO direction = [1, nonzero, nonzero] scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params) self.assertAllClose(self.evaluate(scalarizer(multi_objectives)), self.evaluate(tf.constant([0], dtype=tf.float32))) # direction with coordinates that are so small in magnitude that would be # considered zeros. direction = [1, 1e-30, 1e-30] scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params) self.assertAllClose(self.evaluate(scalarizer(multi_objectives)), self.evaluate(tf.constant([3], dtype=tf.float32))) # direction with absolute zero coordinates. direction = [1, 0, 0] scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params) self.assertAllClose(self.evaluate(scalarizer(multi_objectives)), self.evaluate(tf.constant([3], dtype=tf.float32)))
def testCustomTransform(self): transform = lambda m, s, o: m * s + o scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( [1, 0, 0], self._hv_params, transform) self.assertAllClose( self.evaluate(scalarizer(self._batch_multi_objectives)), self.evaluate(tf.constant([3, 6], dtype=tf.float32))) transform2 = lambda m, s, o: tf.multiply(m, m) * s + o scalarizer2 = multi_objective_scalarizer.HyperVolumeScalarizer( [0.1, 0.2, 0.2], self._hv_params, transform2) self.assertAllClose( self.evaluate(scalarizer2(self._batch_multi_objectives)), self.evaluate(tf.constant([1.5, 24.], dtype=tf.float32)))
def testAxisAlignedDirection(self): direction = [0, 1, 0] scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params) self.assertAllEqual( self.evaluate(scalarizer(self._batch_multi_objectives)), self.evaluate(tf.constant([2, 5], dtype=tf.float32)))
def testDirectionNormalization(self): for direction in [[1, 2, 2], [0.1, 0.2, 0.2]]: scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params) self.assertAllClose( self.evaluate(scalarizer(self._batch_multi_objectives)), self.evaluate(tf.constant([1.5, 6], dtype=tf.float32)))
def testNegativeObjectives(self): direction = [1, 0, 0] scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params) self.assertAllEqual( self.evaluate(scalarizer(-1.0 * self._batch_multi_objectives)), self.evaluate(tf.constant([0, 0], dtype=tf.float32)))
def setUp(self): super(ScalarizeObjectivesTest, self).setUp() hv_params = [ multi_objective_scalarizer.HyperVolumeScalarizer.PARAMS(slope=1, offset=0) ] * 3 self._scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( [0, 1, 0.01], hv_params)
def testInvalidObjectives(self): with self.assertRaisesRegex( ValueError, 'The number of input objectives should be'): direction = [1, 0, 0] scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params) multi_objectives = tf.constant([[1, 2, 3, 4]], dtype=tf.float32) scalarizer(multi_objectives)
def testCallDirectionWrongBatchSizeRaisesValueError(self): direction = [1, 0, 0] scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params) with self.assertRaisesRegex(ValueError, 'does not match the shape of'): scalarizer.set_parameters(direction=tf.constant( [[0, 1, 0], [1, 0, 0], [0, 0, 1]], dtype=tf.float32), transform_params={}) self.evaluate(scalarizer(self._batch_multi_objectives))
def testNegativeObjectives(self): direction = [1, 0, 0] scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params) multi_objectives = tf.constant([[-3, 2, 1], [-6, 5, 4]], dtype=tf.float32) self.assertAllEqual( self.evaluate(scalarizer(multi_objectives)), self.evaluate(tf.constant([0, 0], dtype=tf.float32)))
def testSetParametersDirectionOnly(self): direction = [1, 0, 0] scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params) scalarizer.set_parameters(direction=tf.constant([[0, 1, 0], [0, 0, 1]], dtype=tf.float32), transform_params={}) self.assertAllClose( self.evaluate(scalarizer(self._batch_multi_objectives)), self.evaluate(tf.constant([2, 4], dtype=tf.float32)))
def testObjectiveTranformation(self): hv_params = copy.deepcopy(self._hv_params) hv_params[0] = multi_objective_scalarizer.HyperVolumeScalarizer.PARAMS( slope=-1, offset=2) direction = [1, 0, 0] scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, hv_params) self.assertAllEqual( self.evaluate(scalarizer(-1.0 * self._batch_multi_objectives)), self.evaluate(tf.constant([5, 8], dtype=tf.float32)))
def testSetParametersDirectionWithWrongNumberOfObjectivesRaisesValueError( self): direction = [1, 0, 0] scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params) with self.assertRaisesRegex( ValueError, 'The number of objectives in scalarization parameter'): scalarizer.set_parameters( direction=tf.constant([[0, 1]] * 2, dtype=tf.float32), transform_params={})
def testSetParametersInvalidTransformationParamsKeysRaisesValueError(self): direction = [1, 0, 0] scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params) with self.assertRaisesRegex(ValueError, 'All transform_params keys should be'): scalarizer.set_parameters( direction=tf.constant([[0, 1, 0], [0, 0, 1]], dtype=tf.float32), transform_params={ 'weights': tf.constant([1, 1, 1], dtype=tf.float32) })
def testSetParametersDirectionAndOffset(self): direction = [1, 0, 0] scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params) scalarizer.set_parameters( direction=tf.constant([[0, 1, 0], [0, 0, 1]], dtype=tf.float32), transform_params={ multi_objective_scalarizer.HyperVolumeScalarizer.OFFSET_KEY: tf.constant([[0.5, 0.5, 0.5], [0.1, 0.1, 0.1]], dtype=tf.float32) }) self.assertAllClose( self.evaluate(scalarizer(self._batch_multi_objectives)), self.evaluate(tf.constant([2.5, 4.1], dtype=tf.float32)))
def setUp(self): super(GreedyRewardPredictionPolicyTest, self).setUp() self._obs_spec = tensor_spec.TensorSpec([2], tf.float32) self._time_step_spec = ts.time_step_spec(self._obs_spec) self._action_spec = tensor_spec.BoundedTensorSpec((), tf.int32, 0, 2) hv_params = [ multi_objective_scalarizer.HyperVolumeScalarizer.PARAMS(slope=1, offset=0) ] * 3 self._scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( [0, 1, 0.01], hv_params) self._bias = np.asarray([-1, -1, -1]) self._kernel_weights = [ np.asarray([[1, 2, 3], [4, 5, 6]]), np.asarray([[3, 1, 2], [5, 4, 6]]), np.asarray([[2, 3, 1], [5, 6, 4]]) ]
def setUp(self): super(MultiObjectiveAgentTest, self).setUp() tf.compat.v1.enable_resource_variables() self._time_step_spec = ts.time_step_spec( observation_spec=tensor_spec.TensorSpec([2], tf.float32), reward_spec=tensor_spec.TensorSpec([3], tf.float32)) self._action_spec = tensor_spec.BoundedTensorSpec( dtype=tf.int32, shape=(), minimum=0, maximum=2) self._observation_spec = self._time_step_spec.observation hv_params = [ multi_objective_scalarizer.HyperVolumeScalarizer.PARAMS( slope=1, offset=0) ] * 3 self._scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( [0, 1, 0.01], hv_params) self._bias = np.asarray([-1, -1, -1]) self._kernel_weights = [ np.asarray([[1, 2, 3], [4, 5, 6]]), np.asarray([[3, 1, 2], [5, 4, 6]]), np.asarray([[2, 3, 1], [5, 6, 4]]) ]
def testCustomTransform(self): transform = lambda m, s, o: m * s + o scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( [1, 0, 0], self._hv_params, transform) self.assertAllClose(scalarizer(self._batch_multi_objectives), [3, 6]) transform2 = lambda m, s, o: tf.multiply(m, m) * s + o scalarizer2 = multi_objective_scalarizer.HyperVolumeScalarizer( [0.1, 0.2, 0.2], self._hv_params, transform2) self.assertAllClose(scalarizer2(self._batch_multi_objectives), [1.5, 24.]) def default_transform(metrics, slopes, offsets): transformed_metrics = metrics return transformed_metrics * slopes + offsets scalarizer3 = multi_objective_scalarizer.HyperVolumeScalarizer( [0.1, 0.2, 0.2], self._hv_params, default_transform) default_scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( [0.1, 0.2, 0.2], self._hv_params) self.assertAllClose( self.evaluate(scalarizer3(self._batch_multi_objectives)), self.evaluate(default_scalarizer(self._batch_multi_objectives))) # Apply sigmoid to the 2nd metric. sigmoid_metric_mask = [False, True, False] batch_size = self._batch_multi_objectives.shape[0] sigmoid_batch_mask = tf.reshape( tf.tile(sigmoid_metric_mask, [batch_size]), [batch_size, len(sigmoid_metric_mask)]) def sigmoid_metric_transform(metrics: tf.Tensor, slopes, offsets): transformed_values = tf.where(sigmoid_batch_mask, tf.sigmoid(metrics), metrics) return transformed_values * slopes + offsets sigmoid_scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer( [0.1, 0.2, 0.2], self._hv_params, sigmoid_metric_transform) self.assertAllClose(sigmoid_scalarizer(self._batch_multi_objectives), [1.321196, 1.489961]) sigmoid_scalarizer2 = multi_objective_scalarizer.HyperVolumeScalarizer( [0, 1.0, 0], self._hv_params, sigmoid_metric_transform) self.assertAllClose(sigmoid_scalarizer2(self._batch_multi_objectives), [0.880797, 0.993307])
def testZeroLengthDirection(self): with self.assertRaisesRegex(ValueError, 'nearly-zero vector'): direction = [0, 0, 0] multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params)
def testDirectionWithWrongDimension(self): with self.assertRaisesRegex(ValueError, 'direction has 2 elements but'): direction = [1, 0] multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params)
def testInvalidParams(self): with self.assertRaisesRegex(ValueError, 'nearly-zero vector'): multi_objective_scalarizer.HyperVolumeScalarizer([], []) with self.assertRaisesRegex(ValueError, 'at least two objectives'): multi_objective_scalarizer.HyperVolumeScalarizer( [1], [self._hv_params[0]])
def testDirectionWithNegativeCoordinates(self): with self.assertRaisesRegex(ValueError, 'has negative coordinates'): direction = [-1, 0, 0] multi_objective_scalarizer.HyperVolumeScalarizer( direction, self._hv_params)