问题
I am trying to train a convolutional auto encoder, along with the bounding box for penalizing the inside the boundign box region, for anomaly detection.
My custom loss function and supporting functions are below.
def assymetric_loss(input_bboxes):
def custom_loss(input_images,recons_images):
losses=[]
for i in range(20):
input_image=input_images[i]
recons_image=recons_images[i]
bbox=input_bboxes[i]
#check_null=tf.equal(tf.size(bbox) , 0)
x = tf.Variable(-1.0, dtype=tf.float32)
check_equal=tf.math.equal(bbox[0],x)
loss=tf.cond(check_equal ,
lambda: tf.reduce_sum(tf.square(tf.subtract(input_image,recons_image))),
lambda: error1(input_image,recons_image, bbox))
losses.append(loss)
loss = tf.stack(losses)
return loss
return custom_loss
other functions that i have used to help me get the custom loss i wants are given below. this include create mask and inverse mask inorder to penalize the inside and outside bbox area differently.
def create_mask_from_bounding_boxes(image, bbox):
bounding_box_masked_image = image
x,y,_= image.get_shape().as_list()
ymin, xmin, ymax, xmax = bbox[0],bbox[1],bbox[2],bbox[3]
h = xmax - xmin
z0 = tf.zeros([xmin, 512])
z1 = tf.concat(
[tf.zeros([h, ymin]),
tf.ones([h, ymax - ymin]),
tf.zeros([h, 512 - ymax])],
axis=1)
z2 = tf.zeros([512 - xmax, 512])
tf_temp=tf.concat([z0, z1, z2], axis=0)
mask_temp=tf.stack([tf_temp, tf_temp, tf_temp], axis=-1)
bounding_box_masked_image = bounding_box_masked_image*mask_temp
return bounding_box_masked_image
def create_inverse_mask_from_bounding_boxes(image, bbox):
bounding_box_masked_image = image
x,y,c= image.get_shape()
ymin, xmin, ymax, xmax = bbox[0],bbox[1],bbox[2],bbox[3]
h = xmax - xmin
z0 = tf.ones([xmin, 512])
z1 = tf.concat(
[tf.ones([h, ymin]),
tf.zeros([h, ymax - ymin]),
tf.ones([h, 512 - ymax])],
axis=1)
z2 = tf.ones([512 - xmax, 512])
tf_temp=tf.concat([z0, z1, z2], axis=0)
mask_temp=tf.stack([tf_temp, tf_temp, tf_temp], axis=-1)
bounding_box_masked_image = bounding_box_masked_image*mask_temp
return bounding_box_masked_image
def error1(input_image,recons_image, bbox):
bbarea_input_image=create_mask_from_bounding_boxes(input_image, bbox)
bbarea_recons_image=create_mask_from_bounding_boxes(recons_image, bbox)
square = tf.square(tf.subtract(bbarea_input_image, bbarea_recons_image))
reconstruction_error_bbarea=tf.reduce_sum(square)
nonbbx_area_input_image = create_inverse_mask_from_bounding_boxes(input_image, bbox)
nonbbx_area_recons_image = create_inverse_mask_from_bounding_boxes(recons_image, bbox)
square2 = tf.square(tf.subtract(nonbbx_area_input_image, nonbbx_area_recons_image))
reconstruction_error_nonbbx=tf.reduce_sum(square2)
return reconstruction_error_nonbbx+reconstruction_error_bbarea
and finally compiling the model inputting the custom loss function.
input_images = Input(shape = (512, 512, 3))
input_bboxes = Input(shape = (4,))
input_lebels= Input(shape=(8,))
recons_images,latent_space=Autoencoder_VGG(input_images)
autoencoder_model=Model(inputs=[input_images,input_bboxes], outputs=[recons_images])
autoencoder_model.compile(optimizer='adam',
loss=assymetric_loss(input_bboxes), # Call the loss function with the selected layer
metrics=['accuracy'])
And finally the error:
raise ValueError('An operation has None
for gradient. '
ValueError: An operation has None
for gradient. Please make sure that all of your ops have a gradient defined (i.e. are differentiable). Common ops without gradient: K.argmax, K.round, K.eval.
来源:https://stackoverflow.com/questions/62468956/why-am-i-getting-none-gradient-error-in-keras-custom-loss-function