Google I / O 18-20 मई को लौटता है! जगह आरक्षित करें और अपना शेड्यूल बनाएं अभी रजिस्टर करें

प्रशिक्षण चौकियों

TensorFlow.org पर देखें Google Colab में चलाएं GitHub पर स्रोत देखें नोटबुक डाउनलोड करें

वाक्यांश "सेविंग ए टेंसोरफ्लो मॉडल" का अर्थ आमतौर पर दो चीजों में से एक होता है:

  1. चौकी, या
  2. सावेदमोडल।

चेकपॉइंट एक मॉडल द्वारा उपयोग किए जाने वाले सभी मापदंडों ( tf.Variable ऑब्जेक्ट्स) के सटीक मूल्य को कैप्चर करता है। चेकपॉइंट में मॉडल द्वारा परिभाषित गणना का कोई विवरण शामिल नहीं है और इस प्रकार आमतौर पर केवल तब उपयोगी होता है जब स्रोत कोड जो सहेजे गए पैरामीटर मान का उपयोग करेगा उपलब्ध है।

दूसरी ओर सेव्डमॉडल प्रारूप में पैरामीटर मान (चेकपॉइंट) के अलावा मॉडल द्वारा परिभाषित गणना का क्रमबद्ध विवरण शामिल है। इस प्रारूप में मॉडल मॉडल बनाने वाले स्रोत कोड से स्वतंत्र होते हैं। इस प्रकार वे TensorFlow Serving, TensorFlow Lite, TensorFlow.js, या अन्य प्रोग्रामिंग भाषाओं में प्रोग्राम (C, C++, Java, Go, Rust, C# आदि) TensorFlow APIs के माध्यम से परिनियोजन के लिए उपयुक्त हैं।

यह गाइड लेखन और पढ़ने वाली चौकियों के लिए एपीआई को कवर करता है।

सेट अप

import tensorflow as tf
class Net(tf.keras.Model):
  """A simple linear model."""

  def __init__(self):
    super(Net, self).__init__()
    self.l1 = tf.keras.layers.Dense(5)

  def call(self, x):
    return self.l1(x)
net = Net()

tf.keras ट्रेनिंग एपीआई से बचत

बचाने और बहाल करने पर tf.keras गाइड देखें।

tf.keras.Model.save_weights एक TensorFlow चेकपॉइंट बचाता है।

net.save_weights('easy_checkpoint')

लेखन चौकियों

TensorFlow मॉडल की स्थिर स्थिति को tf.Variable ऑब्जेक्ट्स में संग्रहित किया tf.Variable है। इन्हें सीधे बनाया जा सकता है, लेकिन अक्सरtf.keras.layers या tf.keras.Model जैसे उच्च-स्तरीय API के माध्यम से बनाए tf.keras.Model

चर को प्रबंधित करने का सबसे आसान तरीका उन्हें पायथन ऑब्जेक्ट्स से जोड़ना है, फिर उन वस्तुओं को संदर्भित करना है।

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

आप Model.save_weights साथ एक मॉडल-चेकपॉइंट को आसानी से सहेज सकते हैं।

मैनुअल चेकपॉइंटिंग

सेट अप

tf.train.Checkpoint की सभी विशेषताओं को प्रदर्शित करने में मदद करने के लिए, एक खिलौना डाटासेट और अनुकूलन कदम को परिभाषित करें:

def toy_dataset():
  inputs = tf.range(10.)[:, None]
  labels = inputs * 5. + tf.range(5.)[None, :]
  return tf.data.Dataset.from_tensor_slices(
    dict(x=inputs, y=labels)).repeat().batch(2)
def train_step(net, example, optimizer):
  """Trains `net` on `example` using `optimizer`."""
  with tf.GradientTape() as tape:
    output = net(example['x'])
    loss = tf.reduce_mean(tf.abs(output - example['y']))
  variables = net.trainable_variables
  gradients = tape.gradient(loss, variables)
  optimizer.apply_gradients(zip(gradients, variables))
  return loss

चौकी वस्तुएं बनाएं

मैन्युअल रूप से एक चेकपॉइंट बनाने के लिए एक tf.train.Checkpoint ऑब्जेक्ट का उपयोग करें, जहां आप जिस ऑब्जेक्ट को चेकपॉइंट करना चाहते हैं, उसे ऑब्जेक्ट पर विशेषताओं के रूप में सेट किया गया है।

एक tf.train.CheckpointManager कई चौकियों के प्रबंधन के लिए भी सहायक हो सकता है।

opt = tf.keras.optimizers.Adam(0.1)
dataset = toy_dataset()
iterator = iter(dataset)
ckpt = tf.train.Checkpoint(step=tf.Variable(1), optimizer=opt, net=net, iterator=iterator)
manager = tf.train.CheckpointManager(ckpt, './tf_ckpts', max_to_keep=3)

मॉडल को प्रशिक्षित और जांचना

निम्न प्रशिक्षण पाश मॉडल और एक अनुकूलक का एक उदाहरण बनाता है, फिर उन्हें एक tf.train.Checkpoint ऑब्जेक्ट में tf.train.Checkpoint है। यह डेटा के प्रत्येक बैच पर प्रशिक्षण चरण को लूप में कॉल करता है, और समय-समय पर डिस्क पर चौकियों को लिखता है।

def train_and_checkpoint(net, manager):
  ckpt.restore(manager.latest_checkpoint)
  if manager.latest_checkpoint:
    print("Restored from {}".format(manager.latest_checkpoint))
  else:
    print("Initializing from scratch.")

  for _ in range(50):
    example = next(iterator)
    loss = train_step(net, example, opt)
    ckpt.step.assign_add(1)
    if int(ckpt.step) % 10 == 0:
      save_path = manager.save()
      print("Saved checkpoint for step {}: {}".format(int(ckpt.step), save_path))
      print("loss {:1.2f}".format(loss.numpy()))
train_and_checkpoint(net, manager)
Initializing from scratch.
Saved checkpoint for step 10: ./tf_ckpts/ckpt-1
loss 29.00
Saved checkpoint for step 20: ./tf_ckpts/ckpt-2
loss 22.42
Saved checkpoint for step 30: ./tf_ckpts/ckpt-3
loss 15.86
Saved checkpoint for step 40: ./tf_ckpts/ckpt-4
loss 9.40
Saved checkpoint for step 50: ./tf_ckpts/ckpt-5
loss 3.20

पुनर्स्थापित करें और प्रशिक्षण जारी रखें

पहले प्रशिक्षण चक्र के बाद आप एक नया मॉडल और प्रबंधक पास कर सकते हैं, लेकिन प्रशिक्षण ठीक वहीं से लें जहां आपने छोड़ा था:

opt = tf.keras.optimizers.Adam(0.1)
net = Net()
dataset = toy_dataset()
iterator = iter(dataset)
ckpt = tf.train.Checkpoint(step=tf.Variable(1), optimizer=opt, net=net, iterator=iterator)
manager = tf.train.CheckpointManager(ckpt, './tf_ckpts', max_to_keep=3)

train_and_checkpoint(net, manager)
Restored from ./tf_ckpts/ckpt-5
Saved checkpoint for step 60: ./tf_ckpts/ckpt-6
loss 1.19
Saved checkpoint for step 70: ./tf_ckpts/ckpt-7
loss 0.66
Saved checkpoint for step 80: ./tf_ckpts/ckpt-8
loss 0.90
Saved checkpoint for step 90: ./tf_ckpts/ckpt-9
loss 0.32
Saved checkpoint for step 100: ./tf_ckpts/ckpt-10
loss 0.34

tf.train.CheckpointManager ऑब्जेक्ट पुरानी चौकियों को हटा देता है। ऊपर यह केवल तीन सबसे हाल की चौकियों को रखने के लिए कॉन्फ़िगर किया गया है।

print(manager.checkpoints)  # List the three remaining checkpoints
['./tf_ckpts/ckpt-8', './tf_ckpts/ckpt-9', './tf_ckpts/ckpt-10']

ये पथ, जैसे './tf_ckpts/ckpt-10' डिस्क पर फ़ाइलें नहीं हैं। इसके बजाय वे एक index फ़ाइल और एक या अधिक डेटा फ़ाइलों के लिए उपसर्ग हैं जिनमें चर मान शामिल हैं। इन उपसर्गों को एक एकल checkpoint फ़ाइल ( './tf_ckpts/checkpoint' ) में एक साथ समूहीकृत किया जाता है, जहाँ CheckpointManager अपनी स्थिति बचाता है।

ls ./tf_ckpts
checkpoint           ckpt-8.data-00000-of-00001  ckpt-9.index
ckpt-10.data-00000-of-00001  ckpt-8.index
ckpt-10.index            ckpt-9.data-00000-of-00001

यांत्रिकी लोड हो रहा है

TensorFlow नामांकित किनारों के साथ एक निर्देशित ग्राफ़ को लोड करके ऑब्जेक्ट से शुरू करके चेकपॉइंट किए गए मानों के लिए चर से मेल खाता है। एज नाम आमतौर पर ऑब्जेक्ट में विशेषता नामों से आते हैं, उदाहरण के लिए "l1" में self.l1 = tf.keras.layers.Dense(5)tf.train.Checkpoint अपने कीवर्ड तर्क नामों का उपयोग करता है, जैसे कि tf.train.Checkpoint(step=...) में "step"

ऊपर के उदाहरण से निर्भरता ग्राफ इस तरह दिखता है:

उदाहरण प्रशिक्षण पाश के लिए निर्भरता ग्राफ का दृश्य

अनुकूलक लाल रंग में है, नियमित चर नीले रंग में हैं, और अनुकूलक स्लॉट चर नारंगी रंग में हैं। अन्य नोड्स—उदाहरण के लिए, tf.train.Checkpoint प्रतिनिधित्व करते tf.train.Checkpoint —काले रंग में हैं।

स्लॉट चर अनुकूलक के राज्य का हिस्सा हैं, लेकिन एक विशिष्ट चर के लिए बनाए जाते हैं। उदाहरण के लिए, ऊपर 'm' किनारे गति के अनुरूप हैं, जिसे एडम अनुकूलक प्रत्येक चर के लिए ट्रैक करता है। स्लॉट चर केवल एक चेकपॉइंट में सहेजे जाते हैं यदि चर और अनुकूलक दोनों सहेजे जाएंगे, इस प्रकार धराशायी किनारों।

कॉलिंग restore को tf.train.Checkpoint ऑब्जेक्ट अनुरोधित पुनर्स्थापनाओं को कतार में tf.train.Checkpoint , जैसे ही Checkpoint ऑब्जेक्ट से मिलान पथ होता है, वैरिएबल मान को पुनर्स्थापित करता है। उदाहरण के लिए, आप ऊपर दिए गए मॉडल से बस पूर्वाग्रह को लोड कर सकते हैं जो नेटवर्क और परत के माध्यम से एक पथ को फिर से जोड़कर इसे परिभाषित करता है।

to_restore = tf.Variable(tf.zeros([5]))
print(to_restore.numpy())  # All zeros
fake_layer = tf.train.Checkpoint(bias=to_restore)
fake_net = tf.train.Checkpoint(l1=fake_layer)
new_root = tf.train.Checkpoint(net=fake_net)
status = new_root.restore(tf.train.latest_checkpoint('./tf_ckpts/'))
print(to_restore.numpy())  # This gets the restored value.
[0. 0. 0. 0. 0.]
[2.2704186 3.0526643 3.8114467 3.4453893 4.2802196]

इन नई वस्तुओं के लिए निर्भरता ग्राफ आपके द्वारा ऊपर लिखे गए बड़े चेकपॉइंट का बहुत छोटा सबग्राफ है। इसमें केवल पूर्वाग्रह और एक बचत काउंटर शामिल है जो tf.train.Checkpoint नंबर चौकियों के लिए उपयोग करता है।

पूर्वाग्रह चर के लिए एक उपसमूह का दृश्य

restore एक स्थिति ऑब्जेक्ट लौटाता है, जिसमें वैकल्पिक दावे हैं। नए Checkpoint में बनाए गए सभी ऑब्जेक्ट को पुनर्स्थापित कर दिया गया है, इसलिए status.assert_existing_objects_matched पास हो जाता है।

status.assert_existing_objects_matched()
<tensorflow.python.training.tracking.util.CheckpointLoadStatus at 0x7f2a4cbccb38>

चेकपॉइंट में कई ऑब्जेक्ट हैं जो मेल नहीं खाते हैं, जिनमें लेयर का कर्नेल और ऑप्टिमाइज़र के वेरिएबल्स शामिल हैं। status.assert_consumed केवल तभी पास होता है यदि चेकपॉइंट और प्रोग्राम बिल्कुल मेल खाते हैं, और यहां एक अपवाद फेंक देंगे।

विलंबित पुनर्स्थापन

जब इनपुट आकार उपलब्ध होते हैं, तो TensorFlow में Layer ऑब्जेक्ट अपनी पहली कॉल में चर के निर्माण में देरी कर सकते हैं। उदाहरण के लिए एक Dense परत के कर्नेल का आकार परत के इनपुट और आउटपुट आकार दोनों पर निर्भर करता है, और इसलिए एक निर्माता तर्क के रूप में आवश्यक आउटपुट आकार अपने आप में चर बनाने के लिए पर्याप्त जानकारी नहीं है। चूँकि एक Layer कॉल करने से वेरिएबल की वैल्यू भी पढ़ जाती है, वैरिएबल के निर्माण और उसके पहले उपयोग के बीच एक रिस्टोर होना चाहिए।

इस मुहावरे का समर्थन करने के लिए, tf.train.Checkpoint कतारें पुनर्स्थापित करता है जो अभी तक एक मिलान चर नहीं है।

delayed_restore = tf.Variable(tf.zeros([1, 5]))
print(delayed_restore.numpy())  # Not restored; still zeros
fake_layer.kernel = delayed_restore
print(delayed_restore.numpy())  # Restored
[[0. 0. 0. 0. 0.]]
[[4.6544    4.6866627 4.729344  4.9574785 4.8010526]]

मैन्युअल रूप से निरीक्षण चौकियों

tf.train.load_checkpoint एक CheckpointReader देता है जो चेकपॉइंट सामग्री तक निचले स्तर की पहुँच देता है। इसमें प्रत्येक चर की कुंजी से लेकर चेकपॉइंट में प्रत्येक चर के आकार और dtype तक मैपिंग शामिल है। एक चर की कुंजी इसका ऑब्जेक्ट पथ है, जैसे ऊपर प्रदर्शित ग्राफ़ में।

reader = tf.train.load_checkpoint('./tf_ckpts/')
shape_from_key = reader.get_variable_to_shape_map()
dtype_from_key = reader.get_variable_to_dtype_map()

sorted(shape_from_key.keys())
['_CHECKPOINTABLE_OBJECT_GRAPH',
 'iterator/.ATTRIBUTES/ITERATOR_STATE',
 'net/l1/bias/.ATTRIBUTES/VARIABLE_VALUE',
 'net/l1/bias/.OPTIMIZER_SLOT/optimizer/m/.ATTRIBUTES/VARIABLE_VALUE',
 'net/l1/bias/.OPTIMIZER_SLOT/optimizer/v/.ATTRIBUTES/VARIABLE_VALUE',
 'net/l1/kernel/.ATTRIBUTES/VARIABLE_VALUE',
 'net/l1/kernel/.OPTIMIZER_SLOT/optimizer/m/.ATTRIBUTES/VARIABLE_VALUE',
 'net/l1/kernel/.OPTIMIZER_SLOT/optimizer/v/.ATTRIBUTES/VARIABLE_VALUE',
 'optimizer/beta_1/.ATTRIBUTES/VARIABLE_VALUE',
 'optimizer/beta_2/.ATTRIBUTES/VARIABLE_VALUE',
 'optimizer/decay/.ATTRIBUTES/VARIABLE_VALUE',
 'optimizer/iter/.ATTRIBUTES/VARIABLE_VALUE',
 'optimizer/learning_rate/.ATTRIBUTES/VARIABLE_VALUE',
 'save_counter/.ATTRIBUTES/VARIABLE_VALUE',
 'step/.ATTRIBUTES/VARIABLE_VALUE']

इसलिए यदि आप net.l1.kernel के मान में रुचि रखते हैं तो आप निम्न कोड के साथ मान प्राप्त कर सकते हैं:

key = 'net/l1/kernel/.ATTRIBUTES/VARIABLE_VALUE'

print("Shape:", shape_from_key[key])
print("Dtype:", dtype_from_key[key].name)
Shape: [1, 5]
Dtype: float32

यह आपको एक वैरिएबल के मूल्य का निरीक्षण करने की अनुमति देता है एक get_tensor विधि भी प्रदान करता है:

reader.get_tensor(key)
array([[4.6544   , 4.6866627, 4.729344 , 4.9574785, 4.8010526]],
      dtype=float32)

सूची और शब्दकोश ट्रैकिंग

जैसा कि self.l1 = tf.keras.layers.Dense(5) जैसे प्रत्यक्ष विशेषता असाइनमेंट के साथ होता है, विशेषताओं के लिए सूचियाँ और शब्दकोश निर्दिष्ट करना उनकी सामग्री को ट्रैक करेगा।

save = tf.train.Checkpoint()
save.listed = [tf.Variable(1.)]
save.listed.append(tf.Variable(2.))
save.mapped = {'one': save.listed[0]}
save.mapped['two'] = save.listed[1]
save_path = save.save('./tf_list_example')

restore = tf.train.Checkpoint()
v2 = tf.Variable(0.)
assert 0. == v2.numpy()  # Not restored yet
restore.mapped = {'two': v2}
restore.restore(save_path)
assert 2. == v2.numpy()

आप सूचियों और शब्दकोशों के लिए रैपर ऑब्जेक्ट देख सकते हैं। ये रैपर अंतर्निहित डेटा-संरचनाओं के जांच योग्य संस्करण हैं। विशेषता आधारित लोडिंग की तरह, ये रैपर जैसे ही कंटेनर में जोड़े जाते हैं, वैरिएबल के मान को पुनर्स्थापित करते हैं।

restore.listed = []
print(restore.listed)  # ListWrapper([])
v1 = tf.Variable(0.)
restore.listed.append(v1)  # Restores v1, from restore() in the previous cell
assert 1. == v1.numpy()
ListWrapper([])

वही ट्रैकिंग स्वचालित रूप से tf.keras.Model उपवर्गों पर लागू tf.keras.Model , और उदाहरण के लिए परतों की सूचियों को ट्रैक करने के लिए इसका उपयोग किया जा सकता है।

सारांश

TensorFlow ऑब्जेक्ट उनके द्वारा उपयोग किए जाने वाले चर के मानों को सहेजने और पुनर्स्थापित करने के लिए एक आसान स्वचालित तंत्र प्रदान करते हैं।