(Tensorflow)仅当 y_true 的总和可用时的自定义损失函数

问题描述 投票:0回答:1

我是一名化学工程师,我对计算机科学的了解并不深。但无论如何,我想为非线性函数 f(x) 创建一个神经网络。但问题是,我只能访问函数输出的任意线性和,即 y=c1f(x1)+c2f(x2)+c3 f(x3)+c4f(x4)+...+cnf(xn) 其中 c 和 x 给定,n 不固定(大约 20) .

因此,我决定对给定的 k 批次数据集进行处理,将 x、c、n 和 y_true 设置为:

y_true=[y1, 0, 0, ..., 0, y2, 0, 0, ..., 0, ..., yk, 0, 0, ... , 0]

x=[x11, x12, x13, ..., x1n1, x21, x22, x23, ..., x2n2,...,xk1,xk2,xk3,...,xknk]

c=[c11,c12,c13,...,c1n1,c21,c22,c23,..., c2n2,...,ck1,ck2,ck3,...,cknk]

n=[1, 1, 1, ..., 1, 2, 2, 2, ..., 2, ..., k, k, k, ..., k]

然后,我想到损失函数可以定义为:

sum(mse(y_truei-y_predi·ci))) 对于 i=1, 2, ..., k 其中 a·b 是 a 和 b 与 y_pred 的点积=f(x).

所以我定义了自定义损失函数和主要代码,如下所示:

def loss_Tm(data, y_pred):
    y_true=data[:, 0]
    _count=data[:, 1]
    _n=tf.cast(data[:, 2], tf.int32)
    N=tf.reduce_max(_n)
    T_diff=np.array([])

    i=0
    while i<N:
        A=tf.where(i==_n, y_true-y_pred*_count, 0)
        T_diff=np.append(T_diff, tf.reduce_sum(A))
        i+=1
    return tf.reduce_mean(tf.square(T_diff))

model.compile(loss=loss_Tm)
model.fit(x, np.concatenate((y_true, count, n), 1))

但是我在运行时收到此错误消息:

NotImplementedError: Cannot convert a symbolic tf.Tensor (loss_Tm/while/Placeholder:0) to a numpy array.
This error may indicate that you're trying to pass a Tensor to a NumPy call, which is not supported.

所以我尝试像这样使用张量:

def loss_Tm(data, y_pred):
    y_true=data[:, 0]
    _count=data[:, 1]
    _n=tf.cast(data[:, 2], tf.int32)
    N=tf.reduce_max(_n)
    T_diff=tf.zeros(0)

    i=0
    while i<N:
        A=tf.where(i==_n, y_true-y_pred*_count, 0)
        T_diff=tf.concat([T_diff, [tf.reduce_sum(A)]], 0)
        i+=1
    return tf.reduce_mean(tf.square(T_diff))

model.compile(loss=loss_Tm)
model.fit(input, np.concatenate((y_true, count, n), 1))

但它引发了这个值错误:

ValueError: 'T_diff' has shape (0,) before the loop, but shape (1,) after one iteration.
Use tf.autograph.experimental.set_loop_options to set shape invariants.

由于我无法使 T_diff 形状不变,所以我选择从一个巨大尺寸的张量开始,即:

def loss_Tm(data, y_pred):
    y_true=data[:, 0]
    _count=data[:, 1]
    _n=tf.cast(data[:, 2], tf.int32)
    N=tf.reduce_max(_n)
    T_diff=tf.zeros(500,)

    i=0
    while i<N:
        A=tf.where(i==_n, y_true-y_pred*_count, 0)
        T_diff[i]=tf.reduce_sum(A)
        i+=1
    #B=tf.stack(T_diff)
    return tf.reduce_mean(tf.square(T_diff))

model.compile(loss=loss_Tm)
model.fit(input, np.concatenate((y_true, count, n), 1))

但是它引发了这个问题

TypeError: 'Tensor' object does not support item assignment

我也尝试使用这样的列表对象:

