प्रभावी टेंसरफ्लो 2

TensorFlow उपयोगकर्ताओं को अधिक उत्पादक बनाने के लिए TensorFlow 2.0 में कई बदलाव किए गए हैं। TensorFlow 2.0 हटा एपीआई निरर्थक , एपीआई और अधिक सुसंगत बनाता है ( एकीकृत RNNs , एकीकृत Optimizers ), और साथ अजगर क्रम के साथ बेहतर तरीके से एकीकृत उत्सुक निष्पादन

कई RFC के परिवर्तन है कि TensorFlow 2.0 बनाने में चले गए हैं समझा दिया है। यह मार्गदर्शिका एक दृष्टिकोण प्रस्तुत करती है कि TensorFlow 2.0 में किस तरह का विकास दिखना चाहिए। यह माना जाता है कि आप TensorFlow 1.x के साथ कुछ परिचित हैं।

प्रमुख परिवर्तनों का संक्षिप्त सारांश

एपीआई सफाई

अनेक API या तो कर रहे हैं चला गया या ले जाया गया TF 2.0 में। बड़े बदलाव से कुछ को हटाने शामिल tf.app , tf.flags , और tf.logging अब खुला स्रोत के पक्ष में ABSL-py , परियोजनाओं में रहते थे rehoming tf.contrib , और मुख्य सफाई tf.* द्वारा नाम स्थान जैसे सबपैकेज में कम इस्तेमाल किया कार्यों चलती tf.math । - कुछ एपीआई उनके 2.0 समकक्ष के साथ प्रतिस्थापित किया गया है tf.summary , tf.keras.metrics , और tf.keras.optimizers । सबसे आसान तरीका है स्वचालित रूप से इन renames लागू करने के लिए उपयोग करने के लिए है v2 उन्नयन स्क्रिप्ट

उत्सुक निष्पादन

TensorFlow 1.x उपयोगकर्ताओं को मैन्युअल एक साथ एक सिलाई करने की आवश्यकता है सार वाक्य रचना पेड़ बनाकर (ग्राफ) tf.* API कॉल। यह तो स्वयं एक करने के लिए उत्पादन tensors और इनपुट tensors का एक सेट पारित करके सार वाक्य रचना पेड़ संकलित करने के लिए उपयोगकर्ताओं की आवश्यकता है session.run कॉल। TensorFlow 2.0 उत्सुकता से निष्पादित करता है (जैसे पायथन सामान्य रूप से करता है) और 2.0 में, ग्राफ़ और सत्र को कार्यान्वयन विवरण की तरह महसूस करना चाहिए।

उत्सुक निष्पादन की एक उल्लेखनीय प्रतिफल है कि है tf.control_dependencies अब आवश्यकता है (एक के भीतर के रूप में कोड की सभी पंक्तियों के क्रम में निष्पादित tf.function , क्रम में साइड इफेक्ट कार्यान्वित के साथ कोड लिखित)।

कोई और वैश्विक नहीं

TensorFlow 1.x परोक्ष रूप से वैश्विक नामस्थानों पर बहुत अधिक निर्भर करता है। जब आप बुलाया tf.Variable , यह डिफ़ॉल्ट ग्राफ में डाल दिया जाएगा, और यह वहाँ रहेगा, भले ही आप अजगर चर यह की ओर इशारा करते नज़र खो दिया है। तो आपको लगता है कि ठीक हो सकता है tf.Variable , लेकिन आप नाम पता था कि तभी जब कि यह साथ बनाया गया था। यह करना मुश्किल था यदि आप चर के निर्माण के नियंत्रण में नहीं थे। नतीजतन, तंत्र के सभी प्रकार के मदद उपयोगकर्ताओं को अपने चर फिर से खोजने के लिए प्रयास करने के लिए प्रचुर मात्रा में है, और चौखटे उपयोगकर्ता-निर्मित चर को खोजने के लिए: परिवर्तनशील स्कोप, वैश्विक संग्रह, जैसे सहायक तरीकों tf.get_global_step , tf.global_variables_initializer , अनुकूलक परोक्ष कंप्यूटिंग ढ़ाल सभी प्रशिक्षित चरों पर, और इसी तरह। TensorFlow 2.0 सभी इन तंत्रों (की को हटा चर 2.0 आरएफसी ) डिफ़ॉल्ट तंत्र के पक्ष में: अपने चर का रखें ट्रैक! यदि आप एक का ट्रैक खो देते हैं tf.Variable , यह कचरा एकत्र हो जाता है।

