简体   繁体   English

在自定义损失函数中重塑张量

[英]Reshape tensor in custom loss function

I have a problem similar to this question . 我有一个与问题类似的问题 I am trying to devise a loss function in keras given as: 我正在尝试设计如下的喀拉斯损失函数:

def depth_loss_func(lr):
    def loss(actual_depth,pred_depth):
        actual_shape = actual_depth.get_shape().as_list()
        dim = np.prod(actual_shape[1:])
        actual_vec = K.reshape(actual_depth,[-1,dim])
        pred_vec = K.reshape(pred_depth,[-1,dim])
        di = K.log(pred_vec)-K.log(actual_vec)
        di_mean = K.mean(di)
        sq_mean = K.mean(K.square(di))

        return (sq_mean - (lr*di_mean*di_mean))
    return loss

based on the answer given in this question . 根据这个问题给出的答案。 However, I am getting an error: 但是,我得到一个错误:

 TypeError: unsupported operand type(s) for *: 'NoneType' and 'NoneType'

Specifically this statement gives the following output 具体来说,该语句提供以下输出

(Pdb) actual_depth.get_shape()
TensorShape([Dimension(None), Dimension(None), Dimension(None)])

The backend is TensorFlow. 后端是TensorFlow。 Thanks for your help. 谢谢你的帮助。

I managed to reproduce you exception with a Tensor of shape (None, None, None, 9) , when calling np.prod() like this: 当调用np.prod()(None, None, None, 9)我设法重现了形状为(None, None, None, 9)的张量的异常:

from keras import backend as K

#create tensor placeholder
z = K.placeholder(shape=(None, None, None, 9))
#obtain its static shape with int_shape from Keras
actual_shape = K.int_shape(z)
#obtain product, error fires here... TypeError between None and None
dim = np.prod(actual_shape[1:])

This happens because you are trying to multiply two elements of type None , even though you sliced your actual_shape (as more than 1 elements where None ). 发生这种情况是因为您试图将None类型的两个元素相乘,即使您切了actual_shape (作为None元素也超过了1个)。 In some cases you can even get TypeError between None and int , if only one none-type element remains after slicing. 在某些情况下,如果切片后仅剩下一个none-type元素,则甚至可以在Noneint之间获得TypeError

Taking a look at the answer you mentioned, they specify what to do in those situations, quoting from it: 看一下您提到的答案 ,他们指定了在这些情况下的处理方式,并引用了以下内容:

For the cases where more than 1 dimension are undefined, we can use tf.shape() with tf.reduce_prod() alternatively. 对于未定义1个以上维度的情况,可以将tf.shape()tf.reduce_prod()交替使用。

Based on that, we can translate those operations to the Keras API, by using K.shape() ( docs ) and K.prod() ( docs ), respectively: 基于此,我们可以分别使用K.shape()docs )和K.prod()docs )将这些操作转换为K.shape() API:

z = K.placeholder(shape=(None, None, None, 9))
#obtain Real shape and calculate dim with prod, no TypeError this time
dim = K.prod(K.shape(z)[1:])
#reshape
z2 = K.reshape(z, [-1,dim])

Also, for the case where only one dimension is undefined remember to use K.int_shape(z) or its wrapper K.get_variable_shape(z) instead of just get_shape() , as also defined in the backend ( docs ). 同样,对于只有一个维度未定义的情况,请记住使用K.int_shape(z)或其包装K.get_variable_shape(z)而不是仅在后端( docs )中定义的get_shape() )。 Hope this solves your problem. 希望这能解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM