รูปแบบฮับ TF1

เมื่อเปิดตัวในปี 2018 TensorFlow Hub ได้นำเสนอเนื้อหาประเภทเดียว: รูปแบบ TF1 Hub สำหรับการนำเข้าไปยังโปรแกรม TensorFlow 1

หน้านี้อธิบายวิธีใช้รูปแบบ TF1 Hub ใน TF1 (หรือโหมดความเข้ากันได้ของ TF1 ของ TF2) กับคลาส hub.Module และ API ที่เกี่ยวข้อง (การใช้งานทั่วไปคือการสร้าง tf.Graph ซึ่งอาจอยู่ภายใน TF1 Estimator โดยการรวมโมเดลอย่างน้อยหนึ่งโมเดลในรูปแบบ TF1 Hub กับ tf.compat.layers หรือ tf.layers )

ผู้ใช้ TensorFlow 2 (นอกโหมดความเข้ากันได้ของ TF1) ต้องใช้ API ใหม่กับ hub.load() หรือ hub.KerasLayer API ใหม่จะโหลดประเภทสินทรัพย์ TF2 SavedModel ใหม่ แต่ยังมี การรองรับที่จำกัดสำหรับการโหลดรูปแบบ TF1 Hub ลงใน TF2

การใช้โมเดลในรูปแบบ TF1 Hub

การสร้างอินสแตนซ์โมเดลในรูปแบบ TF1 Hub

โมเดลในรูปแบบ TF1 Hub ถูกนำเข้าไปยังโปรแกรม TensorFlow โดยการสร้างวัตถุ hub.Module จากสตริงที่มี URL หรือเส้นทางของระบบไฟล์ เช่น:

m = hub.Module("path/to/a/module_dir")

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

โมดูลแคช

เมื่อสร้างโมดูลจาก URL เนื้อหาโมดูลจะถูกดาวน์โหลดและแคชในไดเร็กทอรีชั่วคราวของระบบโลคัล ตำแหน่งที่โมดูลถูกแคชสามารถแทนที่ได้โดยใช้ตัวแปรสภาพแวดล้อม TFHUB_CACHE_DIR โปรดดูรายละเอียดที่ การแคช

การใช้โมดูล

เมื่อสร้างอินสแตนซ์แล้ว โมดูล m สามารถเรียกได้ว่าเป็นศูนย์หรือหลายครั้ง เช่น ฟังก์ชัน Python ตั้งแต่อินพุตเทนเซอร์ไปจนถึงเอาต์พุตเทนเซอร์:

y = m(x)

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

โมดูลสามารถกำหนดลายเซ็นที่มีชื่อได้หลาย ลายเซ็น เพื่อให้สามารถนำไปใช้ได้มากกว่าหนึ่งวิธี (คล้ายกับวิธีที่อ็อบเจกต์ Python มี เมธอด ) เอกสารประกอบของโมดูลควรอธิบายลายเซ็นที่มีอยู่ การโทรด้านบนใช้ลายเซ็นชื่อ "default" คุณสามารถเลือกลายเซ็นใดก็ได้โดยส่งชื่อไปยังอาร์กิวเมนต์ signature= ทางเลือก

หากลายเซ็นมีหลายอินพุต จะต้องส่งผ่านเป็น dict โดยมีคีย์ที่กำหนดโดยลายเซ็น ในทำนองเดียวกัน หากลายเซ็นมีหลายเอาต์พุต สิ่งเหล่านี้สามารถดึงออกมาเป็น dict โดยผ่าน as_dict=True ภายใต้คีย์ที่กำหนดโดยลายเซ็น (คีย์ "default" มีไว้สำหรับเอาต์พุตเดี่ยวที่ส่งคืนหาก as_dict=False ) ดังนั้นรูปแบบทั่วไปของการใช้โมดูลจึงดูเหมือน:

outputs = m(dict(apples=x1, oranges=x2), signature="fruit_to_pet", as_dict=True)
y1 = outputs["cats"]
y2 = outputs["dogs"]

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

ลองใช้โมดูลสำรอง

เมื่อใดก็ตามที่มีหลายโมดูลสำหรับงานเดียวกัน TensorFlow Hub ขอแนะนำให้ติดตั้งลายเซ็นที่เข้ากันได้ (อินเทอร์เฟซ) เพื่อให้การลองใช้โมดูลที่แตกต่างกันทำได้ง่ายพอๆ กับการเปลี่ยนที่จับโมดูลเป็นไฮเปอร์พารามิเตอร์ที่มีค่าสตริง

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

การสร้างโมดูลใหม่

บันทึกความเข้ากันได้

รูปแบบ TF1 Hub มุ่งสู่ TensorFlow 1 ซึ่งรองรับเพียงบางส่วนโดย TF Hub ใน TensorFlow 2 โปรดพิจารณาเผยแพร่ในรูปแบบ TF2 SavedModel ใหม่แทน

รูปแบบ TF1 Hub คล้ายกับรูปแบบ SavedModel ของ TensorFlow 1 ในระดับ syntax (ชื่อไฟล์และข้อความโปรโตคอลเดียวกัน) แต่มีความหมายต่างกันเพื่อให้โมดูลใช้ซ้ำ การจัดองค์ประกอบ และการฝึกอบรมซ้ำ (เช่น การจัดเก็บตัวเริ่มต้นทรัพยากรที่แตกต่างกัน การติดแท็กที่แตกต่างกัน อนุสัญญาสำหรับ metagraphs) วิธีที่ง่ายที่สุดในการแยกความแตกต่างบนดิสก์คือการมีอยู่หรือไม่มีไฟล์ tfhub_module.pb

