I know the functional API supports declaring input shape in an Input layer, and then passing that to a Model() object, but what's the equivalent for Sequential()? I'd expect something like this to work:
model = Sequential()
model.add(Input(batch_shape=(batch_size, height, width, channels)))
model.add(Convolutions/RNNs/Dense/Whatever)
model.compile(...)
but it doesn't.
AttributeError: 'TensorVariable' object has no attribute 'inbound_nodes'
What am I missing? Shouldn't the API's work similarly?
I'd even expect something like (my preferred API, because all models always have at least one input, right?):
model = Sequential((batch_size, height, width, channels))
model.add(Convolutions/RNNs/Dense/Whatever)
model.compile(...)
Also, why is it called batch_input_shape in some layers, and batch_shape in others? It's a bit confusing, honestly.
I wholeheartedly agree. Similar concerns with issue #4074 . I'd be happy to work on this / contribute to improving this.
If pull request #4069 was merged, it would help tremendously. I (or anyone else) could start jotting out candidate solution as a child class / child classes (which could be tried out easier by others).
I know the functional API supports declaring input shape in an Input layer, and then passing that to a Model() object, but what's the equivalent for Sequential()?
InputLayer or just Layer.
model = Sequential()
model.add(InputLayer(batch_input_shape=(batch_size, height, width, channels)))
model.add(Convolutions/RNNs/Dense/Whatever)
model.compile(...)
What am I missing? Shouldn't the API's work similarly?
Input is a function which returns a tensor. You add layers to Sequential models. Not tensors
I'd even expect something like (my preferred API, because all models always have at least one input, right?):
model = Sequential([Layer(batch_input_shape=(batch_size, height, width, channels))])
model.add(...)
model.add(...)
...
Also, why is it called batch_input_shape in some layers, and batch_shape in others? It's a bit confusing, honestly.
Its not.
All layers take batch_input_shape and input_shape arguments. There is "input" in the argument names because they specify the shapes of the tensors which will be "input" to the layer.
The Input function takes batch_shape and shape arguments. No "input" here. Since here the arguments specify the shape of the tensor (placeholder to be more precise) itself. We are simply asking Keras to create a placeholder of a given shape.
Ah, much thanks for the explanation @farizrahman4u. :smile:
So it's called InputLayer! As Input is a function and not a constructor for a Layer subclass I would have expected it to follow the naming convention of being all snake_case, like with the distinction between Merge() and merge(), e.g. input(). Why is it capitalized? :confounded:
The distinction between batch_input_shape and batch_shape sure makes sense then though, however, it would still be a cleaner API if:
model = Sequential(shape=(batch_size, height, width, channels))
model.add(...)
model.add(...)
worked and simply called the function for creating a placeholder in its constructor if batch_input_shape is not None, IMO, and the reason for it not being like this already seems like it has more to do with internals and requiring refactoring, than anything else.
I'll keep with the functional convention I think, as it closest resembles sklearn's make_pipeline:
model = Sequential([
InputLayer(batch_input_shape=(batch_size, height, width, channels)),
Convolution(...),
Pooling(...),
Flatten(...),
Dense(...),
Whatever(...),
])
model.compile(...)
Why is it capitalized?
There is already a built-in function in python called input().
Why is it capitalized?
There is already a built-in function in python called input().
Yuck (*).
If the first letter means that the object is a class, breaking that rule for that reason is confusing to say the least. The docstring for the function Input is fueling that sentiment further. The first line reads "Input() is used to instantiate a Keras tensor.". Since the function is creating a tensor what about calling it input_tensor (if you really really want to have "input" in the name) ?
(*: the concept of layers is really nice. So much that comparatively Input is looking relatively inelegant, but that's a matter of personal taste).
@farizrahman4u got it right.
Basically Input is the equivalent of instantiating an InputLayer and calling it in one go. Reading the guide "getting started with the functional API" should clear up any questions.
Yuck indeed.
Most helpful comment
InputLayeror justLayer.Inputis a function which returns a tensor. You add layers toSequentialmodels. Not tensorsIts not.
All layers take
batch_input_shapeandinput_shapearguments. There is "input" in the argument names because they specify the shapes of the tensors which will be "input" to the layer.The
Inputfunction takesbatch_shapeandshapearguments. No "input" here. Since here the arguments specify the shape of the tensor (placeholder to be more precise) itself. We are simply asking Keras to create a placeholder of a given shape.