TensorFlow 2.x ใน TFX

TensorFlow 2.0 เปิดตัวในปี 2019 โดยมี การผสานรวม Keras อย่างแน่นหนา การดำเนินการอย่างกระตือรือร้น ตามค่าเริ่มต้น และ การดำเนินการฟังก์ชัน Pythonic ท่ามกลาง คุณสมบัติและการปรับปรุงใหม่ อื่นๆ

คู่มือนี้ให้ภาพรวมทางเทคนิคที่ครอบคลุมของ TF 2.x ใน TFX

จะใช้เวอร์ชันไหน?

TFX เข้ากันได้กับ TensorFlow 2.x และ API ระดับสูงที่มีอยู่ใน TensorFlow 1.x (โดยเฉพาะตัวประมาณค่า) ยังคงทำงานต่อไป

เริ่มโปรเจ็กต์ใหม่ใน TensorFlow 2.x

เนื่องจาก TensorFlow 2.x ยังคงความสามารถระดับสูงของ TensorFlow 1.x ไว้ การใช้เวอร์ชันเก่ากับโปรเจ็กต์ใหม่จึงไม่มีประโยชน์ แม้ว่าคุณจะไม่ได้วางแผนที่จะใช้ฟีเจอร์ใหม่ก็ตาม

ดังนั้น หากคุณกำลังเริ่มโปรเจ็กต์ TFX ใหม่ เราขอแนะนำให้คุณใช้ TensorFlow 2.x คุณอาจต้องการอัปเดตโค้ดของคุณในภายหลังเมื่อมีการรองรับ Keras และฟีเจอร์ใหม่อื่นๆ อย่างเต็มรูปแบบ และขอบเขตของการเปลี่ยนแปลงจะถูกจำกัดมากขึ้นหากคุณเริ่มต้นด้วย TensorFlow 2.x แทนที่จะพยายามอัปเกรดจาก TensorFlow 1.x ใน อนาคต

การแปลงโปรเจ็กต์ที่มีอยู่เป็น TensorFlow 2.x

โค้ดที่เขียนสำหรับ TensorFlow 1.x ส่วนใหญ่เข้ากันได้กับ TensorFlow 2.x และจะยังคงทำงานใน TFX ต่อไป

อย่างไรก็ตาม หากคุณต้องการใช้ประโยชน์จากการปรับปรุงและคุณลักษณะใหม่ๆ เมื่อพร้อมใช้งานใน TF 2.x คุณสามารถทำตาม คำแนะนำในการโยกย้ายไปยัง TF 2.x

ตัวประมาณค่า

Estimator API ยังคงอยู่ใน TensorFlow 2.x แต่ไม่ใช่จุดเน้นของคุณสมบัติและการพัฒนาใหม่ๆ โค้ดที่เขียนใน TensorFlow 1.x หรือ 2.x โดยใช้ Estimators จะยังคงทำงานตามที่คาดไว้ใน TFX

นี่คือตัวอย่าง TFX แบบ end-to-end โดยใช้ตัวประมาณค่าล้วนๆ: ตัวอย่างแท็กซี่ (ตัวประมาณ)

Keras พร้อม model_to_estimator

คุณสามารถรวมโมเดล Keras ได้ด้วยฟังก์ชัน tf.keras.estimator.model_to_estimator ซึ่งช่วยให้โมเดลทำงานเสมือนเป็นตัวประมาณค่าได้ หากต้องการใช้สิ่งนี้:

  1. สร้างโมเดล Keras
  2. ส่งโมเดลที่คอมไพล์แล้วไปที่ model_to_estimator
  3. ใช้ผลลัพธ์ของ model_to_estimator ใน Trainer ซึ่งเป็นวิธีที่คุณใช้ประมาณการโดยทั่วไป
# Build a Keras model.
def _keras_model_builder():
  """Creates a Keras model."""
  ...

  model = tf.keras.Model(inputs=inputs, outputs=output)
  model.compile()

  return model


# Write a typical trainer function
def trainer_fn(trainer_fn_args, schema):
  """Build the estimator, using model_to_estimator."""
  ...

  # Model to estimator
  estimator = tf.keras.estimator.model_to_estimator(
      keras_model=_keras_model_builder(), config=run_config)

  return {
      'estimator': estimator,
      ...
  }

