TensorBoard Scalars: การบันทึกเมตริกการฝึกอบรมใน Keras

ดูบน TensorFlow.org ทำงานใน Google Colab ดูแหล่งที่มาบน GitHub

ภาพรวม

แมชชีนเลิร์นนิงมักเกี่ยวข้องกับการทำความเข้าใจเมตริกหลัก เช่น การสูญเสีย และการเปลี่ยนแปลงเมื่อการฝึกอบรมดำเนินไป ตัวชี้วัดเหล่านี้สามารถช่วยให้คุณเข้าใจว่าคุณกำลัง overfitting เช่นหรือถ้าคุณไม่จำเป็นในการฝึกอบรมกำลังนานเกินไป คุณอาจต้องการเปรียบเทียบเมตริกเหล่านี้ในการรันการฝึกต่างๆ เพื่อช่วยดีบักและปรับปรุงโมเดลของคุณ

TensorBoard ของสเกลาแดชบอร์ดช่วยให้คุณเห็นภาพตัวชี้วัดเหล่านี้โดยใช้ API ที่เรียบง่ายกับความพยายามน้อยมาก บทช่วยสอนนี้นำเสนอตัวอย่างพื้นฐานที่จะช่วยให้คุณเรียนรู้วิธีใช้ API เหล่านี้กับ TensorBoard เมื่อพัฒนาโมเดล Keras ของคุณ คุณจะได้เรียนรู้วิธีใช้ Keras TensorBoard callback และ TensorFlow Summary APIs เพื่อแสดงภาพสเกลาร์เริ่มต้นและกำหนดเอง

ติดตั้ง

# Load the TensorBoard notebook extension.
%load_ext tensorboard
from datetime import datetime
from packaging import version

import tensorflow as tf
from tensorflow import keras

import numpy as np

print("TensorFlow version: ", tf.__version__)
assert version.parse(tf.__version__).release[0] >= 2, \
    "This notebook requires TensorFlow 2.0 or above."
TensorFlow version:  2.2

ตั้งค่าข้อมูลสำหรับการถดถอยอย่างง่าย

ขณะนี้คุณกำลังจะใช้ Keras ในการคำนวณการถดถอยคือหาสิ่งที่ดีที่สุดของสายเหมาะสำหรับชุดข้อมูลที่จับคู่ (ในขณะที่ใช้เครือข่ายประสาทและเชื้อสายลาด overkill สำหรับชนิดของปัญหานี้ ก็จะทำให้เป็นตัวอย่างที่ง่ายมากที่จะเข้าใจ.)

คุณกำลังจะใช้ TensorBoard การสังเกตวิธีการฝึกอบรมและการสูญเสียการทดสอบการเปลี่ยนแปลงทั่ว epochs หวังว่าคุณจะเห็นการสูญเสียการฝึกอบรมและการทดสอบลดลงเมื่อเวลาผ่านไปและคงที่

ครั้งแรกที่สร้าง 1000 จุดข้อมูลคร่าว ๆ ตามแนวการ y = 0.5x + 2 แยกจุดข้อมูลเหล่านี้เป็นชุดการฝึกและการทดสอบ ความหวังของคุณคือโครงข่ายประสาทเรียนรู้ความสัมพันธ์นี้

data_size = 1000
# 80% of the data is for training.
train_pct = 0.8

train_size = int(data_size * train_pct)

# Create some input data between -1 and 1 and randomize it.
x = np.linspace(-1, 1, data_size)
np.random.shuffle(x)

# Generate the output data.
# y = 0.5x + 2 + noise
y = 0.5 * x + 2 + np.random.normal(0, 0.05, (data_size, ))

# Split into test and train pairs.
x_train, y_train = x[:train_size], y[:train_size]
x_test, y_test = x[train_size:], y[train_size:]

การฝึกอบรมแบบจำลองและการสูญเสียการบันทึก

ตอนนี้คุณพร้อมที่จะกำหนด ฝึกฝน และประเมินโมเดลของคุณแล้ว

เข้าสู่ระบบเกลาสูญเสียในขณะที่คุณฝึกคุณจะทำต่อไปนี้:

  1. สร้าง Keras โทรกลับ TensorBoard
  2. ระบุไดเรกทอรีบันทึก
  3. ผ่านการเรียกกลับ TensorBoard เพื่อ Keras' Model.fit ()