चर को ट्रैक करने की आवश्यकता उपयोगकर्ता के लिए कुछ अतिरिक्त काम बनाती है, लेकिन केरस ऑब्जेक्ट्स (नीचे देखें) के साथ, बोझ कम हो जाता है।

कार्य, सत्र नहीं

एक session.run कॉल लगभग एक समारोह कॉल की तरह है: आप इनपुट और समारोह के नाम से जाना निर्दिष्ट करें, और तुम वापस आउटपुट का एक सेट मिलता है। TensorFlow 2.0 में, आप का उपयोग कर एक अजगर समारोह को सजाने कर सकते हैं tf.function JIT संकलन के लिए यह चिह्नित करने के लिए इतना है कि TensorFlow एक भी ग्राफ (के रूप में इसे चलाता कार्य 2.0 आरएफसी )। यह तंत्र TensorFlow 2.0 को ग्राफ़ मोड के सभी लाभ प्राप्त करने की अनुमति देता है:

  • प्रदर्शन: फ़ंक्शन को अनुकूलित किया जा सकता है (नोड प्रूनिंग, कर्नेल फ़्यूज़न, आदि)
  • पोर्टेबिलिटी: समारोह निर्यात किया जा सकता / reimported ( SavedModel 2.0 आरएफसी ,) उन पुन: उपयोग और शेयर मॉड्यूलर TensorFlow कार्यों के लिए अनुमति देता है।
# TensorFlow 1.X
outputs = session.run(f(placeholder), feed_dict={placeholder: input})
# TensorFlow 2.0
outputs = f(input)

Python और TensorFlow कोड को स्वतंत्र रूप से प्रतिच्छेद करने की शक्ति के साथ, उपयोगकर्ता Python की अभिव्यक्ति का लाभ उठा सकते हैं। लेकिन पोर्टेबल TensorFlow एक पायथन दुभाषिया के बिना संदर्भों में निष्पादित होता है, जैसे कि मोबाइल, C++ और जावास्क्रिप्ट। मदद उपयोगकर्ताओं को जोड़ते समय उनके कोड को फिर से लिखने के लिए होने से बचने के लिए @tf.function , हस्ताक्षर उनके TensorFlow समकक्ष में अजगर निर्माणों के एक सबसेट धर्मान्तरित:

  • for / while -> tf.while_loop ( break और continue का समर्थन कर रहे)
  • if -> tf.cond
  • for _ in dataset -> dataset.reduce

ऑटोग्राफ नियंत्रण प्रवाह के मनमाने नेस्टिंग का समर्थन करता है, जिससे अनुक्रम मॉडल, सुदृढीकरण सीखने, कस्टम प्रशिक्षण लूप, और बहुत कुछ जैसे कई जटिल एमएल कार्यक्रमों को प्रदर्शन और संक्षिप्त रूप से लागू करना संभव हो जाता है।

मुहावरेदार TensorFlow 2.0 के लिए सिफारिशें

अपने कोड को छोटे कार्यों में पुन: सक्रिय करें

