在通过 keras(使用 tensorflow 后端)计算混合密度网络时,我遇到了一个问题。这个 MDN 的目标是学习图像的潜在表示(为了在自动编码器中实现 MDN 的预测)。然后,我想将我的输入图像建模为多元正态分布,并作为网络输出获得一个 mu 和 sigma 向量(每个维度为 64),以及一组 N 个权重 alpha(其中 N 是混合物中的分量数)。如果我认为每个参数的输出形状为 64,一切正常,但获得比组件更多的 alpha 因子(在我的情况下是 64 维 alpha)是没有意义的。当我尝试指定 alpha 以获得与 mu 和 sigma 不同的形状时,会出现一些问题。
为了在 tensorflow 的 MixtureSameFamily 模块中实现协方差矩阵,我考虑了 sigma 向量的对角矩阵。然后,我在许多论坛上发现了这个损失函数(负对数似然),并尝试将其适应我的问题:
def slice_parameter_vectors(parameter_vector):
return tf.split(parameter_vector,[1*components,64*components,64*components],axis=1)
def gnll_loss(y, parameter_vector):
alpha, mu, sigma = slice_parameter_vectors(parameter_vector) # Unpack parameter vectors
gm = tfd.MixtureSameFamily(
mixture_distribution=tfd.Categorical(probs=alpha),
components_distribution=tfd.MultivariateNormalDiag(
loc=mu,
scale_diag= sigma))
log_likelihood = gm.log_prob(tf.transpose(y)) # Evaluate log-probability of y
return -tf.reduce_mean(log_likelihood, axis=-1)
如果我尝试向我的网络提供一些数据并对其进行编译,我总是会遇到以下错误:
InvalidArgumentError: Incompatible shapes: [64,1,2] vs. [2,64]
[[{{node loss_20/concatenate_6_loss/MultivariateNormalDiag/log_prob/affine_linear_operator/inverse/sub}} = Sub[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:GPU:0"](loss_20/concatenate_6_loss/MixtureSameFamily/log_prob/pad_sample_dims/Reshape, loss_20/concatenate_6_loss/split:1)]]
[[{{node loss_20/mul/_4221}} = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_1846_loss_20/mul", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]
64 是向量的维度,2 是批量大小。使用 1 的批量大小是可行的,但给了我一些 NaN 作为损失。
以下是 alpha、mu 和 sigma 层的构建方式:
fc = Dense((no_parameters-1) * components*64 + components, activation="tanh", name="fc")(layer)
alphas = Dense(1*components, activation="softmax", name="alphas")(fc)
mus = Dense(64*components, name="mus")(fc)
sigmas = Dense(64*components, activation=nnelu, name="sigmas")(fc)
pvec = Concatenate(axis=1)([alphas,mus,sigmas])
mdn = Model(inputs=inputs,outputs=pvec)
因此,问题是:是否有可能通过 tensorflow 做到这一点?有没有其他人在这里使用这种网络,可以向我解释如何处理损失函数?
亲切的问候,
阿德里安