Exemplo n.º 1
0
    def test_call_on_placeholder(self, initializer):
        with tf.Graph().as_default():
            inputs = tf.compat.v1.placeholder(dtype=tf.float32,
                                              shape=[None, None])
            rff_layer = kernel_layers.RandomFourierFeatures(
                output_dim=5,
                kernel_initializer=initializer,
                name="random_fourier_features",
            )
            with self.assertRaisesRegex(
                    ValueError,
                    "The last dimension of the input tensor should be defined",
            ):
                rff_layer(inputs)

            inputs = tf.compat.v1.placeholder(dtype=tf.float32,
                                              shape=[2, None])
            rff_layer = kernel_layers.RandomFourierFeatures(
                output_dim=5,
                kernel_initializer=initializer,
                name="random_fourier_features",
            )
            with self.assertRaisesRegex(
                    ValueError,
                    "The last dimension of the input tensor should be defined",
            ):
                rff_layer(inputs)

            inputs = tf.compat.v1.placeholder(dtype=tf.float32,
                                              shape=[None, 3])
            rff_layer = kernel_layers.RandomFourierFeatures(
                output_dim=5, name="random_fourier_features")
            rff_layer(inputs)
Exemplo n.º 2
0
    def test_different_params_similar_approximation(self, initializer, scale):
        tf.compat.v1.set_random_seed(12345)
        rff_layer1 = kernel_layers.RandomFourierFeatures(
            output_dim=3000,
            kernel_initializer=initializer,
            scale=scale,
            name="rff1",
        )
        rff_layer2 = kernel_layers.RandomFourierFeatures(
            output_dim=2000,
            kernel_initializer=initializer,
            scale=scale,
            name="rff2",
        )
        # Two distinct inputs.
        x = tf.constant([[1.0, -1.0, 0.5]])
        y = tf.constant([[-1.0, 1.0, 1.0]])

        # Apply both layers to both inputs.
        output_x1 = math.sqrt(2.0 / 3000.0) * rff_layer1(x)
        output_y1 = math.sqrt(2.0 / 3000.0) * rff_layer1(y)
        output_x2 = math.sqrt(2.0 / 2000.0) * rff_layer2(x)
        output_y2 = math.sqrt(2.0 / 2000.0) * rff_layer2(y)

        # Compute the inner products of the outputs (on inputs x and y) for both
        # layers. For any fixed random features layer rff_layer, and inputs x,
        # y, rff_layer(x)^T * rff_layer(y) ~= K(x,y) up to a normalization
        # factor.
        approx_kernel1 = kernelized_utils.inner_product(output_x1, output_y1)
        approx_kernel2 = kernelized_utils.inner_product(output_x2, output_y2)
        self._assert_all_close(approx_kernel1, approx_kernel2, atol=0.08)
Exemplo n.º 3
0
  def test_bad_kernel_approximation(self, initializer, scale, exact_kernel_fn):
    """Approximation is bad when output dimension is small."""
    # Two distinct inputs.
    x = tf.constant([[1.0, -1.0, 0.5]])
    y = tf.constant([[-1.0, 1.0, 1.0]])

    small_output_dim = 10
    tf.compat.v1.set_random_seed(1234)
    # Initialize layer.
    rff_layer = kernel_layers.RandomFourierFeatures(
        output_dim=small_output_dim,
        kernel_initializer=initializer,
        scale=scale,
        name='random_fourier_features')

    # Apply layer to both inputs.
    output_x = math.sqrt(2.0 / small_output_dim) * rff_layer(x)
    output_y = math.sqrt(2.0 / small_output_dim) * rff_layer(y)

    # The inner products of the outputs (on inputs x and y) approximates the
    # real value of the RBF kernel but poorly since the output dimension of the
    # layer is small.
    exact_kernel_value = exact_kernel_fn(x, y)
    approx_kernel_value = kernelized_utils.inner_product(output_x, output_y)
    abs_error = tf.abs(exact_kernel_value - approx_kernel_value)
    if not tf.executing_eagerly():
      with self.cached_session() as sess:
        keras_backend._initialize_variables(sess)
        abs_error_eval = sess.run([abs_error])
        self.assertGreater(abs_error_eval[0][0], 0.01)
        self.assertLess(abs_error_eval[0][0], 0.5)
    else:
      self.assertGreater(abs_error, 0.01)
      self.assertLess(abs_error, 0.5)
Exemplo n.º 4
0
 def test_unsupported_kernel_type(self):
     with self.assertRaisesRegex(
             ValueError,
             r'Unsupported kernel type: \'unsupported_kernel\'.'):
         _ = kernel_layers.RandomFourierFeatures(3,
                                                 'unsupported_kernel',
                                                 stddev=2.0)
Exemplo n.º 5
0
 def test_invalid_input_shape(self):
     inputs = tf.random.uniform((3, 2, 4), seed=1)
     rff_layer = kernel_layers.RandomFourierFeatures(output_dim=10,
                                                     scale=3.0)
     with self.assertRaisesRegex(
             ValueError, "The rank of the input tensor should be 2"):
         _ = rff_layer(inputs)