นอกเหนือจากไฟล์โมดูลผู้ใช้ของ Trainer แล้วไปป์ไลน์ที่เหลือยังคงไม่เปลี่ยนแปลง

Native Keras (เช่น Keras ที่ไม่มี model_to_estimator )

ตัวอย่างและ Colab

นี่คือตัวอย่างบางส่วนที่มี Keras ดั้งเดิม:

นอกจากนี้เรายังมี Keras Colab ต่อองค์ประกอบด้วย

ส่วนประกอบ TFX

ส่วนต่อไปนี้จะอธิบายว่าส่วนประกอบ TFX ที่เกี่ยวข้องรองรับ Keras ดั้งเดิมได้อย่างไร

แปลงร่าง

ปัจจุบันการแปลงมีการสนับสนุนรุ่นทดลองสำหรับโมเดล Keras

องค์ประกอบ Transform นั้นสามารถใช้กับ Keras ดั้งเดิมได้โดยไม่มีการเปลี่ยนแปลง คำจำกัดความ preprocessing_fn ยังคงเหมือนเดิม โดยใช้ TensorFlow และ tf.Transform ops

ฟังก์ชันการให้บริการและฟังก์ชัน eval มีการเปลี่ยนแปลงสำหรับ Keras ดั้งเดิม รายละเอียดจะมีการหารือในส่วนผู้ฝึกอบรมและผู้ประเมินดังต่อไปนี้

เทรนเนอร์

ในการกำหนดค่า Keras ดั้งเดิม จะต้องตั้งค่า GenericExecutor สำหรับส่วนประกอบ Trainer เพื่อแทนที่ตัวดำเนินการตามค่าเริ่มต้นของ Estimator สำหรับรายละเอียด โปรดตรวจสอบ ที่นี่

ไฟล์โมดูล Keras พร้อม Transform

ไฟล์โมดูลการฝึกอบรมจะต้องมี run_fn ซึ่งจะถูกเรียกโดย GenericExecutor ซึ่ง Keras run_fn ทั่วไปจะมีลักษณะดังนี้:

def run_fn(fn_args: TrainerFnArgs):
  """Train the model based on given args.

  Args:
    fn_args: Holds args used to train the model as name/value pairs.
  """
  tf_transform_output = tft.TFTransformOutput(fn_args.transform_output)

  # Train and eval files contains transformed examples.
  # _input_fn read dataset based on transformed schema from tft.
  train_dataset = _input_fn(fn_args.train_files, fn_args.data_accessor,
                            tf_transform_output.transformed_metadata.schema)
  eval_dataset = _input_fn(fn_args.eval_files, fn_args.data_accessor,
                           tf_transform_output.transformed_metadata.schema)

  model = _build_keras_model()

  model.fit(
      train_dataset,
      steps_per_epoch=fn_args.train_steps,
      validation_data=eval_dataset,
      validation_steps=fn_args.eval_steps)

  signatures = {
      'serving_default':
          _get_serve_tf_examples_fn(model,
                                    tf_transform_output).get_concrete_function(
                                        tf.TensorSpec(
                                            shape=[None],
                                            dtype=tf.string,
                                            name='examples')),
  }
  model.save(fn_args.serving_model_dir, save_format='tf', signatures=signatures)

ใน run_fn ด้านบน จำเป็นต้องมีลายเซ็นการให้บริการเมื่อส่งออกโมเดลที่ผ่านการฝึกอบรม เพื่อให้โมเดลนั้นสามารถนำตัวอย่างดิบมาทำนายได้ ฟังก์ชั่นการให้บริการทั่วไปจะมีลักษณะดังนี้:

def _get_serve_tf_examples_fn(model, tf_transform_output):
  """Returns a function that parses a serialized tf.Example."""

  # the layer is added as an attribute to the model in order to make sure that
  # the model assets are handled correctly when exporting.
  model.tft_layer = tf_transform_output.transform_features_layer()

  @tf.function
  def serve_tf_examples_fn(serialized_tf_examples):
    """Returns the output to be used in the serving signature."""
    feature_spec = tf_transform_output.raw_feature_spec()
    feature_spec.pop(_LABEL_KEY)
    parsed_features = tf.io.parse_example(serialized_tf_examples, feature_spec)

    transformed_features = model.tft_layer(parsed_features)

    return model(transformed_features)

  return serve_tf_examples_fn

