2017-07-18 55 views
4

我遇到类似this question的问题。我试图给出keras制定一个损失函数:基于在this question给出了答案自定义丢失函数中的重整张量

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 

。不过,我得到一个错误:

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

具体来说这一说法提供了以下输出

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

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

回答

1

我设法复制您的例外与形状(None, None, None, 9)的张量,打电话时np.prod()这样的:

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 (因为多于1个元素,其中None)。在某些情况下,如果在切片后只剩下一个无类型元素,则您甚至可以在Noneint之间得到TypeError

考虑看看answer你所提到的,他们指定在这些情况下该怎么做,从它引用:

For the cases where more than 1 dimension are undefined, we can use tf.shape() with tf.reduce_prod() alternatively.

此基础上,我们可以将这些操作转换为Keras API,通过使用K.shape()docs)和K.prod()docs),分别为:

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(),也在后端定义(docs)。希望这能解决你的问题。

+0

很高兴看到这解决了你的问题,祝你好运与你的编码。如果你发现这个答案有用,也可以考虑提高它。 – DarkCygnus

+1

非常感谢@GrayCygnus! – shunyo

相关问题