Exemplo n.º 6
0
 def test_output_shape(self):
     inputs = tf.random.uniform((3, 2), seed=1)
     rff_layer = kernel_layers.RandomFourierFeatures(
         output_dim=7, name="random_fourier_features", trainable=True
     )
     outputs = rff_layer(inputs)
     self.assertEqual([3, 7], outputs.shape.as_list())
Exemplo n.º 7
0
    def test_compute_output_shape(self, output_dim, initializer, scale):
        rff_layer = kernel_layers.RandomFourierFeatures(output_dim,
                                                        initializer,
                                                        scale=scale,
                                                        name="rff")
        with self.assertRaises(ValueError):
            rff_layer.compute_output_shape(tf.TensorShape(None))
        with self.assertRaises(ValueError):
            rff_layer.compute_output_shape(tf.TensorShape([]))
        with self.assertRaises(ValueError):
            rff_layer.compute_output_shape(tf.TensorShape([3]))
        with self.assertRaises(ValueError):
            rff_layer.compute_output_shape(tf.TensorShape([3, 2, 3]))

        with self.assertRaisesRegex(
                ValueError,
                "The last dimension of the input tensor should be defined",
        ):
            rff_layer.compute_output_shape(tf.TensorShape([3, None]))

        self.assertEqual(
            [None, output_dim],
            rff_layer.compute_output_shape((None, 3)).as_list(),
        )
        self.assertEqual(
            [None, output_dim],
            rff_layer.compute_output_shape(tf.TensorShape([None,
                                                           2])).as_list(),
        )
        self.assertEqual([4, output_dim],
                         rff_layer.compute_output_shape((4, 1)).as_list())
Exemplo n.º 8
0
    def test_good_kernel_approximation_multiple_inputs(self, initializer,
                                                       scale, exact_kernel_fn):
        # Parameters.
        input_dim = 5
        output_dim = 2000
        x_rows = 20
        y_rows = 30

        x = tf.constant(np.random.uniform(size=(x_rows, input_dim)),
                        dtype=tf.float32)
        y = tf.constant(np.random.uniform(size=(y_rows, input_dim)),
                        dtype=tf.float32)

        tf.compat.v1.set_random_seed(1234)
        rff_layer = kernel_layers.RandomFourierFeatures(
            output_dim=output_dim,
            kernel_initializer=initializer,
            scale=scale,
            name="random_fourier_features",
        )

        # The shapes of output_x and output_y are (x_rows, output_dim) and
        # (y_rows, output_dim) respectively.
        output_x = math.sqrt(2.0 / output_dim) * rff_layer(x)
        output_y = math.sqrt(2.0 / output_dim) * rff_layer(y)

        approx_kernel_matrix = kernelized_utils.inner_product(
            output_x, output_y)
        exact_kernel_matrix = exact_kernel_fn(x, y)
        self._assert_all_close(approx_kernel_matrix,
                               exact_kernel_matrix,
                               atol=0.05)
Exemplo n.º 9
0
    def test_get_config(self, output_dim, initializer, scale, trainable):
        rff_layer = kernel_layers.RandomFourierFeatures(
            output_dim,
            initializer,
            scale=scale,
            trainable=trainable,
            name="random_fourier_features",
        )
        expected_initializer = initializer
        if not isinstance(initializer, str):
            expected_initializer = initializers.serialize(initializer)

        expected_dtype = ("float32"
                          if base_layer_utils.v2_dtype_behavior_enabled() else
                          None)
        expected_config = {
            "output_dim": output_dim,
            "kernel_initializer": expected_initializer,
            "scale": scale,
            "name": "random_fourier_features",
            "trainable": trainable,
            "dtype": expected_dtype,
        }
        self.assertLen(expected_config, len(rff_layer.get_config()))
        self.assertSameElements(list(expected_config.items()),
                                list(rff_layer.get_config().items()))
Exemplo n.º 10
0
 def test_unsupported_kernel_type(self):
     with self.assertRaisesRegex(
         ValueError, "Unsupported `kernel_initializer`"
     ):
         _ = kernel_layers.RandomFourierFeatures(
             3, "unsupported_kernel", stddev=2.0
         )
Exemplo n.º 11
0
    def test_get_config(self, output_dim, initializer, scale, trainable):
        rff_layer = kernel_layers.RandomFourierFeatures(
            output_dim,
            initializer,
            scale=scale,
            trainable=trainable,
            name='random_fourier_features',
        )
        expected_initializer = initializer
        if not isinstance(initializer, six.string_types):
            expected_initializer = initializers.serialize(initializer)

        expected_dtype = ('float32'
                          if base_layer_utils.v2_dtype_behavior_enabled() else
                          None)
        expected_config = {
            'output_dim': output_dim,
            'kernel_initializer': expected_initializer,
            'scale': scale,
            'name': 'random_fourier_features',
            'trainable': trainable,
            'dtype': expected_dtype,
        }
        self.assertLen(expected_config, len(rff_layer.get_config()))
        self.assertSameElements(list(expected_config.items()),
                                list(rff_layer.get_config().items()))
