<p dir="auto"><strong>System information</strong>.</p>
<ul dir="auto">
<li>Have I written custom code (as opposed to using a stock example script provided in Keras):</li>
<li>OS Platform and Distribution (e.g., Linux Ubuntu 16.04):</li>
<li>TensorFlow installed from (source or binary):</li>
<li>TensorFlow version (use command below): 2.4.1, 2.6.4</li>
<li>Python version:</li>
<li>Bazel version (if compiling from source):</li>
<li>GPU model and memory:</li>
<li>Exact command to reproduce:</li>
</ul>
<p dir="auto"><strong>Describe the problem</strong>.</p>
<p dir="auto">I want to build sinmple model which consist of different version of same model, here which is <code class="notranslate">efficient-net</code>. The model build successfully. The training also works fine. But until now, I would get the following error if I use <code class="notranslate">ModelCheckpoint</code> to save model in the runtime.</p>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="RuntimeError: Unable to create link (name already exists)"><pre class="notranslate"><span class="pl-ent">RuntimeError</span>: <span class="pl-s">Unable to create link (name already exists)</span></pre></div>
<p dir="auto">To solve this, one of (dirty) workaround (suggestion get from web) is to rename weight variable. But that raise another issue at the time of model saving due to unexpected suffix with variable name.</p>
<blockquote>
<p dir="auto">/opt/conda/lib/python3.7/site-packages/tensorflow/python/ops/resource_variable_ops.py in write_object_proto_for_resource_variable(resource_variable, proto, options)<br>
2319     raise ValueError("Cowardly refusing to save variable {} because of"<br>
2320                      " unexpected suffix which won't be restored.".format(<br>
-&gt; 2321                          resource_variable.name))<br>
2322   proto.variable.name = meta_graph._op_name(resource_variable.name)  # pylint: disable=protected-access<br>
2323   proto.variable.trainable = resource_variable.trainable</p>
</blockquote>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="ValueError: Cowardly refusing to save 
variable normalization/mean:00 because of unexpected suffix which won't be restored."><pre class="notranslate"><span class="pl-ent">ValueError</span>: <span class="pl-s">Cowardly refusing to save </span>
<span class="pl-s">variable normalization/mean:00 because of unexpected suffix which won't be restored.</span></pre></div>
<p dir="auto"><strong>Standalone code to reproduce the issue</strong>.</p>
<p dir="auto">Here is the code to reproduce.</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from tensorflow.keras.applications import (
    EfficientNetB0, EfficientNetB1, EfficientNetB2
)
image_sizes_maps = {
    'B0': [EfficientNetB0, 224],
    'B1': [EfficientNetB1, 240],
    'B2': [EfficientNetB2, 260],
}"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">tensorflow</span>.<span class="pl-s1">keras</span>.<span class="pl-s1">applications</span> <span class="pl-k">import</span> (
    <span class="pl-v">EfficientNetB0</span>, <span class="pl-v">EfficientNetB1</span>, <span class="pl-v">EfficientNetB2</span>
)
<span class="pl-s1">image_sizes_maps</span> <span class="pl-c1">=</span> {
    <span class="pl-s">'B0'</span>: [<span class="pl-v">EfficientNetB0</span>, <span class="pl-c1">224</span>],
    <span class="pl-s">'B1'</span>: [<span class="pl-v">EfficientNetB1</span>, <span class="pl-c1">240</span>],
    <span class="pl-s">'B2'</span>: [<span class="pl-v">EfficientNetB2</span>, <span class="pl-c1">260</span>],
}</pre></div>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="def get_model():
    base_embeds = []    
    model_input = tf.keras.Input(shape=(None, None, 3),name='effnets')
    
    for key,value in image_sizes_maps.items():
        base_model, image_size = value
        x = tf.image.resize(model_input, [image_size, image_size], name=f'resize_{key}')
        z = base_model(
            include_top=False, 
        )(x)
        base_embeds.append(z)
   
    model = tf.keras.Model(model_input, base_embeds)
    return model"><pre class="notranslate"><span class="pl-k">def</span> <span class="pl-en">get_model</span>():
    <span class="pl-s1">base_embeds</span> <span class="pl-c1">=</span> []    
    <span class="pl-s1">model_input</span> <span class="pl-c1">=</span> <span class="pl-s1">tf</span>.<span class="pl-s1">keras</span>.<span class="pl-v">Input</span>(<span class="pl-s1">shape</span><span class="pl-c1">=</span>(<span class="pl-c1">None</span>, <span class="pl-c1">None</span>, <span class="pl-c1">3</span>),<span class="pl-s1">name</span><span class="pl-c1">=</span><span class="pl-s">'effnets'</span>)
    
    <span class="pl-k">for</span> <span class="pl-s1">key</span>,<span class="pl-s1">value</span> <span class="pl-c1">in</span> <span class="pl-s1">image_sizes_maps</span>.<span class="pl-en">items</span>():
        <span class="pl-s1">base_model</span>, <span class="pl-s1">image_size</span> <span class="pl-c1">=</span> <span class="pl-s1">value</span>
        <span class="pl-s1">x</span> <span class="pl-c1">=</span> <span class="pl-s1">tf</span>.<span class="pl-s1">image</span>.<span class="pl-en">resize</span>(<span class="pl-s1">model_input</span>, [<span class="pl-s1">image_size</span>, <span class="pl-s1">image_size</span>], <span class="pl-s1">name</span><span class="pl-c1">=</span><span class="pl-s">f'resize_<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">key</span><span class="pl-kos">}</span></span>'</span>)
        <span class="pl-s1">z</span> <span class="pl-c1">=</span> <span class="pl-en">base_model</span>(
            <span class="pl-s1">include_top</span><span class="pl-c1">=</span><span class="pl-c1">False</span>, 
        )(<span class="pl-s1">x</span>)
        <span class="pl-s1">base_embeds</span>.<span class="pl-en">append</span>(<span class="pl-s1">z</span>)
   
    <span class="pl-s1">model</span> <span class="pl-c1">=</span> <span class="pl-s1">tf</span>.<span class="pl-s1">keras</span>.<span class="pl-v">Model</span>(<span class="pl-s1">model_input</span>, <span class="pl-s1">base_embeds</span>)
    <span class="pl-k">return</span> <span class="pl-s1">model</span></pre></div>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="MODEL = get_model()"><pre class="notranslate"><span class="pl-v">MODEL</span> <span class="pl-c1">=</span> <span class="pl-en">get_model</span>()</pre></div>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# DIRTY SOLUTION
