具有更大预定义张量的自定义损失函数

Custom loss function with a larger predefined tensor

我想尝试训练一个神经网络来为我进行非线性拟合。

我生成一组模型参数 p,根据给定的一组 x 值计算模型输出(y 值)。 NN 输入是 y,输出应该是预测参数 p'.

而不是使用像 pp' 之间的 MSE 这样的损失函数,我认为首先生成预测的 y' 然后使用 y' 之间的 MSE 会更好=13=] 和 y'。 (我遇到的问题是,当 x >> 0 时,某些参数的微小差异可能会导致拟合曲线出现巨大的“漂移”。)

我发现 Keras 使用损失函数的符号评估(我认为?)。因此,我使用 Keras 后端调用实现了我的模型版本,如下所示:

x = np.linspace(0, 10, num=1000)

# regular model
def model(x, a):
    return np.cos(a * x)

def Kmodel(x, params):
    a = params[:, 0]
    # other parameters omitted, params[:, n]
    # simplified model for illustration
    return K.cos(a * x)

# THIS CAUSES ISSUES
keras_x = K.constant(x)

def regression_loss(p_true, p_pred):
    y_true = Kmodel(keras_x, p_true)
    y_pred = Kmodel(keras_x, p_pred)
    mse = K.mean(K.square(y_true - y_pred))
    return mse

但是,我不知道如何将所有内容乘以 x。它涉及增加向量的维数,因为我们有 1000 个 x 值,而不是我使用的许多参数。 Keras 不喜欢它:

W tensorflow/core/framework/op_kernel.cc:1733] INVALID_ARGUMENT: required broadcastable shapes

Graph execution error:
<snip>
File "/tmp/ipykernel_4109/793156309.py", line 9, in Kmodel
      return a * x
Node: 'regression_loss/mul'
required broadcastable shapes
     [[{{node regression_loss/mul}}]] [Op:__inference_train_function_18838]

我在网上发现了类似的问题,但是none好像可以解决这个广播问题。例如,, , , .

嗯,你只需要确保 ax 的形状相同。例如,您可以使用 tf.repeat:

import tensorflow as tf
import numpy as np

x = np.linspace(0, 10, num=1000)

# regular model
def model(x, a):
    return np.cos(a * x)

def Kmodel(x, params):
    a = tf.repeat(params[:, 0], repeats=tf.shape(x)[0] // tf.shape(params)[0])

    # other parameters omitted, params[:, n]
    # simplified model for illustration
    return tf.keras.backend.cos(a * x)

# THIS CAUSES ISSUES
keras_x = tf.keras.backend.constant(x)

def regression_loss(p_true, p_pred):
    y_true = Kmodel(keras_x, p_true)
    y_pred = Kmodel(keras_x, p_pred)
    mse = tf.keras.backend.mean(tf.keras.backend.square(y_true - y_pred))
    return mse

y_true = tf.constant([[0., 1.], [0., 0.]])
y_pred = tf.constant([[1., 1.], [1., 0.]])

regression_loss(y_true, y_pred)
<tf.Tensor: shape=(), dtype=float32, numpy=1.6316855>

tf.reshape:

def Kmodel(x, params):
    y = tf.repeat(tf.expand_dims(x, axis=-1), repeats=tf.shape(params)[0])
    y = tf.reshape(y, (tf.shape(params)[0], tf.shape(x)[0]))

    return tf.keras.backend.cos(tf.expand_dims(params[:, 0], axis=-1)* x)