我正在尝试构建一个 MDN 来学习 P(y | x),其中 y 和 x 的维度均为 D,K 分量具有完整(非对角线)协方差。从 NN 隐藏层的输出,我需要构建分量均值、权重和协方差。对于协方差,我想要一组下三角矩阵(即协方差的 Cholesky 因子),即 [K, D, D] 张量,因此我可以利用这样一个事实,即对于正定矩阵,您只需要随身携带矩阵的一个三角形。
目前,对均值 (locs)、权重 (logs) 和协方差 (scales) 进行参数化的 NN 看起来像这样:
def neural_network(X):
# 2 hidden layers with 15 hidden units
net = tf.layers.dense(X, 15, activation=tf.nn.relu)
net = tf.layers.dense(net, 15, activation=tf.nn.relu)
locs = tf.reshape(tf.layers.dense(net, K*D, activation=None), shape=(K, D))
logits = tf.layers.dense(net, K, activation=None)
scales = # some function of tf.layers.dense(net, K*D*(D+1)/2, activation=None) ?
return locs, scales, logits
问题是,对于尺度,将 tf.layers.dense(net, K*D*(D-1)/2, activation=None) 转化为最有效的方法是什么K DxD 下三角矩阵的张量(对角线元素取幂以确保正定性)?
请您参考如下方法:
长话短说:使用 tf.contrib.distributions.fill_triangular
假设 X 是 K 维 D 元素的张量,我们将其定义为 placeholder .
# batch of D-dimensional inputs
X = tf.placeholder(tf.float64, [None, D])
神经网络的定义与 OP 一样。
# 2 hidden layers with 15 hidden units
net = tf.layers.dense(X, 15, activation=tf.nn.relu)
net = tf.layers.dense(net, 15, activation=tf.nn.relu)
多元高斯的均值只是先前隐藏层的线性密集层。输出的形状为 (None, D),因此无需将维度乘以 K 并进行整形。
# Parametrisation of the means
locs = tf.layers.dense(net, D, activation=None)
接下来,我们定义下三角协方差矩阵。关键是要用tf.contrib.distributions.fill_triangular在另一个线性密集层的输出上。
# Parametrisation of the lower-triangular covariance matrix
covariance_weights = tf.layers.dense(net, D*(D+1)/2, activation=None)
lower_triangle = tf.contrib.distributions.fill_triangular(covariance_weights)
最后一件事:我们需要确保协方差矩阵是正半定的。通过应用 softplus 很容易实现对角元素的激活函数。
# Diagonal elements must be positive
diag = tf.matrix_diag_part(lower_triangle)
diag_positive = tf.layers.dense(diag, D, activation=tf.nn.softplus)
covariance_matrix = lower_triangle - tf.matrix_diag(diag) + tf.matrix_diag(diag_positive)
就是这样,我们已经使用神经网络对多元正态分布进行了参数化。
奖励:可训练的多元正态分布
Tensorflow Probability包有一个可训练的多元正态分布,下三角协方差矩阵随时可用:tfp.trainable_distributions.multivariate_normal_tril
可以按如下方式使用:
mvn = tfp.trainable_distributions.multivariate_normal_tril(net, D)
它使用与tfp.distributions.MultivariateNormalTriL 相同的方法输出多元正态三角分布,包括mean、covariance、sample等
我建议使用它而不是自己构建。
