ML Community Day คือวันที่ 9 พฤศจิกายน! ร่วมกับเราสำหรับการปรับปรุงจาก TensorFlow, JAX และอื่น ๆ เรียนรู้เพิ่มเติม

เทนเซอร์โฟลว์ที่มีประสิทธิภาพ 2

ดูบน TensorFlow.org ทำงานใน Google Colab ดูบน GitHub ดาวน์โหลดโน๊ตบุ๊ค

ภาพรวม

คู่มือนี้แสดงรายการแนวทางปฏิบัติที่ดีที่สุดในการเขียนโค้ดโดยใช้ TensorFlow 2 (TF2) โปรดดูที่ ส่วนโยกย้ายของคู่มือ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการย้ายรหัส TF1.x ของคุณเพื่อ TF2

ติดตั้ง

นำเข้า TensorFlow และการอ้างอิงอื่นๆ สำหรับตัวอย่างในคู่มือนี้

import tensorflow as tf
import tensorflow_datasets as tfds

คำแนะนำสำหรับ TensorFlow 2 . ที่เป็นสำนวน

รีแฟคเตอร์โค้ดของคุณเป็นโมดูลที่เล็กลง

แนวปฏิบัติที่ดีคือการปรับโครงสร้างโค้ดของคุณให้เป็นฟังก์ชันขนาดเล็กลงซึ่งเรียกว่าตามความจำเป็น เพื่อประสิทธิภาพที่ดีที่สุดคุณควรพยายามที่จะตกแต่งบล็อกที่ใหญ่ที่สุดของการคำนวณที่คุณสามารถใน tf.function (หมายเหตุว่าฟังก์ชั่นที่เรียกว่างูหลามที่ซ้อนกันโดย tf.function ไม่จำเป็นต้องใช้ของประดับตกแต่งของตัวเองต่างหากถ้าคุณต้องการที่จะใช้ที่แตกต่างกัน jit_compile ตั้งค่าสำหรับ tf.function ) ขึ้นอยู่กับกรณีการใช้งานของคุณ นี่อาจเป็นขั้นตอนการฝึกอบรมหลายขั้นตอน หรือแม้แต่วงการฝึกทั้งหมดของคุณ สำหรับกรณีการใช้งานการอนุมาน อาจเป็นการส่งต่อรุ่นเดียว

ปรับอัตราการเรียนรู้เริ่มต้นสำหรับบาง tf.keras.optimizer s

เครื่องมือเพิ่มประสิทธิภาพ Keras บางตัวมีอัตราการเรียนรู้ที่แตกต่างกันใน TF2 หากคุณเห็นการเปลี่ยนแปลงพฤติกรรมการบรรจบกันของแบบจำลองของคุณ ให้ตรวจสอบอัตราการเรียนรู้เริ่มต้น

มีการเปลี่ยนแปลงที่ไม่เป็น optimizers.SGD , optimizers.Adam หรือ optimizers.RMSprop

อัตราการเรียนรู้เริ่มต้นต่อไปนี้มีการเปลี่ยนแปลง:

ใช้ tf.Module และชั้น Keras การจัดการตัวแปร

tf.Module และ tf.keras.layers.Layer เสนอ s สะดวก variables และ trainable_variables คุณสมบัติซึ่งรวบรวมขึ้นซ้ำขึ้นอยู่กับตัวแปรทั้งหมด ทำให้ง่ายต่อการจัดการตัวแปรในเครื่องไปยังตำแหน่งที่ถูกใช้

ชั้น Keras / รุ่นสืบทอดจาก tf.train.Checkpointable และบูรณาการกับ @tf.function ซึ่งจะทำให้มันเป็นไปได้ที่ด่านโดยตรงหรือส่งออก SavedModels จากวัตถุ Keras คุณไม่จำเป็นต้องใช้ Keras' Model.fit API เพื่อใช้ประโยชน์จากการผสานรวมเหล่านี้

อ่านส่วนที่เกี่ยวกับ การเรียนรู้การถ่ายโอนและการปรับจูน ในคู่มือ Keras เพื่อเรียนรู้วิธีการเก็บรวบรวมย่อยของตัวแปรที่เกี่ยวข้องโดยใช้ Keras

รวม tf.data.Dataset และ tf.function

