TF2 वर्कफ़्लो में TF1.x मॉडल का उपयोग करें

TensorFlow.org पर देखें Google Colab में चलाएं गिटहब पर देखें नोटबुक डाउनलोड करें

यह मार्गदर्शिका एक मॉडलिंग कोड शिम का एक सिंहावलोकन और उदाहरण प्रदान करती है जिसे आप अपने मौजूदा TF1.x मॉडल का उपयोग TF2 वर्कफ़्लोज़ जैसे उत्सुक निष्पादन, tf.function और वितरण रणनीतियों में अपने मॉडलिंग कोड में न्यूनतम परिवर्तनों के साथ करने के लिए कर सकते हैं।

उपयोग का दायरा

इस गाइड में वर्णित शिम TF1.x मॉडल के लिए डिज़ाइन किया गया है जो इस पर निर्भर करता है:

  1. चर निर्माण और पुन: उपयोग को नियंत्रित करने के लिए tf.compat.v1.get_variable और tf.compat.v1.variable_scope , और
  2. ग्राफ-संग्रह आधारित एपीआई जैसे tf.compat.v1.global_variables() , tf.compat.v1.trainable_variables , tf.compat.v1.losses.get_regularization_losses() , और tf.compat.v1.get_collection() ट्रैक रखने के लिए भार और नियमितीकरण हानियों का

इसमें tf.compat.v1.layer , tf.contrib.layers API और TensorFlow-Slim के शीर्ष पर निर्मित अधिकांश मॉडल शामिल हैं।

निम्नलिखित TF1.x मॉडल के लिए शिम आवश्यक नहीं है:

  1. स्टैंड-अलोन केरस मॉडल जो पहले से ही अपने सभी प्रशिक्षण योग्य वजन और नियमितीकरण के नुकसान को क्रमशः model.trainable_weights और model.losses के माध्यम से ट्रैक करते हैं।
  2. tf.Module s जो पहले से ही अपने सभी प्रशिक्षित वजन को module.trainable_variables .trainable_variables के माध्यम से ट्रैक करते हैं, और केवल वज़न बनाते हैं यदि वे पहले से नहीं बनाए गए हैं।

इन मॉडलों के TF2 में उत्सुक निष्पादन और tf.function के आउट-ऑफ़-द-बॉक्स के साथ काम करने की संभावना है।

सेट अप

TensorFlow और अन्य निर्भरताएँ आयात करें।

pip uninstall -y -q tensorflow
# Install tf-nightly as the DeterministicRandomTestTool is available only in
# Tensorflow 2.8

pip install -q tf-nightly
import tensorflow as tf
import tensorflow.compat.v1 as v1
import sys
import numpy as np

from contextlib import contextmanager

track_tf1_style_variables डेकोरेटर

इस गाइड में वर्णित प्रमुख शिम tf.compat.v1.keras.utils.track_tf1_style_variables है, एक डेकोरेटर जिसका उपयोग आप tf.keras.layers.Layer और tf.Module से संबंधित विधियों के भीतर TF1.x-शैली के वज़न को ट्रैक करने के लिए कर सकते हैं और नियमितीकरण घाटे पर कब्जा

tf.keras.layers.Layer या tf.Module की कॉल विधियों को tf.compat.v1.keras.utils.track_tf1_style_variables से सजाने से tf.compat.v1.get_variable (और एक्सटेंशन tf.compat.v1.layers ) प्रत्येक कॉल पर हमेशा एक नया चर बनाने के बजाय सजाए गए तरीके के अंदर सही ढंग से काम करने के लिए। यह लेयर या मॉड्यूल को डेकोरेटेड मेथड के अंदर get_variable के माध्यम से बनाए गए या एक्सेस किए गए किसी भी वज़न को परोक्ष रूप से ट्रैक करने का कारण बनेगा।

मानक स्तर के तहत वजन को ट्रैक करने के अलावा। layer.variable / मॉड्यूल। module.variable / आदि। properties, यदि विधि tf.keras.layers.Layer से संबंधित है, तो get_variable या tf.compat.v1.layers तर्कों के माध्यम से निर्दिष्ट किसी भी नियमितीकरण हानि को मानक परत के तहत परत द्वारा ट्रैक किया जाएगा। संपत्ति को layer.losses है।

यह ट्रैकिंग तंत्र TF1.x-शैली मॉडल-फ़ॉरवर्ड-पास कोड के केरस परतों के अंदर या TF2 में tf.Module s के बड़े वर्गों का उपयोग करने में सक्षम बनाता है, यहां तक ​​कि TF2 व्यवहार सक्षम होने पर भी।

उपयोग के उदाहरण

नीचे दिए गए उपयोग उदाहरण tf.keras.layers.Layer विधियों को सजाने के लिए उपयोग किए जाने वाले मॉडलिंग शिम को प्रदर्शित करते हैं, लेकिन जहां वे विशेष रूप से केरस सुविधाओं के साथ बातचीत कर रहे हैं, वे tf.Module विधियों को सजाने के दौरान भी लागू होते हैं।

tf.compat.v1.get_variable के साथ निर्मित परत

कल्पना कीजिए कि आपके पास सीधे tf.compat.v1.get_variable के शीर्ष पर एक परत लागू की गई है:

def dense(self, inputs, units):
  out = inputs
  with tf.compat.v1.variable_scope("dense"):
    # The weights are created with a `regularizer`,
    kernel = tf.compat.v1.get_variable(
        shape=[out.shape[-1], units],
        regularizer=tf.keras.regularizers.L2(),
        initializer=tf.compat.v1.initializers.glorot_normal,
        name="kernel")
    bias = tf.compat.v1.get_variable(
        shape=[units,],
        initializer=tf.compat.v1.initializers.zeros,
        name="bias")
    out = tf.linalg.matmul(out, kernel)
    out = tf.compat.v1.nn.bias_add(out, bias)
  return out

इसे एक परत में बदलने के लिए शिम का उपयोग करें और इसे इनपुट पर कॉल करें।

class DenseLayer(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs):
    out = inputs
    with tf.compat.v1.variable_scope("dense"):
      # The weights are created with a `regularizer`,
      # so the layer should track their regularization losses
      kernel = tf.compat.v1.get_variable(
          shape=[out.shape[-1], self.units],
          regularizer=tf.keras.regularizers.L2(),
          initializer=tf.compat.v1.initializers.glorot_normal,
          name="kernel")
      bias = tf.compat.v1.get_variable(
          shape=[self.units,],
          initializer=tf.compat.v1.initializers.zeros,
          name="bias")
      out = tf.linalg.matmul(out, kernel)
      out = tf.compat.v1.nn.bias_add(out, bias)
    return out

layer = DenseLayer(10)
x = tf.random.normal(shape=(8, 20))
layer(x)
WARNING:tensorflow:From /tmp/ipykernel_27038/795621215.py:7: The name tf.keras.utils.track_tf1_style_variables is deprecated. Please use tf.compat.v1.keras.utils.track_tf1_style_variables instead.
<tf.Tensor: shape=(8, 10), dtype=float32, numpy=
array([[-0.51018804, -0.58145535,  0.25050664, -0.09880018,  0.71741414,
        -0.08512568,  0.33404148,  0.50894034,  0.19362557,  0.03945067],
       [-0.66160053,  0.43442816, -0.6187523 ,  0.00753711,  1.3946855 ,
         0.22528797,  0.55661404, -1.6155301 ,  1.5854199 , -0.4165327 ],
       [ 0.15855707,  0.43848652,  0.04762229,  0.22020248,  0.88300526,
         0.31525093, -0.10912375,  0.03332198,  1.3462385 , -0.37986106],
       [ 0.02546233, -0.01084138,  0.0417656 ,  1.1082407 ,  0.926408  ,
         0.46938205,  1.0183189 ,  1.2039868 , -0.09619217, -0.50863194],
       [-1.6222394 ,  0.17156005, -0.07482994,  0.646423  ,  1.0284312 ,
         2.3619173 ,  0.6322627 ,  0.5350776 , -2.2700598 , -0.8211552 ],
       [-1.1044651 ,  0.7303245 ,  1.0183476 ,  1.2858934 ,  0.4575533 ,
         0.93400717,  0.5323913 , -0.01242167,  0.8308919 ,  0.03202473],
       [ 0.3880633 , -1.2345276 ,  0.7713047 , -0.33720714,  1.0418141 ,
        -1.055242  , -1.6942265 ,  1.705035  ,  0.8671215 ,  0.8162696 ],
       [ 0.02216246, -0.5235669 ,  0.01065174, -1.1682817 ,  0.44079733,
         0.25890222, -1.0779501 ,  0.37716752, -0.27636313, -0.6359312 ]],
      dtype=float32)>

