โมเดลที่บันทึกไว้แบบใช้ซ้ำได้

การแนะนำ

TensorFlow Hub เป็นแหล่งรวบรวม SavedModels สำหรับ TensorFlow 2 รวมถึงทรัพยากรอื่นๆ สามารถโหลด SavedModels กลับเข้าไปในโปรแกรม Python ได้ด้วย obj = hub.load(url) [ เรียนรู้เพิ่มเติม ] อ็อบเจ็กต์ obj ที่ส่งคืนมานั้นเป็นผลลัพธ์จาก tf.saved_model.load() (ดู คู่มือ SavedModel ของ TensorFlow) อ็อบเจ็กต์นี้สามารถมีแอตทริบิวต์ใดๆ ก็ได้ เช่น tf.functions, tf.Variables (ที่เริ่มต้นจากค่าที่ฝึกฝนไว้ล่วงหน้า), ทรัพยากรอื่นๆ และสามารถมีอ็อบเจ็กต์อื่นๆ เพิ่มเติมได้เรื่อยๆ

หน้านี้อธิบายถึงอินเทอร์เฟซที่จะต้องนำไปใช้โดย obj ที่โหลดมา เพื่อนำ กลับมาใช้ใหม่ ในโปรแกรม TensorFlow Python SavedModels ที่สอดคล้องกับอินเทอร์เฟซนี้เรียกว่า Reusable SavedModels

การนำกลับมาใช้ใหม่หมายถึงการสร้างแบบจำลองขนาดใหญ่ขึ้นโดยใช้ obj เป็นพื้นฐาน รวมถึงความสามารถในการปรับแต่งเพิ่มเติม การปรับแต่งเพิ่มเติมหมายถึงการฝึกฝนน้ำหนักใน obj ที่โหลดมาเพิ่มเติมในฐานะส่วนหนึ่งของแบบจำลองโดยรอบ ฟังก์ชันการสูญเสียและตัวเพิ่มประสิทธิภาพจะถูกกำหนดโดยแบบจำลองโดยรอบ obj กำหนดเพียงการแมปอินพุตไปยังแอคติเวชันเอาต์พุต ("การส่งผ่านไปข้างหน้า") ซึ่งอาจรวมถึงเทคนิคต่างๆ เช่น dropout หรือ batch normalization

ทีม TensorFlow Hub แนะนำให้ใช้งานอินเทอร์เฟซ Reusable SavedModel ใน SavedModels ทั้งหมดที่ต้องการนำกลับมาใช้ใหม่ในลักษณะดังกล่าว ยูทิลิตี้หลายอย่างจากไลบรารี tensorflow_hub โดยเฉพาะ hub.KerasLayer ต้องการให้ SavedModels ใช้งานอินเทอร์เฟซนี้

ความสัมพันธ์กับ SignatureDefs

อินเทอร์เฟซนี้ในแง่ของ tf.functions และคุณสมบัติอื่นๆ ของ TF2 นั้นแยกต่างหากจากลายเซ็นของ SavedModel ซึ่งมีให้ใช้งานมาตั้งแต่ TF1 และยังคงใช้ใน TF2 สำหรับการอนุมาน (เช่น การปรับใช้ SavedModels ไปยัง TF Serving หรือ TF Lite) ลายเซ็นสำหรับการอนุมานนั้นไม่แสดงออกได้เพียงพอที่จะรองรับการปรับแต่งอย่างละเอียด และ tf.function ก็มี API Python ที่เป็นธรรมชาติและแสดงออกได้ดีกว่าสำหรับโมเดลที่นำกลับมาใช้ใหม่

ความสัมพันธ์กับไลบรารีการสร้างแบบจำลอง