TensorFlow ชุดข้อมูล แพคเกจ ( 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-09-22 22:13:17.284138: 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 เป็นวิธีที่ดีที่สุดในการสตรีมข้อมูลการฝึกอบรมจากดิสก์ ชุดข้อมูลมี iterables (ไม่ iterators) และการทำงานเช่นเดียวกับงูหลาม iterables อื่น ๆ ในการดำเนินการความกระตือรือร้น คุณเต็มสามารถใช้ชุดข้อมูล async prefetching / สตรีมมิ่งคุณสมบัติโดยการตัดรหัสของคุณใน 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 API คุณจะไม่ต้องกังวลเกี่ยวกับการทำซ้ำชุดข้อมูล

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

ใช้ลูปการฝึกของ Keras

ถ้าคุณไม่จำเป็นต้องควบคุมระดับต่ำของกระบวนการฝึกอบรมของคุณโดยใช้ Keras' ในตัว fit , evaluate และ predict วิธีการที่จะแนะนำ เมธอดเหล่านี้จัดเตรียมอินเทอร์เฟซแบบเดียวกันเพื่อฝึกโมเดลโดยไม่คำนึงถึงการใช้งาน (ตามลำดับ ฟังก์ชัน หรือคลาสย่อย)

ข้อดีของวิธีการเหล่านี้ ได้แก่ :

  • พวกเขายอมรับอาร์เรย์ Numpy, Python กำเนิดและ tf.data.Datasets
  • พวกเขาใช้การทำให้เป็นมาตรฐานและการสูญเสียการเปิดใช้งานโดยอัตโนมัติ
  • พวกเขาสนับสนุน tf.distribute ที่รหัสการฝึกอบรมยังคงเหมือนเดิม โดยไม่คำนึงถึงการกำหนดค่าฮาร์ดแวร์
  • พวกเขาสนับสนุน callables โดยพลการเป็นการสูญเสียและตัวชี้วัด
  • พวกเขาสนับสนุนการเรียกกลับเช่น tf.keras.callbacks.TensorBoard และเรียกกลับที่กำหนดเอง
  • พวกมันมีประสิทธิภาพ โดยอัตโนมัติโดยใช้กราฟ 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 9ms/step - loss: 1.5774 - accuracy: 0.5063
Epoch 2/5
2021-09-22 22:13:26.932626: 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.4498 - accuracy: 0.9125
Epoch 3/5
2021-09-22 22:13:27.323101: 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.2929 - accuracy: 0.9563
Epoch 4/5
2021-09-22 22:13:27.717803: 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.2055 - accuracy: 0.9875
Epoch 5/5
2021-09-22 22:13:28.088985: 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.1669 - accuracy: 0.9937
2021-09-22 22:13:28.458529: 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 3ms/step - loss: 1.6056 - accuracy: 0.6500
Loss 1.6056102514266968, Accuracy 0.6499999761581421
2021-09-22 22:13:28.956635: 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. ย้ำกว่ากำเนิดงูหลามหรือ tf.data.Dataset ที่จะได้รับสำหรับกระบวนการของตัวอย่าง
  2. ใช้ tf.GradientTape การไล่ระดับสีการเก็บรวบรวม
  3. ใช้หนึ่งใน tf.keras.optimizers ใช้การปรับปรุงน้ำหนักกับตัวแปรแบบของ

จดจำ:

  • เสมอรวมถึง training การโต้แย้งเกี่ยวกับ call วิธีการของชั้น subclassed และรูปแบบ
  • ให้แน่ใจว่าจะเรียกรูปแบบที่มี 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-09-22 22:13:29.878252: 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-09-22 22:13:30.266807: 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-09-22 22:13:30.626589: 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-09-22 22:13:31.040058: 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-09-22 22:13:31.417637: 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 กับการควบคุมการไหลหลาม

tf.function มีวิธีการแปลงการควบคุมการไหลขึ้นอยู่กับข้อมูลเข้าสู่เทียบเท่ากราฟโหมดเหมือน tf.cond และ tf.while_loop

ตำแหน่งทั่วไปหนึ่งที่ซึ่งโฟลว์การควบคุมที่ขึ้นกับข้อมูลปรากฏขึ้นอยู่ในแบบจำลองลำดับ tf.keras.layers.RNN wraps เซลล์ RNN ช่วยให้คุณทั้งแบบคงที่หรือแบบไดนามิกเหยียดเกิดซ้ำ ตัวอย่างเช่น คุณสามารถใช้ไดนามิก unroll ใหม่ได้ดังนี้

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

วัตถุที่สูญเสียเป็น callable และคาดว่า ( 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 มูลค่า 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.summary API เพื่อเขียนข้อมูลสรุปสำหรับการแสดงใน 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-09-22 22:13:32.370558: 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.143
  accuracy: 0.997
2021-09-22 22:13:32.752675: 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.119
  accuracy: 0.997
2021-09-22 22:13:33.122889: 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.106
  accuracy: 0.997
2021-09-22 22:13:33.522935: 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.089
  accuracy: 1.000
Epoch:  4
  loss:     0.079
  accuracy: 1.000
2021-09-22 22:13:33.899024: 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 มีความสอดคล้องกันเกี่ยวกับการจัดการชื่อเมตริก เมื่อคุณผ่านสตริงในรายการของตัวชี้วัดว่าสตริงที่แน่นอนจะถูกใช้เป็นตัวชี้วัดของ 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.0962 - acc: 0.9969 - accuracy: 0.9969 - my_accuracy: 0.9969
2021-09-22 22:13:34.802566: 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'])

แก้จุดบกพร่อง

ใช้การดำเนินการอย่างกระตือรือร้นเพื่อรันโค้ดของคุณทีละขั้นตอนเพื่อตรวจสอบรูปร่าง ประเภทข้อมูล และค่า APIs บางอย่างเช่น 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 คู่มือ เพื่อเรียนรู้เพิ่มเติม

แหล่งข้อมูลและการอ่านเพิ่มเติม

  • อ่าน TF2 คู่มือ และ บทเรียน ที่จะเรียนรู้เพิ่มเติมเกี่ยวกับวิธีการใช้ TF2

  • หากคุณเคยใช้ TF1.x มาก่อน ขอแนะนำเป็นอย่างยิ่งให้คุณย้ายรหัสของคุณไปยัง TF2 อ่าน คู่มือการโยกย้าย เพื่อเรียนรู้เพิ่มเติม