title: Keras custom loss function for YOLO
body: <p>I am trying to define a custom loss function in Keras</p>
  
  <pre><code>def yolo_loss(y_true, y_pred):
  </code></pre>
  
  <p>Here the shape of y_true and y_pred are [batch_size,19,19,5]. </p>
  
  <p>for <strong>each image in the batch</strong>, I want to compute the loss as:</p>
  
  <pre><code>loss =   
  square(y_true[:,:,0] - y_pred[:,:,0])  
  + square(y_true[:,:,1] - y_pred[:,:,1])   
  + square(y_true[:,:,2] - y_pred[:,:,2])   
  + (sqrt(y_true[:,:,3]) - sqrt(y_pred[:,:,3]))  
  + (sqrt(y_true[:,:,4]) - sqrt(y_pred[:,:,4]))
  </code></pre>
  
  <p>I thought of a couple of ways of doing this,  </p>
  
  <p>1) using a for loop:</p>
  
  <pre><code>def yolo_loss(y_true, y_pred):
      y_ret = tf.zeros([1,y_true.shape[0]])
      for i in range(0,int(y_true.shape[0])):
          op1 = y_true[i,:,:,:]
          op2 = y_pred[i,:,:,:]
          class_error = tf.reduce_sum(tf.multiply((op1[:,:,0]-op2[:,:,0]),(op1[:,:,0]-op2[:,:,0])))
          row_error = tf.reduce_sum(tf.multiply((op1[:,:,1]-op2[:,:,1]),(op1[:,:,1]-op2[:,:,1])))
          col_error = tf.reduce_sum(tf.multiply((op1[:,:,2]-op2[:,:,2]),(op1[:,:,2]-op2[:,:,2])))
          h_error = tf.reduce_sum(tf.abs(tf.sqrt(op1[:,:,3])-tf.sqrt(op2[:,:,3])))
          w_error = tf.reduce_sum(tf.abs(tf.sqrt(op1[:,:,4])-tf.sqrt(op2[:,:,4])))
          total_error = class_error + row_error + col_error + h_error + w_error
          y_ret[0,i] = total_error
      return y_ret
  </code></pre>
  
  <p>This however gives me an error:</p>
  
  <blockquote>
    <p>ValueError: Cannot convert a partially known TensorShape to a Tensor:
    (1, ?)</p>
  </blockquote>
  
  <p>This is because I guess the batch size is undefined.</p>
  
  <p>2) Another way is to apply the sqrt transformations to each of the image tensors in the batch and then subtract them and then apply the square transform.</p>
  
  <p>for e.g</p>
  
  <pre><code>1) sqrt(y_true[:,:,:,3])  
  2) sqrt(y_pred[:,:,:,3])  
  3) sqrt(y_true[:,:,:,4])  
  4) sqrt(y_pred[:,:,:,4])  
  5) y_new = y_true-y_pred  
  6) square(y_new[:,:,:,0])  
  7) square(y_new[:,:,:,1])  
  8) square(y_new[:,:,:,2])  
  9) reduce_sum for each new tensor in the batch and return o/p in shape [1,batch_size]
  </code></pre>
  
  <p>However I could not find a way to do this in Keras.</p>
  
  <p>Can someone suggest, what would be the best way to implement this loss function. I am using Keras with tensorflow at the backend.</p>