TensorBoard อ่านข้อมูลบันทึกจากลำดับชั้นของไดเรกทอรีบันทึก ในสมุดบันทึกนี้ไดเรกทอรีล็อกราก logs/scalars , suffixed โดยไดเรกทอรีย่อย timestamped ไดเร็กทอรีย่อยการประทับเวลาช่วยให้คุณสามารถระบุและเลือกการฝึกปฏิบัติได้อย่างง่ายดายในขณะที่คุณใช้ TensorBoard และทำซ้ำกับโมเดลของคุณ

logdir = "logs/scalars/" + datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = keras.callbacks.TensorBoard(log_dir=logdir)

model = keras.models.Sequential([
    keras.layers.Dense(16, input_dim=1),
    keras.layers.Dense(1),
])

model.compile(
    loss='mse', # keras.losses.mean_squared_error
    optimizer=keras.optimizers.SGD(learning_rate=0.2),
)

print("Training ... With default parameters, this takes less than 10 seconds.")
training_history = model.fit(
    x_train, # input
    y_train, # output
    batch_size=train_size,
    verbose=0, # Suppress chatty output; use Tensorboard instead
    epochs=100,
    validation_data=(x_test, y_test),
    callbacks=[tensorboard_callback],
)

print("Average test loss: ", np.average(training_history.history['loss']))
Training ... With default parameters, this takes less than 10 seconds.
Average test loss:  0.05271831926424056

ตรวจสอบการสูญเสียโดยใช้ TensorBoard

ตอนนี้ เริ่ม TensorBoard โดยระบุไดเร็กทอรีบันทึกของรูทที่คุณใช้ด้านบน

รอสักครู่เพื่อให้ UI ของ TensorBoard หมุน

%tensorboard --logdir logs/scalars

คุณอาจเห็น TensorBoard แสดงข้อความ "ไม่มีแดชบอร์ดที่ใช้งานสำหรับชุดข้อมูลปัจจุบัน" นั่นเป็นเพราะยังไม่ได้บันทึกข้อมูลการบันทึกเริ่มต้น เมื่อการฝึกดำเนินไป โมเดล Keras จะเริ่มบันทึกข้อมูล TensorBoard จะรีเฟรชเป็นระยะและแสดงเมตริกสเกลาร์ของคุณ หากคุณใจร้อน คุณสามารถแตะลูกศรรีเฟรชที่ด้านบนขวา

ในขณะที่คุณดูความคืบหน้าของการฝึก ให้สังเกตว่าทั้งการสูญเสียการฝึกอบรมและการตรวจสอบลดลงอย่างรวดเร็ว และยังคงมีเสถียรภาพ อันที่จริง คุณสามารถหยุดการฝึกได้หลังจากผ่านไป 25 ยุค เพราะการฝึกนั้นไม่ได้ดีขึ้นมากหลังจากนั้น

วางเมาส์เหนือกราฟเพื่อดูจุดข้อมูลที่ต้องการ คุณยังสามารถลองซูมเข้าด้วยเมาส์ของคุณ หรือเลือกบางส่วนเพื่อดูรายละเอียดเพิ่มเติม

สังเกตตัวเลือก "วิ่ง" ทางด้านซ้าย "การวิ่ง" หมายถึงชุดบันทึกจากรอบการฝึก ในกรณีนี้คือผลลัพธ์ของ Model.fit() โดยทั่วไปแล้ว นักพัฒนาจะต้องทดลองและพัฒนาโมเดลของตนไปเรื่อยๆ

ใช้ตัวเลือกการวิ่งเพื่อเลือกการวิ่งเฉพาะ หรือเลือกจากการฝึกหรือการตรวจสอบเท่านั้น การเปรียบเทียบการทำงานจะช่วยให้คุณประเมินว่าโค้ดเวอร์ชันใดแก้ปัญหาของคุณได้ดีกว่า

ตกลง กราฟการสูญเสียของ TensorBoard แสดงให้เห็นว่าการสูญเสียลดลงอย่างต่อเนื่องสำหรับทั้งการฝึกอบรมและการตรวจสอบ จากนั้นจึงทำให้เสถียร นั่นหมายความว่าเมตริกของโมเดลน่าจะดีมาก! มาดูกันว่าโมเดลมีพฤติกรรมอย่างไรในชีวิตจริง

เมื่อได้รับข้อมูลการป้อนข้อมูล (60, 25, 2), เส้น y = 0.5x + 2 ควรผลผลิต (32, 14.5, 3) โมเดลเห็นด้วยหรือไม่?

