Remodelar tensor en función de pérdida personalizada

Tengo un problema similar a esta pregunta . Estoy tratando de idear una función de pérdida en keras dado como:

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 

Basado en la respuesta dada en esta pregunta . Sin embargo, estoy recibiendo un error:

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

Específicamente esta statement da la siguiente salida

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

El backend es TensorFlow. Gracias por tu ayuda.

np.prod() reproducir tu excepción con un Tensor de forma (None, None, None, 9) , cuando np.prod() a np.prod() esta manera:

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

Esto sucede porque está tratando de multiplicar dos elementos del tipo None , incluso aunque haya cortado su actual_shape (como más de 1 elementos donde None ). En algunos casos, incluso puede obtener TypeError entre None e int , si solo queda un elemento sin tipo después del corte.

Echando un vistazo a la respuesta que mencionó, especifican qué hacer en esas situaciones, citando de ella:

Para los casos en que más de 1 dimensión no está definida, podemos usar tf.shape () con tf.reduce_prod () alternativamente.

En base a eso, podemos traducir esas operaciones a la API de Keras, utilizando K.shape() ( docs ) y K.prod() ( docs ), respectivamente:

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

Además, para el caso en que solo una dimensión no esté definida, recuerde usar K.int_shape(z) o su envoltorio K.get_variable_shape(z) lugar de solo get_shape() , como también se define en el backend ( docs ). Espero que esto resuelva tu problema.