TensorFlow 1.x में एक आम उपयोग पैटर्न "पानी के नल" रणनीति है, जहां सभी संभव संगणना के मिलन preemptively बाहर रखी गई थी, और उसके बाद का चयन किया tensors के माध्यम से मूल्यांकन किया गया session.run । TensorFlow 2.0 में, उपयोगकर्ताओं को अपने कोड को छोटे कार्यों में पुन: सक्रिय करना चाहिए जिन्हें आवश्यकतानुसार कहा जाता है। सामान्य तौर पर, इसके साथ इन छोटे कार्यों में से प्रत्येक को सजाने के लिए आवश्यक नहीं है tf.function ; केवल का उपयोग tf.function , उदाहरण के लिए प्रशिक्षण या अपने मॉडल के फॉरवर्ड पास से एक कदम - उच्च स्तरीय संगणना को सजाने के लिए।

चरों को प्रबंधित करने के लिए केरस परतों और मॉडलों का उपयोग करें

Keras मॉडल और परतों सुविधाजनक की पेशकश variables और trainable_variables गुण है, जो रिकर्सिवली सभी आश्रित चरों इकट्ठा। इससे वेरिएबल को स्थानीय रूप से उस स्थान पर प्रबंधित करना आसान हो जाता है जहां उनका उपयोग किया जा रहा है।

कंट्रास्ट:

def dense(x, W, b):
  return tf.nn.sigmoid(tf.matmul(x, W) + b)

@tf.function
def multilayer_perceptron(x, w0, b0, w1, b1, w2, b2 ...):
  x = dense(x, w0, b0)
  x = dense(x, w1, b1)
  x = dense(x, w2, b2)
  ...

# You still have to manage w_i and b_i, and their shapes are defined far away from the code.

केरस संस्करण के साथ:

# Each layer can be called, with a signature equivalent to linear(x)
layers = [tf.keras.layers.Dense(hidden_size, activation=tf.nn.sigmoid) for _ in range(n)]
perceptron = tf.keras.Sequential(layers)

# layers[3].trainable_variables => returns [w3, b3]
# perceptron.trainable_variables => returns [w0, b0, ...]

Keras परतों / मॉडल से विरासत tf.train.Checkpointable और साथ एकीकृत कर रहे हैं @tf.function है, जो यह संभव सीधे जांच की चौकी या निर्यात SavedModels को Keras वस्तुओं से बना देता है। आप जरूरी Keras के उपयोग करने के लिए की जरूरत नहीं है Model.fit एपीआई इन एकीकरण का लाभ उठाने के लिए।

यहां एक स्थानांतरण सीखने का उदाहरण दिया गया है जो दर्शाता है कि कैसे केरस प्रासंगिक चर का एक सबसेट एकत्र करना आसान बनाता है। मान लें कि आप एक साझा ट्रंक के साथ एक बहु-सिर वाले मॉडल का प्रशिक्षण ले रहे हैं:

trunk = tf.keras.Sequential([...])
head1 = tf.keras.Sequential([...])
head2 = tf.keras.Sequential([...])

path1 = tf.keras.Sequential([trunk, head1])
path2 = tf.keras.Sequential([trunk, head2])

# Train on primary dataset
for x, y in main_dataset:
  with tf.GradientTape() as tape:
    # training=True is only needed if there are layers with different
    # behavior during training versus inference (e.g. Dropout).
    prediction = path1(x, training=True)
    loss = loss_fn_head1(prediction, y)
  # Simultaneously optimize trunk and head1 weights.
  gradients = tape.gradient(loss, path1.trainable_variables)
  optimizer.apply_gradients(zip(gradients, path1.trainable_variables))

# Fine-tune second head, reusing the trunk
for x, y in small_dataset:
  with tf.GradientTape() as tape:
    # training=True is only needed if there are layers with different
    # behavior during training versus inference (e.g. Dropout).
    prediction = path2(x, training=True)
    loss = loss_fn_head2(prediction, y)
  # Only optimize head2 weights, not trunk weights
  gradients = tape.gradient(loss, head2.trainable_variables)
  optimizer.apply_gradients(zip(gradients, head2.trainable_variables))

