Google I/O הוא עטיפה! התעדכן בהפעלות של TensorFlow. צפה בהפעלות

Tensorflow יעיל 2

הצג באתר TensorFlow.org הפעל בגוגל קולאב הצג ב-GitHub הורד מחברת

סקירה כללית

מדריך זה מספק רשימה של שיטות עבודה מומלצות לכתיבת קוד באמצעות TensorFlow 2 (TF2), הוא נכתב עבור משתמשים שעברו לאחרונה מ-TensorFlow 1 (TF1). עיין בסעיף ההעברה של המדריך למידע נוסף על העברת קוד TF1 שלך ל-TF2.

להכין

ייבא את TensorFlow ותלות אחרות עבור הדוגמאות במדריך זה.

import tensorflow as tf
import tensorflow_datasets as tfds

המלצות עבור TensorFlow 2 אידיומטי

שחזר את הקוד שלך למודולים קטנים יותר

תרגול טוב הוא לחדש את הקוד שלך לפונקציות קטנות יותר שנקראות לפי הצורך. לקבלת הביצועים הטובים ביותר, עליך לנסות לקשט את בלוקי החישוב הגדולים ביותר שאתה יכול ב- tf.function (שים לב שפונקציות הפיתון המקוננות הנקראות על ידי tf.function אינן דורשות עיטורים נפרדים משלהן, אלא אם כן אתה רוצה להשתמש ב- jit_compile שונה הגדרות עבור tf.function .). בהתאם למקרה השימוש שלך, זה יכול להיות שלבי אימון מרובים או אפילו כל לולאת האימון שלך. למקרים של שימוש בהסקת מסקנות, זה עשוי להיות מעבר קדימה של דגם בודד.

התאם את קצב הלמידה המוגדר כברירת מחדל עבור חלק tf.keras.optimizer

לחלק מממטבי Keras יש שיעורי למידה שונים ב-TF2. אם אתה רואה שינוי בהתנהגות ההתכנסות של המודלים שלך, בדוק את שיעורי הלמידה המוגדרים כברירת מחדל.

אין שינויים עבור optimizers.SGD , optimizers.Adam , או optimizers.RMSprop .

שיעורי ברירת המחדל הבאים של הלמידה השתנו:

השתמש tf.Module s ו-Keras לניהול משתנים

tf.Module s ו- tf.keras.layers.Layer s מציעים את המשתנים הנוחים ואת מאפייני variables ל- trainable_variables , אשר אוספים באופן רקורסיבי את כל המשתנים התלויים. זה מקל על ניהול משתנים באופן מקומי למקום שבו הם נמצאים בשימוש.

שכבות/מודלים של Keras יורשים מ- tf.train.Checkpointable ומשולבים ב- @tf.function , המאפשר לבצע ביקורת ישירות או לייצא SavedModels מאובייקטים של Keras. אינך חייב בהכרח להשתמש ב- Model.fit API של Keras כדי לנצל את האינטגרציות הללו.

קרא את הסעיף על למידת העברה וכיוונון עדין במדריך Keras כדי ללמוד כיצד לאסוף תת-קבוצה של משתנים רלוונטיים באמצעות Keras.

שלב את tf.data.Dataset s ו- tf.function

חבילת TensorFlow Datasets ( tfds ) מכילה כלי עזר לטעינת מערכי נתונים מוגדרים מראש כאובייקטי tf.data.Dataset . עבור דוגמה זו, אתה יכול לטעון את מערך הנתונים של MNIST באמצעות tfds :

datasets, info = tfds.load(name='mnist', with_info=True, as_supervised=True)
mnist_train, mnist_test = datasets['train'], datasets['test']

לאחר מכן הכינו את הנתונים לאימון:

  • קנה מידה מחדש של כל תמונה.
  • ערבבו את סדר הדוגמאות.
  • אסוף קבוצות של תמונות ותוויות.
BUFFER_SIZE = 10 # Use a much larger value for real code
BATCH_SIZE = 64
NUM_EPOCHS = 5


