I am trying to pass a custom mean function into GPflow 2.0. I have some (x,y,z) data with several observations for each x,y point. I wanted to pass the average z value for each (x,y) pair as the mean function. My code for the custom mean function is below where train_xy
are the (x,y,z) tuples in my training data (x and y are inputs, and z is the output).
Below is my code setting up the mean function and passing it into a simple GPR model.
class CustomMean(gpflow.mean_functions.MeanFunction):
"""
means = mean(grouped by unique tuples of input1 & input2)
"""
def __init__(self, X):
# MeanFunction.__init__(self)
self.X = Parameter(X)
def __call__(self, X):
mean_arr = []
X = np.unique(X, axis=0)
for i in range(len(X)):
y_list = train_xy[(train_xy['input1'] == X[i, 0]) & (train_xy['input2'] == X[i, 1])]['output']
mean_arr.append(y_list.mean())
mean_arr = np.asarray(mean_arr, dtype=np.float64)
mean_arr[np.isnan(mean_arr)] = 0
means = tf.convert_to_tensor(mean_arr)
return means
k = gpflow.kernels.Linear()
mean_func = CustomMean(X_train.values.astype('float64'))
m = gpflow.models.GPR(data=(X_train, y_train), kernel=k, mean_function=mean_func)
pred_mean, pred_var = m.predict_f(X_test.values.astype('float64'))
I ran into problems when I called the predict_f
function:
InvalidArgumentError Traceback (most recent call last)
<ipython-input-140-c7b24d06c38e> in <module>()
----> 1 pred_mean, pred_var = m.predict_f(X_test.values.astype('float64'))
~/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/gpflow/models/gpr.py in predict_f(self, Xnew, full_cov, full_output_cov)
103 kmn, kmm + s, knn, err, full_cov=full_cov, white=False
104 ) # [N, P], [N, P] or [P, N, N]
--> 105 f_mean = f_mean_zero + self.mean_function(Xnew)
106 return f_mean, f_var
...
InvalidArgumentError: Incompatible shapes: [1250,2596] vs. [1104] [Op:AddV2]
And it looks like the error is tied to something called f_mean = f_mean_zero + self.mean_function(Xnew)
. When I look at the shape of this, the dimensions are very large. I have 2596 unique (x,y) pairs in my training data (out of 3750 total rows) and 1104 unique (x,y) pairs in test (out of 1250 total rows). f_mean_zero
is (1250, 2596), whereas self.mean_function(Xnew)
returns a one-dimensional tensor of means (as expected). I don't understand the dimension of f_mean_zero
, particularly since (x,y) pairs in my test data are in my training data.
It seems like a similar issue to this ticket but there is no solution. Thank you!