提交 9aa32a6e 编写于 作者: F Francois Chollet 提交者: TensorFlower Gardener

Enable mixing value tensors (eager tensors or numpy arrays) and Keras symbolic...

Enable mixing value tensors (eager tensors or numpy arrays) and Keras symbolic tensors when building Keras graphs-of-layers in an eager scope.
In these cases, the value tensors are treated as symbolic constants.

This enables the following pattern to work in the same way in both V1 and V2:

```
lstm = LSTM(2)
inputs = keras.Input((None, 3))
outputs = lstm(inputs, initial_state=tf.ones(shape))
```

(without this change, the above code works in V1 but fails in V2 with an artificial exception).

Known issue: in case a random tensor is used, there is a (usually harmless) behavior discrepancy remaining between V1 and V2, which is that in V2 we'd be using the same random value every time, whereas in V1 we'd be drawing new random values (since the tensor would be treated as a random op and not as a constant). We think this is not a problem because in V2 users should have the mental model "tensors are values" and thus would be expecting a random tensor to behave like a constant value and not like a random generator.

PiperOrigin-RevId: 224915621
上级 3ef97d1e
......@@ -66,12 +66,6 @@ def quick_execute(op_name, num_outputs, inputs, attrs, ctx, name=None):
six.raise_from(core._status_to_exception(e.code, message), None)
except TypeError as e:
if any(ops._is_keras_symbolic_tensor(x) for x in inputs):
if any(isinstance(x, ops.EagerTensor) for x in inputs):
raise TypeError("You are attempting to mix computation of symbolic "
"Tensors (computation rooted at tf.keras.Input()) "
"and concrete values. This is not supported. "
"If you need this support, file an issue on the "
"TensorFlow GitHub repository.")
raise core._SymbolicException
raise e
# pylint: enable=protected-access
......
......@@ -167,19 +167,26 @@ class BaseLayerTest(test.TestCase):
def test_mixing_keras_symbolic_tensors_and_eager_tensors(self):
x1 = keras.Input((3,))
x2 = array_ops.ones((3, 3))
with self.assertRaisesRegexp(
TypeError,
'mix computation of symbolic Tensors'):
math_ops.matmul(x1, x2)
y = math_ops.matmul(x1, x2)
self.assertEqual(y.graph, keras.backend.get_graph())
fn = keras.backend.function(inputs=[x1], outputs=[y])
x_val = np.random.random((3, 3))
y_val = np.ones((3, 3))
self.assertAllClose(fn([x_val])[0],
np.matmul(x_val, y_val),
atol=1e-5)
def test_mixing_keras_symbolic_tensors_and_numpy_arrays(self):
# For the time being we treat Numpy arrays as EagerTensors when mixing both.
x1 = keras.Input((3,))
x2 = np.ones((3, 3), dtype='float32')
with self.assertRaisesRegexp(
TypeError,
'mix computation of symbolic Tensors'):
math_ops.matmul(x1, x2)
y = math_ops.matmul(x1, x2)
self.assertEqual(y.graph, keras.backend.get_graph())
fn = keras.backend.function(inputs=[x1], outputs=[y])
x_val = np.random.random((3, 3))
y_val = np.ones((3, 3))
self.assertAllClose(fn([x_val])[0],
np.matmul(x_val, y_val),
atol=1e-5)
if __name__ == '__main__':
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册