SavedModel ที่นำกลับมาใช้ใหม่ได้นั้นใช้เฉพาะส่วนประกอบพื้นฐานของ TensorFlow 2 เท่านั้น โดยไม่ขึ้นอยู่กับไลบรารีสร้างโมเดลใดๆ เช่น Keras หรือ Sonnet ซึ่งช่วยให้สามารถนำกลับมาใช้ใหม่ได้ในไลบรารีสร้างโมเดลต่างๆ โดยไม่ต้องพึ่งพาโค้ดสร้างโมเดลเดิม

จะต้องมีการปรับแต่งบ้างเล็กน้อยเพื่อโหลด SavedModels ที่นำกลับมาใช้ใหม่ได้ลงในหรือบันทึกจากไลบรารีสร้างโมเดลใดๆ ก็ได้ สำหรับ Keras นั้น hub.KerasLayer จะทำหน้าที่โหลด และการบันทึกในรูปแบบ SavedModel ที่มีอยู่ใน Keras ได้รับการออกแบบใหม่สำหรับ TF2 โดยมีเป้าหมายเพื่อให้มีอินเทอร์เฟซที่ครอบคลุมมากขึ้น (ดู RFC จากเดือนพฤษภาคม 2019)

ความสัมพันธ์กับ "API ของ SavedModel ทั่วไป" ที่เฉพาะเจาะจงกับงาน

คำจำกัดความของอินเทอร์เฟซในหน้านี้อนุญาตให้มีอินพุตและเอาต์พุตจำนวนและประเภทใดก็ได้ API ของ Common SavedModel สำหรับ TF Hub ปรับปรุงอินเทอร์เฟซทั่วไปนี้ด้วยข้อกำหนดการใช้งานสำหรับงานเฉพาะเพื่อให้สามารถแลกเปลี่ยนโมเดลได้อย่างง่ายดาย

คำจำกัดความของอินเทอร์เฟซ

คุณลักษณะ

SavedModel ที่นำกลับมาใช้ใหม่ได้ คือ SavedModel ของ TensorFlow 2 ซึ่ง obj = tf.saved_model.load(...) จะส่งคืนอ็อบเจ็กต์ที่มีคุณสมบัติดังต่อไปนี้

  • __call__ . จำเป็น ต้องเป็นฟังก์ชัน tf ที่ใช้ในการคำนวณของโมเดล ("การส่งผ่านไปข้างหน้า") ตามข้อกำหนดด้านล่าง

  • variables : รายการของอ็อบเจ็กต์ tf.Variable ซึ่งแสดงรายการตัวแปรทั้งหมดที่ใช้ในการเรียกใช้ __call__ ในทุกกรณี รวมถึงตัวแปรที่สามารถฝึกฝนได้และตัวแปรที่ไม่สามารถฝึกฝนได้

    สามารถละเว้นรายการนี้ได้หากว่างเปล่า

  • trainable_variables : รายการของอ็อบเจ็กต์ tf.Variable ที่ v.trainable เป็นจริงสำหรับทุกองค์ประกอบ ตัวแปรเหล่านี้ต้องเป็นส่วนย่อยของ variables ตัวแปรเหล่านี้คือตัวแปรที่จะถูกฝึกฝนเมื่อทำการปรับแต่งอ็อบเจ็กต์ ผู้สร้าง SavedModel อาจเลือกที่จะละเว้นตัวแปรบางตัวที่สามารถฝึกฝนได้แต่เดิม เพื่อระบุว่าไม่ควรแก้ไขตัวแปรเหล่านั้นในระหว่างการปรับแต่ง

    สามารถละเว้นรายการนี้ได้หากว่างเปล่า โดยเฉพาะอย่างยิ่งหาก SavedModel ไม่รองรับการปรับแต่งอย่างละเอียด

  • regularization_losses : รายการของ tf.functions แต่ละฟังก์ชันรับอินพุตเป็นศูนย์และส่งคืนค่าเทนเซอร์ float แบบสเกลาร์เพียงค่าเดียว สำหรับการปรับแต่งอย่างละเอียด ผู้ใช้ SavedModel ควรเพิ่มฟังก์ชันเหล่านี้เป็นเงื่อนไขการปรับค่าเพิ่มเติมลงใน loss (ในกรณีที่ง่ายที่สุดโดยไม่ต้องปรับขนาดเพิ่มเติม) โดยทั่วไป ฟังก์ชันเหล่านี้ใช้เพื่อแสดงตัวควบคุมน้ำหนัก (เนื่องจากไม่มีอินพุต tf.functions เหล่านี้จึงไม่สามารถแสดงตัวควบคุมกิจกรรมได้)

    สามารถละเว้นรายการนี้ได้หากว่างเปล่า โดยเฉพาะอย่างยิ่งหาก SavedModel ไม่รองรับการปรับแต่งอย่างละเอียด หรือไม่ต้องการกำหนดการควบคุมน้ำหนัก