एक मानक केरस परत की तरह ट्रैक किए गए चर और कैप्चर किए गए नियमितीकरण नुकसान तक पहुंचें।

layer.trainable_variables
layer.losses
2021-12-04 02:24:42.941890: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
[<tf.Tensor: shape=(), dtype=float32, numpy=0.10789324>]

यह देखने के लिए कि हर बार जब आप परत को कॉल करते हैं तो वज़न का पुन: उपयोग किया जाता है, सभी वज़न को शून्य पर सेट करें और परत को फिर से कॉल करें।

print("Resetting variables to zero:", [var.name for var in layer.trainable_variables])

for var in layer.trainable_variables:
  var.assign(var * 0.0)

# Note: layer.losses is not a live view and
# will get reset only at each layer call
print("layer.losses:", layer.losses)
print("calling layer again.")
out = layer(x)
print("layer.losses: ", layer.losses)
out
Resetting variables to zero: ['dense/bias:0', 'dense/kernel:0']
layer.losses: [<tf.Tensor: shape=(), dtype=float32, numpy=0.0>]
calling layer again.
layer.losses:  [<tf.Tensor: shape=(), dtype=float32, numpy=0.0>]
<tf.Tensor: shape=(8, 10), dtype=float32, numpy=
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)>

आप परिवर्तित परत का उपयोग सीधे केरस कार्यात्मक मॉडल निर्माण में भी कर सकते हैं।

inputs = tf.keras.Input(shape=(20))
outputs = DenseLayer(10)(inputs)
model = tf.keras.Model(inputs=inputs, outputs=outputs)

x = tf.random.normal(shape=(8, 20))
model(x)

# Access the model variables and regularization losses
model.weights
model.losses
[<tf.Tensor: shape=(), dtype=float32, numpy=0.1345337>]

tf.compat.v1.layers के साथ निर्मित मॉडल

कल्पना कीजिए कि आपके पास tf.compat.v1.layers के शीर्ष पर एक परत या मॉडल सीधे लागू किया गया है:

def model(self, inputs, units):
  with tf.compat.v1.variable_scope('model'):
    out = tf.compat.v1.layers.conv2d(
        inputs, 3, 3,
        kernel_regularizer="l2")
    out = tf.compat.v1.layers.flatten(out)
    out = tf.compat.v1.layers.dense(
        out, units,
        kernel_regularizer="l2")
    return out

इसे एक परत में बदलने के लिए शिम का उपयोग करें और इसे इनपुट पर कॉल करें।

class CompatV1LayerModel(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs):
    with tf.compat.v1.variable_scope('model'):
      out = tf.compat.v1.layers.conv2d(
          inputs, 3, 3,
          kernel_regularizer="l2")
      out = tf.compat.v1.layers.flatten(out)
      out = tf.compat.v1.layers.dense(
          out, self.units,
          kernel_regularizer="l2")
      return out

layer = CompatV1LayerModel(10)
x = tf.random.normal(shape=(8, 5, 5, 5))
layer(x)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:12: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  if sys.path[0] == '':
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/legacy_tf_layers/convolutional.py:575: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead.
  return layer.apply(inputs)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:13: UserWarning: `tf.layers.flatten` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Flatten` instead.
  del sys.path[0]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/legacy_tf_layers/core.py:541: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead.
  return layer.apply(inputs)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:16: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
  app.launch_new_instance()
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/legacy_tf_layers/core.py:261: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead.
  return layer.apply(inputs)
<tf.Tensor: shape=(8, 10), dtype=float32, numpy=
array([[ 2.4439096 , -0.2912227 ,  1.5531251 ,  1.284059  ,  0.10077369,
        -0.4231838 ,  1.0458903 , -0.01530766,  0.07358164, -0.6108157 ],
       [-0.4576063 ,  0.34942552,  2.3044965 ,  1.1483003 , -1.2211238 ,
         0.5634397 ,  0.73821646, -0.07581732,  0.5747937 , -0.66470885],
       [-2.2948585 , -2.709268  ,  1.7494816 , -0.9808065 , -2.9099958 ,
         0.5067346 , -1.011502  ,  2.559535  , -3.0888772 ,  0.3522656 ],
       [ 1.7788265 ,  0.8846102 ,  0.45562026,  0.01498583, -0.12482446,
        -0.32868862, -0.7743829 ,  2.3106992 , -0.0997327 , -0.7715093 ],
       [ 0.40295708,  0.04771695, -0.21336336, -0.13069987,  2.279875  ,
         2.7284563 ,  0.6444641 , -1.1919906 ,  0.96321577,  1.0182515 ],
       [ 0.47900966,  0.04906505,  1.1335449 ,  0.2907704 ,  0.7732022 ,
         0.68217   ,  0.51932573, -0.45156685,  2.081223  ,  1.068861  ],
       [ 0.10084352,  1.6456002 ,  0.63820475,  1.5959243 ,  0.22463399,
         0.07713126,  0.7467398 , -1.5435244 ,  1.2494736 , -0.07683721],
       [ 2.1396816 ,  1.5613532 , -1.1726325 , -0.88917583,  1.6447946 ,
        -1.0071977 , -1.8496083 ,  1.1887017 ,  2.1971662 ,  2.1175954 ]],
      dtype=float32)>

ट्रैक किए गए चरों तक पहुंचें और एक मानक केरस परत की तरह नियमितीकरण के नुकसान पर कब्जा कर लिया।

layer.trainable_variables
layer.losses
[<tf.Tensor: shape=(), dtype=float32, numpy=0.03623246>,
 <tf.Tensor: shape=(), dtype=float32, numpy=0.14618248>]
प्लेसहोल्डर17

यह देखने के लिए कि हर बार जब आप परत को कॉल करते हैं तो वज़न का पुन: उपयोग किया जाता है, सभी वज़न को शून्य पर सेट करें और परत को फिर से कॉल करें।

print("Resetting variables to zero:", [var.name for var in layer.trainable_variables])

for var in layer.trainable_variables:
  var.assign(var * 0.0)

out = layer(x)
print("layer.losses: ", layer.losses)
out
Resetting variables to zero: ['model/conv2d/bias:0', 'model/conv2d/kernel:0', 'model/dense/bias:0', 'model/dense/kernel:0']
layer.losses:  [<tf.Tensor: shape=(), dtype=float32, numpy=0.0>, <tf.Tensor: shape=(), dtype=float32, numpy=0.0>]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:12: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  if sys.path[0] == '':
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:13: UserWarning: `tf.layers.flatten` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Flatten` instead.
  del sys.path[0]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:16: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
  app.launch_new_instance()
<tf.Tensor: shape=(8, 10), dtype=float32, numpy=
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)>

आप परिवर्तित परत का उपयोग सीधे केरस कार्यात्मक मॉडल निर्माण में भी कर सकते हैं।

inputs = tf.keras.Input(shape=(5, 5, 5))
outputs = CompatV1LayerModel(10)(inputs)
model = tf.keras.Model(inputs=inputs, outputs=outputs)