# You can publish just the trunk computation for other people to reuse.
tf.saved_model.save(trunk, output_path)

tf.data.Datasets और @tf.function को मिलाएं

स्मृति में फिट होने वाले प्रशिक्षण डेटा पर पुनरावृत्ति करते समय, नियमित पायथन पुनरावृत्ति का उपयोग करने के लिए स्वतंत्र महसूस करें। अन्यथा, tf.data.Dataset सबसे अच्छा तरीका है डिस्क से प्रशिक्षण डेटा स्ट्रीम करने के लिए है। डेटासेट हैं iterables (नहीं iterators) , और काम बस उत्सुक मोड में अन्य अजगर iterables की तरह। आप पूरी तरह से डाटासेट async प्रीफेचिंग / में अपने कोड लपेटकर सुविधाओं स्ट्रीमिंग का उपयोग कर सकते tf.function , जो हस्ताक्षर का उपयोग कर बराबर ग्राफ संचालन के साथ अजगर यात्रा बदल देता है।

@tf.function
def train(model, dataset, optimizer):
  for x, y in dataset:
    with tf.GradientTape() as tape:
      # training=True is only needed if there are layers with different
      # behavior during training versus inference (e.g. Dropout).
      prediction = model(x, training=True)
      loss = loss_fn(prediction, y)
    gradients = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

आप Keras का उपयोग करते हैं Model.fit एपीआई, आप डाटासेट यात्रा के बारे में चिंता करने की ज़रूरत नहीं होगी।

model.compile(optimizer=optimizer, loss=loss_fn)
model.fit(dataset)

पायथन नियंत्रण प्रवाह के साथ ऑटोग्राफ का लाभ उठाएं

हस्ताक्षर के लिए एक रास्ता की तरह ग्राफ मोड समकक्ष में डेटा पर निर्भर नियंत्रण प्रवाह परिवर्तित करने के लिए प्रदान करता है tf.cond और tf.while_loop

अनुक्रम मॉडल में एक सामान्य स्थान जहां डेटा-निर्भर नियंत्रण प्रवाह दिखाई देता है। tf.keras.layers.RNN एक RNN सेल लपेटता है, या तो स्थिर या गतिशील पुनरावृत्ति उतारना करने के लिए आप की अनुमति देता है। प्रदर्शन के लिए, आप निम्नानुसार डायनेमिक अनरोल को फिर से लागू कर सकते हैं:

class DynamicRNN(tf.keras.Model):

  def __init__(self, rnn_cell):
    super(DynamicRNN, self).__init__(self)
    self.cell = rnn_cell

  def call(self, input_data):
    # [batch, time, features] -> [time, batch, features]
    input_data = tf.transpose(input_data, [1, 0, 2])
    outputs = tf.TensorArray(tf.float32, input_data.shape[0])
    state = self.cell.zero_state(input_data.shape[1], dtype=tf.float32)
    for i in tf.range(input_data.shape[0]):
      output, state = self.cell(input_data[i], state)
      outputs = outputs.write(i, output)
    return tf.transpose(outputs.stack(), [1, 0, 2]), state

हस्ताक्षर की सुविधाओं के एक अधिक विस्तृत अवलोकन के लिए, को देखने के गाइड

tf.metrics डेटा एकत्र करता है और tf.summary उन्हें लॉग करता है

सारांश लॉग ऑन करने के लिए, उपयोग tf.summary.(scalar|histogram|...) और एक संदर्भ प्रबंधक का उपयोग कर एक लेखक के लिए यह अनुप्रेषित। (यदि आप संदर्भ प्रबंधक को छोड़ देते हैं, तो कुछ नहीं होता।) TF 1.x के विपरीत, सारांश सीधे लेखक को भेजे जाते हैं; कोई अलग "मर्ज" सेशन और अलग से कोई है add_summary कॉल, जिसका अर्थ है कि step मूल्य callsite में प्रदान किया जाना चाहिए।