print(model.predict([60, 25, 2]))
# True values to compare predictions against: 
# [[32.0]
#  [14.5]
#  [ 3.0]]
[[32.234306 ]
 [14.5974245]
 [ 3.0074697]]

ไม่เลว!

การบันทึกสเกลาร์แบบกำหนดเอง

เกิดอะไรขึ้นถ้าคุณต้องการที่จะเข้าสู่ระบบค่าที่กำหนดเองเช่น อัตราการเรียนรู้แบบไดนามิก ? ในการทำเช่นนั้น คุณต้องใช้ TensorFlow Summary API

ฝึกแบบจำลองการถดถอยและบันทึกอัตราการเรียนรู้ที่กำหนดเอง โดยใช้วิธีดังนี้:

  1. สร้างนักเขียนไฟล์โดยใช้ tf.summary.create_file_writer()
  2. กำหนดฟังก์ชันอัตราการเรียนรู้ที่กำหนดเอง นี้จะถูกส่งผ่านไปยัง Keras LearningRateScheduler โทรกลับ
  3. ภายในฟังก์ชั่นอัตราการเรียนรู้การใช้งาน tf.summary.scalar() เพื่อเข้าสู่ระบบการเรียนรู้อัตราที่กำหนดเอง
  4. ผ่านการเรียกกลับ LearningRateScheduler ไปยัง Model.fit()

โดยทั่วไปการเข้าสู่ระบบเกลากำหนดเองคุณต้องใช้ tf.summary.scalar() กับนักเขียนไฟล์ นักเขียนไฟล์เป็นผู้รับผิดชอบในการเขียนข้อมูลสำหรับการทำงานนี้ไปยังไดเรกทอรีที่ระบุไว้และถูกนำมาใช้โดยปริยายเมื่อคุณใช้ tf.summary.scalar()

logdir = "logs/scalars/" + datetime.now().strftime("%Y%m%d-%H%M%S")
file_writer = tf.summary.create_file_writer(logdir + "/metrics")
file_writer.set_as_default()

def lr_schedule(epoch):
  """
  Returns a custom learning rate that decreases as epochs progress.
  """
  learning_rate = 0.2
  if epoch > 10:
    learning_rate = 0.02
  if epoch > 20:
    learning_rate = 0.01
  if epoch > 50:
    learning_rate = 0.005

  tf.summary.scalar('learning rate', data=learning_rate, step=epoch)
  return learning_rate

lr_callback = keras.callbacks.LearningRateScheduler(lr_schedule)
tensorboard_callback = keras.callbacks.TensorBoard(log_dir=logdir)

model = keras.models.Sequential([
    keras.layers.Dense(16, input_dim=1),
    keras.layers.Dense(1),
])

model.compile(
    loss='mse', # keras.losses.mean_squared_error
    optimizer=keras.optimizers.SGD(),
)

training_history = model.fit(
    x_train, # input
    y_train, # output
    batch_size=train_size,
    verbose=0, # Suppress chatty output; use Tensorboard instead
    epochs=100,
    validation_data=(x_test, y_test),
    callbacks=[tensorboard_callback, lr_callback],
)

มาดู TensorBoard กันอีกครั้ง

%tensorboard --logdir logs/scalars

การใช้ "วิ่ง" ตัวเลือกทางด้านซ้ายแจ้งให้ทราบว่าคุณมี <timestamp>/metrics การทำงาน การเลือกการดำเนินการนี้จะแสดงกราฟ "อัตราการเรียนรู้" ที่ให้คุณตรวจสอบความคืบหน้าของอัตราการเรียนรู้ในระหว่างการดำเนินการนี้

คุณยังสามารถเปรียบเทียบเส้นโค้งการฝึกและการสูญเสียการตรวจสอบของการวิ่งนี้กับการวิ่งครั้งก่อนๆ ของคุณได้ คุณอาจสังเกตเห็นว่าตารางอัตราการเรียนรู้ส่งคืนค่าที่ไม่ต่อเนื่อง ทั้งนี้ขึ้นอยู่กับยุค แต่พล็อตอัตราการเรียนรู้อาจดูราบรื่น TensorBoard มีพารามิเตอร์การปรับให้เรียบซึ่งคุณอาจต้องลดเป็นศูนย์เพื่อดูค่าที่ยังไม่ได้ปรับให้เรียบ

รุ่นนี้ทำอย่างไร?

print(model.predict([60, 25, 2]))
# True values to compare predictions against: 
# [[32.0]
#  [14.5]
#  [ 3.0]]
[[32.234013 ]
 [14.5973015]
 [ 3.0074618]]