Repository: keras-team/keras

Issue:
Masking a layer that has an integer dtype raises an error in TensorFlow but not Theano.
The following:
```python
from keras.layers import Input, Masking

document = Input(shape = (10, ), dtype = "int32")
mask = Masking(mask_value = 21)
document_mask = mask(document)
```
produces this error:

```
----> 5 document_mask = mask(document)

/home/airalcorn2/.pyenv/versions/3.5.2/lib/python3.5/site-packages/keras/engine/topology.py in __call__(self, inputs, **kwargs)
    594 
    595             # Actually call the layer, collecting output(s), mask(s), and shape(s).
--> 596             output = self.call(inputs, **kwargs)
    597             output_mask = self.compute_mask(inputs, previous_mask)
    598 

/home/airalcorn2/.pyenv/versions/3.5.2/lib/python3.5/site-packages/keras/layers/core.py in call(self, inputs)
     62         boolean_mask = K.any(K.not_equal(inputs, self.mask_value),
     63                              axis=-1, keepdims=True)
---> 64         return inputs * K.cast(boolean_mask, K.floatx())
     65 
     66     def get_config(self):

/home/airalcorn2/.pyenv/versions/3.5.2/lib/python3.5/site-packages/tensorflow/python/ops/math_ops.py in binary_op_wrapper(x, y)
    827       if not isinstance(y, sparse_tensor.SparseTensor):
    828         try:
--> 829           y = ops.convert_to_tensor(y, dtype=x.dtype.base_dtype, name="y")
    830         except TypeError:
    831           # If the RHS is not a tensor, it might be a tensor aware object

/home/airalcorn2/.pyenv/versions/3.5.2/lib/python3.5/site-packages/tensorflow/python/framework/ops.py in convert_to_tensor(value, dtype, name, preferred_dtype)
    674       name=name,
    675       preferred_dtype=preferred_dtype,
--> 676       as_ref=False)
    677 
    678 

/home/airalcorn2/.pyenv/versions/3.5.2/lib/python3.5/site-packages/tensorflow/python/framework/ops.py in internal_convert_to_tensor(value, dtype, name, as_ref, preferred_dtype)
    739 
    740         if ret is None:
--> 741           ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
    742 
    743         if ret is NotImplemented:

/home/airalcorn2/.pyenv/versions/3.5.2/lib/python3.5/site-packages/tensorflow/python/framework/ops.py in _TensorTensorConversionFunction(t, dtype, name, as_ref)
    612     raise ValueError(
    613         "Tensor conversion requested dtype %s for Tensor with dtype %s: %r"
--> 614         % (dtype.name, t.dtype.name, str(t)))
    615   return t
    616 

ValueError: Tensor conversion requested dtype int32 for Tensor with dtype float32: 'Tensor("masking_1/Cast_1:0", shape=(?, 1), dtype=float32)'
```

when using TensorFlow as the backend, but works fine with Theano. The issue seems to be that [Keras casts the mask to a float](https://github.com/fchollet/keras/blob/master/keras/layers/core.py#L64), even when the inputs are not floats themselves. Changing the return value to:

```python
inputs * K.cast(boolean_mask, inputs.dtype)
```

fixes the issue.


Discussion:

Resolving patch:
diff --git a/keras/layers/core.py b/keras/layers/core.py
--- a/keras/layers/core.py
+++ b/keras/layers/core.py
@@ -61,7 +61,7 @@ def compute_mask(self, inputs, mask=None):
     def call(self, inputs):
         boolean_mask = K.any(K.not_equal(inputs, self.mask_value),
                              axis=-1, keepdims=True)
-        return inputs * K.cast(boolean_mask, K.floatx())
+        return inputs * K.cast(boolean_mask, inputs.dtype)
 
     def get_config(self):
         config = {'mask_value': self.mask_value}


Test patch: