I’m experimenting with setting up a classical RBF kernel method wtihin Flux
, i.e., I want to train the model:
where, for simplicity, take the kernel k to be a Gaussian. n is fixed, and the X_i are fixed; this is really just a regression problem. But thinking of it in a network architecture, what we want to have happen is:
which nis to say we go from d=>n=>1
, where d
is the dimension of the input argument.
What I am struggling with is getting the kernel layer to properly vectorize its output (i.e., if i input a d x 10
array, I should get a n x 10
output array), and if i push it all the way through i should end up with a 1 x 10
output array. This is what I’ve been trying:
Random.seed!(100)
n_pts = 100;
X_pts = [randn(Float32, 2,1) for _ in 1:n_pts];
X_train = randn(Float32, 2, 1000)
h = 1.0f0;
kernel(x, y) = exp(-sum(abs2, x - y) / (2 * h));
function k_layer(x)
return [kernel(x, X_) for X_ in X_pts]
end
f_kernel = Chain(k_layer, Dense(n_pts => 1, bias=false));
and
f_kernel(rand(Float32,2))
works fine, but not
f_kernel(rand(Float32,2,10))
returns
DimensionMismatch: a has size (2, 10), b has size (2, 1), mismatch at dim 2
EDIT: The following works, but I have no sense of how clever/efficient an implementation it is:
f_kernel = Chain(x -> MapCols{2}(kernel_layers, x), final_layer)