我有一个类似于
this question的问题.我试图在keras中设计一个损失函数,如下所示:
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
基于this question给出的答案.但是,我收到一个错误:
TypeError: unsupported operand type(s) for *: 'NoneType' and 'NoneType'
具体而言,此语句提供以下输出
(Pdb) actual_depth.get_shape()
TensorShape([Dimension(None), Dimension(None), Dimension(None)])
后端是TensorFlow.谢谢你的帮助.
最佳答案 当我像这样调用np.prod()时,我设法用Tensor of shape(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:])
发生这种情况是因为您尝试将两个类型为None的元素相乘,即使您对actual_shape进行切片(因为多于1个元素为None).在某些情况下,如果在切片后只剩下一个非类型元素,您甚至可以在None和int之间获得TypeError.
看一下你提到的answer,它们指明在这些情况下该做什么,引用它:
For the cases where more than 1 dimension are undefined, we can use tf.shape() with tf.reduce_prod() alternatively.
基于此,我们可以分别使用K.shape()(docs)和K.prod()(docs)将这些操作转换为Keras 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])
此外,对于只有一个维度未定义的情况,请记住使用K.int_shape(z)或其包装器K.get_variable_shape(z)而不仅仅是get_shape(),这也在后端(docs)中定义.希望这能解决你的问题.