<p dir="auto"><em>Please make sure that this is a Bug or a Feature Request and provide all applicable information asked by the template.<br>
If your issue is an <strong>implementation question</strong>, please ask your question on <a href="http://stackoverflow.com/questions/tagged/keras" rel="nofollow">StackOverflow</a> or <a href="https://keras-slack-autojoin.herokuapp.com/" rel="nofollow">on the Keras Slack channel</a> instead of opening a GitHub issue.</em></p>
<p dir="auto"><strong>System information</strong></p>
<ul dir="auto">
<li>Have I written custom code (as opposed to using example directory):  Yes</li>
<li>OS Platform and Distribution (e.g., Linux Ubuntu 16.04):  macOS 10.14.6</li>
<li>TensorFlow backend (yes / no):  Yes</li>
<li>TensorFlow version:  1.14.0</li>
<li>Keras version:  2.2.5</li>
<li>Python version:  2.7.16</li>
</ul>
<p dir="auto">You can obtain the TensorFlow version with:<br>
python -c "import tensorflow as tf; print(tf.GIT_VERSION, tf.VERSION)"<br>
You can obtain the Keras version with:<br>
python -c 'import keras as k; print(k.<strong>version</strong>)'</p>
<p dir="auto"><strong>Describe the current behavior</strong><br>
Nested call to <code class="notranslate">_standardize_args</code> in superclass (<code class="notranslate">RNN</code>) <code class="notranslate">__call__</code> fails with assertion failure:</p>
<blockquote>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="assert initial_state is None and constants is None"><pre class="notranslate"><code class="notranslate">assert initial_state is None and constants is None
</code></pre></div>
</blockquote>
<p dir="auto">when a <code class="notranslate">ConvRNN2D</code> is <code class="notranslate">__call__</code>ed with a non-default <code class="notranslate">initial_state</code>.</p>
<p dir="auto"><strong>Describe the expected behavior</strong><br>
The non-default <code class="notranslate">initial_state</code> should be successfully passed through and used by the convolutional RNN cell.</p>
<p dir="auto"><strong>Code to reproduce the issue</strong></p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="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:])"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">keras</span>.<span class="pl-s1">layers</span> <span class="pl-k">import</span> <span class="pl-v">Input</span>, <span class="pl-v">ConvLSTM2D</span>
<span class="pl-s1">input</span> <span class="pl-c1">=</span> <span class="pl-v">Input</span>(<span class="pl-s1">shape</span><span class="pl-c1">=</span>(<span class="pl-c1">1</span>,<span class="pl-c1">128</span>,<span class="pl-c1">128</span>,<span class="pl-c1">4</span>))
<span class="pl-s1">filter</span> <span class="pl-c1">=</span> <span class="pl-v">ConvLSTM2D</span>(<span class="pl-c1">4</span>,<span class="pl-c1">7</span>,<span class="pl-s1">strides</span><span class="pl-c1">=</span><span class="pl-c1">2</span>,<span class="pl-s1">padding</span><span class="pl-c1">=</span><span class="pl-s">'same'</span>,<span class="pl-s1">return_state</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)
<span class="pl-s1">shrunk</span> <span class="pl-c1">=</span> <span class="pl-en">filter</span>(<span class="pl-s1">input</span>)
<span class="pl-en">filter</span>(<span class="pl-s1">shrunk</span>[<span class="pl-c1">0</span>], <span class="pl-s1">initial_state</span> <span class="pl-c1">=</span> <span class="pl-s1">shrunk</span>[<span class="pl-c1">1</span>:])</pre></div>
<p dir="auto"><strong>Other info / logs</strong><br>
It appears that <code class="notranslate">ConvRNN2D.__call__</code> replicates much of the logic from <code class="notranslate">RNN.__call__</code> and that the replicated logic is the source of the error. Among other things, <code class="notranslate">ConvRNN2D.__call__</code> begins by calling <code class="notranslate">_standardize_args</code>, and then post-processes these in roughly the same way as <code class="notranslate">RNN.__call__</code>, including adding <code class="notranslate">initial_state</code> and <code class="notranslate">constants</code> to both the list <code class="notranslate">full_input</code> and the dict <code class="notranslate">kwargs</code>, meaning that the arguments are being passed in twice.<br>
Naively commenting out the lines that insert to <code class="notranslate">kwargs</code> results in a different error:</p>
<blockquote>
<p dir="auto">Traceback (most recent call last):<br>
File "", line 1, in <br>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/keras/layers/convolutional_recurrent.py", line 324, in <strong>call</strong><br>
output = super(ConvRNN2D, self).<strong>call</strong>(full_input, **kwargs)<br>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/keras/layers/recurrent.py", line 576, in <strong>call</strong><br>
output = super(RNN, self).<strong>call</strong>(full_input, **kwargs)<br>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/keras/engine/base_layer.py", line 434, in <strong>call</strong><br>
self.assert_input_compatibility(inputs)<br>
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<br>
str(inputs))<br>
ValueError: Layer conv_lst_m2d_1 expects 5 inputs, but it received 3 input tensors. Input received: [&lt;tf.Tensor 'conv_lst_m2d_1_1/TensorArrayReadV3:0' shape=(?, 64, 64, 4) dtype=float32&gt;, &lt;tf.Tensor 'conv_lst_m2d_1_1/while/Exit_3:0' shape=(?, 64, 64, 4) dtype=float32&gt;, &lt;tf.Tensor 'conv_lst_m2d_1_1/while/Exit_4:0' shape=(?, 64, 64, 4) dtype=float32&gt;]</p>
</blockquote>
<p dir="auto">This suggests that other of the duplicated code (perhaps the tinkering with <code class="notranslate">self.input_spec</code>) is causing the base class to still expect to use the <code class="notranslate">initial_state</code> twice, if it could be passed in without error.</p>
<p dir="auto">Running on tensorflow.keras<br>
I have a model that is composed of submodels that share a layer</p>
<p dir="auto">When the model is defined by code the layers are indeed shared<br>
If I recreate the model from config (or load from file), the layers are duplicated<br>
This is both problematic in terms of memory duplication for large models, and the inability to continue train the layer as a shared layer</p>
<p dir="auto">code example:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="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)
"><pre class="notranslate"><code class="notranslate">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)

