title: Keras - weighted average of tensors
body: <p>If I've n tensors <code>T_i</code> of shape <code>(?, k)</code>, and one tensor <code>U</code> of shape <code>(?, n)</code>, how can I get the tensor <code>(?, k)</code> that is equal to <code>sum(T_i * U[i])</code> ?</p>
  
  <p>I've tried writing a layer to do so:</p>
  
  <pre><code>class WeightedAverage(_Merge):
      """Layer that computes a mean between samples in several tensors according to weights computed in another tensor.
      E.g. if applied to k tensors `a_0` and `a_k` of shape `(batch_size, n)`, and a tensor `b` of shape `(batch_size, k)`
      the output will be a tensor of shape `(batch_size, n)`
      where each entry `i` will be the dot product between
      `sum(a_j[i] * b[j] over j)`.
      """
      def __init__(self, **kwargs):
          self.weight_tensor = None
          super(WeightedAverage, self).__init__(**kwargs)
  
      def _merge_function(self, inputs):
          if self.weight_tensor is None:
              raise ValueError('A `WeightedAverage` layer should have a weight layer')
          shape = inputs[0].get_shape().as_list()
          k = shape[1]
          n = len(inputs)
          all_inputs = K.reshape(Concatenate()(inputs), (-1, n, k))
          return K.reshape(K.batch_dot(all_inputs, self.weight_tensor, axes=(1, 2)), (-1, k))
  
      def call(self, inputs, weights):
          if weights.shape[1] != len(inputs):
              raise ValueError('A `WeightedAverage` weights layer should have as many'
                               'outputs as there are inputs.')
          shape = weights.get_shape().as_list()
          self.weight_tensor = K.reshape(weights, (-1, 1, shape[1]))
          return super(WeightedAverage, self).call(inputs)
  </code></pre>
  
  <p>that I called with:</p>
  
  <pre><code>x = WeightedAverage(name="weightAverage")(Ts, weights=U)
  </code></pre>
  
  <p>however that fails with a rather long tensorflow trace:</p>
  
  <pre><code>W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  W tensorflow/core/framework/op_kernel.cc:993] Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
  Traceback (most recent call last):
    File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/client/session.py", line 1022, in _do_call
      return fn(*args)
    File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/client/session.py", line 1004, in _run_fn
      status, run_metadata)
    File "/usr/lib/python3.4/contextlib.py", line 66, in __exit__
      next(self.gen)
    File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/framework/errors_impl.py", line 466, in raise_exception_on_not_ok_status
      pywrap_tensorflow.TF_GetCode(status))
  tensorflow.python.framework.errors_impl.InvalidArgumentError: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
     [[Node: batch_2_1/moments/sufficient_statistics/Gather/_519 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/cpu:0", send_device="/job:localhost/replica:0/task:0/gpu:0", send_device_incarnation=1, tensor_name="edge_9178_batch_2_1/moments/sufficient_statistics/Gather", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/cpu:0"]()]]
  
  During handling of the above exception, another exception occurred:
  
  Traceback (most recent call last):
    File "train.py", line 118, in &lt;module&gt;
      cnn.fit(n_epoch=N_EPOCH, batch_size=BATCH_SIZE, generating=args["generate_data"])
    File "/home/ubuntu/models/model.py", line 125, in fit
      epochs=n_epoch
    File "/usr/local/lib/python3.4/dist-packages/keras/engine/training.py", line 1507, in fit
      initial_epoch=initial_epoch)
    File "/usr/local/lib/python3.4/dist-packages/keras/engine/training.py", line 1156, in _fit_loop
      outs = f(ins_batch)
    File "/usr/local/lib/python3.4/dist-packages/keras/backend/tensorflow_backend.py", line 2269, in __call__
      **self.session_kwargs)
    File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/client/session.py", line 767, in run
      run_metadata_ptr)
    File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/client/session.py", line 965, in _run
      feed_dict_string, options, run_metadata)
    File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/client/session.py", line 1015, in _do_run
      target_list, options, run_metadata)
    File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/client/session.py", line 1035, in _do_call
      raise type(e)(node_def, op, message)
  tensorflow.python.framework.errors_impl.InvalidArgumentError: You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
     [[Node: batch_2_1/moments/sufficient_statistics/Gather/_519 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/cpu:0", send_device="/job:localhost/replica:0/task:0/gpu:0", send_device_incarnation=1, tensor_name="edge_9178_batch_2_1/moments/sufficient_statistics/Gather", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/cpu:0"]()]]
  
  Caused by op 'input_1', defined at:
    File "train.py", line 103, in &lt;module&gt;
      weather_model = load_model(args["helper_model"])
    File "/usr/local/lib/python3.4/dist-packages/keras/models.py", line 246, in load_model
      model = model_from_config(model_config, custom_objects=custom_objects)
    File "/usr/local/lib/python3.4/dist-packages/keras/models.py", line 314, in model_from_config
      return layer_module.deserialize(config, custom_objects=custom_objects)
    File "/usr/local/lib/python3.4/dist-packages/keras/layers/__init__.py", line 54, in deserialize
      printable_module_name='layer')
    File "/usr/local/lib/python3.4/dist-packages/keras/utils/generic_utils.py", line 140, in deserialize_keras_object
      list(custom_objects.items())))
    File "/usr/local/lib/python3.4/dist-packages/keras/engine/topology.py", line 2450, in from_config
      process_layer(layer_data)
    File "/usr/local/lib/python3.4/dist-packages/keras/engine/topology.py", line 2419, in process_layer
      custom_objects=custom_objects)
    File "/usr/local/lib/python3.4/dist-packages/keras/layers/__init__.py", line 54, in deserialize
      printable_module_name='layer')
    File "/usr/local/lib/python3.4/dist-packages/keras/utils/generic_utils.py", line 142, in deserialize_keras_object
      return cls.from_config(config['config'])
    File "/usr/local/lib/python3.4/dist-packages/keras/engine/topology.py", line 1242, in from_config
      return cls(**config)
    File "/usr/local/lib/python3.4/dist-packages/keras/legacy/interfaces.py", line 88, in wrapper
      return func(*args, **kwargs)
    File "/usr/local/lib/python3.4/dist-packages/keras/engine/topology.py", line 1337, in __init__
      name=self.name)
    File "/usr/local/lib/python3.4/dist-packages/keras/backend/tensorflow_backend.py", line 431, in placeholder
      x = tf.placeholder(dtype, shape=shape, name=name)
    File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/ops/array_ops.py", line 1502, in placeholder
      name=name)
    File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/ops/gen_array_ops.py", line 2149, in _placeholder
      name=name)
    File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/framework/op_def_library.py", line 763, in apply_op
      op_def=op_def)
    File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/framework/ops.py", line 2327, in create_op
      original_op=self._default_original_op, op_def=op_def)
    File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/framework/ops.py", line 1226, in __init__
      self._traceback = _extract_stack()
  
  InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor 'input_1' with dtype float
     [[Node: input_1 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
     [[Node: batch_2_1/moments/sufficient_statistics/Gather/_519 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/cpu:0", send_device="/job:localhost/replica:0/task:0/gpu:0", send_device_incarnation=1, tensor_name="edge_9178_batch_2_1/moments/sufficient_statistics/Gather", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/cpu:0"]()]]
  
  Exception ignored in: &lt;bound method Session.__del__ of &lt;tensorflow.python.client.session.Session object at 0x7ff0256cf550&gt;&gt;
  Traceback (most recent call last):
    File "/usr/local/lib/python3.4/dist-packages/tensorflow/python/client/session.py", line 582, in __del__
  UnboundLocalError: local variable 'status' referenced before assignment
  *** Error in `python3': corrupted size vs. prev_size: 0x00000000021b4ac0 ***
  Aborted (core dumped)
  </code></pre>