I want to define a simple model that uses basic math operations. I tried to implement it using multiple approaches, but the most obvious ones fail, and I would like to understand why.
Let's look at the code:
import keras.backend as K
from keras.layers import Input, Lambda
from keras.models import Model
import numpy as np
x = Input(shape=(3,))
y = Lambda(lambda x: x ** 2)(x)
print y
# Tensor("lambda_1/pow:0", shape=(?, 3), dtype=float32)
model = Model(inputs=x, outputs=y)
# Works!
y = x ** 2
print y
# Tensor("pow:0", shape=(?, 3), dtype=float32)
model = Model(inputs=x, outputs=y)
# Fails: TypeError: Output tensors to a Model must be Keras tensors.
y = K.pow(x, 2)
print y
# Tensor("Pow:0", shape=(?, 3), dtype=float32)
model = Model(inputs=x, outputs=y)
# Fails: TypeError: Output tensors to a Model must be Keras tensors.
The last two examples fail due to:
/usr/local/lib/python2.7/dist-packages/keras/engine/topology.pyc in __init__(self, inputs, outputs, name)
1521 if not hasattr(x, '_keras_history'):
1522 cls_name = self.__class__.__name__
1523 raise TypeError('Output tensors to a ' + cls_name + ' must be '
-> 1524 'Keras tensors. Found: ' + str(x))
1525 # Build self.output_layers:
1526 for x in self.outputs:
As you can see, the output of y for all models is almost identical, but the intuitive ones fail for some reason. Any idea why this fails?
You can't use ops. You have to use layers. Which is why we have Lambda layer in the first place.
Model(inputs=x, outputs=y)
Here both x and y should be the outputs of Keras layers. To use custom operations, you should wrap them in a Lambda layer (as @farizrahman4u points out), or write your own custom layer (see https://keras.io/layers/writing-your-own-keras-layers/)
Most helpful comment
Here both
xandyshould be the outputs of Keras layers. To use custom operations, you should wrap them in aLambdalayer (as @farizrahman4u points out), or write your own custom layer (see https://keras.io/layers/writing-your-own-keras-layers/)