-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathlayers.py
More file actions
76 lines (58 loc) · 2.29 KB
/
layers.py
File metadata and controls
76 lines (58 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
from keras import backend as K
from keras.engine.topology import Layer
import numpy as np
class KernelEmbedding(Layer):
""" Generate kernel features.
Arguments:
kernel_f: kernel function k(x, y).
centers: matrix of shape (n_center, n_feature).
"""
def __init__(self, kernel_f, centers, **kwargs):
self.kernel_f = kernel_f
self._centers = centers
self.n_center = centers.shape[0]
super(KernelEmbedding, self).__init__(**kwargs)
def build(self, input_shape):
self.centers = self.add_weight(name='centers',
shape=self._centers.shape,
initializer=(lambda shape: self._centers),
trainable=False)
super(KernelEmbedding, self).build(input_shape) # Be sure to call this somewhere!
def call(self, x):
embed = self.kernel_f(x, self.centers)
return embed
def compute_output_shape(self, input_shape):
return (input_shape[0], self.n_center)
def rff(X, W):
"""Calculate random Fourier features according to paper,
'Random Features for Large-Scale Kernel Machines'.
Arguments:
X: data matrix of shape (n, D).
W: weight matrix of shape (D, d).
Returns:
feature matrix of shape (n, d).
"""
d = K.get_variable_shape(W)[1]
dot = K.dot(X, W) # of shape (n, d)
RF = K.concatenate([K.cos(dot), K.sin(dot)], axis=1) / np.sqrt(d, dtype='float32')
return RF
class RFF(Layer):
""" Generate random Fourier features.
Arguments:
weights: of shape (D, d).
"""
def __init__(self, weights, **kwargs):
self._weights = weights
self.d = weights.shape[1]
super(RFF, self).__init__(**kwargs)
def build(self, input_shape):
self.W = self.add_weight(name='rff-weight',
shape=self._weights.shape,
initializer=(lambda shape: self._weights),
trainable=False)
super(RFF, self).build(input_shape) # Be sure to call this somewhere!
def call(self, x):
embed = rff(x, self.W)
return embed
def compute_output_shape(self, input_shape):
return (input_shape[0], 2 * self.d)