title: Custom weighted loss function in Keras for weighing each element
body: <p>I'm trying to create a simple weighted loss function. </p>
  
  <p>Say, I have input dimensions 100 * 5, and output dimensions also 100 * 5. I also have a weight matrix of the same dimension.</p>
  
  <p>Something like the following:</p>
  
  <pre><code>import numpy as np
  train_X = np.random.randn(100, 5)
  train_Y = np.random.randn(100, 5)*0.01 + train_X
  
  weights = np.random.randn(*train_X.shape)
  </code></pre>
  
  <h3>Defining the custom loss function</h3>
  
  <pre><code>def custom_loss_1(y_true, y_pred):
      return K.mean(K.abs(y_true-y_pred)*weights)
  </code></pre>
  
  <h3>Defining the model</h3>
  
  <pre><code>from keras.layers import Dense, Input
  from keras import Model
  import keras.backend as K
  
  input_layer = Input(shape=(5,))
  out = Dense(5)(input_layer)
  model = Model(input_layer, out)
  </code></pre>
  
  <h3>Testing with existing metrics works fine</h3>
  
  <pre><code>model.compile('adam','mean_absolute_error')
  model.fit(train_X, train_Y, epochs=1)
  </code></pre>
  
  <h3>Testing with our custom loss function doesn't work</h3>
  
  <pre><code>model.compile('adam',custom_loss_1)
  model.fit(train_X, train_Y, epochs=10)
  </code></pre>
  
  <p>It gives the following stack trace:</p>
  
  <pre><code>InvalidArgumentError (see above for traceback): Incompatible shapes: [32,5] vs. [100,5]
   [[Node: loss_9/dense_8_loss/mul = Mul[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"](loss_9/dense_8_loss/Abs, loss_9/dense_8_loss/mul/y)]]
  </code></pre>
  
  <p>Where is the number 32 coming from?</p>
  
  <h3>Testing a loss function with weights as Keras tensors</h3>
  
  <pre><code>def custom_loss_2(y_true, y_pred):
      return K.mean(K.abs(y_true-y_pred)*K.ones_like(y_true))
  </code></pre>
  
  <p>This function seems to do the work. So, probably suggests that a Keras tensor as a weight matrix would work. So, I created another version of the loss function.</p>
  
  <h3>Loss function try 3</h3>
  
  <pre><code>from functools import partial
  
  def custom_loss_3(y_true, y_pred, weights):
      return K.mean(K.abs(y_true-y_pred)*K.variable(weights, dtype=y_true.dtype))
  
  cl3 = partial(custom_loss_3, weights=weights)  
  </code></pre>
  
  <p>Fitting data using cl3 gives the same error as above.</p>
  
  <pre><code>InvalidArgumentError (see above for traceback): Incompatible shapes: [32,5] vs. [100,5]
       [[Node: loss_11/dense_8_loss/mul = Mul[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"](loss_11/dense_8_loss/Abs, loss_11/dense_8_loss/Variable/read)]]
  </code></pre>
  
  <p>I wonder what I'm missing! I could have used the notion of sample_weight in Keras; but then I'd have to reshape my inputs to a 3d vector. </p>
  
  <p>I thought that this custom loss function should really have been trivial.</p>