首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有自定义损失函数的TensorFlow 2出现无效参数错误,尽管一切似乎都是正确的

具有自定义损失函数的TensorFlow 2出现无效参数错误,尽管一切似乎都是正确的
EN

Stack Overflow用户
提问于 2021-11-11 16:23:28
回答 1查看 36关注 0票数 0

我目前正在使用TensorFlow 2训练模型,这些模型不仅提供时间序列的点预测,而且还提供预测分布度量(例如,均值和方差)。为此,我创建了一个层,并修改损失函数以优化相应的参数。对于只有一个预测时间序列的一维情况,这种方法非常有效。

对于具有两个时间序列的情况,我想尝试相应地预测相关性,并使用"tensorflow_probability“中的函数"MultivariateNormalFullCovariance”。但是我得到了下面的错误:

代码语言:javascript
复制
InvalidArgumentError:  Input matrix must be square.
     [[node negative_normdist_loss_2/MultivariateNormalFullCovariance/init/Cholesky (defined at d:\20_programming\python\virtualenvs\tensorflow-gpu-2\lib\site-packages\tensorflow_probability\python\distributions\mvn_full_covariance.py:194) ]] [Op:__inference_train_function_1133]

Errors may have originated from an input operation.
Input Source operations connected to node negative_normdist_loss_2/MultivariateNormalFullCovariance/init/Cholesky:
 negative_normdist_loss_2/MultivariateNormalFullCovariance/init/covariance_matrix (defined at d:\20_programming\python\virtualenvs\tensorflow-gpu-2\lib\site-packages\tensorflow_probability\python\distributions\mvn_full_covariance.py:181)

Function call stack:
train_function

我知道输入尺寸有问题,但不幸的是我找不到具体的错误。(相关矩阵已经是二次的,即使它包含两次相同的参数。)

这段代码本身有点宽泛。因此,我将包含示例数据的工作(单变量)和非工作示例(多变量)上传到此目录:

https://drive.google.com/drive/folders/1IIAtKDB8paWV0aFVFALDUAiZTCqa5fAN?usp=sharing

为了获得更好的概述,我还复制了以下基本例程:

代码语言:javascript
复制
def negative_normdist_layer_2(x):
    # Get the number of dimensions of the input
    num_dims = len(x.get_shape())
    # Separate the parameters
    mu1, mu2, sigma11, sigma12, sigma22 = tf.unstack(x, num=5, axis=-1)
    # Add one dimension to make the right shape
    mu1 = tf.expand_dims(mu1, -1)
    mu2 = tf.expand_dims(mu2, -1)
    sigma11 = tf.expand_dims(sigma11, -1)
    sigma12 = tf.expand_dims(sigma12, -1)
    sigma22 = tf.expand_dims(sigma22, -1)
    # Apply a softplus to make positive
    sigma11 = tf.keras.activations.softplus(sigma11)
    sigma22 = tf.keras.activations.softplus(sigma22)
    # Join back together again
    out_tensor = tf.concat((mu1, mu2, sigma11, sigma12, sigma22), axis=num_dims-1)
    return out_tensor

def negative_normdist_loss_2(y_true, y_pred):
    # Separate the parameters
    mu1, mu2, sigma11, sigma12, sigma22 = tf.unstack(y_pred, num=5, axis=-1)
    # Add one dimension to make the right shape
    mu1 = tf.expand_dims(mu1, -1)
    mu2 = tf.expand_dims(mu2, -1)
    sigma11 = tf.expand_dims(sigma11, -1)
    sigma12 = tf.expand_dims(sigma12, -1)
    sigma22 = tf.expand_dims(sigma22, -1)
    # Calculate the negative log likelihood
    dist = tfp.distributions.MultivariateNormalFullCovariance(
        loc = [mu1, mu2], 
        covariance_matrix = [[sigma11, sigma12], [sigma12, sigma22]]
    )
    nll = tf.reduce_mean(-dist.log_prob(y_true))
    return nll

# Define inputs with predefined shape
input_shape = lookback // step, float_data.shape[-1]
inputs = Input(shape=input_shape)

# Build network with some predefined architecture
output1 = Flatten()(inputs)
output2 = Dense(32)(output1)

# Predict the parameters of a negative normdist distribution
outputs = Dense(5)(output2)
distribution_outputs = Lambda(negative_normdist_layer_2)(outputs)

# Construct model
model_norm_2 = Model(inputs=inputs, outputs=distribution_outputs)

opt = Adam()
model_norm_2.compile(loss = negative_normdist_loss_2, optimizer = opt)

history_norm_2 = model_norm_2.fit_generator(train_gen_mult,
                                            steps_per_epoch=500,
                                            epochs=20,
                                            validation_data=val_gen_mult,
                                            validation_steps=val_steps)

我使用的操作系统是Windows10,Python版本是3.6。示例代码中列出的所有库都是最新的,包括tensorflow-gpu。

如果能确定错误的确切原因并找到解决方案,我将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-11 19:38:59

均值和协方差参数必须转置,因为它们的大小假定为(batch_size,2)和(batch_size,2,2) (对于维2的问题)根据MultivariateNormalFullCovariance.There的文档,协方差矩阵的反转存在问题,尽管该层确保对角项为正。你可以使用MultivariateNormalTriL,它采用一个更低的三角矩阵,没有更多的协方差求逆问题(保持软加法):

代码语言:javascript
复制
def negative_normdist_loss_2(y_true, y_pred):
    # Separate the parameters
    mu1, mu2, sigma11, sigma12, sigma22 = tf.unstack(y_pred, num=5, axis=-1)
    mu = tf.transpose([mu1, mu2], perm=[1, 0])
    sigma_tril = tf.transpose([[sigma11, tf.zeros_like(sigma11)], [sigma12, sigma22]], perm=[2, 0, 1])
    dist = tfp.distributions.MultivariateNormalTriL(loc=mu, scale_tril=sigma_tril)
    nll = tf.reduce_mean(-dist.log_prob(y_true))
    return nll

然而,我想知道它背后的想法。它对应于一种无监督的方法,即interesting.The数据允许您估计某种非常规成本函数的均值和协方差参数,但不清楚之后您可以如何处理它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69931659

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档