</code></pre></div>
<p dir="auto">output:</p>
<blockquote>
<p dir="auto">Original Model<br>
&lt;tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x118117320&gt;<br>
&lt;tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x1181173c8&gt;<br>
&lt;tensorflow.python.keras._impl.keras.engine.training.Model object at 0x111c23ba8&gt;<br>
&lt;tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x111f3acf8&gt;<br>
&lt;tensorflow.python.keras._impl.keras.layers.core.Dense object at <strong>0x118109ef0</strong>&gt;<br>
&lt;tensorflow.python.keras._impl.keras.engine.training.Model object at 0x118147390&gt;<br>
&lt;tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x111f3acf8&gt;<br>
&lt;tensorflow.python.keras._impl.keras.layers.core.Dense object at <strong>0x118109ef0</strong>&gt;<br>
&lt;tensorflow.python.keras._impl.keras.layers.merge.Concatenate object at 0x118117dd8&gt;</p>
<p dir="auto">Model from config<br>
&lt;tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x118178d68&gt;<br>
&lt;tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x118178160&gt;<br>
&lt;tensorflow.python.keras._impl.keras.engine.training.Model object at 0x118178240&gt;<br>
&lt;tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x11818a1d0&gt;<br>
&lt;tensorflow.python.keras._impl.keras.layers.core.Dense object at <strong>0x11818a160</strong>&gt;<br>
&lt;tensorflow.python.keras._impl.keras.engine.training.Model object at 0x1181b59e8&gt;<br>
&lt;tensorflow.python.keras._impl.keras.engine.topology.InputLayer object at 0x11818a128&gt;<br>
&lt;tensorflow.python.keras._impl.keras.layers.core.Dense object at <strong>0x11818a898</strong>&gt;<br>
&lt;tensorflow.python.keras._impl.keras.layers.merge.Concatenate object at 0x118194198&gt;</p>
</blockquote>
<p dir="auto">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</p>