def loss_Tm(data, y_pred):
    y_true=data[:, 0]
    _count=data[:, 1]
    _n=tf.cast(data[:, 2], tf.int32)
    N=tf.reduce_max(_n)
    T_diff=[]

    i=0
    while i<N:
        A=tf.where(i==_n, y_true-y_pred*_count, 0)
        T_diff.append(tf.reduce_sum(A))
        i+=1
    return tf.reduce_mean(tf.square(tf.stack(T_diff)))

model.compile(loss=loss_Tm)
model.fit(input, np.concatenate((y_true, count, n), 1))

但我也收到此错误消息:

The tensor <tf.Tensor 'loss_Tm/while/Sum:0' shape=() dtype=float32> cannot be accessed from
FuncGraph(name=train_function, id=2270323096688), because it was defined in
FuncGraph(name=loss_Tm_while_body_305, id=2270325652016), which is out of scope.

任何人都可以帮我弄清楚如何修改代码或算法并让我摆脱这个地狱吗?这个张量流比我想象的要复杂得多:(

ps。我也尝试过这两个,但我认为这不起作用。

def loss_Tm(y_true, y_pred):
    result=tf.cast(0, tf.float32)
    index=0
    for i in range(len(data)):
        calc=tf.tensordot(count[index:index+len(data[i]), 0], y_pred[index:index+len(data[i]), 0], 1)
        obs=tf.reduce_sum(y_true[index:index+len(data[i]), 0])
        result+=tf.square(calc-obs)
        index+=len(data[i])
    return result

这里,

data
是一个字典列表,其中包含涉及的每个变量的系数。但自定义损失函数似乎不允许使用固定大小的张量(即数据)。

def loss_Tm(y_true, y_pred):
    result=tf.cast(0, tf.float32)
    error=tf.cast(y_true[0, 0]-y_pred[0, 0]*count[0, 0], tf.float32)
    i=tf.cast(1, tf.int32)
    c=lambda _, __, i: tf.less(i, tf.cast(len(y_true), tf.int32))
    b=lambda error, result, i: tf.cond(y_true[i, 0]==0, 
                                            lambda: (error-y_pred[i, 0]*count[i, 0], result, i+1), 
                                            lambda: (y_true[i, 0]-y_pred[i, 0]*count[i, 0], result+error**2, i+1))
    error, result, i=tf.while_loop(c, b, [error, result, i])
    result+=error**2
    return result

这个没有报错,但是实际计算出的损失与我设置

verbose=1
时显示的损失值相差100倍,并且会发出如下警告:

Type inference failed. This indicates an invalid graph that escaped type checking.
Error message: INVALID_ARGUMENT: expected compatible input types, but input 1:
type_id: TFT_OPTIONAL
args {
  type_id: TFT_PRODUCT
  args {
    type_id: TFT_TENSOR
    args {
      type_id: TFT_FLOAT
    }
  }
}
 is neither a subtype nor a supertype of the combined inputs preceding it:
type_id: TFT_OPTIONAL
args {
  type_id: TFT_PRODUCT
  args {
    type_id: TFT_TENSOR
    args {
      type_id: TFT_INT32
    }
  }
}

        for Tuple type infernce function 0
        while inferring type of node 'loss_Tm/while/body/_1/loss_Tm/while/cond/output/_340'
tensorflow loss-function
1个回答
0
投票

我尝试了一下,似乎没有任何错误。但这里的返回值仍然与实际损失不同,所以我仍在试图弄清楚:/

def loss_Tm(data, y_pred):
    y_true=data[:, 0]
    _count=data[:, 1]
    _n=tf.cast(data[:, 2], tf.int32)
    N=tf.reduce_max(_n)
    T_diff=tf.zeros(1)

    i=0
    while i<N:
        A=tf.where(i==_n, y_true-y_pred*_count, 0)
        T_diff=T_diff+tf.square(tf.reduce_sum(A))
        i+=1
    return T_diff
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.