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

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

本文介绍了在自定义损失函数中重塑张量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到的问题类似于此问题.我正在尝试设计如下的喀拉斯损失函数:

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)])

后端是TensorFlow.谢谢你的帮助.

The backend is TensorFlow. Thanks for your help.

推荐答案

当调用np.prod()时,我设法重现了形状为(None, None, None, 9)的张量的异常:

I managed to reproduce you exception with a Tensor of shape (None, None, None, 9), when calling np.prod() like this:

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:])

之所以会发生这种情况,是因为您试图对None类型的两个元素进行乘法运算,即使您对actual_shape进行了切片(在None中也包含了超过1个元素).在某些情况下,如果切片后仅剩下一个none-type元素,您甚至可以在Noneint之间获得TypeError.

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). In some cases you can even get TypeError between None and int, if only one none-type element remains after slicing.

看看您提到的答案,他们会指定在这种情况下的处理方法,引用它:

Taking a look at the answer you mentioned, they specify what to do in those situations, quoting from it:

基于此,我们可以使用K.shape()(文档)和K.prod()(文档)分别为:

Based on that, we can translate those operations to the Keras API, by using K.shape() (docs) and K.prod() (docs), respectively:

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])

此外,对于只有一个维度未定义的情况,请记住使用K.int_shape(z)或其包装器K.get_variable_shape(z)而不是仅使用get_shape(),这也在后端中进行了定义(文档).希望这能解决您的问题.

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). Hope this solves your problem.

这篇关于在自定义损失函数中重塑张量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 10:08