วิธีการทั่วไป

ในการกำหนดโมดูลใหม่ ผู้เผยแพร่จะเรียก hub.create_module_spec() ด้วยฟังก์ชัน module_fn ฟังก์ชันนี้สร้างกราฟที่แสดงถึงโครงสร้างภายในของโมดูล โดยใช้ tf.placeholder() สำหรับอินพุตที่ผู้โทรให้มา จากนั้นจะกำหนดลายเซ็นโดยการเรียก hub.add_signature(name, inputs, outputs) อย่างน้อยหนึ่งครั้ง

ตัวอย่างเช่น:

def module_fn():
  inputs = tf.placeholder(dtype=tf.float32, shape=[None, 50])
  layer1 = tf.layers.dense(inputs, 200)
  layer2 = tf.layers.dense(layer1, 100)
  outputs = dict(default=layer2, hidden_activations=layer1)
  # Add default signature.
  hub.add_signature(inputs=inputs, outputs=outputs)

...
spec = hub.create_module_spec(module_fn)

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

อินสแตนซ์ของโมดูลใดๆ สามารถจัดลำดับไปยังดิสก์ได้โดยใช้วิธีการ export(path, session) การส่งออกโมดูลจะทำให้คำจำกัดความเป็นอนุกรมพร้อมกับสถานะปัจจุบันของตัวแปรใน session ไปยังเส้นทางที่ส่งผ่าน สามารถใช้เมื่อส่งออกโมดูลเป็นครั้งแรก รวมทั้งเมื่อส่งออกโมดูลที่ปรับแบบละเอียด

เพื่อความเข้ากันได้กับ TensorFlow Estimators, hub.LatestModuleExporter ส่งออกโมดูลจากจุดตรวจล่าสุด เช่นเดียวกับ tf.estimator.LatestExporter ส่งออกโมเดลทั้งหมดจากจุดตรวจล่าสุด

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

ตัวอย่างจริง

ดู ผู้ส่งออกโมดูลการฝังข้อความ ของเราสำหรับตัวอย่างจริงของวิธีสร้างโมดูลจากรูปแบบการฝังข้อความทั่วไป

ปรับจูน

การฝึกตัวแปรของโมดูลที่นำเข้ามาร่วมกับตัวแปรของโมเดลรอบๆ นั้นเรียกว่า fine-tuning การปรับละเอียดอาจส่งผลให้คุณภาพดีขึ้น แต่เพิ่มความยุ่งยากใหม่เข้าไป เราแนะนำให้ผู้บริโภคพิจารณาการปรับแต่งอย่างละเอียดหลังจากสำรวจการปรับแต่งคุณภาพที่ง่ายกว่าเท่านั้น และเฉพาะในกรณีที่ผู้เผยแพร่โมดูลแนะนำเท่านั้น

สำหรับผู้บริโภค

หากต้องการเปิดใช้งานการปรับแต่งแบบละเอียด ให้สร้างอินสแตนซ์โมดูลด้วย hub.Module(..., trainable=True) เพื่อให้ตัวแปรสามารถฝึกและนำเข้า REGULARIZATION_LOSSES ของ REGULARIZATION_LOSSES หากโมดูลมีรูปแบบกราฟหลายแบบ ให้เลือกแบบที่เหมาะสมกับการฝึกอบรม ปกติจะเป็นแท็กที่มีแท็ก {"train"}

เลือกรูปแบบการฝึกที่ไม่ทำลายน้ำหนักที่ฝึกไว้ล่วงหน้า เช่น อัตราการเรียนรู้ที่ต่ำกว่าการฝึกตั้งแต่เริ่มต้น

สำหรับผู้จัดพิมพ์

เพื่อให้การปรับแต่งง่ายขึ้นสำหรับผู้บริโภค โปรดคำนึงถึงสิ่งต่อไปนี้:

  • การปรับละเอียดจำเป็นต้องทำให้เป็นมาตรฐาน โมดูลของคุณจะถูกส่งออกด้วยคอลเลกชัน REGULARIZATION_LOSSES ซึ่งเป็นสิ่งที่ทำให้ตัวเลือกของคุณ tf.layers.dense(..., kernel_regularizer=...) ฯลฯ ที่ผู้บริโภคได้รับจาก tf.losses.get_regularization_losses() ชอบวิธีนี้ในการกำหนดการสูญเสียการทำให้เป็นมาตรฐาน L1/L2

  • ในรูปแบบผู้เผยแพร่โฆษณา หลีกเลี่ยงการกำหนด L1/L2 การทำให้เป็นมาตรฐานโดยใช้พารามิเตอร์ l1_ และ l2_regularization_strength ของ tf.train.FtrlOptimizer , tf.train.ProximalGradientDescentOptimizer และเครื่องมือเพิ่มประสิทธิภาพใกล้เคียงอื่นๆ สิ่งเหล่านี้ไม่ได้ส่งออกไปพร้อมกับโมดูล และการตั้งค่าจุดแข็งของการทำให้เป็นมาตรฐานทั่วโลกอาจไม่เหมาะสมกับผู้บริโภค ยกเว้นการทำให้เป็นมาตรฐาน L1 ในแบบจำลองกว้าง (เช่น เชิงเส้นกระจัดกระจาย) หรือแบบกว้างและลึก ควรใช้การสูญเสียการทำให้เป็นมาตรฐานแต่ละรายการแทน

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