2

在通过 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 做到这一点?有没有其他人在这里使用这种网络,可以向我解释如何处理损失函数?

亲切的问候,

阿德里安

4

0 回答 0