def scale(image, label):
  image = tf.cast(image, tf.float32)
  image /= 255

  return image, label

כדי לשמור על הדוגמה קצרה, חתוך את מערך הנתונים כך שיחזיר רק 5 אצוות:

train_data = mnist_train.map(scale).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
test_data = mnist_test.map(scale).batch(BATCH_SIZE)

STEPS_PER_EPOCH = 5

train_data = train_data.take(STEPS_PER_EPOCH)
test_data = test_data.take(STEPS_PER_EPOCH)
image_batch, label_batch = next(iter(train_data))
2021-12-08 17:15:01.637157: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

השתמש באיטרציה רגילה של Python כדי לחזור על נתוני אימון שמתאימים לזיכרון. אחרת, tf.data.Dataset היא הדרך הטובה ביותר להזרים נתוני אימון מהדיסק. מערכי נתונים הם איטרבלים (לא איטרטורים) , ועובדים בדיוק כמו איטרבלים אחרים של Python בביצוע נלהב. אתה יכול לנצל באופן מלא את תכונות אחזור/הזרמה אסינכרון של נתונים על ידי גלישת הקוד שלך ב- tf.function , המחליף את איטרציית Python בפעולות הגרפים המקבילות באמצעות AutoGraph.

@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 API, לא תצטרך לדאוג לגבי איטרציה של מערך נתונים.

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

השתמש בלולאות אימון של Keras

אם אינך זקוק לשליטה ברמה נמוכה בתהליך האימון שלך, מומלץ להשתמש בשיטות fit , evaluate והניבוי המובנות של predict . שיטות אלו מספקות ממשק אחיד להכשרת המודל ללא קשר ליישום (רציף, פונקציונלי או תת-מחלקה).

היתרונות של שיטות אלה כוללים:

  • הם מקבלים מערכי Numpy, מחוללי Python ו- tf.data.Datasets .
  • הם מיישמים רגולציה, והפסדי הפעלה באופן אוטומטי.
  • הם תומכים ב- tf.distribute שבו קוד ההדרכה נשאר זהה ללא קשר לתצורת החומרה .
  • הם תומכים בהתקשרויות שרירותיות כהפסדים ומדדים.
  • הם תומכים ב-callbacks כמו tf.keras.callbacks.TensorBoard , ו-callbacks מותאמים אישית.
  • הם בעלי ביצועים, באופן אוטומטי באמצעות גרפים של TensorFlow.

הנה דוגמה לאימון מודל באמצעות ערכת Dataset . לפרטים על איך זה עובד, עיין במדריכי הלימוד .

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.02),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10)
])

# Model is the full model w/o custom layers
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

model.fit(train_data, epochs=NUM_EPOCHS)
loss, acc = model.evaluate(test_data)

print("Loss {}, Accuracy {}".format(loss, acc))
Epoch 1/5
5/5 [==============================] - 9s 7ms/step - loss: 1.5762 - accuracy: 0.4938
Epoch 2/5
2021-12-08 17:15:11.145429: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
5/5 [==============================] - 0s 6ms/step - loss: 0.5087 - accuracy: 0.8969
Epoch 3/5
2021-12-08 17:15:11.559374: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
5/5 [==============================] - 2s 5ms/step - loss: 0.3348 - accuracy: 0.9469
Epoch 4/5
2021-12-08 17:15:13.860407: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
5/5 [==============================] - 0s 5ms/step - loss: 0.2445 - accuracy: 0.9688
Epoch 5/5
2021-12-08 17:15:14.269850: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
5/5 [==============================] - 0s 6ms/step - loss: 0.2006 - accuracy: 0.9719
2021-12-08 17:15:14.717552: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
5/5 [==============================] - 1s 4ms/step - loss: 1.4553 - accuracy: 0.5781
Loss 1.4552843570709229, Accuracy 0.578125
2021-12-08 17:15:15.862684: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

התאם אישית את האימון וכתוב לולאה משלך