ในฟังก์ชันการให้บริการด้านบน การแปลง tf.Transform จะต้องนำไปใช้กับข้อมูลดิบเพื่อการอนุมาน โดยใช้เลเยอร์ tft.TransformFeaturesLayer _serving_input_receiver_fn ก่อนหน้าซึ่งจำเป็นสำหรับตัวประมาณค่าจะไม่จำเป็นต้องใช้กับ Keras อีกต่อไป

ไฟล์โมดูล Keras ที่ไม่มีการแปลง

สิ่งนี้คล้ายกับไฟล์โมดูลที่แสดงด้านบน แต่ไม่มีการแปลง:

def _get_serve_tf_examples_fn(model, schema):

  @tf.function
  def serve_tf_examples_fn(serialized_tf_examples):
    feature_spec = _get_raw_feature_spec(schema)
    feature_spec.pop(_LABEL_KEY)
    parsed_features = tf.io.parse_example(serialized_tf_examples, feature_spec)
    return model(parsed_features)

  return serve_tf_examples_fn


def run_fn(fn_args: TrainerFnArgs):
  schema = io_utils.parse_pbtxt_file(fn_args.schema_file, schema_pb2.Schema())

  # Train and eval files contains raw examples.
  # _input_fn reads the dataset based on raw data schema.
  train_dataset = _input_fn(fn_args.train_files, fn_args.data_accessor, schema)
  eval_dataset = _input_fn(fn_args.eval_files, fn_args.data_accessor, schema)

  model = _build_keras_model()

  model.fit(
      train_dataset,
      steps_per_epoch=fn_args.train_steps,
      validation_data=eval_dataset,
      validation_steps=fn_args.eval_steps)

  signatures = {
      'serving_default':
          _get_serve_tf_examples_fn(model, schema).get_concrete_function(
              tf.TensorSpec(shape=[None], dtype=tf.string, name='examples')),
  }
  model.save(fn_args.serving_model_dir, save_format='tf', signatures=signatures)
tf.distribute.Strategy

ในขณะนี้ TFX รองรับเฉพาะกลยุทธ์ของผู้ปฏิบัติงานคนเดียว (เช่น MirroredStrategy , OneDeviceStrategy )

หากต้องการใช้กลยุทธ์การกระจาย ให้สร้าง tf.distribute.Strategy ที่เหมาะสม และย้ายการสร้างและการคอมไพล์โมเดล Keras ภายในขอบเขตกลยุทธ์

ตัวอย่างเช่น แทนที่ model = _build_keras_model() ด้วย:

  mirrored_strategy = tf.distribute.MirroredStrategy()
  with mirrored_strategy.scope():
    model = _build_keras_model()

  # Rest of the code can be unchanged.
  model.fit(...)

หากต้องการตรวจสอบอุปกรณ์ (CPU/GPU) ที่ใช้โดย MirroredStrategy ให้เปิดใช้งานการบันทึกเทนเซอร์โฟลว์ระดับข้อมูล:

import logging
logging.getLogger("tensorflow").setLevel(logging.INFO)

และคุณควรจะเห็น Using MirroredStrategy with devices (...) ในบันทึก

ผู้ประเมิน

ใน TFMA v0.2x นั้น ModelValidator และ Evaluator ได้ถูกรวมเข้าด้วยกันเป็น องค์ประกอบ Evaluator ใหม่ เพียงตัวเดียว องค์ประกอบ Evaluator ใหม่สามารถทำการประเมินทั้งแบบจำลองเดียวและตรวจสอบความถูกต้องของแบบจำลองปัจจุบันเมื่อเปรียบเทียบกับรุ่นก่อนหน้า ด้วยการเปลี่ยนแปลงนี้ ส่วนประกอบ Pusher จะใช้ผลการให้พรจาก Evaluator แทน ModelValidator

Evaluator ใหม่รองรับโมเดล Keras เช่นเดียวกับโมเดล Estimator _eval_input_receiver_fn และโมเดลที่บันทึกไว้ eval ซึ่งจำเป็นก่อนหน้านี้จะไม่จำเป็นต้องใช้กับ Keras อีกต่อไป เนื่องจากตอนนี้ Evaluator ใช้ SavedModel เดียวกันกับที่ใช้ในการให้บริการ

ดูผู้ประเมินสำหรับข้อมูลเพิ่มเติม