Как создать сумму различных объектов ядра в вероятности TensorFlow?

У меня есть один вопрос об указании функции ядра в Tensorflow-probability.

Обычно, если я хочу создать объект ядра, я пишу

import tensorflow as tf
import tensorflow_probability as tfp
tfp_kernels = tfp.positive_semidefinite_kernels

kernel_obj = tfp_kernels.ExponentiateQuadratic(*args, **karwgs)

Я знаю, что объект ядра поддерживает пакетную трансляцию. Но что, если я хочу создать объект ядра, представляющий собой сумму нескольких разных объектов ядра, например аддитивных гауссовских процессов?

Я не уверен, как «суммировать» объект ядра в Tensorflow. Что я могу сделать, так это создать несколько отдельных объектов ядра K1, ... KJ Кажется, в Интернете нет подобного вопроса.

Спасибо за помощь заранее.


Обновления: я попробовал прямое +, но есть что-то странное с ковариационной матрицей.

Я составил следующий пример:

feature1 = np.array([1, 2, 3, 5], dtype=np.float32)[:, np.newaxis]
feature2 = np.array([4.2, 6.5, 7.4, 8.3], dtype=np.float32)[:, np.newaxis]
features = np.concatenate([feature1, feature2], axis=1)

k1 = tfp_kernels.ExponentiatedQuadratic(amplitude=tf.cast(2.0, tf.float32),
                                        length_scale=tf.cast(2.0, tf.float32),
                                        feature_ndims=1,
                                        name='k1')

k2 = tfp_kernels.ExponentiatedQuadratic(amplitude=tf.cast(1.5, tf.float32),
                                        length_scale=tf.cast(1.5, tf.float32),
                                        feature_ndims=1,
                                        name='k2')

K = k1 + k2


gp_1 = tfd.GaussianProcess(kernel=k1,
                           index_points=feature1,
                           jitter=tf.cast(0, tf.float32),
                           name='gp_1')

gp_2 = tfd.GaussianProcess(kernel=k2,
                           index_points=feature2,
                           jitter=tf.cast(0, tf.float32),
                           name='gp_2')

gp_K1 = tfd.GaussianProcess(kernel=K,
                           index_points=feature1,
                           jitter=tf.cast(0, tf.float32),
                           name='gp_K')

gp_K2 = tfd.GaussianProcess(kernel=K,
                           index_points=feature2,
                           jitter=tf.cast(0, tf.float32),
                           name='gp_K')

gp_K = tfd.GaussianProcess(kernel=K,
                           index_points=features,
                           jitter=tf.cast(0, tf.float32),
                           name='gp_K')


gp_1_cov = gp_1.covariance()
gp_2_cov = gp_2.covariance()
gp_K1_cov = gp_K1.covariance()
gp_K2_cov = gp_K2.covariance()
gp_K_cov = gp_K.covariance()

with tf.Session() as my_sess:
    [gp_1_cov_, gp_2_cov_, gp_K1_cov_, gp_K2_cov_, gp_K_cov_] = my_sess.run([gp_1_cov, gp_2_cov, gp_K1_cov, gp_K2_cov, gp_K_cov])
my_sess.close()

print(gp_1_cov_)
print(gp_2_cov_)
print(gp_K1_cov_)
print(gp_K2_cov_)
print(gp_K_cov_)

Первые четыре матрицы ковариации в порядке, и я дважды проверяю их, сравнивая k(x_i, x_j) по элементам.

Однако я не знаю, как он вычисляет последний. Я старался

  1. feature_1 с ядром_1 и feature_2 с ядром_2
  2. feature_1 с ядром_2 и feature_2 с ядром_1

Ниже приведены результаты последних трех матриц:

[[6.25       5.331647   3.3511252  0.60561347]
 [5.331647   6.25       5.331647   1.6031142 ]
 [3.3511252  5.331647   6.25       3.3511252 ]
 [0.60561347 1.6031142  3.3511252  6.25      ]]
[[6.25       2.7592793  1.3433135  0.54289836]
 [2.7592793  6.25       5.494186   3.7630994 ]
 [1.3433135  5.494186   6.25       5.494186  ]
 [0.54289836 3.7630994  5.494186   6.25      ]]
[[6.25       2.3782768  0.769587   0.06774138]
 [2.3782768  6.25       4.694947   1.0143608 ]
 [0.769587   4.694947   6.25       2.9651313 ]
 [0.06774138 1.0143608  2.9651313  6.25      ]]

Они не совпадают с моим результатом. Кто-нибудь знает, как они вычисляют последнюю матрицу с разными index_points?

Или вообще, как мне указать ядро, чтобы оно соответствовало такой модели, как additive Gaussian processes, где разные index_points соответствуют разным функциям ядра, чтобы я мог подогнать модель y_i = f_1(x_{1,i}) + f_2(x_{2,i}) + ... под структуру вероятностей TensorFlow?


person NiubilityDiu    schedule 18.05.2019    source источник


Ответы (1)


Вы можете просто написать k_sum = k1 + k2! Ознакомьтесь с базовым классом PositiveSemidefiniteKernel, в котором мы переопределили операторы сложения и умножения, если хотите увидеть, как это работает.

person Chris Suter    schedule 19.05.2019
comment
Мне было интересно, могу ли я настроить объект процесса Гаусса с помощью k_sum с разными index_points, например y_i = f_1(x_{1,i}) + f_2(x_{2,i})? Я только что попробовал +, но ковариационная матрица не имеет смысла, если мои index_points представляют собой два разных столбца. - person NiubilityDiu; 19.05.2019
comment
Ах, да, у нас есть дизайн, поддерживающий нарезку ядер, что позволит вам это сделать. Я работаю над тем, чтобы проверить части, которые помогут поддержать это. Я буду следить в ближайшее время! - person Chris Suter; 20.05.2019