אם דגמי Keras עובדים בשבילך, אבל אתה צריך יותר גמישות ושליטה בשלב האימון או לולאות האימון החיצוניות, אתה יכול ליישם את שלבי האימון שלך או אפילו לולאות אימון שלמות. עיין במדריך Keras על fit אישית למידע נוסף.

אתה יכול גם ליישם דברים רבים בתור tf.keras.callbacks.Callback .

לשיטה זו יש רבים מהיתרונות שהוזכרו קודם לכן , אך נותנת לך שליטה על צעד הרכבת ואפילו על הלולאה החיצונית.

ישנם שלושה שלבים ללולאת אימון סטנדרטית:

  1. חזור על מחולל Python או tf.data.Dataset כדי לקבל אצווה של דוגמאות.
  2. השתמש tf.GradientTape כדי לאסוף מעברי צבע.
  3. השתמש באחד מ- tf.keras.optimizers כדי להחיל עדכוני משקל על משתני המודל.

זכור:

  • כלול תמיד ארגומנט training על שיטת call של שכבות ומודלים עם תת-מחלקות.
  • הקפד לקרוא למודל עם ארגומנט training מוגדר כהלכה.
  • בהתאם לשימוש, ייתכן שמשתני מודל לא יהיו קיימים עד שהמודל יופעל על אצווה של נתונים.
  • אתה צריך לטפל באופן ידני בדברים כמו הפסדי רגולציה עבור המודל.

אין צורך להפעיל מאתחלים משתנים או להוסיף תלות בקרה ידנית. tf.function מטפלת בתלות בקרה אוטומטית ובאתחול משתנה ביצירה עבורך.

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.02),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10)
])

optimizer = tf.keras.optimizers.Adam(0.001)
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

@tf.function
def train_step(inputs, labels):
  with tf.GradientTape() as tape:
    predictions = model(inputs, training=True)
    regularization_loss=tf.math.add_n(model.losses)
    pred_loss=loss_fn(labels, predictions)
    total_loss=pred_loss + regularization_loss

  gradients = tape.gradient(total_loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))

for epoch in range(NUM_EPOCHS):
  for inputs, labels in train_data:
    train_step(inputs, labels)
  print("Finished epoch", epoch)
2021-12-08 17:15:16.714849: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Finished epoch 0
2021-12-08 17:15:17.097043: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Finished epoch 1
2021-12-08 17:15:17.502480: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Finished epoch 2
2021-12-08 17:15:17.873701: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Finished epoch 3
Finished epoch 4
2021-12-08 17:15:18.344196: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

נצל את היתרונות של tf.function עם זרימת בקרת Python

tf.function מספק דרך להמיר זרימת בקרה תלוית נתונים למקבילות במצב גרף כמו 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

  @tf.function(input_signature=[tf.TensorSpec(dtype=tf.float32, shape=[None, None, 3])])
  def call(self, input_data):

    # [batch, time, features] -> [time, batch, features]
    input_data = tf.transpose(input_data, [1, 0, 2])
    timesteps =  tf.shape(input_data)[0]
    batch_size = tf.shape(input_data)[1]
    outputs = tf.TensorArray(tf.float32, timesteps)
    state = self.cell.get_initial_state(batch_size = batch_size, dtype=tf.float32)
    for i in tf.range(timesteps):
      output, state = self.cell(input_data[i], state)
      outputs = outputs.write(i, output)
    return tf.transpose(outputs.stack(), [1, 0, 2]), state
lstm_cell = tf.keras.layers.LSTMCell(units = 13)

my_rnn = DynamicRNN(lstm_cell)
outputs, state = my_rnn(tf.random.normal(shape=[10,20,3]))
print(outputs.shape)
(10, 20, 13)

קרא את מדריך tf.function למידע נוסף.

מדדים והפסדים בסגנון חדש

מדדים והפסדים הם שניהם אובייקטים שפועלים בשקיקה וגם ב- tf.function s.

אובייקט אובדן ניתן להתקשרות, ומצפה ל- ( y_true , y_pred ) כארגומנטים:

cce = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
cce([[1, 0]], [[-1.0,3.0]]).numpy()
4.01815

