Caffe2 - Python API
A deep learning, cross platform ML framework
random_fourier_features.py
1 from __future__ import absolute_import
2 from __future__ import division
3 from __future__ import print_function
4 from __future__ import unicode_literals
5 
6 from caffe2.python import schema
7 from caffe2.python.layers.layers import ModelLayer
8 
9 import numpy as np
10 
11 
13  """
14  Implementation of random fourier feature map for feature processing.
15 
16  Applies sqrt(2 / output_dims) * cos(wx+b), where:
17  output_dims is the output feature dimensions, and
18  wx + b applies FC using randomized, fixed weight and bias parameters
19 
20  For more information, see the original paper:
21  https://people.eecs.berkeley.edu/~brecht/papers/07.rah.rec.nips.pdf
22 
23  Inputs:
24  output_dims -- output feature dimensions
25  sigma -- bandwidth for the Gaussian kernel estimator
26  w_init -- initalization options for weight parameter
27  b_init -- initalization options for bias parameter
28 
29  """
30  def __init__(
31  self,
32  model,
33  input_record,
34  output_dims,
35  sigma, # bandwidth
36  w_init=None,
37  b_init=None,
38  name='random_fourier_features',
39  **kwargs):
40 
41  super(RandomFourierFeatures, self).__init__(model, name, input_record,
42  **kwargs)
43  assert isinstance(input_record, schema.Scalar), "Incorrect input type"
44 
45  input_dims = input_record.field_type().shape[0]
46  assert input_dims >= 1, "Expected input dimensions >= 1, got %s" \
47  % input_dims
48  self.output_dims = output_dims
49  assert self.output_dims >= 1, "Expected output dimensions >= 1, got %s" \
50  % self.output_dims
51 
53  (np.float32, (self.output_dims, )),
54  self.get_next_blob_reference('output')
55  )
56 
57  assert sigma > 0.0, "Expected bandwidth > 0, got %s" % sigma
58 
59  # Initialize train_init_net parameters
60  w_init = w_init if w_init else (
61  'GaussianFill', {'mean': 0.0, 'std': 1.0 / sigma}
62  )
63 
64  b_init = b_init if b_init else (
65  'UniformFill', {'min': 0.0, 'max': 2 * np.pi}
66  )
67 
68  self.w = self.create_param(param_name='w',
69  shape=[self.output_dims, input_dims],
70  initializer=w_init,
71  optimizer=model.NoOptim)
72 
73  self.b = self.create_param(param_name='b',
74  shape=[self.output_dims],
75  initializer=b_init,
76  optimizer=model.NoOptim)
77 
78  def add_ops(self, net):
79  # Random features: wx + b
80  cosine_arg = net.FC(self.input_record.field_blobs() + [self.w, self.b],
81  net.NextScopedBlob("cosine_arg"))
82 
83  # Apply cosine to new vectors
84  new_feature_vec = net.Cos([cosine_arg],
85  net.NextScopedBlob('new_feature_vec'))
86 
87  # Multiply each element in vector by sqrt(2/D)
88  scale = np.sqrt(2.0 / self.output_dims)
89  net.Scale([new_feature_vec],
90  self.output_schema.field_blobs(),
91  scale=scale)
def get_next_blob_reference(self, name)
Definition: layers.py:349
def create_param(self, param_name, shape, initializer, optimizer, ps_param=None, regularizer=None)
Definition: layers.py:334