我正在尝试创建一个由两个隐藏层组成的贝叶斯神经网络。我需要附加到每一层的权重来自不同的先验。例如,对于第一层,我使用均值为零的多元高斯矩阵和对角线为 1 的对角线协方差矩阵。对于第二层,我想使用相同的,但协方差矩阵的对角线为 0.5。
因此,我将两个先验定义如下:
def prior_1(kernel_size, bias_size, dtype=None):
n = kernel_size + bias_size
prior_model = keras.Sequential([
tfp.layers.DistributionLambda(
lambda t: tfp.distributions.MultivariateNormalDiag(
loc=tf.zeros(n), scale_diag=tf.ones(n)
))])
return prior_model
def prior_2(kernel_size, bias_size, dtype=None):
n = kernel_size + bias_size
prior_model = keras.Sequential([
tfp.layers.DistributionLambda(
lambda t: tfp.distributions.MultivariateNormalDiag(
loc=tf.zeros(n), scale_diag= 0.5 * tf.ones(n)
))])
return prior_model
后面是
def posterior_1(kernel_size, bias_size, dtype=None):
n = kernel_size + bias_size
posterior_model = keras.Sequential([
tfp.layers.VariableLayer(
tfp.layers.MultivariateNormalTriL.params_size(n), dtype=dtype),
tfp.layers.MultivariateNormalTriL(n),
])
return posterior_model
我对posterior_2
. 然后我建立我的模型如下:
hidden_units = [8, 8]
def create_bnn_model(train_size):
inputs = create_model_inputs()
features = keras.layers.concatenate(list(inputs.values()))
features = layers.BatchNormalization()(features)
features = tfp.layers.DenseVariational(
units=hidden_units[0],
make_prior_fn=prior_1,
make_posterior_fn=posterior_1,
kl_weight=1 / train_size,
activation="sigmoid",
)(features)
features = tfp.layers.DenseVariational(
units=hidden_units[1],
make_prior_fn=prior_2, # Notice that here I changed the prior
make_posterior_fn=posterior_1,
kl_weight=1 / train_size,
activation="sigmoid",
)(features)
# The output is deterministic: a single point estimate.
outputs = layers.Dense(units=1)(features)
model = keras.Model(inputs=inputs, outputs=outputs)
return model
当我运行它时,它给了我无限的损失。但是,如果我make_prior_fn=prior_1
对两个层都使用它,它运行良好,就好像我只是将两个层循环在一起(使用类似的东西for units in hidden_units
)。
我的问题是:我如何创建两个不同的(组)层,以便每个层的权重都用不同的先验和后验训练?可以回答我们本质上是如何创建两个不同的单层贝叶斯神经网络并将它们组合起来的,因为我们可以在每个中设置不同的先验和后验,每个工作方式都与我在上面的代码中设置相同的先验相同。
谢谢!
编辑:我可以为任何想要运行它的人提供完整的代码。