Exemplo n.º 12
0
    def test_compute_output_shape(self, output_dim, initializer, scale):
        rff_layer = kernel_layers.RandomFourierFeatures(output_dim,
                                                        initializer,
                                                        scale=scale,
                                                        name='rff')
        with self.assertRaises(ValueError):
            rff_layer.compute_output_shape(tf.TensorShape(None))
        with self.assertRaises(ValueError):
            rff_layer.compute_output_shape(tf.TensorShape([]))
        with self.assertRaises(ValueError):
            rff_layer.compute_output_shape(tf.TensorShape([3]))
        with self.assertRaises(ValueError):
            rff_layer.compute_output_shape(tf.TensorShape([3, 2, 3]))

        with self.assertRaisesRegex(
                ValueError,
                r'The innermost dimension of input shape must be defined.'):
            rff_layer.compute_output_shape(tf.TensorShape([3, None]))

        self.assertEqual([None, output_dim],
                         rff_layer.compute_output_shape((None, 3)).as_list())
        self.assertEqual([None, output_dim],
                         rff_layer.compute_output_shape(
                             tf.TensorShape([None, 2])).as_list())
        self.assertEqual([4, output_dim],
                         rff_layer.compute_output_shape((4, 1)).as_list())
Exemplo n.º 13
0
 def test_random_features_properties(self, initializer, scale, trainable):
     rff_layer = kernel_layers.RandomFourierFeatures(
         output_dim=10,
         kernel_initializer=initializer,
         scale=scale,
         trainable=trainable)
     self.assertEqual(rff_layer.output_dim, 10)
     self.assertEqual(rff_layer.kernel_initializer, initializer)
     self.assertEqual(rff_layer.scale, scale)
     self.assertEqual(rff_layer.trainable, trainable)
Exemplo n.º 14
0
 def test_call(self, initializer, trainable):
   rff_layer = kernel_layers.RandomFourierFeatures(
       output_dim=10,
       kernel_initializer=initializer,
       scale=1.0,
       trainable=trainable,
       name='random_fourier_features')
   inputs = tf.random.uniform((3, 2), seed=1)
   outputs = rff_layer(inputs)
   self.assertListEqual([3, 10], outputs.shape.as_list())
   num_trainable_vars = 1 if trainable else 0
   self.assertLen(rff_layer.non_trainable_variables, 3 - num_trainable_vars)
Exemplo n.º 15
0
 def test_same_random_features_params_reused(self, output_dim, initializer,
                                             scale, trainable):
     """Applying the layer on the same input twice gives the same output."""
     rff_layer = kernel_layers.RandomFourierFeatures(
         output_dim=output_dim,
         kernel_initializer=initializer,
         scale=scale,
         trainable=trainable,
         name='random_fourier_features')
     inputs = tf.constant(np.random.uniform(low=-1.0, high=1.0,
                                            size=(2, 4)))
     output1 = rff_layer(inputs)
     output2 = rff_layer(inputs)
     self._assert_all_close(output1, output2)
Exemplo n.º 16
0
 def test_state_saving_and_loading(self):
   with self.cached_session():
     input_data = np.random.random((1, 2))
     rff_layer = kernel_layers.RandomFourierFeatures(output_dim=10, scale=3.0)
     inputs = input_layer.Input((2,))
     outputs = rff_layer(inputs)
     model = training.Model(inputs, outputs)
     output_data = model.predict(input_data)
     temp_dir = self.get_temp_dir()
     self.addCleanup(shutil.rmtree, temp_dir)
     saved_model_dir = os.path.join(temp_dir, 'rff_model')
     model.save(saved_model_dir)
     new_model = save.load_model(saved_model_dir)
     new_output_data = new_model.predict(input_data)
     self.assertAllClose(output_data, new_output_data, atol=1e-4)
Exemplo n.º 17
0
 def test_invalid_scale(self):
     with self.assertRaisesRegex(
             ValueError,
             "When provided, `scale` should be a positive float"):
         _ = kernel_layers.RandomFourierFeatures(output_dim=10, scale=0.0)
Exemplo n.º 18
0
 def test_invalid_output_dim(self):
     with self.assertRaisesRegex(
             ValueError, "`output_dim` should be a positive integer"):
         _ = kernel_layers.RandomFourierFeatures(output_dim=-3, scale=2.0)
Exemplo n.º 19
0
 def test_no_eager_Leak(self):
     # Tests that repeatedly constructing and building a Layer does not leak
     # Python objects.
     inputs = tf.random.uniform((5, 4), seed=1)
     kernel_layers.RandomFourierFeatures(output_dim=4, name="rff")(inputs)
     kernel_layers.RandomFourierFeatures(output_dim=10, scale=2.0)(inputs)