השתמש במדדים כדי לאסוף ולהציג נתונים

אתה יכול להשתמש ב- tf.metrics כדי לצבור נתונים וב- tf.summary כדי לרשום סיכומים ולהפנות אותם לכותב באמצעות מנהל הקשר. הסיכומים נשלחים ישירות לכותב מה שאומר שעליך לספק את ערך step באתר הקריאה.

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

השתמש ב-API של tf.summary כדי לכתוב נתוני סיכום להדמיה ב-TensorBoard. למידע נוסף, קרא את מדריך tf.summary .

# Create the metrics
loss_metric = tf.keras.metrics.Mean(name='train_loss')
accuracy_metric = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')

@tf.function
def train_step(inputs, labels):
  with tf.GradientTape() as tape:
    predictions = model(inputs, training=True)
    regularization_loss=tf.math.add_n(model.losses)
    pred_loss=loss_fn(labels, predictions)
    total_loss=pred_loss + regularization_loss

  gradients = tape.gradient(total_loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  # Update the metrics
  loss_metric.update_state(total_loss)
  accuracy_metric.update_state(labels, predictions)


for epoch in range(NUM_EPOCHS):
  # Reset the metrics
  loss_metric.reset_states()
  accuracy_metric.reset_states()

  for inputs, labels in train_data:
    train_step(inputs, labels)
  # Get the metric results
  mean_loss=loss_metric.result()
  mean_accuracy = accuracy_metric.result()

  print('Epoch: ', epoch)
  print('  loss:     {:.3f}'.format(mean_loss))
  print('  accuracy: {:.3f}'.format(mean_accuracy))
2021-12-08 17:15:19.339736: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Epoch:  0
  loss:     0.142
  accuracy: 0.991
2021-12-08 17:15:19.781743: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Epoch:  1
  loss:     0.125
  accuracy: 0.997
2021-12-08 17:15:20.219033: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Epoch:  2
  loss:     0.110
  accuracy: 0.997
2021-12-08 17:15:20.598085: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Epoch:  3
  loss:     0.099
  accuracy: 0.997
Epoch:  4
  loss:     0.085
  accuracy: 1.000
2021-12-08 17:15:20.981787: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

שמות מדדים של קרס

דגמי Keras עקביים בטיפול בשמות מדדים. כאשר אתה מעביר מחרוזת ברשימת המדדים, המחרוזת המדויקת משמשת name המדד . שמות אלו גלויים באובייקט ההיסטוריה המוחזר על ידי model.fit , וביומנים המועברים ל- keras.callbacks . מוגדר למחרוזת שהעברת ברשימת המדדים.

model.compile(
    optimizer = tf.keras.optimizers.Adam(0.001),
    loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics = ['acc', 'accuracy', tf.keras.metrics.SparseCategoricalAccuracy(name="my_accuracy")])
history = model.fit(train_data)
5/5 [==============================] - 1s 5ms/step - loss: 0.0963 - acc: 0.9969 - accuracy: 0.9969 - my_accuracy: 0.9969
2021-12-08 17:15:21.942940: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
history.history.keys()
dict_keys(['loss', 'acc', 'accuracy', 'my_accuracy'])

איתור באגים

השתמש בביצוע נלהב כדי להפעיל את הקוד שלך שלב אחר שלב כדי לבדוק צורות, סוגי נתונים וערכים. ממשקי 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]

זה עובד גם בתוך דגמי Keras וממשקי API אחרים התומכים בביצוע נלהב:

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]))

הערות:

אל תשמור tf.Tensors בחפצים שלך

אובייקטים טנסוריים אלה עשויים להיווצר ב- tf.function או בהקשר להוט, והטנסורים הללו מתנהגים אחרת. השתמש תמיד ב- tf.Tensor s רק עבור ערכי ביניים.

כדי לעקוב אחר מצב, השתמש ב- tf.Variable s מכיוון שהם תמיד ניתנים לשימוש משני ההקשרים. קרא את המדריך tf.Variable למידע נוסף.

משאבים וקריאה נוספת