# IF WE DON'T DO IT, THEN IT WILL CAUSE 
# Unable to create link (name already exists)
for i in range(len(MODEL.weights)):
    MODEL.weights[i]._handle_name = MODEL.weights[i].name + str(i)"><pre class="notranslate"><span class="pl-c"># DIRTY SOLUTION</span>
<span class="pl-c"># IF WE DON'T DO IT, THEN IT WILL CAUSE </span>
<span class="pl-c"># Unable to create link (name already exists)</span>
<span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-en">len</span>(<span class="pl-v">MODEL</span>.<span class="pl-s1">weights</span>)):
    <span class="pl-v">MODEL</span>.<span class="pl-s1">weights</span>[<span class="pl-s1">i</span>].<span class="pl-s1">_handle_name</span> <span class="pl-c1">=</span> <span class="pl-v">MODEL</span>.<span class="pl-s1">weights</span>[<span class="pl-s1">i</span>].<span class="pl-s1">name</span> <span class="pl-c1">+</span> <span class="pl-en">str</span>(<span class="pl-s1">i</span>)</pre></div>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="MODEL.save(&quot;model&quot;)"><pre class="notranslate"><span class="pl-v">MODEL</span>.<span class="pl-en">save</span>(<span class="pl-s">"model"</span>)</pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="2022-09-04 21:11:19.660403: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_17/3402985690.py in &lt;module&gt;
----&gt; 1 MODEL.save(&quot;E0_E6&quot;)

ValueError: Cowardly refusing to save 
variable normalization/mean:00 because of unexpected suffix which won't be restored."><pre class="notranslate"><code class="notranslate">2022-09-04 21:11:19.660403: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_17/3402985690.py in &lt;module&gt;
----&gt; 1 MODEL.save("E0_E6")

ValueError: Cowardly refusing to save 
variable normalization/mean:00 because of unexpected suffix which won't be restored.
</code></pre></div>
<p dir="auto"><strong>Additional Content</strong></p>
<p dir="auto">With this, you can check if there is duplicate variable name.</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from collections import Counter

def non_unique(l):
    def low(x):
        return x.lower() if isinstance(x, str) else x
    c = Counter(map(low, l))
    return [x for x in l if c[low(x)] &gt; 1]

hold_w = []
for i, w in enumerate(MODEL.weights): 
    hold_w.append(w.name)

# It will return empty if all variable names are unique.
non_unique(hold_w)"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">collections</span> <span class="pl-k">import</span> <span class="pl-v">Counter</span>

<span class="pl-k">def</span> <span class="pl-en">non_unique</span>(<span class="pl-s1">l</span>):
    <span class="pl-k">def</span> <span class="pl-en">low</span>(<span class="pl-s1">x</span>):
        <span class="pl-k">return</span> <span class="pl-s1">x</span>.<span class="pl-en">lower</span>() <span class="pl-k">if</span> <span class="pl-en">isinstance</span>(<span class="pl-s1">x</span>, <span class="pl-s1">str</span>) <span class="pl-k">else</span> <span class="pl-s1">x</span>
    <span class="pl-s1">c</span> <span class="pl-c1">=</span> <span class="pl-v">Counter</span>(<span class="pl-en">map</span>(<span class="pl-s1">low</span>, <span class="pl-s1">l</span>))
    <span class="pl-k">return</span> [<span class="pl-s1">x</span> <span class="pl-k">for</span> <span class="pl-s1">x</span> <span class="pl-c1">in</span> <span class="pl-s1">l</span> <span class="pl-k">if</span> <span class="pl-s1">c</span>[<span class="pl-en">low</span>(<span class="pl-s1">x</span>)] <span class="pl-c1">&gt;</span> <span class="pl-c1">1</span>]

<span class="pl-s1">hold_w</span> <span class="pl-c1">=</span> []
<span class="pl-k">for</span> <span class="pl-s1">i</span>, <span class="pl-s1">w</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-v">MODEL</span>.<span class="pl-s1">weights</span>): 
    <span class="pl-s1">hold_w</span>.<span class="pl-en">append</span>(<span class="pl-s1">w</span>.<span class="pl-s1">name</span>)

<span class="pl-c"># It will return empty if all variable names are unique.</span>
<span class="pl-en">non_unique</span>(<span class="pl-s1">hold_w</span>)</pre></div>
<p dir="auto">I am not very clear about the timesteps in the input of RNN and LSTM. In my understanding, if we set timesteps as K, Keras will look back for K steps (So, the RNN or LSTM will be unrolled for K times) and make the prediction. Is it correct?</p>
<p dir="auto">Also, How does LSTM in Keras unroll itself? Which parameter decides the length of TruncatedBPTT? Thanks</p>