如何解决Tensorflow Probability 中标准化流的变分推理
在上一次我读过一些关于使用规范化流来改进变分推理 f.e. Link1 Link2。
Tensorflow 概率已经在双射子模块中提供了 RealNVP 和 MaskedAutoregressiveFlow,并且在层子模块中提供了一个 AutoregressiveTransform 层。因此,我认为构建贝叶斯神经网络会很简单直接 使用变分推理和使用 Tensorflow Probability 的归一化流给出的后验训练。
从其中一个教程 (Link) 开始,我能够构建一个带有 mean_field_posterior 的 BNN。
然后事情开始变得复杂。我编写了以下改编自此示例 (Link) 的函数,以生成使用掩蔽自回归流转换正态分布的后验。
def posterior_vi_maf(kernel_size,bias_size=0,dtype=None):
n = kernel_size + bias_size
return tf.keras.Sequential(
[
tfk.layers.InputLayer(input_shape=(0,),dtype=tf.float32),tfpl.distributionLambda(
lambda t: tfd.MultivariatenormalDiag(
loc=tf.zeros(tf.concat([tf.shape(t)[:-1],[4]],axis=0)),scale_diag=tf.ones(4),tfp.layers.AutoregressiveTransform(
tfb.AutoregressiveNetwork(
params=2,hidden_units=[10,10],activation="relu"
)
),]
)
比较后验_vi_maf 和后验_平均_场的形状和输出,从技术角度来看,似乎一切都应该可行。
p1 = posterior_vi_maf(16,4,dtype=tf.float32)
p2 = posterior_mean_field(16,dtype=tf.float32)
assert p1(x).shape == p2(x).shape
assert isinstance(p1(x),tfd.distribution)
assert isinstance(p2(x),tfd.distribution)
ValueError: Shape must be rank 1 but is rank 2 for '{{node dense_variational/BiasAdd}} = BiasAdd[T=DT_FLOAT,data_format="NHWC"](dense_variational/MatMul,dense_variational/split:1)' with input shapes: [?,?,16],[?,16].
有什么建议为什么会发生这种情况和/或我如何解决这个问题?
import numpy as np
import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions
tfk = tf.keras
tfl = tf.keras.layers
tfpl = tfp.layers
tfb = tfp.bijectors
np.random.seed(2)
tf.random.set_seed(2)
N = 100
x = tfd.normal(loc=0,scale=1).sample(N)
y = tfd.normal(loc=x * 0.5,scale=0.3).sample()
def negloglik(y_true,y_pred):
nll = -tf.reduce_mean(y_pred.log_prob(y_true))
return nll
def prior(kernel_size,dtype=None):
n = kernel_size + bias_size
return lambda t: tfd.Independent(
tfd.normal(loc=tf.zeros(n,dtype=dtype),scale=1),reinterpreted_batch_ndims=1,)
def posterior_mean_field(kernel_size,dtype=None):
n = kernel_size + bias_size
c = np.log(np.expm1(1.0))
return tf.keras.Sequential(
[
tfp.layers.VariableLayer(2 * n,tfp.layers.distributionLambda(
lambda t: tfd.Independent(
tfd.normal(
loc=t[...,:n],scale=1e-5 + 0.01 * tf.nn.softplus(c + t[...,n:]),)
),]
)
model = tf.keras.Sequential(name="small_vi_nn")
model.add(tfl.Input(1))
model.add(
tfpl.DenseVariational(
units=16,make_posterior_fn=posterior_vi_maf,make_prior_fn=prior,kl_weight=1 / N,kl_use_exact=False,activation="relu",)
)
model.add(
tfpl.DenseVariational(
units=2,make_posterior_fn=posterior_mean_field,)
)
model.add(
tfpl.distributionLambda(
make_distribution_fn=lambda t: tfd.normal(
loc=t[:,0],scale=1e-3 + tf.math.softplus(0.05 * t[:,0]),)
)
)
optimizer = tf.keras.optimizers.Adam(learning_rate=0.01,amsgrad=True)
model.compile(optimizer=optimizer,loss=negloglik)
model.fit(
x,y,epochs=2,shuffle=True,verbose=True,)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。