ฟังก์ชัน __call__

obj SavedModel ที่ได้รับการกู้คืนจะมีแอตทริบิวต์ obj.__call__ ซึ่งเป็นฟังก์ชัน tf ที่ได้รับการกู้คืน และอนุญาตให้เรียกใช้ obj ได้ดังต่อไปนี้

บทสรุป (รหัสเทียม):

outputs = obj(inputs, trainable=..., **kwargs)

ข้อโต้แย้ง

เหตุผลมีดังต่อไปนี้

  • มีอาร์กิวเมนต์ตำแหน่งที่จำเป็นหนึ่งตัวสำหรับชุดการเปิดใช้งานอินพุตของ SavedModel ประเภทของอาร์กิวเมนต์นี้เป็นหนึ่งในประเภทต่อไปนี้

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

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

  • อาจมีอาร์กิวเมนต์คีย์เวิร์ดเสริม ` training ที่รับค่าบูลีนของ Python คือ True หรือ False ค่าเริ่มต้นคือ False หากโมเดลรองรับการปรับแต่งอย่างละเอียด และหากการคำนวณแตกต่างกันระหว่างสองแบบ (เช่น ใน dropout และ batch normalization) ความแตกต่างนั้นจะถูกนำมาใช้ด้วยอาร์กิวเมนต์นี้ มิฉะนั้น อาร์กิวเมนต์นี้อาจไม่มีอยู่

    ไม่จำเป็นว่าฟังก์ชัน __call__ จะต้องรับอาร์กิวเมนต์ training ที่มีค่าเป็น Tensor ผู้เรียกใช้จะต้องใช้ tf.cond() หากจำเป็นเพื่อส่งต่อค่าระหว่างอาร์กิวเมนต์เหล่านั้น

  • ผู้สร้าง SavedModel อาจเลือกที่จะยอมรับ kwargs เสริมเพิ่มเติมที่มีชื่อเฉพาะเจาะจงได้

    • สำหรับอาร์กิวเมนต์ที่มีค่าเป็น Tensor นั้น ผู้สร้าง SavedModel จะกำหนด dtypes และ shapes ที่อนุญาต tf.function ยอมรับค่าเริ่มต้นของ Python สำหรับอาร์กิวเมนต์ที่ถูกติดตามด้วยอินพุต tf.TensorSpec อาร์กิวเมนต์ดังกล่าวสามารถใช้เพื่ออนุญาตการปรับแต่งไฮเปอร์พารามิเตอร์เชิงตัวเลขที่เกี่ยวข้องใน __call__ (เช่น อัตรา dropout)

    • สำหรับอาร์กิวเมนต์ที่มีค่าเป็น Python นั้น ตัวสร้าง SavedModel จะกำหนดค่าที่อนุญาตได้ อาร์กิวเมนต์เหล่านี้สามารถใช้เป็นแฟล็กเพื่อทำการเลือกแบบแยกส่วนในฟังก์ชันที่ถูกติดตาม (แต่ระวังการเพิ่มจำนวนการติดตามอย่างมหาศาล)

ฟังก์ชัน __call__ ที่ได้รับการกู้คืนจะต้องแสดงร่องรอยการทำงานสำหรับชุดค่าผสมของอาร์กิวเมนต์ที่อนุญาตทั้งหมด การสลับ training ระหว่าง True และ False จะต้องไม่เปลี่ยนแปลงความถูกต้องของอาร์กิวเมนต์

ผลลัพธ์

outputs จากการเรียกใช้ obj อาจเป็นดังนี้

  • เทนเซอร์เดียวสำหรับเอาต์พุตเดียว
  • รายการของเทนเซอร์สำหรับลำดับเอาต์พุตที่ไม่มีชื่อเรียงตามลำดับ
  • พจนานุกรมของเทนเซอร์ที่ใช้ชุดชื่อเอาต์พุตเฉพาะเป็นคีย์

(การแก้ไขอินเทอร์เฟซในอนาคตอาจอนุญาตให้มีการซ้อนที่ซับซ้อนมากขึ้น) ประเภทการส่งคืนอาจแตกต่างกันไปขึ้นอยู่กับ kwargs ที่มีค่าเป็น Python ซึ่งช่วยให้สามารถใช้แฟล็กที่สร้างเอาต์พุตเพิ่มเติมได้ ตัวสร้าง SavedModel จะกำหนดประเภทข้อมูลและรูปร่างของเอาต์พุต รวมถึงการพึ่งพาของอินพุต

เรียกฟังก์ชันที่ระบุชื่อได้

SavedModel ที่นำกลับมาใช้ใหม่ได้สามารถจัดเตรียมส่วนประกอบของโมเดลได้หลายส่วนตามที่อธิบายไว้ข้างต้น โดยการใส่ส่วนประกอบเหล่านั้นลงในซับออบเจ็กต์ที่มีชื่อ เช่น obj.foo , obj.bar เป็นต้น แต่ละซับออบเจ็กต์จะมีเมธอด __call__ และแอตทริบิวต์สนับสนุนเกี่ยวกับตัวแปรต่างๆ ที่เฉพาะเจาะจงสำหรับส่วนประกอบของโมเดลนั้น สำหรับตัวอย่างข้างต้น จะมี obj.foo.__call__ , obj.foo.variables และอื่นๆ

โปรดทราบว่าอินเทอร์เฟซนี้ ไม่ รองรับวิธีการเพิ่ม tf.function โดยตรงเป็น tf.foo

ผู้ใช้งาน Reusable SavedModels คาดว่าจะจัดการได้เพียงระดับการซ้อนกันเพียงระดับเดียวเท่านั้น ( obj.bar แต่ไม่ใช่ obj.bar.baz ) (การแก้ไขอินเทอร์เฟซในอนาคตอาจอนุญาตให้มีการซ้อนกันที่ลึกกว่านี้ และอาจยกเว้นข้อกำหนดที่ว่าวัตถุระดับบนสุดจะต้องสามารถเรียกใช้งานได้)

คำกล่าวปิดท้าย

ความสัมพันธ์กับ API ที่อยู่ระหว่างดำเนินการ

เอกสารนี้อธิบายถึงอินเทอร์เฟซของคลาส Python ซึ่งประกอบด้วยค่าพื้นฐาน เช่น tf.function และ tf.Variable ที่ยังคงใช้งานได้แม้ผ่านการแปลงเป็นรูปแบบที่สามารถจัดเก็บได้โดยใช้ tf.saved_model.save() และ tf.saved_model.load() อย่างไรก็ตาม อินเทอร์เฟซนี้มีอยู่แล้วในอ็อบเจ็กต์ดั้งเดิมที่ส่งไปยัง tf.saved_model.save() การปรับใช้กับอินเทอร์เฟซนั้นทำให้สามารถแลกเปลี่ยนชิ้นส่วนของโมเดลระหว่าง API การสร้างโมเดลภายในโปรแกรม TensorFlow เดียวกันได้