summary_writer = tf.summary.create_file_writer('/tmp/summaries')
with summary_writer.as_default():
  tf.summary.scalar('loss', 0.1, step=42)

उन्हें सारांश, उपयोग के रूप में प्रवेश करने से पहले डेटा एकत्रित करने के tf.metrics । मेट्रिक्स स्टेटफुल हैं: वे मान जमा होते हैं और एक संचयी परिणाम लौटने जब आप कॉल result (जैसे विधि Mean.result )। साफ संचित साथ मूल्यों Model.reset_states

def train(model, optimizer, dataset, log_freq=10):
  avg_loss = tf.keras.metrics.Mean(name='loss', dtype=tf.float32)
  for images, labels in dataset:
    loss = train_step(model, optimizer, images, labels)
    avg_loss.update_state(loss)
    if tf.equal(optimizer.iterations % log_freq, 0):
      tf.summary.scalar('loss', avg_loss.result(), step=optimizer.iterations)
      avg_loss.reset_states()

def test(model, test_x, test_y, step_num):
  # training=False is only needed if there are layers with different
  # behavior during training versus inference (e.g. Dropout).
  loss = loss_fn(model(test_x, training=False), test_y)
  tf.summary.scalar('loss', loss, step=step_num)

train_summary_writer = tf.summary.create_file_writer('/tmp/summaries/train')
test_summary_writer = tf.summary.create_file_writer('/tmp/summaries/test')

with train_summary_writer.as_default():
  train(model, optimizer, dataset)

with test_summary_writer.as_default():
  test(model, test_x, test_y, optimizer.iterations)

सारांश लॉग निर्देशिका में TensorBoard को इंगित करके उत्पन्न सारांश की कल्पना करें:

tensorboard --logdir /tmp/summaries

डिबगिंग करते समय tf.config.run_functions_eagerly का उपयोग करें

TensorFlow 2.0 में, उत्सुक निष्पादन आपको आकृतियों, डेटा प्रकारों और मानों का निरीक्षण करने के लिए कोड को चरण-दर-चरण चलाने देता है। कुछ विशेष API, जैसे tf.function , tf.keras , आदि प्रदर्शन और पोर्टेबिलिटी के लिए ग्राफ़ निष्पादन, उपयोग करने के लिए डिजाइन किए हैं। जब डिबगिंग, उपयोग tf.config.run_functions_eagerly(True) इस कोड को अंदर उत्सुक निष्पादन उपयोग करने के लिए।

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

@tf.function
def f(x):
  if x > 0:
    import pdb
    pdb.set_trace()
    x = x + 1
  return x

tf.config.run_functions_eagerly(True)
f(tf.constant(1))
f()
-> x = x + 1
(Pdb) l
  6     @tf.function
  7     def f(x):
  8       if x > 0:
  9         import pdb
 10         pdb.set_trace()
 11  ->     x = x + 1
 12       return x
 13
 14     tf.config.run_functions_eagerly(True)
 15     f(tf.constant(1))
[EOF]

यह केरस मॉडल और अन्य एपीआई के अंदर भी काम करता है जो उत्सुक निष्पादन का समर्थन करते हैं:

class CustomModel(tf.keras.models.Model):

  @tf.function
  def call(self, input_data):
    if tf.reduce_mean(input_data) > 0:
      return input_data
    else:
      import pdb
      pdb.set_trace()
      return input_data // 2


tf.config.run_functions_eagerly(True)
model = CustomModel()
model(tf.constant([-2, -4]))
call()
-> return input_data // 2
(Pdb) l
 10         if tf.reduce_mean(input_data) > 0:
 11           return input_data
 12         else:
 13           import pdb
 14           pdb.set_trace()
 15  ->       return input_data // 2
 16
 17
 18     tf.config.run_functions_eagerly(True)
 19     model = CustomModel()
 20     model(tf.constant([-2, -4]))