自定义损失函数中张量到numpy数组的转换

2024-10-02 12:22:37 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我的自定义损失函数:

import tensorflow.keras.backend as K
import cmath

epsylon=np.finfo(float).eps

def to_array(tensor):
    return tf.make_ndarray(tensor)


def addError(test,range_min,range_max,result):
    err = abs(log(range_max/max(range_min,epsylon)))
    if range_min <= test <= range_max:
        result.append(err)
    else:
        e1=abs(log(test/max(range_min,epsylon)))
        e2=abs(log(test/max(range_max,epsylon)))
        result.append( min(e1,e2) / max(err,epsylon) *100 + err)


def rangeLoss(yTrue,yPred):
    #print(type(yPred))
    a_pred=to_array(yPred)
    a_true=to_array(yTrue)

    result=[]

    for i in range(a_true.size):
        range_min=abs(a_pred[i*2])
        range_max=abs(a_pred[i*2+1])
        test= abs(a_true[i])

        addError(test,range_min,range_max,result)


    return tf.constant(result)

当我进行训练时,它失败了

/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/framework/tensor_util.py:591 MakeNdarray
        shape = [d.size for d in tensor.tensor_shape.dim]

    AttributeError: 'Tensor' object has no attribute 'tensor_shape'

当我修改为_数组以使用原张量时

def to_array(tensor):
    proto_tensor = tf.make_tensor_proto(tensor)
    return tf.make_ndarray(proto_tensor)

我发现以下错误:

    /home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/framework/tensor_util.py:451 make_tensor_proto
        _AssertCompatible(values, dtype)
    /home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/framework/tensor_util.py:328 _AssertCompatible
        raise TypeError("Expected any non-tensor type, got a tensor instead.")

    TypeError: Expected any non-tensor type, got a tensor instead.

我尝试过的另一个选项是tensor.numpy(),这导致了以下错误:

    <ipython-input-20-0a8051a4a034>:8 to_array
        return tensor.numpy()

    AttributeError: 'Tensor' object has no attribute 'numpy'

当然还有tensor.eval(session=tf.compat.v1.Session()),它也失败了

我该怎么做


Tags: totestmakereturntftensorflowdefrange
1条回答
网友
1楼 · 发布于 2024-10-02 12:22:37

我通过切片原始张量解决了这个问题。代码如下:

def above_zero(value):
    return tf.math.maximum(value,np.finfo(float).eps)

def range_loss(yTrue,yPred):
    #shapes: yTrue: (None,1)
    #        yPred: (None,2)
    yTrueSize=yTrue.shape[1]
    min=above_zero(tf.math.abs(yPred[:,:yTrueSize]))
    max=above_zero(tf.math.abs(yPred[:,yTrueSize:]))

    #following step should not be needed, but let's do it just in case
    yTrue=above_zero(tf.math.abs(yTrue))

    baseError    = tf.math.abs(tf.math.log(max/min))
    baseErrorDiv = above_zero(baseError)

    topRange     = tf.math.maximum(min,max)
    bottomRange  = tf.math.minimum(min,max)

    extraError = tf.math.maximum(0.0,tf.math.log(yTrue/topRange))+tf.math.maximum(0.0,tf.math.log(bottomRange/yTrue))
    extraError /= baseErrorDiv

    totalError=tf.math.pow(extraError,2.0)*100+tf.math.pow(baseError,2.0)

    return tf.math.reduce_sum(totalError)

相关问题 更多 >

    热门问题