Issue 1:
Please make sure that this is a Bug or a Feature Request and provide all applicable information asked by the template.

If your issue is an implementation question, please ask your question on StackOverflow or on the Keras Slack channel instead of opening a GitHub issue.

System information

Have I written custom code (as opposed to using example directory): Yes

OS Platform and Distribution (e.g., Linux Ubuntu 16.04): macOS 10.14.6

TensorFlow backend (yes / no): Yes

TensorFlow version: 1.14.0

Keras version: 2.2.5

Python version: 2.7.16

You can obtain the TensorFlow version with:

python -c "import tensorflow as tf; print(tf.GIT_VERSION, tf.VERSION)"

You can obtain the Keras version with:

python -c 'import keras as k; print(k.version)'

Describe the current behavior

Nested call to _standardize_args in superclass (RNN) __call__ fails with assertion failure:

assert initial_state is None and constants is None

when a ConvRNN2D is __call__ed with a non-default initial_state.

Describe the expected behavior

The non-default initial_state should be successfully passed through and used by the convolutional RNN cell.

Code to reproduce the issue

from keras.layers import Input, ConvLSTM2D
input = Input(shape=(1,128,128,4))
filter = ConvLSTM2D(4,7,strides=2,padding='same',return_state=True)
shrunk = filter(input)
filter(shrunk[0], initial_state = shrunk[1:])

Other info / logs

It appears that ConvRNN2D.__call__ replicates much of the logic from RNN.__call__ and that the replicated logic is the source of the error. Among other things, ConvRNN2D.__call__ begins by calling _standardize_args, and then post-processes these in roughly the same way as RNN.__call__, including adding initial_state and constants to both the list full_input and the dict kwargs, meaning that the arguments are being passed in twice.

Naively commenting out the lines that insert to kwargs results in a different error:

Traceback (most recent call last):

File "", line 1, in

File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/keras/layers/convolutional_recurrent.py", line 324, in call

output = super(ConvRNN2D, self).call(full_input, **kwargs)

File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/keras/layers/recurrent.py", line 576, in call

output = super(RNN, self).call(full_input, **kwargs)

File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/keras/engine/base_layer.py", line 434, in call

self.assert_input_compatibility(inputs)

File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/keras/engine/base_layer.py", line 293, in assert_input_compatibility

str(inputs))

ValueError: Layer conv_lst_m2d_1 expects 5 inputs, but it received 3 input tensors. Input received: [<tf.Tensor 'conv_lst_m2d_1_1/TensorArrayReadV3:0' shape=(?, 64, 64, 4) dtype=float32>, <tf.Tensor 'conv_lst_m2d_1_1/while/Exit_3:0' shape=(?, 64, 64, 4) dtype=float32>, <tf.Tensor 'conv_lst_m2d_1_1/while/Exit_4:0' shape=(?, 64, 64, 4) dtype=float32>]

This suggests that other of the duplicated code (perhaps the tinkering with self.input_spec) is causing the base class to still expect to use the initial_state twice, if it could be passed in without error.

Issue 2:
Running on tensorflow.keras

I have a model that is composed of submodels that share a layer

When the model is defined by code the layers are indeed shared

If I recreate the model from config (or load from file), the layers are duplicated

This is both problematic in terms of memory duplication for large models, and the inability to continue train the layer as a shared layer

code example:

import tensorflow
keras = tensorflow.keras

def dump(model):
for layer in model.layers:
print(layer)
if hasattr(layer, 'layers'):
dump(layer)

INPUT_LEN = 10
DENSE_SIZE = 1

input_layer = keras.layers.Input(shape=(INPUT_LEN,))
shared_layer = keras.layers.Dense(DENSE_SIZE)
submodel1 = keras.models.Model(inputs=input_layer, outputs=shared_layer(input_layer))
submodel2 = keras.models.Model(inputs=input_layer, outputs=shared_layer(input_layer))

input_layer1 = keras.layers.Input(shape=(INPUT_LEN,))
input_layer2 = keras.layers.Input(shape=(INPUT_LEN,))
m2 = keras.models.Model(inputs=[input_layer1, input_layer2], outputs=keras.layers.concatenate([submodel1(input_layer1), submodel2(input_layer2)]))

print('Original Model')
dump(m2)
m2_loaded = keras.models.Model.from_config(m2.get_config())
m2_loaded.set_weights(m2.get_weights())
print('Model from config')
dump(m2_loaded)

output:

Original Model

<tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x118117320>

<tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x1181173c8>

<tensorflow.python.keras._impl.keras.engine.training.Model object at 0x111c23ba8>

<tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x111f3acf8>

<tensorflow.python.keras._impl.keras.layers.core.Dense object at 0x118109ef0>

<tensorflow.python.keras._impl.keras.engine.training.Model object at 0x118147390>

<tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x111f3acf8>

<tensorflow.python.keras._impl.keras.layers.core.Dense object at 0x118109ef0>

<tensorflow.python.keras._impl.keras.layers.merge.Concatenate object at 0x118117dd8>

Model from config

<tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x118178d68>

<tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x118178160>

<tensorflow.python.keras._impl.keras.engine.training.Model object at 0x118178240>

<tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x11818a1d0>

<tensorflow.python.keras._impl.keras.layers.core.Dense object at 0x11818a160>

<tensorflow.python.keras._impl.keras.engine.training.Model object at 0x1181b59e8>

<tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x11818a128>

<tensorflow.python.keras._impl.keras.layers.core.Dense object at 0x11818a898>

<tensorflow.python.keras._impl.keras.layers.merge.Concatenate object at 0x118194198>

Note that in the original model the dense layers share the same layer (same pointer), and in the model created from config, they are different