x = tf.random.normal(shape=(8, 5, 5, 5))
model(x)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:12: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  if sys.path[0] == '':
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/legacy_tf_layers/base.py:573: UserWarning: `layer.updates` will be removed in a future version. This property should not be used in TensorFlow 2.0, as `updates` are applied automatically.
  _add_elements_to_collection(self.updates, tf.compat.v1.GraphKeys.UPDATE_OPS)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:13: UserWarning: `tf.layers.flatten` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Flatten` instead.
  del sys.path[0]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:16: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
  app.launch_new_instance()
<tf.Tensor: shape=(8, 10), dtype=float32, numpy=
array([[ 0.19487001,  0.54727787,  1.1044168 , -0.6613899 , -0.26437742,
        -1.1580509 , -0.24707682,  0.97752655,  0.59436107,  0.13125825],
       [ 0.48974586, -1.3510125 ,  0.7186962 , -0.8996632 , -0.60448873,
         0.06332532,  0.31494308,  0.23021704, -1.9166642 ,  0.3890404 ],
       [-0.06499191, -0.21485235,  0.01158494,  1.4407377 , -0.0488929 ,
        -0.37594396, -0.4386894 , -0.08751169,  1.0905663 , -1.5450519 ],
       [-2.2749739 , -2.4603422 , -1.3834419 , -2.8800466 ,  0.8954872 ,
        -3.0429187 , -0.7885461 ,  1.6037437 , -3.1845028 , -1.0725503 ],
       [ 0.98735195, -0.45159122,  0.892656  ,  0.477053  ,  0.31193537,
        -0.44723228, -0.01815075, -0.47465172, -1.665448  , -2.105824  ],
       [-2.5408387 , -1.7552321 , -1.924145  , -0.6395873 ,  0.4081779 ,
        -0.48731515, -3.2637763 , -1.4409767 , -2.032539  ,  0.10204412],
       [ 2.1583526 ,  0.78955674, -0.07266375,  0.06652926,  2.1300716 ,
        -1.6256162 ,  0.56154627, -0.76179224,  2.2985756 , -1.5504618 ],
       [ 2.062847  ,  0.971378  , -1.0830508 ,  1.8224751 , -0.3542943 ,
         0.74113446, -0.6204865 ,  1.4503044 , -0.4979878 , -0.4383126 ]],
      dtype=float32)>
# Access the model variables and regularization losses
model.weights
model.losses
[<tf.Tensor: shape=(), dtype=float32, numpy=0.03079858>,
 <tf.Tensor: shape=(), dtype=float32, numpy=0.12991619>]

बैच सामान्यीकरण अद्यतन और मॉडल training तर्क कैप्चर करें

TF1.x में, आप इस तरह बैच सामान्यीकरण करते हैं:

  x_norm = tf.compat.v1.layers.batch_normalization(x, training=training)

  # ...

  update_ops = tf.compat.v1.get_collection(tf.GraphKeys.UPDATE_OPS)
  train_op = optimizer.minimize(loss)
  train_op = tf.group([train_op, update_ops])

ध्यान दें कि:

  1. बैच सामान्यीकरण मूविंग एवरेज अपडेट को get_collection द्वारा ट्रैक किया जाता है जिसे लेयर से अलग कहा जाता है
  2. tf.compat.v1.layers.batch_normalization लिए एक training तर्क की आवश्यकता होती है (जिसे TF-स्लिम बैच सामान्यीकरण परतों का उपयोग करते समय आमतौर पर is_training कहा जाता है)

TF2 में, उत्सुक निष्पादन और स्वचालित नियंत्रण निर्भरता के कारण, बैच सामान्यीकरण मूविंग एवरेज अपडेट को तुरंत निष्पादित किया जाएगा। उन्हें अद्यतन संग्रह से अलग से एकत्र करने और उन्हें स्पष्ट नियंत्रण निर्भरता के रूप में जोड़ने की कोई आवश्यकता नहीं है।

इसके अतिरिक्त, यदि आप अपनी tf.keras.layers.Layer की फ़ॉरवर्ड पास विधि को एक training तर्क देते हैं, तो केरस वर्तमान प्रशिक्षण चरण और किसी भी नेस्टेड परतों को उसी तरह पारित करने में सक्षम होगा जैसे यह किसी अन्य परत के लिए करता है। केरस training तर्क को कैसे संभालता है, इस बारे में अधिक जानकारी के लिए tf.keras.Model के लिए API दस्तावेज़ देखें।

यदि आप tf.Module विधियों को सजा रहे हैं, तो आपको आवश्यकतानुसार सभी training तर्कों को मैन्युअल रूप से पास करना सुनिश्चित करना होगा। हालांकि, बैच सामान्यीकरण मूविंग एवरेज अपडेट अभी भी स्वचालित रूप से लागू होंगे और स्पष्ट नियंत्रण निर्भरता की कोई आवश्यकता नहीं होगी।

निम्नलिखित कोड स्निपेट प्रदर्शित करते हैं कि शिम में बैच सामान्यीकरण परतों को कैसे एम्बेड किया जाए और केरस मॉडल में इसका उपयोग कैसे किया जाए ( tf.keras.layers.Layer पर लागू)।

class CompatV1BatchNorm(tf.keras.layers.Layer):

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs, training=None):
    print("Forward pass called with `training` =", training)
    with v1.variable_scope('batch_norm_layer'):
      return v1.layers.batch_normalization(x, training=training)
print("Constructing model")
inputs = tf.keras.Input(shape=(5, 5, 5))
outputs = CompatV1BatchNorm()(inputs)
model = tf.keras.Model(inputs=inputs, outputs=outputs)

print("Calling model in inference mode")
x = tf.random.normal(shape=(8, 5, 5, 5))
model(x, training=False)

print("Moving average variables before training: ",
      {var.name: var.read_value() for var in model.non_trainable_variables})

# Notice that when running TF2 and eager execution, the batchnorm layer directly
# updates the moving averages while training without needing any extra control
# dependencies
print("calling model in training mode")
model(x, training=True)

print("Moving average variables after training: ",
      {var.name: var.read_value() for var in model.non_trainable_variables})
प्लेसहोल्डर26 l10n-प्लेसहोल्डर
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:7: UserWarning: `tf.layers.batch_normalization` is deprecated and will be removed in a future version. Please use `tf.keras.layers.BatchNormalization` instead. In particular, `tf.control_dependencies(tf.GraphKeys.UPDATE_OPS)` should not be used (consult the `tf.keras.layers.BatchNormalization` documentation).
  import sys
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/legacy_tf_layers/normalization.py:463: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead.
  return layer.apply(inputs, training=training)
Constructing model
Forward pass called with `training` = None
Calling model in inference mode
Forward pass called with `training` = False
Moving average variables before training:  {'batch_norm_layer/batch_normalization/moving_mean:0': <tf.Tensor: shape=(5,), dtype=float32, numpy=array([0., 0., 0., 0., 0.], dtype=float32)>, 'batch_norm_layer/batch_normalization/moving_variance:0': <tf.Tensor: shape=(5,), dtype=float32, numpy=array([1., 1., 1., 1., 1.], dtype=float32)>}
calling model in training mode
Forward pass called with `training` = True
Moving average variables after training:  {'batch_norm_layer/batch_normalization/moving_mean:0': <tf.Tensor: shape=(5,), dtype=float32, numpy=
array([-0.00177554, -0.00036542, -0.00099426, -0.00112544,  0.0008541 ],
      dtype=float32)>, 'batch_norm_layer/batch_normalization/moving_variance:0': <tf.Tensor: shape=(5,), dtype=float32, numpy=
array([1.0005339, 1.0003369, 0.9976748, 1.0001523, 1.0009514],
      dtype=float32)>}

चर-दायरा आधारित चर पुन: उपयोग

get_variable का पुन: उपयोग करेगा जो वेरिएबल स्कोप में TF1.x है। यह तब तक सही है जब तक आपके पास ऊपर बताए अनुसार स्वतः-जनरेटेड नामों वाली किसी भी tf.compat.v1.layers के लिए कम से कम एक गैर-रिक्त बाहरी दायरा है।

उत्सुक निष्पादन और tf.function

जैसा कि ऊपर देखा गया है, tf.keras.layers.Layer और tf.Module के लिए सजाए गए तरीके उत्सुक निष्पादन के अंदर चलते हैं और tf.function के साथ भी संगत हैं। इसका मतलब है कि आप अपने फॉरवर्ड पास के माध्यम से आगे बढ़ने के लिए पीडीबी और अन्य इंटरैक्टिव टूल्स का उपयोग कर सकते हैं क्योंकि यह चल रहा है।

वितरण रणनीतियाँ

@track_tf1_style_variables -सज्जित परत या मॉड्यूल विधियों के अंदर get_variable के लिए कॉल मानक tf.Variable का उपयोग करते हैं। हुड के तहत परिवर्तनीय चर निर्माण। इसका मतलब है कि आप उन्हें tf.distribute के साथ उपलब्ध विभिन्न वितरण रणनीतियों जैसे कि MirroredStrategy और TPUStrategy के साथ उपयोग कर सकते हैं।

डेकोरेटेड कॉल में नेस्टिंग tf.Variable s, tf.Module s, tf.keras.layers & tf.keras.models

tf.compat.v1.keras.utils.track_tf1_style_variables में अपने लेयर कॉल को सजाने से केवल tf.compat.v1.get_variable के माध्यम से बनाए गए (और पुन: उपयोग किए गए) चरों की स्वचालित अंतर्निहित ट्रैकिंग जुड़ जाएगी। यह सीधे tf.Variable कॉल द्वारा बनाए गए वज़न को कैप्चर नहीं करेगा, जैसे कि विशिष्ट Keras परतों द्वारा उपयोग किए जाने वाले और अधिकांश tf.Module s। यह खंड बताता है कि इन नेस्टेड मामलों को कैसे संभालना है।

(पहले से मौजूद उपयोग) tf.keras.layers और tf.keras.models

नेस्टेड केरस परतों और मॉडलों के पहले से मौजूद उपयोगों के लिए, tf.compat.v1.keras.utils.get_or_create_layer का उपयोग करें। यह केवल मौजूदा TF1.x नेस्टेड Keras उपयोगों के माइग्रेशन को आसान बनाने के लिए अनुशंसित है; tf.Variables और tf.Modules के लिए नीचे वर्णित अनुसार नए कोड को स्पष्ट विशेषता सेटिंग का उपयोग करना चाहिए।

tf.compat.v1.keras.utils.get_or_create_layer का उपयोग करने के लिए, उस कोड को लपेटें जो आपके नेस्टेड मॉडल को एक विधि में बनाता है, और इसे विधि में पास करें। उदाहरण:

class NestedModel(tf.keras.Model):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units

  def build_model(self):
    inp = tf.keras.Input(shape=(5, 5))
    dense_layer = tf.keras.layers.Dense(
        10, name="dense", kernel_regularizer="l2",
        kernel_initializer=tf.compat.v1.ones_initializer())
    model = tf.keras.Model(inputs=inp, outputs=dense_layer(inp))
    return model

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs):
    # Get or create a nested model without assigning it as an explicit property
    model = tf.compat.v1.keras.utils.get_or_create_layer(
        "dense_model", self.build_model)
    return model(inputs)

layer = NestedModel(10)
layer(tf.ones(shape=(5,5)))
<tf.Tensor: shape=(5, 10), dtype=float32, numpy=
array([[5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.]], dtype=float32)>

यह विधि सुनिश्चित करती है कि इन नेस्टेड परतों का सही ढंग से पुन: उपयोग किया जाता है और टेंसरफ़्लो द्वारा ट्रैक किया जाता है। ध्यान दें कि उपयुक्त विधि पर @track_tf1_style_variables डेकोरेटर की अभी भी आवश्यकता है। मॉडल बिल्डर विधि get_or_create_layer (इस मामले में, self.build_model ) में पारित हो गई है, इसमें कोई तर्क नहीं होना चाहिए।

वजन ट्रैक किया जाता है:

assert len(layer.weights) == 2
weights = {x.name: x for x in layer.variables}

assert set(weights.keys()) == {"dense/bias:0", "dense/kernel:0"}

layer.weights
[<tf.Variable 'dense/kernel:0' shape=(5, 10) dtype=float32, numpy=
 array([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]], dtype=float32)>,
 <tf.Variable 'dense/bias:0' shape=(10,) dtype=float32, numpy=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)>]

और नियमितीकरण का नुकसान भी:

tf.add_n(layer.losses)
<tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.5], dtype=float32)>
प्लेसहोल्डर33

वृद्धिशील प्रवासन: tf.Variables .चर और tf.Modules

यदि आपको अपने सजाए गए तरीकों में tf.Variable कॉल या tf.Module s एम्बेड करने की आवश्यकता है (उदाहरण के लिए, यदि आप इस गाइड में बाद में वर्णित गैर-विरासत TF2 API में वृद्धिशील माइग्रेशन का अनुसरण कर रहे हैं), तो आपको अभी भी इन्हें स्पष्ट रूप से ट्रैक करने की आवश्यकता है, निम्नलिखित आवश्यकताओं के साथ:

  • स्पष्ट रूप से सुनिश्चित करें कि चर/मॉड्यूल/परत केवल एक बार बनाई गई है
  • उदाहरण विशेषताओं के रूप में उन्हें स्पष्ट रूप से संलग्न करें जैसे आप एक विशिष्ट मॉड्यूल या परत को परिभाषित करते समय करते हैं
  • फॉलो-ऑन कॉल में पहले से बनाई गई वस्तु का स्पष्ट रूप से पुन: उपयोग करें

यह सुनिश्चित करता है कि वजन प्रत्येक कॉल के लिए नया नहीं बनाया गया है और सही ढंग से पुन: उपयोग किया जाता है। इसके अतिरिक्त, यह यह भी सुनिश्चित करता है कि मौजूदा वज़न और नियमितीकरण के नुकसान पर नज़र रखी जाए।

यह कैसे दिख सकता है इसका एक उदाहरण यहां दिया गया है:

class NestedLayer(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def __call__(self, inputs):
    out = inputs
    with tf.compat.v1.variable_scope("inner_dense"):
      # The weights are created with a `regularizer`,
      # so the layer should track their regularization losses
      kernel = tf.compat.v1.get_variable(
          shape=[out.shape[-1], self.units],
          regularizer=tf.keras.regularizers.L2(),
          initializer=tf.compat.v1.initializers.glorot_normal,
          name="kernel")
      bias = tf.compat.v1.get_variable(
          shape=[self.units,],
          initializer=tf.compat.v1.initializers.zeros,
          name="bias")
      out = tf.linalg.matmul(out, kernel)
      out = tf.compat.v1.nn.bias_add(out, bias)
    return out

class WrappedDenseLayer(tf.keras.layers.Layer):

  def __init__(self, units, **kwargs):
    super().__init__(**kwargs)
    self.units = units
    # Only create the nested tf.variable/module/layer/model
    # once, and then reuse it each time!
    self._dense_layer = NestedLayer(self.units)

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs):
    with tf.compat.v1.variable_scope('outer'):
      outputs = tf.compat.v1.layers.dense(inputs, 3)
      outputs = tf.compat.v1.layers.dense(inputs, 4)
      return self._dense_layer(outputs)

layer = WrappedDenseLayer(10)

layer(tf.ones(shape=(5, 5)))
34 एल10एन-प्लेसहोल्डर
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:38: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:39: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
<tf.Tensor: shape=(5, 10), dtype=float32, numpy=
array([[-0.4987283 ,  0.06630042, -0.09875254,  0.20954818,  0.03599668,
         0.3980474 ,  0.11181635,  0.6891558 , -0.33903462,  0.15674731],
       [-0.4987283 ,  0.06630042, -0.09875254,  0.20954818,  0.03599668,
         0.3980474 ,  0.11181635,  0.6891558 , -0.33903462,  0.15674731],
       [-0.4987283 ,  0.06630042, -0.09875254,  0.20954818,  0.03599668,
         0.3980474 ,  0.11181635,  0.6891558 , -0.33903462,  0.15674731],
       [-0.4987283 ,  0.06630042, -0.09875254,  0.20954818,  0.03599668,
         0.3980474 ,  0.11181635,  0.6891558 , -0.33903462,  0.15674731],
       [-0.4987283 ,  0.06630042, -0.09875254,  0.20954818,  0.03599668,
         0.3980474 ,  0.11181635,  0.6891558 , -0.33903462,  0.15674731]],
      dtype=float32)>

ध्यान दें कि नेस्टेड मॉड्यूल की स्पष्ट ट्रैकिंग की आवश्यकता है, भले ही इसे track_tf1_style_variables डेकोरेटर से सजाया गया हो। ऐसा इसलिए है क्योंकि सजाए गए तरीकों वाले प्रत्येक मॉड्यूल/लेयर का अपना वेरिएबल स्टोर इससे जुड़ा होता है।

वजन सही ढंग से ट्रैक किया जाता है:

assert len(layer.weights) == 6
weights = {x.name: x for x in layer.variables}

assert set(weights.keys()) == {"outer/inner_dense/bias:0",
                               "outer/inner_dense/kernel:0",
                               "outer/dense/bias:0",
                               "outer/dense/kernel:0",
                               "outer/dense_1/bias:0",
                               "outer/dense_1/kernel:0"}

layer.trainable_weights
[<tf.Variable 'outer/inner_dense/bias:0' shape=(10,) dtype=float32, numpy=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)>,
 <tf.Variable 'outer/inner_dense/kernel:0' shape=(4, 10) dtype=float32, numpy=
 array([[-0.20786692,  0.14702448, -0.2577947 ,  0.1885891 ,  0.28935957,
          0.02086618, -0.20579144, -0.7509229 , -0.23490003,  0.00370591],
        [ 0.09247629, -0.37428686, -0.6002815 , -0.2702465 ,  0.20350575,
          0.34964404, -0.32633537,  0.50722903, -0.0419833 , -0.61815673],
        [ 0.24821116,  0.15504731, -0.12409697, -0.2506969 ,  0.22316858,
         -0.44847375, -0.08295754, -0.8262154 ,  0.7674222 , -0.40613693],
        [-0.7447006 ,  0.2992331 , -0.45639235,  0.0669547 ,  0.39443025,
          0.3182467 ,  0.10884362,  0.5395837 ,  0.32210502, -0.30076835]],
       dtype=float32)>,
 <tf.Variable 'outer/dense/bias:0' shape=(3,) dtype=float32, numpy=array([0., 0., 0.], dtype=float32)>,
 <tf.Variable 'outer/dense/kernel:0' shape=(5, 3) dtype=float32, numpy=
 array([[ 0.6283595 , -0.80413634, -0.5471641 ],
        [ 0.25296038, -0.7657203 ,  0.5884425 ],
        [-0.7180575 , -0.29509914,  0.44014376],
        [ 0.81024987,  0.39888996,  0.80002993],
        [-0.32921118, -0.7010279 ,  0.820375  ]], dtype=float32)>,
 <tf.Variable 'outer/dense_1/bias:0' shape=(4,) dtype=float32, numpy=array([0., 0., 0., 0.], dtype=float32)>,
 <tf.Variable 'outer/dense_1/kernel:0' shape=(5, 4) dtype=float32, numpy=
 array([[ 0.7941524 , -0.58552563,  0.46828055, -0.44095916],
        [-0.16019303,  0.27973688, -0.60373306, -0.20117629],
        [ 0.6345844 ,  0.30732214,  0.18921828,  0.37930095],
        [-0.50815696, -0.2471816 , -0.10282421,  0.21441567],
        [-0.71987414,  0.18304104, -0.5701992 ,  0.4926386 ]],
       dtype=float32)>]

साथ ही नियमितीकरण का नुकसान:

layer.losses
[<tf.Tensor: shape=(), dtype=float32, numpy=0.058749676>]

ध्यान दें कि यदि NestedLayer इसके बजाय एक गैर- tf.Module होता, तो चरों को अभी भी ट्रैक किया जाएगा लेकिन नियमितीकरण हानियों को स्वचालित रूप से ट्रैक नहीं किया जाएगा, इसलिए आपको उन्हें अलग से स्पष्ट रूप से ट्रैक करना होगा।

चर नामों पर मार्गदर्शन

स्पष्ट tf.Variable कॉल और Keras परतें एक अलग परत नाम / चर नाम ऑटोजेनरेशन तंत्र का उपयोग करती हैं, जिसका उपयोग आप get_variable और variable_scopes के संयोजन से कर सकते हैं। यद्यपि शिम आपके चर नामों को TF1.x ग्राफ़ से TF2 उत्सुक निष्पादन और tf.function पर जाने पर भी get_variable द्वारा बनाए गए चर के लिए मिलान करेगा, यह tf.Variable कॉल और Keras परतों के लिए उत्पन्न चर नामों के लिए इसकी गारंटी नहीं दे सकता है। आप अपने मेथड डेकोरेटर्स में एम्बेड करते हैं। कई चरों के लिए TF2 उत्सुक निष्पादन और tf.function में समान नाम साझा करना भी संभव है।

इस गाइड में बाद में शुद्धता की पुष्टि और TF1.x चौकियों की मैपिंग के अनुभागों का अनुसरण करते समय आपको इसका विशेष ध्यान रखना चाहिए।

सजाए गए तरीके में tf.compat.v1.make_template का उपयोग करना

यह अत्यधिक अनुशंसा की जाती है कि आप tf.compat.v1.make_template का उपयोग करने के बजाय सीधे tf.compat.v1.keras.utils.track_tf1_style_variables का उपयोग tf.compat.v1.make_template , क्योंकि यह TF2 के शीर्ष पर एक पतली परत है

पिछले TF1.x कोड के लिए इस अनुभाग में दिए गए मार्गदर्शन का पालन करें जो पहले से ही tf.compat.v1.make_template पर निर्भर था।

क्योंकि tf.compat.v1.make_template कोड को लपेटता है जो get_variable का उपयोग करता है, track_tf1_style_variables डेकोरेटर आपको लेयर कॉल में इन टेम्प्लेट का उपयोग करने और वज़न और नियमितीकरण के नुकसान को सफलतापूर्वक ट्रैक करने की अनुमति देता है।

हालांकि, केवल एक बार make_template को कॉल करना सुनिश्चित करें और फिर प्रत्येक लेयर कॉल में उसी टेम्पलेट का पुन: उपयोग करें। अन्यथा, हर बार जब आप परत को चरों के नए सेट के साथ कॉल करते हैं तो एक नया टेम्पलेट बनाया जाएगा।

उदाहरण के लिए,

class CompatV1TemplateScaleByY(tf.keras.layers.Layer):

  def __init__(self, **kwargs):
    super().__init__(**kwargs)
    def my_op(x, scalar_name):
      var1 = tf.compat.v1.get_variable(scalar_name,
                            shape=[],
                            regularizer=tf.compat.v1.keras.regularizers.L2(),
                            initializer=tf.compat.v1.constant_initializer(1.5))
      return x * var1
    self.scale_by_y = tf.compat.v1.make_template('scale_by_y', my_op, scalar_name='y')

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs):
    with tf.compat.v1.variable_scope('layer'):
      # Using a scope ensures the `scale_by_y` name will not be incremented
      # for each instantiation of the layer.
      return self.scale_by_y(inputs)

layer = CompatV1TemplateScaleByY()

out = layer(tf.ones(shape=(2, 3)))
print("weights:", layer.weights)
print("regularization loss:", layer.losses)
print("output:", out)
weights: [<tf.Variable 'layer/scale_by_y/y:0' shape=() dtype=float32, numpy=1.5>]
regularization loss: [<tf.Tensor: shape=(), dtype=float32, numpy=0.022499999>]
output: tf.Tensor(
[[1.5 1.5 1.5]
 [1.5 1.5 1.5]], shape=(2, 3), dtype=float32)

नेटिव TF2 में इंक्रीमेंटल माइग्रेशन

जैसा कि पहले उल्लेख किया गया है, track_tf1_style_variables आपको TF2-शैली ऑब्जेक्ट-ओरिएंटेड tf.Variable / tf.keras.layers.Layer / tf.Module उपयोग को लीगेसी tf.compat.v1.get_variable / tf.compat.v1.layers -style के साथ मिलाने की अनुमति देता है। एक ही सजाए गए मॉड्यूल/परत के अंदर उपयोग।

इसका मतलब यह है कि अपने TF1.x मॉडल को पूरी तरह से TF2-संगत बनाने के बाद, आप सभी नए मॉडल घटकों को देशी (गैर- tf.compat.v1 ) TF2 एपीआई के साथ लिख सकते हैं और उन्हें अपने पुराने कोड के साथ इंटरऑपरेट कर सकते हैं।

हालाँकि, यदि आप अपने पुराने मॉडल घटकों को संशोधित करना जारी रखते हैं, तो आप अपनी विरासत-शैली tf.compat.v1 उपयोग को वृद्धिशील रूप से विशुद्ध रूप से देशी ऑब्जेक्ट-ओरिएंटेड API पर स्विच करना चुन सकते हैं जो नए लिखे गए TF2 कोड के लिए अनुशंसित हैं।

tf.compat.v1.get_variable उपयोग को या तो self.add_weight कॉल से बदला जा सकता है यदि आप एक Keras लेयर/मॉडल को सजा रहे हैं, या tf.Variable कॉल्स के साथ यदि आप Keras ऑब्जेक्ट्स या tf.Module s को सजा रहे हैं।

कार्यात्मक-शैली और ऑब्जेक्ट-ओरिएंटेड tf.compat.v1.layers को आम तौर पर समतुल्य tf.keras.layers लेयर से बदला जा सकता है, जिसमें बिना किसी तर्क परिवर्तन की आवश्यकता होती है।

आप अपने मॉडल के कुछ हिस्सों या सामान्य पैटर्न को अलग-अलग परतों/मॉड्यूल में पूरी तरह से देशी एपीआई के लिए अपने वृद्धिशील कदम के दौरान भी विचार कर सकते हैं, जो स्वयं track_tf1_style_variables का उपयोग कर सकते हैं।

स्लिम और contrib.layers पर एक नोट

पुराने TF 1.x कोड की एक बड़ी मात्रा स्लिम लाइब्रेरी का उपयोग करती है, जिसे TF 1.x के साथ tf.contrib.layers के रूप में पैक किया गया था। स्लिम का उपयोग करके कोड को देशी TF 2 में कनवर्ट करना v1.layers को कनवर्ट करने की तुलना में अधिक शामिल है। वास्तव में, अपने स्लिम कोड को पहले v1.layers में बदलना, फिर केरस में कनवर्ट करना समझदारी हो सकती है। स्लिम कोड को परिवर्तित करने के लिए कुछ सामान्य दिशानिर्देश नीचे दिए गए हैं।

  • सुनिश्चित करें कि सभी तर्क स्पष्ट हैं। यदि संभव हो तो arg_scopes निकालें। यदि आपको अभी भी उनका उपयोग करने की आवश्यकता है, तो normalizer_fn और activation_fn को अपनी परतों में विभाजित करें।
  • वियोज्य रूपांतरण परतें एक या अधिक विभिन्न केरस परतों (गहराई से, बिंदुवार, और अलग करने योग्य केरस परतों) के लिए मैप करती हैं।
  • स्लिम और v1.layers के अलग-अलग तर्क नाम और डिफ़ॉल्ट मान हैं।
  • ध्यान दें कि कुछ तर्कों के अलग-अलग पैमाने होते हैं।

चेकपॉइंट संगतता की अनदेखी करते हुए मूल TF2 में प्रवासन

निम्नलिखित कोड नमूना चेकपॉइंट संगतता पर विचार किए बिना एक मॉडल के विशुद्ध रूप से देशी एपीआई के लिए एक वृद्धिशील कदम दर्शाता है।

class CompatModel(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs, training=None):
    with tf.compat.v1.variable_scope('model'):
      out = tf.compat.v1.layers.conv2d(
          inputs, 3, 3,
          kernel_regularizer="l2")
      out = tf.compat.v1.layers.flatten(out)
      out = tf.compat.v1.layers.dropout(out, training=training)
      out = tf.compat.v1.layers.dense(
          out, self.units,
          kernel_regularizer="l2")
      return out

इसके बाद, compat.v1 API को उनके मूल ऑब्जेक्ट-ओरिएंटेड समकक्षों के साथ टुकड़े-टुकड़े में बदलें। कनवल्शन लेयर को लेयर कंस्ट्रक्टर में बनाए गए Keras ऑब्जेक्ट पर स्विच करके प्रारंभ करें।

class PartiallyMigratedModel(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units
    self.conv_layer = tf.keras.layers.Conv2D(
      3, 3,
      kernel_regularizer="l2")

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs, training=None):
    with tf.compat.v1.variable_scope('model'):
      out = self.conv_layer(inputs)
      out = tf.compat.v1.layers.flatten(out)
      out = tf.compat.v1.layers.dropout(out, training=training)
      out = tf.compat.v1.layers.dense(
          out, self.units,
          kernel_regularizer="l2")
      return out

v1.keras.utils.DeterministicRandomTestTool वर्ग का उपयोग यह सत्यापित करने के लिए करें कि यह वृद्धिशील परिवर्तन मॉडल को पहले जैसा ही व्यवहार के साथ छोड़ देता है।

random_tool = v1.keras.utils.DeterministicRandomTestTool(mode='num_random_ops')
with random_tool.scope():
  layer = CompatModel(10)

  inputs = tf.random.normal(shape=(10, 5, 5, 5))
  original_output = layer(inputs)

  # Grab the regularization loss as well
  original_regularization_loss = tf.math.add_n(layer.losses)

print(original_regularization_loss)
tf.Tensor(0.17953834, shape=(), dtype=float32)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:12: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  if sys.path[0] == '':
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:13: UserWarning: `tf.layers.flatten` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Flatten` instead.
  del sys.path[0]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:14: UserWarning: `tf.layers.dropout` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dropout` instead.
  
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/legacy_tf_layers/core.py:413: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead.
  return layer.apply(inputs, training=training)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:17: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
random_tool = v1.keras.utils.DeterministicRandomTestTool(mode='num_random_ops')
with random_tool.scope():
  layer = PartiallyMigratedModel(10)

  inputs = tf.random.normal(shape=(10, 5, 5, 5))
  migrated_output = layer(inputs)

  # Grab the regularization loss as well
  migrated_regularization_loss = tf.math.add_n(layer.losses)

print(migrated_regularization_loss)
tf.Tensor(0.17953834, shape=(), dtype=float32)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:14: UserWarning: `tf.layers.flatten` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Flatten` instead.
  
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:15: UserWarning: `tf.layers.dropout` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dropout` instead.
  from ipykernel import kernelapp as app
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:18: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
# Verify that the regularization loss and output both match
np.testing.assert_allclose(original_regularization_loss.numpy(), migrated_regularization_loss.numpy())
np.testing.assert_allclose(original_output.numpy(), migrated_output.numpy())

आपने अब सभी व्यक्तिगत compat.v1.layers को देशी Keras परतों से बदल दिया है।

class NearlyFullyNativeModel(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units
    self.conv_layer = tf.keras.layers.Conv2D(
      3, 3,
      kernel_regularizer="l2")
    self.flatten_layer = tf.keras.layers.Flatten()
    self.dense_layer = tf.keras.layers.Dense(
      self.units,
      kernel_regularizer="l2")

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs):
    with tf.compat.v1.variable_scope('model'):
      out = self.conv_layer(inputs)
      out = self.flatten_layer(out)
      out = self.dense_layer(out)
      return out
random_tool = v1.keras.utils.DeterministicRandomTestTool(mode='num_random_ops')
with random_tool.scope():
  layer = NearlyFullyNativeModel(10)

  inputs = tf.random.normal(shape=(10, 5, 5, 5))
  migrated_output = layer(inputs)

  # Grab the regularization loss as well
  migrated_regularization_loss = tf.math.add_n(layer.losses)

print(migrated_regularization_loss)
tf.Tensor(0.17953834, shape=(), dtype=float32)
# Verify that the regularization loss and output both match
np.testing.assert_allclose(original_regularization_loss.numpy(), migrated_regularization_loss.numpy())
np.testing.assert_allclose(original_output.numpy(), migrated_output.numpy())

अंत में, किसी भी शेष (अब आवश्यक नहीं) variable_scope उपयोग और track_tf1_style_variables डेकोरेटर दोनों को हटा दें।

अब आपके पास उस मॉडल का एक संस्करण बचा है जो पूरी तरह से देशी एपीआई का उपयोग करता है।

class FullyNativeModel(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units
    self.conv_layer = tf.keras.layers.Conv2D(
      3, 3,
      kernel_regularizer="l2")
    self.flatten_layer = tf.keras.layers.Flatten()
    self.dense_layer = tf.keras.layers.Dense(
      self.units,
      kernel_regularizer="l2")

  def call(self, inputs):
    out = self.conv_layer(inputs)
    out = self.flatten_layer(out)
    out = self.dense_layer(out)
    return out
random_tool = v1.keras.utils.DeterministicRandomTestTool(mode='num_random_ops')
with random_tool.scope():
  layer = FullyNativeModel(10)

  inputs = tf.random.normal(shape=(10, 5, 5, 5))
  migrated_output = layer(inputs)

  # Grab the regularization loss as well
  migrated_regularization_loss = tf.math.add_n(layer.losses)

print(migrated_regularization_loss)
tf.Tensor(0.17953834, shape=(), dtype=float32)
# Verify that the regularization loss and output both match
np.testing.assert_allclose(original_regularization_loss.numpy(), migrated_regularization_loss.numpy())
np.testing.assert_allclose(original_output.numpy(), migrated_output.numpy())

नेटिव TF2 में माइग्रेशन के दौरान चेकपॉइंट संगतता बनाए रखना

मूल TF2 एपीआई के लिए उपरोक्त माइग्रेशन प्रक्रिया ने चर नाम (केरस एपीआई बहुत अलग वजन नाम उत्पन्न करते हैं), और ऑब्जेक्ट-ओरिएंटेड पथ जो मॉडल में अलग-अलग वजन को इंगित करते हैं, दोनों को बदल दिया। इन परिवर्तनों का प्रभाव यह है कि उन्होंने किसी भी मौजूदा TF1-शैली नाम-आधारित चौकियों या TF2-शैली वस्तु-उन्मुख चौकियों दोनों को तोड़ दिया होगा।

हालांकि, कुछ मामलों में, आप अपना मूल नाम-आधारित चेकपॉइंट लेने में सक्षम हो सकते हैं और TF1.x चेकपॉइंट्स का पुन: उपयोग करने वाली मार्गदर्शिका में दिए गए विवरण जैसे दृष्टिकोणों के साथ उनके नए नामों में चरों का मानचित्रण ढूंढ़ सकते हैं।

इसे संभव बनाने के लिए कुछ सुझाव इस प्रकार हैं:

  • वेरिएबल्स में अभी भी एक name तर्क है जिसे आप सेट कर सकते हैं।
  • केरस मॉडल एक name तर्क भी लेते हैं जिसके रूप में वे अपने चर के लिए उपसर्ग के रूप में सेट करते हैं।
  • v1.name_scope फ़ंक्शन का उपयोग चर नाम उपसर्गों को सेट करने के लिए किया जा सकता है। यह tf.variable_scope से बहुत अलग है। यह केवल नामों को प्रभावित करता है, और चर और पुन: उपयोग को ट्रैक नहीं करता है।

उपरोक्त बिंदुओं को ध्यान में रखते हुए, निम्नलिखित कोड नमूने एक वर्कफ़्लो प्रदर्शित करते हैं जिसे आप अपने कोड के अनुकूल कर सकते हैं ताकि एक साथ चेकपॉइंट को अपडेट करते हुए मॉडल के हिस्से को क्रमिक रूप से अपडेट किया जा सके।

  1. कार्यात्मक-शैली tf.compat.v1.layers को उनके ऑब्जेक्ट-ओरिएंटेड संस्करणों में स्विच करके प्रारंभ करें।
class FunctionalStyleCompatModel(tf.keras.layers.Layer):

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs, training=None):
    with tf.compat.v1.variable_scope('model'):
      out = tf.compat.v1.layers.conv2d(
          inputs, 3, 3,
          kernel_regularizer="l2")
      out = tf.compat.v1.layers.conv2d(
          out, 4, 4,
          kernel_regularizer="l2")
      out = tf.compat.v1.layers.conv2d(
          out, 5, 5,
          kernel_regularizer="l2")
      return out

layer = FunctionalStyleCompatModel()
layer(tf.ones(shape=(10, 10, 10, 10)))
[v.name for v in layer.weights]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:8: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:11: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  # This is added back by InteractiveShellApp.init_path()
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:14: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
['model/conv2d/bias:0',
 'model/conv2d/kernel:0',
 'model/conv2d_1/bias:0',
 'model/conv2d_1/kernel:0',
 'model/conv2d_2/bias:0',
 'model/conv2d_2/kernel:0']
  1. इसके बाद, tf.keras.layers.Layer / tf.Module ऑब्जेक्ट के गुणों के रूप में compat.v1.layer ऑब्जेक्ट और compat.v1.get_variable द्वारा बनाए गए किसी भी वेरिएबल को असाइन करें, जिसका तरीका track_tf1_style_variables से सजाया गया है (ध्यान दें कि कोई भी ऑब्जेक्ट-ओरिएंटेड TF2 स्टाइल चेकपॉइंट्स अब वेरिएबल नाम और नए ऑब्जेक्ट-ओरिएंटेड पथ द्वारा पथ दोनों को सहेज लेंगे)।
class OOStyleCompatModel(tf.keras.layers.Layer):

  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.conv_1 = tf.compat.v1.layers.Conv2D(
          3, 3,
          kernel_regularizer="l2")
    self.conv_2 = tf.compat.v1.layers.Conv2D(
          4, 4,
          kernel_regularizer="l2")

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs, training=None):
    with tf.compat.v1.variable_scope('model'):
      out = self.conv_1(inputs)
      out = self.conv_2(out)
      out = tf.compat.v1.layers.conv2d(
          out, 5, 5,
          kernel_regularizer="l2")
      return out

layer = OOStyleCompatModel()
layer(tf.ones(shape=(10, 10, 10, 10)))
[v.name for v in layer.weights]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:19: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
['model/conv2d/kernel:0',
 'model/conv2d/bias:0',
 'model/conv2d_1/kernel:0',
 'model/conv2d_1/bias:0',
 'model/conv2d_2/bias:0',
 'model/conv2d_2/kernel:0']
  1. चर नाम (compat.v1.layers के लिए), या ऑब्जेक्ट-ओरिएंटेड ऑब्जेक्ट ग्राफ़ द्वारा पथों को बचाने के लिए इस बिंदु पर लोड किए गए चेकपॉइंट को फिर से सहेजें।
weights = {v.name: v for v in layer.weights}
assert weights['model/conv2d/kernel:0'] is layer.conv_1.kernel
assert weights['model/conv2d_1/bias:0'] is layer.conv_2.bias
  1. अब आप ऑब्जेक्ट-ओरिएंटेड compat.v1.layers को नेटिव Keras लेयर्स के लिए स्वैप कर सकते हैं, जबकि अभी भी हाल ही में सहेजे गए चेकपॉइंट को लोड करने में सक्षम हैं। सुनिश्चित करें कि आप बदली हुई परतों के स्वतः-जनित variable_scopes को अभी भी रिकॉर्ड करके शेष compat.v1.layers के लिए चर नामों को संरक्षित करते हैं। ये स्विच की गई परतें/चर अब केवल चर नाम पथ के बजाय चेकपॉइंट में चर के लिए ऑब्जेक्ट विशेषता पथ का उपयोग करेंगे।

सामान्य तौर पर, आप गुणों से जुड़े चरों में compat.v1.get_variable के उपयोग को निम्न द्वारा प्रतिस्थापित कर सकते हैं:

  • उन्हें tf.Variable , OR . का उपयोग करने के लिए स्विच करना
  • tf.keras.layers.Layer.add_weight का उपयोग करके उन्हें अपडेट करना। ध्यान दें कि यदि आप सभी लेयर्स को एक बार में स्विच नहीं कर रहे हैं तो यह शेष compat.v1.layers के लिए ऑटो-जेनरेटेड लेयर/वेरिएबल नामकरण बदल सकता है जिसमें name तर्क गुम है। यदि ऐसा है, तो आपको हटाए गए compat.v1.layer के जनरेट किए गए स्कोप नाम के अनुरूप एक वेरिएबल_स्कोप को मैन्युअल रूप से खोलकर और बंद करके शेष compat.v1.layers के लिए variable_scope नामों को समान रखना चाहिए। अन्यथा मौजूदा चौकियों के रास्ते विरोध कर सकते हैं और चेकपॉइंट लोडिंग गलत तरीके से व्यवहार करेगी।
def record_scope(scope_name):
  """Record a variable_scope to make sure future ones get incremented."""
  with tf.compat.v1.variable_scope(scope_name):
    pass

class PartiallyNativeKerasLayersModel(tf.keras.layers.Layer):

  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.conv_1 = tf.keras.layers.Conv2D(
          3, 3,
          kernel_regularizer="l2")
    self.conv_2 = tf.keras.layers.Conv2D(
          4, 4,
          kernel_regularizer="l2")

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs, training=None):
    with tf.compat.v1.variable_scope('model'):
      out = self.conv_1(inputs)
      record_scope('conv2d') # Only needed if follow-on compat.v1.layers do not pass a `name` arg
      out = self.conv_2(out)
      record_scope('conv2d_1') # Only needed if follow-on compat.v1.layers do not pass a `name` arg
      out = tf.compat.v1.layers.conv2d(
          out, 5, 5,
          kernel_regularizer="l2")
      return out

layer = PartiallyNativeKerasLayersModel()
layer(tf.ones(shape=(10, 10, 10, 10)))
[v.name for v in layer.weights]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:26: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
['partially_native_keras_layers_model/model/conv2d_13/kernel:0',
 'partially_native_keras_layers_model/model/conv2d_13/bias:0',
 'partially_native_keras_layers_model/model/conv2d_14/kernel:0',
 'partially_native_keras_layers_model/model/conv2d_14/bias:0',
 'model/conv2d_2/bias:0',
 'model/conv2d_2/kernel:0']

चर के निर्माण के बाद इस चरण में एक चेकपॉइंट को सहेजने से इसमें केवल वर्तमान में उपलब्ध ऑब्जेक्ट पथ होंगे।

सुनिश्चित करें कि आप हटाए गए compat.v1.layers के दायरे को रिकॉर्ड करते हैं, ताकि शेष compat.v1.layers के लिए ऑटो-जेनरेट किए गए वज़न नामों को सुरक्षित रखा जा सके।

weights = set(v.name for v in layer.weights)
assert 'model/conv2d_2/kernel:0' in weights
assert 'model/conv2d_2/bias:0' in weights
  1. उपरोक्त चरणों को तब तक दोहराएं जब तक कि आप अपने मॉडल में सभी compat.v1.layers और compat.v1.get_variable s को पूरी तरह से देशी समकक्षों से बदल नहीं देते।
class FullyNativeKerasLayersModel(tf.keras.layers.Layer):

  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.conv_1 = tf.keras.layers.Conv2D(
          3, 3,
          kernel_regularizer="l2")
    self.conv_2 = tf.keras.layers.Conv2D(
          4, 4,
          kernel_regularizer="l2")
    self.conv_3 = tf.keras.layers.Conv2D(
          5, 5,
          kernel_regularizer="l2")


  def call(self, inputs, training=None):
    with tf.compat.v1.variable_scope('model'):
      out = self.conv_1(inputs)
      out = self.conv_2(out)
      out = self.conv_3(out)
      return out

layer = FullyNativeKerasLayersModel()
layer(tf.ones(shape=(10, 10, 10, 10)))
[v.name for v in layer.weights]
['fully_native_keras_layers_model/model/conv2d_16/kernel:0',
 'fully_native_keras_layers_model/model/conv2d_16/bias:0',
 'fully_native_keras_layers_model/model/conv2d_17/kernel:0',
 'fully_native_keras_layers_model/model/conv2d_17/bias:0',
 'fully_native_keras_layers_model/model/conv2d_18/kernel:0',
 'fully_native_keras_layers_model/model/conv2d_18/bias:0']

यह सुनिश्चित करने के लिए परीक्षण करना याद रखें कि नया अपडेट किया गया चेकपॉइंट अभी भी आपकी अपेक्षा के अनुरूप व्यवहार करता है। यह सुनिश्चित करने के लिए कि आपका माइग्रेट कोड सही ढंग से चलता है, इस प्रक्रिया के प्रत्येक वृद्धिशील चरण पर मान्य संख्यात्मक शुद्धता मार्गदर्शिका में वर्णित तकनीकों को लागू करें।

TF1.x से TF2 व्यवहार परिवर्तनों को संभालना मॉडलिंग शिम्स द्वारा कवर नहीं किया गया

इस गाइड में वर्णित मॉडलिंग शिम यह सुनिश्चित कर सकता है कि get_variable , tf.compat.v1.layers , और variable_scope सेमेन्टिक्स के साथ बनाए गए चर, परतें और नियमितीकरण नुकसान उत्सुक निष्पादन और tf.function का उपयोग किए बिना पहले की तरह काम करना जारी रखते हैं। संग्रह पर निर्भर हैं।

इसमें सभी TF1.x-विशिष्ट शब्दार्थ शामिल नहीं हैं जिन पर आपका मॉडल फ़ॉरवर्ड पास निर्भर हो सकता है। कुछ मामलों में, शिम आपके मॉडल फ़ॉरवर्ड पास को TF2 में अपने आप चलाने के लिए अपर्याप्त हो सकते हैं। TF1.x और TF2 के बीच व्यवहार संबंधी अंतरों के बारे में अधिक जानने के लिए TF1.x बनाम TF2 व्यवहार मार्गदर्शिका पढ़ें।