Convnets, การบีบ, Xception พร้อม Keras และ TPU

1. ภาพรวม

ในชั้นเรียนนี้ คุณจะได้เรียนรู้เกี่ยวกับสถาปัตยกรรม ConvNet สมัยใหม่ และใช้ความรู้เพื่อติดตั้งใช้งาน ConvNet ที่เรียบง่ายแต่มีประสิทธิภาพที่เรียกว่า "squeezenet"

ห้องทดลองนี้ประกอบด้วยคำอธิบายทางทฤษฎีที่จำเป็นเกี่ยวกับเครือข่ายประสาทแบบ Convolutive และเป็นจุดเริ่มต้นที่ดีสำหรับนักพัฒนาซอฟต์แวร์ที่เรียนรู้เกี่ยวกับการเรียนรู้เชิงลึก

ห้องทดลองนี้เป็นส่วนที่ 4 ของชุด "Keras ใน TPU" คุณสามารถดำเนินการตามลำดับต่อไปนี้หรือทำแยกต่างหากก็ได้

ca8cc21f6838eccc.png

สิ่งที่คุณจะได้เรียนรู้

  • เพื่อเป็นผู้เชี่ยวชาญในสไตล์การใช้งานของ Keras
  • วิธีสร้างโมเดลโดยใช้สถาปัตยกรรม SqueezeNet
  • ใช้ TPU เพื่อฝึกที่รวดเร็วและทำซ้ำในสถาปัตยกรรม
  • วิธีใช้การเสริมข้อมูลด้วย tf.data.dataset
  • เพื่อปรับแต่งโมเดลขนาดใหญ่ที่ฝึกไว้แล้ว (Xception) บน TPU

ความคิดเห็น

โปรดแจ้งให้เราทราบหากพบข้อผิดพลาดใน Code Lab นี้ คุณแสดงความคิดเห็นได้ผ่านปัญหาเกี่ยวกับ GitHub [ feedback link]

2. คู่มือเริ่มต้นใช้งานฉบับย่อของ Google Colaboratory

ห้องทดลองนี้ใช้ Google Collaboratory โดยที่คุณไม่ต้องตั้งค่าใดๆ Colaboratory เป็นแพลตฟอร์มสมุดบันทึกออนไลน์สำหรับวัตถุประสงค์ด้านการศึกษา โดยมีการอบรมเรื่อง CPU, GPU และ TPU ให้ฟรี

688858c21e3beff2.png

คุณสามารถเปิดสมุดบันทึกตัวอย่างนี้และเรียกใช้เซลล์ 2-3 เซลล์เพื่อทำความคุ้นเคยกับ Colaboratory

c3df49e90e5a654f.png Welcome to Colab.ipynb

เลือกแบ็กเอนด์ TPU

8832c6208c99687d.png

ในเมนู Colab ให้เลือกรันไทม์ > เปลี่ยนประเภทรันไทม์ แล้วเลือก TPU ใน Code Lab นี้ คุณจะได้ใช้ TPU (Tensor Processing Unit) ที่มีประสิทธิภาพซึ่งได้รับการสนับสนุนมาเพื่อการฝึกแบบเร่งฮาร์ดแวร์ การเชื่อมต่อกับรันไทม์จะเกิดขึ้นโดยอัตโนมัติในการดำเนินการครั้งแรก หรือคุณจะใช้ปุ่ม "เชื่อมต่อ" ที่มุมบนขวาก็ได้

การดำเนินการของ Notebook

76d05caa8b4db6da.png

เรียกใช้ทีละเซลล์ด้วยการคลิกที่เซลล์แล้วกด Shift-ENTER นอกจากนี้ คุณยังเรียกใช้ทั้งสมุดบันทึกได้ด้วยรันไทม์ > เรียกใช้ทั้งหมด

สารบัญ

429f106990037ec4.png

สมุดบันทึกทั้งหมดมีสารบัญ คุณเปิดเมนูได้โดยใช้ลูกศรสีดําทางด้านซ้าย

เซลล์ที่ซ่อนอยู่

edc3dba45d26f12a.png

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

การตรวจสอบสิทธิ์

cdd4b41413100543.png

Colab สามารถเข้าถึงที่เก็บข้อมูล Google Cloud Storage ส่วนตัวได้หากคุณตรวจสอบสิทธิ์ด้วยบัญชีที่ได้รับอนุญาต ข้อมูลโค้ดด้านบนจะทริกเกอร์ขั้นตอนการตรวจสอบสิทธิ์

3. [INFO] Tensor Compute Unit (TPU) คืออะไร

สรุป

f88cf6facfc70166.png

โค้ดสำหรับการฝึกโมเดลใน TPU ใน Keras (และเปลี่ยนเป็น GPU หรือ CPU หากไม่มี TPU)

try: # detect TPUs
    tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
    strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
    strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines

# use TPUStrategy scope to define model
with strategy.scope():
  model = tf.keras.Sequential( ... )
  model.compile( ... )

# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)

ในวันนี้เราจะใช้ TPU เพื่อสร้างและเพิ่มประสิทธิภาพตัวแยกประเภทดอกไม้ด้วยความเร็วแบบอินเทอร์แอกทีฟ (นาทีต่อการฝึกแต่ละครั้ง)

688858c21e3beff2.png

ทำไมต้องใช้ TPU

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

8eb3e718b8e2ed08.png

ภาพประกอบ: เลเยอร์โครงข่ายประสาทเทียมแบบหนาแน่นเป็นการคูณเมทริกซ์ โดยมีรูปภาพ 8 ชุดที่ประมวลผลผ่านโครงข่ายประสาทเทียมพร้อมกัน โปรดทำการคำนวณแบบคูณแถว x คอลัมน์ 1 รายการเพื่อยืนยันว่ากำลังทำผลรวมถ่วงน้ำหนักของค่าพิกเซลทั้งหมดของรูปภาพ เลเยอร์ Conv แสดงเป็นการคูณเมทริกซ์ได้ด้วย แม้ว่าจะซับซ้อนกว่าเล็กน้อย (ดูคำอธิบายที่นี่ในส่วนที่ 1)

ฮาร์ดแวร์

MXU และ VPU

แกน TPU v2 สร้างขึ้นจาก Matrix Multiply Unit (MXU) ซึ่งเรียกใช้การคูณเมทริกซ์ และ Vectorประมวลผลข้อมูล Unit (VPU) สำหรับงานอื่นๆ ทั้งหมด เช่น การเปิดใช้งาน, softmax เป็นต้น VPU จะจัดการการคำนวณ Float 32 และ int32 ส่วน MXU จะทำงานในรูปแบบจุดลอยตัว 16-32 บิตที่มีความแม่นยำแบบผสม

7d68944718f76b18.png

ผสมจุดทศนิยมที่มีความแม่นยำและ bFloat 16

MXU จะคำนวณการคูณเมทริกซ์โดยใช้อินพุต bfloat16 และเอาต์พุต Float32 การสะสมข้อมูลขั้นกลางจะดำเนินการด้วยความแม่นยำระดับ float32

19c5fc432840c714.png

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

นั่นคือเหตุผลที่ Google เปิดตัวรูปแบบ bFlo 16 ใน TPU โดย bfloat16 เป็น Float 32 ที่ตัดให้สั้นลงโดยมีช่วงและบิตเลขชี้กำลังเหมือนกับ Float 32 นอกจากข้อเท็จจริงที่ว่า TPU จะคํานวณการคูณเมทริกซ์ด้วยความแม่นยำแบบผสมกับอินพุต bFloat16 แต่เอาต์พุต Float 32 หมายความว่าโดยทั่วไปแล้วไม่จําเป็นต้องเปลี่ยนแปลงโค้ดเพื่อให้ได้รับประโยชน์จากประสิทธิภาพที่เพิ่มขึ้นจากความแม่นยำที่ลดลง

อาร์เรย์แบบซิสโตลิก

MXU ใช้การคูณเมทริกซ์ในฮาร์ดแวร์โดยใช้สถาปัตยกรรมที่เรียกว่า "อาร์เรย์ Systolic" ซึ่งองค์ประกอบข้อมูลจะไหลผ่านอาร์เรย์ของหน่วยการประมวลผลฮาร์ดแวร์ (ในทางการแพทย์ "ซิสโตลิค" หมายถึงการหดตัวของหัวใจและการไหลเวียนของเลือด ในที่นี้หมายถึงการไหลเวียนของข้อมูล)

องค์ประกอบพื้นฐานของการคูณเมทริกซ์คือผลคูณระหว่างเส้นจากเมทริกซ์หนึ่งและคอลัมน์จากเมทริกซ์อีกตัวหนึ่ง (ดูภาพประกอบที่ด้านบนของส่วนนี้) สําหรับการคูณเมทริกซ์ Y=X*W องค์ประกอบหนึ่งๆ ของผลลัพธ์จะเป็นดังนี้

Y[2,0] = X[2,0]*W[0,0] + X[2,1]*W[1,0] + X[2,2]*W[2,0] + ... + X[2,n]*W[n,0]

ใน GPU ผู้ใช้จะเขียนโปรแกรมการคูณจุดนี้ลงใน "แกนหลัก" ของ GPU จากนั้นจะเรียกใช้บน "แกนหลัก" ทั้งหมดที่มีให้ใช้งานแบบขนานกันเพื่อพยายามคํานวณค่าทั้งหมดของเมทริกซ์ผลลัพธ์พร้อมกัน หากเมทริกซ์ผลลัพธ์มีขนาดใหญ่ 128x128 จะต้องมีขนาด 128x128=16K "แกน" พร้อมใช้งาน ซึ่งโดยทั่วไปแล้วเป็นไปไม่ได้ GPU ที่ใหญ่ที่สุดมีแกนประมาณ 4,000 แกน ส่วน TPU จะใช้ฮาร์ดแวร์ขั้นต่ำเพียงเล็กน้อยสำหรับหน่วยประมวลผลใน MXU โดยมีเพียง bfloat16 x bfloat16 => float32 ตัวสะสมแบบทวีคูณเท่านั้น ไม่ใช่อย่างอื่น ซึ่ง TPU เหล่านี้มีขนาดเล็กมากจนทำให้ TPU ขนาด 16K นำไปใช้ในขนาด 128x128 MXU และประมวลผลการคูณเมทริกซ์ได้ในคราวเดียว

f1b283fc45966717.gif

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

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

Cloud TPU

เมื่อขอ "Cloud TPU v2" 1 เครื่องใน Google Cloud Platform คุณจะได้รับเครื่องเสมือน (VM) ที่มีบอร์ด TPU ที่ต่อกับ PCI บอร์ด TPU มีชิป TPU แบบ Dual-Core 4 ชิป แต่ละแกน TPU มี VPU (หน่วยประมวลผลเวกเตอร์) และ MXU (หน่วยการคูณเมทริกซ์) ขนาด 128x128 จากนั้น "Cloud TPU" นี้จะเชื่อมต่อผ่านเครือข่ายกับ VM ที่ส่งคำขอ ภาพรวมทั้งหมดจะมีลักษณะดังนี้

dfce5522ed644ece.png

ภาพประกอบ: VM ที่มีตัวเร่ง "Cloud TPU" ที่เชื่อมต่อเครือข่าย "Cloud TPU" เองสร้างจาก VM ที่มีบอร์ด TPU ประกอบ PCI ซึ่งมีชิป TPU แบบ Dual Core 4 ชิปอยู่

พ็อด TPU

ในศูนย์ข้อมูลของ Google นั้น TPU จะเชื่อมต่อกับการเชื่อมต่อระหว่างการประมวลผลประสิทธิภาพสูง (HPC) ซึ่งทำให้ปรากฏเป็น Accelerator ขนาดใหญ่มากตัวเดียว Google เรียกอุปกรณ์นี้ว่าพ็อดและรวมแกน TPU v2 ได้สูงสุด 512 แกน หรือแกน TPU v3 2048 แกน

2ec1e0d341e7fc34.jpeg

ภาพ: พ็อด TPU v3 บอร์ดและชั้นวาง TPU เชื่อมต่อกันผ่านการเชื่อมต่อถึงกัน HPC

ในระหว่างการฝึก ระบบจะแลกเปลี่ยนการไล่ระดับสีระหว่างแกน TPU โดยใช้อัลกอริทึม All-reduce ( คำอธิบายที่ดีของ all-reduce ที่นี่) โมเดลที่กำลังฝึกจะใช้ประโยชน์จากฮาร์ดแวร์ได้ด้วยการฝึกในแบบกลุ่มขนาดใหญ่

d97b9cc5d40fdb1d.gif

ภาพประกอบ: การซิงค์การไล่ระดับสีระหว่างการฝึกโดยใช้อัลกอริทึม All-Reduce ในเครือข่าย HPC แบบ Toroidal Mesh แบบ 2 มิติของ Google TPU

ซอฟต์แวร์

การฝึกอบรมกลุ่มขนาดใหญ่

ขนาดกลุ่มที่เหมาะที่สุดสำหรับ TPU คือรายการข้อมูล 128 ครั้งต่อแกน TPU แต่ฮาร์ดแวร์สามารถแสดงการใช้งานที่ดีจากรายการข้อมูล 8 ครั้งต่อแกน TPU ได้แล้ว โปรดทราบว่า Cloud TPU 1 แกนมี 8 แกน

เราจะใช้ Keras API ใน Code Lab นี้ ใน Keras ข้อมูลกลุ่มที่คุณระบุคือขนาดกลุ่มแบบรวมสำหรับ TPU ทั้งหมด แบทช์จะแยกเป็น 8 โดยอัตโนมัติและทำงานบน 8 แกนของ TPU

da534407825f01e3.png

ดูเคล็ดลับเพิ่มเติมเกี่ยวกับประสิทธิภาพได้ที่คู่มือประสิทธิภาพ TPU สำหรับชุดอาหารที่มีขนาดใหญ่มาก อาจต้องมีการดูแลเป็นพิเศษในบางรุ่น ดูรายละเอียดเพิ่มเติมที่ LARSOptimizer

ขั้นสูง: XLA

โปรแกรม Tensorflow จะกำหนดกราฟการคำนวณ TPU ไม่ได้เรียกใช้โค้ด Python โดยตรง แต่จะเรียกใช้กราฟการคำนวณที่กำหนดโดยโปรแกรม Tensorflow สำหรับเบื้องหลังการทำงาน คอมไพเลอร์ชื่อ XLA (Accelerated Linear Algebra) จะแปลงกราฟ Tensorflow ของโหนดการคำนวณเป็นโค้ดเครื่อง TPU นอกจากนี้ คอมไพเลอร์นี้จะเพิ่มประสิทธิภาพขั้นสูงหลายอย่างในโค้ดและเลย์เอาต์หน่วยความจำด้วย การคอมไพล์จะเกิดขึ้นโดยอัตโนมัติเมื่อมีการส่งงานไปยัง TPU คุณไม่จำเป็นต้องใส่ XLA ไว้ในเชนการบิลด์อย่างชัดเจน

edce61112cd57972.png

ภาพประกอบ: หากต้องการเรียกใช้บน TPU ระบบจะแปลกราฟการคํานวณที่โปรแกรม Tensorflow กำหนดเป็นการแสดงผล XLA (คอมไพเลอร์คณิตศาสตร์เชิงเส้นแบบเร่ง) ก่อน จากนั้น XLA จะคอมไพล์เป็นโค้ดเครื่อง TPU

การใช้ TPU ใน Keras

TPU รองรับผ่าน Keras API ตั้งแต่ Tensorflow 2.1 การรองรับ Keras ทำงานบน TPU และพ็อด TPU ต่อไปนี้เป็นตัวอย่างที่ทำงานบน TPU, GPU และ CPU

try: # detect TPUs
    tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
    strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
    strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines

# use TPUStrategy scope to define model
with strategy.scope():
  model = tf.keras.Sequential( ... )
  model.compile( ... )

# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)

ในข้อมูลโค้ดนี้

  • TPUClusterResolver().connect() พบ TPU ในเครือข่าย คำสั่งนี้ใช้งานได้โดยไม่ต้องมีพารามิเตอร์ในระบบ Google Cloud ส่วนใหญ่ (งาน AI Platform, Colaboratory, Kubeflow, VM สำหรับการเรียนรู้เชิงลึกที่สร้างผ่านยูทิลิตี "ctpu up") ระบบเหล่านี้จะทราบตำแหน่งของ TPU ได้จากตัวแปรสภาพแวดล้อม TPU_NAME หากคุณสร้าง TPU ด้วยตนเอง ให้ตั้งค่าตัวแปรสภาพแวดล้อม TPU_NAME ใน VM ที่ใช้อยู่ หรือเรียกใช้ TPUClusterResolver ด้วยพารามิเตอร์ที่ชัดเจน TPUClusterResolver(tp_uname, zone, project)
  • TPUStrategy คือส่วนที่ใช้การกระจายและอัลกอริทึมการซิงค์แบบไล่ระดับสี "all-reduce"
  • นำกลยุทธ์ไปใช้ผ่านขอบเขต ต้องกําหนดรูปแบบภายใน strategy scope()
  • ฟังก์ชัน tpu_model.fit คาดหวังออบเจ็กต์ tf.data.Dataset สำหรับอินพุตสำหรับการฝึก TPU

งานทั่วไปในการพอร์ต TPU

  • แม้ว่าการโหลดข้อมูลในโมเดล Tensorflow จะมีหลายวิธี แต่สำหรับ TPU จะต้องใช้ tf.data.Dataset API
  • TPU ทํางานได้เร็วมาก และการนำเข้าข้อมูลมักจะเป็นปัญหาคอขวดเมื่อใช้งาน TPU คุณสามารถใช้เครื่องมือในการตรวจหาจุดคอขวดของข้อมูลและเคล็ดลับอื่นๆ เกี่ยวกับประสิทธิภาพได้ในคู่มือประสิทธิภาพ TPU
  • หมายเลข int8 หรือ int16 จะถือว่าเป็น int32 TPU ไม่มีฮาร์ดแวร์จำนวนเต็มที่ทำงานน้อยกว่า 32 บิต
  • ระบบไม่รองรับการดำเนินการบางอย่างของ Tensorflow ดูรายการได้ที่นี่ ข่าวดีคือข้อจํากัดนี้มีผลกับโค้ดการฝึกเท่านั้น เช่น การส่งผ่านไปข้างหน้าและย้อนกลับผ่านโมเดล คุณยังคงใช้การดำเนินการ Tensorflow ทั้งหมดในไปป์ไลน์อินพุตข้อมูลได้เนื่องจากการดำเนินการนี้จะทำบน CPU
  • ไม่รองรับ tf.py_func บน TPU

4. [INFO] ตัวแยกประเภทโครงข่ายระบบประสาทเทียม 101

สรุป

หากคุณทราบคำศัพท์ทั้งหมดในตัวหนาในย่อหน้าถัดไปแล้ว คุณสามารถย้ายไปยังแบบฝึกหัดถัดไป หากคุณเพิ่งเริ่มศึกษาเกี่ยวกับการเรียนรู้เชิงลึก โปรดอ่านต่อ

สำหรับโมเดลที่สร้างเป็นเลเยอร์ตามลำดับ Keras จะมี Sสัมผัสประสบการณ์ API เช่น ตัวจัดประเภทรูปภาพที่ใช้เลเยอร์แบบหนา 3 เลเยอร์สามารถเขียนใน Keras ดังนี้

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[192, 192, 3]),
    tf.keras.layers.Dense(500, activation="relu"),
    tf.keras.layers.Dense(50, activation="relu"),
    tf.keras.layers.Dense(5, activation='softmax') # classifying into 5 classes
])

# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy']) # % of correct answers

# train the model
model.fit(dataset, ... )

688858c21e3beff2.png

โครงข่ายประสาทแบบหนาแน่น

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

c21bae6dade487bc.png

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

ประสาท, การเปิดใช้งาน, RELU

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

644f4213a4ee70e5.png

ฟังก์ชันเปิดใช้งานที่ได้รับความนิยมสูงสุดเรียกว่า RELU สำหรับหน่วยเชิงเส้นแบบ Rectified Linear ฟังก์ชันนี้เป็นฟังก์ชันที่เรียบง่ายมากตามที่คุณเห็นบนกราฟด้านบน

การเปิดใช้งาน Softmax

เครือข่ายด้านบนสิ้นสุดด้วยชั้นนิวรอน 5 ชั้น เนื่องจากเราจัดหมวดหมู่ดอกไม้ออกเป็น 5 หมวดหมู่ (กุหลาบ ทิวลิป บัวบก เดซี่ ทานตะวัน) เซลล์ประสาทในชั้นกลางจะเปิดใช้งานโดยใช้ฟังก์ชันการเปิดใช้งาน RELU แบบคลาสสิก แต่ในชั้นสุดท้าย เราต้องการคำนวณจำนวนระหว่าง 0 ถึง 1 ซึ่งแสดงถึงความน่าจะเป็นของดอกกุหลาบ ดอกทิวลิป และอื่นๆ สำหรับกรณีนี้ เราจะใช้ฟังก์ชันเปิดใช้งานที่ชื่อ "softmax"

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

ef0d98c0952c262d.png d51252f75894479e.gif

Cross-entropy loss

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

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

7bdf8753d20617fb.png

การไล่ระดับสี

"การฝึก" เครือข่ายประสาทเทียมหมายถึงการใช้รูปภาพและป้ายกำกับสำหรับการฝึกเพื่อปรับน้ำหนักและค่ากําหนดให้น้อยที่สุดเพื่อลดฟังก์ชันการสูญเสีย Cross-Entropy วิธีการทํางานมีดังนี้

ครอสเอนโทรปีเป็นฟังก์ชันของน้ำหนัก การให้น้ำหนักพิเศษ พิกเซลของรูปภาพที่ใช้ในการฝึก และคลาสที่รู้จัก

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

gradient descent2.png

การแบ่งกลุ่มย่อยและโมเมนตัม

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

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

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

52e824fe4716c4a0.png

ภาพ: จุดยอด การไล่ระดับสีมีค่า 0 แต่ไม่ได้มีค่าต่ำสุดในทุกทิศทาง (การระบุแหล่งที่มาของรูปภาพ วิกิมีเดีย: โดย Nicoguaro - ผลงานของตนเอง, CC BY 3.0)

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

อภิธานศัพท์

กลุ่มหรือกลุ่มย่อย: การฝึกจะทํากับชุดข้อมูลและป้ายกำกับการฝึกอยู่เสมอ ซึ่งจะช่วยให้อัลกอริทึมบรรจบกัน มิติข้อมูล "กลุ่ม" มักจะเป็นมิติข้อมูลแรกของเทนเซอร์ข้อมูล เช่น Tensor ของรูปร่าง [100, 192, 192, 3] จะมีภาพขนาด 192x192 พิกเซล 100 ภาพที่มี 3 ค่าต่อพิกเซล (RGB)

Cross-Entropy Loss: ฟังก์ชันการสูญเสียแบบพิเศษที่มักใช้ในตัวแยกประเภท

เลเยอร์แบบหนาแน่น: เลเยอร์ของเซลล์ประสาทที่เซลล์ประสาทแต่ละเซลล์เชื่อมต่อกับเซลล์ประสาททั้งหมดในเลเยอร์ก่อนหน้า

ฟีเจอร์: บางครั้งอินพุตของเครือข่ายประสาทจะเรียกว่า "ฟีเจอร์" ศิลปะในการหาว่าส่วนใดของชุดข้อมูล (หรือชุดค่าผสมของส่วนต่างๆ) ที่จะป้อนลงในเครือข่ายประสาทเพื่อให้ได้การคาดการณ์ที่ดีเรียกว่า "การปรับแต่งฟีเจอร์"

ป้ายกำกับ: อีกชื่อหนึ่งของ "ชั้นเรียน" หรือคำตอบที่ถูกต้องในปัญหาการแยกประเภทภายใต้การควบคุมดูแล

อัตราการเรียนรู้: เศษส่วนของการไล่ระดับสีที่มีการอัปเดตน้ำหนักและน้ำหนักพิเศษในแต่ละการวนซ้ำการฝึก

logits: เอาต์พุตของชั้นเซลล์ก่อนใช้ฟังก์ชันการเปิดใช้งานเรียกว่า "logits" คํานี้มาจาก "ฟังก์ชันลอจิสติก" หรือที่เรียกว่า "ฟังก์ชัน Sigmoid" ซึ่งเคยเป็นฟังก์ชันการเปิดใช้งานที่ได้รับความนิยมสูงสุด "เอาต์พุตระบบประสาทก่อนฟังก์ชันโลจิสติกส์" ถูกย่อเป็น "logits"

loss: ฟังก์ชันข้อผิดพลาดที่เปรียบเทียบเอาต์พุตของโครงข่ายระบบประสาทเทียมกับคำตอบที่ถูกต้อง

neuron: คํานวณผลรวมถ่วงน้ำหนักของอินพุต เพิ่มค่ากําหนด และส่งผลลัพธ์ผ่านฟังก์ชันการเปิดใช้งาน

การเข้ารหัสแบบ One-Hot: คลาส 3 จาก 5 ได้รับการเข้ารหัสเป็นเวกเตอร์ขององค์ประกอบ 5 โดยค่า 0 ทั้งหมดยกเว้นค่าตัวที่ 3 ซึ่งก็คือ 1

relu: หน่วยเชิงเส้นที่แก้ไขแล้ว ฟังก์ชันการเปิดใช้งานยอดนิยมสําหรับเซลล์ประสาท

sigmoid: ฟังก์ชันการเปิดใช้งานอีกรูปแบบหนึ่งที่เคยได้รับความนิยมและยังคงมีประโยชน์ในบางกรณี

softmax: ฟังก์ชันการเปิดใช้งานพิเศษที่ทํางานกับเวกเตอร์ เพิ่มความแตกต่างระหว่างองค์ประกอบที่ใหญ่ที่สุดกับองค์ประกอบอื่นๆ ทั้งหมด และทำให้เวกเตอร์มีผลรวมเป็น 1 เพื่อให้ตีความเป็นเวกเตอร์ของความน่าจะเป็นได้ ใช้เป็นขั้นตอนสุดท้ายในการจัดประเภท

tensor: "Tensor" คล้ายกับเมทริกซ์ แต่มีมิติข้อมูลเป็นจำนวนเท่าใดก็ได้ เทนเซอร์ 1 มิติคือเวกเตอร์ Tensor 2 มิติคือเมทริกซ์ และจากนั้นคุณสามารถมี Tensor ที่มีมิติข้อมูล 3, 4, 5 หรือมากกว่าได้

5. [ข้อมูล] โครงข่ายประสาทแบบ Convolutive

สรุป

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

convolutional.gif

ภาพประกอบ: การกรองรูปภาพด้วยฟิลเตอร์ 2 ตัวต่อกันที่ประกอบด้วยน้ำหนักที่เรียนรู้ได้ 4x4x3=48 รายการในแต่ละตัว

โครงข่ายประสาทแบบ Convolutive ง่ายๆ ใน Keras จะมีลักษณะดังนี้

model = tf.keras.Sequential([
  # input: images of size 192x192x3 pixels (the three stands for RGB channels)
  tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu', input_shape=[192, 192, 3]),
  tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=6, padding='same', activation='relu'),
  tf.keras.layers.Flatten(),
  # classifying into 5 categories
  tf.keras.layers.Dense(5, activation='softmax')
])

model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy'])

688858c21e3beff2.png

Convolutional Neural Nets 101

ในเลเยอร์ของเครือข่าย ConvNet "เซลล์ประสาท" 1 เซลล์จะทำการรวมพิกเซลที่มีน้ำหนักเหนือกว่าในบริเวณเล็กๆ ของรูปภาพเท่านั้น เซลล์นี้จะเพิ่มการให้น้ำหนักพิเศษและป้อนผลรวมผ่านฟังก์ชันเปิดใช้งาน เช่นเดียวกับที่เซลล์ประสาทในชั้นที่หนาแน่นปกติสามารถทำ จากนั้นระบบจะดําเนินการนี้ซ้ำไปทั่วทั้งรูปภาพโดยใช้น้ำหนักเดียวกัน โปรดทราบว่าในชั้นที่มีความหนาแน่น เซลล์ประสาทแต่ละเซลล์จะมีน้ำหนักเป็นของตัวเอง ในตัวอย่างนี้ น้ำหนัก "ปะปน" หนึ่งจะเลื่อนผ่านภาพของทั้ง 2 ทิศทาง ("คอนโวลูชัน") เอาต์พุตจะมีค่าเท่ากับจำนวนพิกเซลในรูปภาพ (แต่ต้องมีระยะห่างจากขอบบางจุด) การดำเนินการกรองโดยใช้ตัวกรองที่มีน้ำหนัก 4x4x3=48

อย่างไรก็ตาม น้ำหนัก 48 อาจไม่เพียงพอ หากต้องการเพิ่มระดับอิสระ เราจะทําการดำเนินการเดียวกันซ้ำด้วยชุดน้ำหนักใหม่ ซึ่งจะสร้างเอาต์พุตตัวกรองชุดใหม่ สมมติว่าเป็น "ช่อง" ของเอาต์พุตโดยเปรียบเทียบกับช่อง R,G,B ในภาพอินพุต

Screen Shot 29-07-2016 ที่ 16.02.37.png

น้ำหนักสองชุด (หรือมากกว่านั้น) สามารถสรุปเป็น 1 เซนเซอร์ได้โดยการเพิ่มมิติข้อมูลใหม่ ซึ่งจะให้รูปร่างทั่วไปของเทนเซอร์น้ำหนักสําหรับชั้น Conv เนื่องจากจำนวนช่องอินพุตและเอาต์พุตเป็นพารามิเตอร์ เราจึงเริ่มวางซ้อนและต่อเลเยอร์ Conv ได้

d1b557707bcd1cb9.png

ภาพ: โครงข่ายประสาทแบบคอนโวลูชัน (Convolutional Neural Network) แปลง "คิวบ์" ของข้อมูลเป็น "คิวบ์" อื่นๆ ของข้อมูล

Convlution แบบเพิ่มระยะการกรอง, การรวมข้อมูลสูงสุด

การทำ Convolution ด้วยระยะ 2 หรือ 3 จะช่วยให้เราย่อขนาดคิวบข้อมูลที่ได้ในมิติข้อมูลแนวนอนได้ด้วย ซึ่งทำได้ 2 วิธีดังนี้

  • Strided Convolution: ตัวกรองแบบเลื่อนตามด้านบนแต่มีระยะก้าว >1
  • การรวมกลุ่มสูงสุด: หน้าต่างเลื่อนที่ใช้การดำเนินการ MAX (โดยปกติจะเป็นแพตช์ 2x2 ทำซ้ำทุก 2 พิกเซล)

2b2d4263bb8470b.gif

ภาพประกอบ: การเลื่อนกรอบเวลาการคํานวณ 3 พิกเซลส่งผลให้ค่าเอาต์พุตน้อยลง การกรองเชิงกริดแบบเพิ่มระยะหรือ Max Pooling (ค่าสูงสุดในกรอบ 2x2 ที่เลื่อนด้วยระยะ 2) เป็นวิธีย่อขนาดคิวบข้อมูลในมิติข้อมูลแนวนอน

ตัวแยกประเภทเชิงปฏิสัมพันธ์

สุดท้าย เราแนบส่วนหัวการแยกประเภทโดยทำให้ลูกบาศก์ข้อมูลสุดท้ายแบนแล้วป้อนผ่านเลเยอร์ที่เปิดใช้งาน Softmax อย่างหนาแน่น ตัวแยกประเภทแบบ ConvNet ทั่วไปอาจมีลักษณะดังนี้

4a61aaffb6cba3d1.png

ภาพ: ตัวแยกประเภทรูปภาพที่ใช้เลเยอร์ Convolutional และ softmax โดยจะใช้ฟิลเตอร์ขนาด 3x3 และ 1x1 โดยเลเยอร์สูงสุดคือกลุ่มจุดข้อมูลขนาด 2x2 ส่วนหัวการจัดประเภทใช้เลเยอร์แบบหนาแน่นที่มีการเปิดใช้งาน Softmax

ใน Keras

กองคอลเล็กชันภาพที่แสดงด้านบนเขียนเป็น Keras ได้ดังนี้

model = tf.keras.Sequential([
  # input: images of size 192x192x3 pixels (the three stands for RGB channels)    
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu', input_shape=[192, 192, 3]),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=16, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=8, padding='same', activation='relu'),
  tf.keras.layers.Flatten(),
  # classifying into 5 categories
  tf.keras.layers.Dense(5, activation='softmax')
])

model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy'])

6. [NEW INFO] สถาปัตยกรรมคอนโวลูชันสมัยใหม่

สรุป

7968830b57b708c0.png

ภาพประกอบ: "โมดูล" คอนเวชัน อะไรคือวิธีที่ดีที่สุดในตอนนี้ เลเยอร์พูลสูงสุดตามด้วยเลเยอร์คอนโวลูชัน (Convolutional) 1x1 หรือเลเยอร์หลายๆ แบบรวมกัน ลองทดสอบทั้งหมด เชื่อมโยงผลลัพธ์ แล้วปล่อยให้เครือข่ายตัดสินใจ ทางด้านขวา: สถาปัตยกรรม ConvNet "Inception" ที่ใช้โมดูลดังกล่าว

ใน Keras หากต้องการสร้างโมเดลที่การไหลของข้อมูลสามารถแยกเข้าและออกได้ คุณต้องใช้รูปแบบโมเดล "ฟังก์ชัน" มีตัวอย่างดังต่อไปนี้

l = tf.keras.layers # syntax shortcut

y = l.Conv2D(filters=32, kernel_size=3, padding='same',
             activation='relu', input_shape=[192, 192, 3])(x) # x=input image

# module start: branch out
y1 = l.Conv2D(filters=32, kernel_size=1, padding='same', activation='relu')(y)
y3 = l.Conv2D(filters=32, kernel_size=3, padding='same', activation='relu')(y)
y = l.concatenate([y1, y3]) # output now has 64 channels
# module end: concatenation

# many more layers ...

# Create the model by specifying the input and output tensors.
# Keras layers track their connections automatically so that's all that's needed.
z = l.Dense(5, activation='softmax')(y)
model = tf.keras.Model(x, z)

688858c21e3beff2.png

เคล็ดลับการใช้ราคาถูกอื่นๆ

ตัวกรองขนาด 3x3 ขนาดเล็ก

40a7b15fb7dbe75c.png

ในภาพนี้ คุณจะเห็นผลลัพธ์ของตัวกรอง 3x3 2 รายการต่อกัน ลองย้อนรอยดูว่าจุดข้อมูลใดที่ทำให้เกิดผลลัพธ์นี้ ตัวกรอง 3x3 2 รายการนี้ที่อยู่ติดกันจะคํานวณชุดค่าผสมของภูมิภาค 5x5 รูปแบบนี้ไม่ใช่รูปแบบเดียวกับที่ตัวกรอง 5x5 จะคํานวณ แต่ให้ลองใช้เพราะตัวกรอง 3x3 2 ตัวต่อกันมีราคาถูกกว่าตัวกรอง 5x5 ตัวเดียว

1x1 convolution ใช่ไหม

fd7cac16f8ecb423.png

ในทางคณิตศาสตร์ คอนโวลูชัน "1x1" คือการคูณด้วยค่าคงที่ ไม่ใช่แนวคิดที่เป็นประโยชน์มาก อย่างไรก็ตาม ในเครือข่ายประสาทแบบ Convolutive โปรดทราบว่าตัวกรองจะมีผลกับคิวบ์ข้อมูล ไม่ใช่แค่รูปภาพ 2 มิติ ดังนั้น ตัวกรอง "1x1" จะคำนวณผลรวมถ่วงน้ำหนักของคอลัมน์ข้อมูลขนาด 1x1 (ดูภาพประกอบ) และเมื่อคุณเลื่อนไปยังข้อมูล คุณจะเห็นชุดค่าผสมเชิงเส้นของแชแนลของอินพุต วิธีนี้มีประโยชน์จริงๆ หากคุณคิดว่าแชแนลเป็นผลลัพธ์ของการกรองแต่ละแบบ เช่น ตัวกรองสำหรับ "หูชี้" อีกแชแนลหนึ่งสำหรับ "มีดหวี" และแชแนลที่ 3 สำหรับ "ตากรีด" ดังนั้น เลเยอร์คอนโวลูชัน (Convolutional) "1x1" จะคำนวณชุดค่าผสมเชิงเส้นที่เป็นไปได้ของฟีเจอร์เหล่านี้ ซึ่งอาจเป็นประโยชน์เมื่อมองหา "แมว" นอกจากนี้ เลเยอร์ 1x1 ยังใช้น้ำหนักน้อยกว่าอีกด้วย

7. แบบบีบ

เราได้แสดงวิธีง่ายๆ ในการรวมไอเดียเหล่านี้เข้าด้วยกันในกระดาษ "Squeezenet" ผู้เขียนแนะนำการออกแบบโมดูลคอนโวลูชัน (Convolutional) แบบง่ายๆ โดยใช้เพียงเลเยอร์คอนโวลูชัน 1x1 และ 3x3 เท่านั้น

1730ac375379269b.png

ภาพ: สถาปัตยกรรมบีบตาม "โมดูลไฟ" โดยจะสลับเลเยอร์ 1x1 ที่ "บีบ" ข้อมูลขาเข้าในมิติข้อมูลแนวตั้ง ตามด้วยเลเยอร์คอนโวลูชันแบบ 1x1 และ 3x3 ที่ขนานกัน 2 ชั้น ซึ่งจะ "ขยาย" ความลึกของข้อมูลอีกครั้ง

การลงมือปฏิบัติ

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

c3df49e90e5a654f.png Keras_Flowers_TPU (playground).ipynb

ข้อมูลเพิ่มเติม

การกำหนดฟังก์ชันตัวช่วยสำหรับโมดูล SqueezeNet จะมีประโยชน์สำหรับการฝึกนี้

def fire(x, squeeze, expand):
  y = l.Conv2D(filters=squeeze, kernel_size=1, padding='same', activation='relu')(x)
  y1 = l.Conv2D(filters=expand//2, kernel_size=1, padding='same', activation='relu')(y)
  y3 = l.Conv2D(filters=expand//2, kernel_size=3, padding='same', activation='relu')(y)
  return tf.keras.layers.concatenate([y1, y3])

# this is to make it behave similarly to other Keras layers
def fire_module(squeeze, expand):
  return lambda x: fire(x, squeeze, expand)

# usage:
x = l.Input(shape=[192, 192, 3])
y = fire_module(squeeze=24, expand=48)(x) # typically, squeeze is less than expand
y = fire_module(squeeze=32, expand=64)(y)
...
model = tf.keras.Model(x, y)

วัตถุประสงค์ในครั้งนี้คือการเพิ่มความแม่นยำเป็น 80%

สิ่งที่ควรลอง

เริ่มต้นด้วยชั้น Conv 1 ชั้น แล้วตามด้วย "fire_modules" สลับกับชั้น MaxPooling2D(pool_size=2) คุณสามารถทดสอบเลเยอร์ Max Pooling 2-4 ชั้นในเครือข่าย รวมถึงใช้โมดูล Fire ติดต่อกัน 1, 2 หรือ 3 โมดูลระหว่างเลเยอร์ Max Pooling

ในโมดูลการยิง โดยทั่วไปพารามิเตอร์ "squeeze" ควรมีค่าน้อยกว่าพารามิเตอร์ "expand" พารามิเตอร์เหล่านี้คือจำนวนตัวกรอง โดยทั่วไปแล้ว ช่วงอายุจะอยู่ที่ 8-196 อักขระ คุณอาจทดสอบกับสถาปัตยกรรมที่จํานวนตัวกรองจะค่อยๆ เพิ่มขึ้นผ่านเครือข่าย หรือทดสอบสถาปัตยกรรมที่เรียบง่ายซึ่งโมดูลที่เริ่มทำงานทั้งหมดมีจำนวนตัวกรองเท่ากันก็ได้

มีตัวอย่างดังต่อไปนี้

x = tf.keras.layers.Input(shape=[*IMAGE_SIZE, 3]) # input is 192x192 pixels RGB

y = tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu')(x)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.GlobalAveragePooling2D()(y)
y = tf.keras.layers.Dense(5, activation='softmax')(y)

model = tf.keras.Model(x, y)

ในตอนนี้ คุณอาจสังเกตเห็นว่าการทดสอบของคุณทำงานได้ไม่ดีนักและวัตถุประสงค์ความแม่นยํา 80% ดูเหมือนจะดำเนินไปได้ไกล ได้เวลาดูเคล็ดลับประหยัดๆ อีก 2-3 ข้อ

การปรับให้เป็นมาตรฐานแบบกลุ่ม

การหาค่ามัธยฐานของกลุ่มจะช่วยแก้ปัญหาการบรรจบที่คุณพบ เราจะอธิบายเทคนิคนี้อย่างละเอียดในเวิร์กช็อปครั้งถัดไป ในระหว่างนี้โปรดใช้เทคนิคนี้เป็นตัวช่วย "เวทมนตร์" แบบกล่องดำโดยเพิ่มบรรทัดนี้หลังชั้น Conv ทั้งหมดในเครือข่าย รวมถึงชั้นภายในฟังก์ชัน fire_module

y = tf.keras.layers.BatchNormalization(momentum=0.9)(y)
# please adapt the input and output "y"s to whatever is appropriate in your context

เราต้องลดพารามิเตอร์โมเมนตัมจากค่าเริ่มต้น 0.99 เหลือ 0.9 เนื่องจากชุดข้อมูลมีขนาดเล็ก ไม่ต้องสนใจรายละเอียดนี้ในตอนนี้

การเสริมข้อมูล

คุณจะได้รับจุดเปอร์เซ็นต์เพิ่มขึ้นอีก 2-3 เปอร์เซ็นต์โดยการเพิ่มข้อมูลด้วยการเปลี่ยนรูปแบบที่ทำได้ง่ายๆ เช่น การพลิกความอิ่มตัวไปทางซ้ายไปขวา

4ed2958e09b487ca.png

ad795b70334e0d6b.png

ซึ่งทำได้ง่ายมากใน Tensorflow ด้วย tf.data.Dataset API กําหนดฟังก์ชันการเปลี่ยนรูปแบบใหม่สําหรับข้อมูล

def data_augment(image, label):
    image = tf.image.random_flip_left_right(image)
    image = tf.image.random_saturation(image, lower=0, upper=2)
    return image, label

จากนั้นใช้ในการเปลี่ยนรูปแบบข้อมูลขั้นสุดท้าย (เซลล์ "ชุดข้อมูลการฝึกและการตรวจสอบ", ฟังก์ชัน "get_batched_dataset"):

dataset = dataset.repeat() # existing line
# insert this
if augment_data:
  dataset = dataset.map(data_augment, num_parallel_calls=AUTO)
dataset = dataset.shuffle(2048) # existing line

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

ตอนนี้ความแม่นยำ 80% ใน 35 ยุคควรอยู่ใกล้แค่เอื้อม

วิธีแก้ปัญหา

นี่คือสมุดบันทึกโซลูชัน คุณสามารถใช้ฟีเจอร์นี้หากพบปัญหา

c3df49e90e5a654f.png Keras_Flowers_TPU_squeezenet.ipynb

สิ่งที่เราได้พูดถึง

  • 🤔 โมเดล "สไตล์การใช้งาน" ของ Keras
  • 🤓 สถาปัตยกรรม Squeezenet
  • 🤓 การขยายข้อมูลด้วย tf.data.datset

โปรดใช้เวลาสักครู่เพื่อทบทวนรายการตรวจสอบนี้

8. Xception ที่ปรับแต่งแล้ว

คอนโวลูชันแบบแยกแยะได้

อีกวิธีหนึ่งในการใช้งานเลเยอร์คอนโวลูชัน (Convolutional) ที่ได้รับความนิยมเมื่อเร็วๆ นี้ ได้แก่ Convolution ที่แยกความลึกได้ พูดง่ายๆ ก็คือพูดง่ายๆ แต่แนวคิดนี้ค่อนข้างเรียบง่าย โดยติดตั้งใช้งานใน Tensorflow และ Keras เป็น tf.keras.layers.SeparableConv2D

Convolution ที่แยกกันได้จะเรียกใช้ตัวกรองในรูปภาพ แต่ใช้ชุดน้ำหนักที่แตกต่างกันสำหรับแต่ละแชแนลของรูปภาพอินพุต ตามด้วย "1x1 Convolution" ซึ่งเป็นชุดของผลิตภัณฑ์แบบจุดเพื่อให้ได้ผลรวมถ่วงน้ำหนักของแชแนลที่กรอง เมื่อใช้น้ำหนักใหม่ทุกครั้ง ระบบจะคำนวณการรวมช่องที่มีน้ำหนักตามที่จำเป็น

615720b803bf8dda.gif

ภาพประกอบ: การกรองแบบแยก ระยะที่ 1: Convolution โดยใช้ตัวกรองแยกกันสําหรับแต่ละแชแนล ระยะที่ 2: การรวมช่องแบบเชิงเส้น ทำซ้ำด้วยชุดน้ำหนักใหม่จนกว่าจะถึงจำนวนช่องเอาต์พุตที่ต้องการ ระยะที่ 1 ทำซ้ำได้เช่นกันโดยใช้น้ำหนักใหม่ทุกครั้ง แต่ในทางปฏิบัติแล้วไม่ค่อยมี

Convolution แบบแยกได้ใช้ในสถาปัตยกรรมเครือข่าย ConvNet ล่าสุด ได้แก่ MobileNetV2, Xception, EfficientNet โปรดทราบว่า MobileNetV2 คือโมเดลที่คุณใช้สำหรับการเรียนรู้แบบโอนก่อนหน้านี้

โดยมีค่าใช้จ่ายที่ถูกกว่าคอนโวลูชันทั่วไป (Convolution) ทั่วไปและพบว่ามีประสิทธิผลพอๆ กันในทางปฏิบัติ จำนวนน้ำหนักของตัวอย่างที่แสดงด้านบนมีดังนี้

เลเยอร์ Convolution: 4 x 4 x 3 x 5 = 240

ชั้น Convolutional ที่แยกกันได้: 4 x 4 x 3 + 3 x 5 = 48 + 15 = 63

ต่อไปนี้เป็นโจทย์ให้ผู้อ่านคำนวณจำนวนการคูณที่จำเป็นต้องใช้เพื่อปรับขนาดชั้น Conv แต่ละรูปแบบในลักษณะที่คล้ายกัน Convolution ที่เปรียบเทียบได้จะมีขนาดเล็กกว่าและคำนวณได้อย่างมีประสิทธิภาพมากกว่า

การลงมือปฏิบัติ

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

c3df49e90e5a654f.png Keras Flowers transfer learning (playground).ipynb

เป้าหมาย: ความแม่นยำ > 95% (ไม่จริง เป็นไปได้จริงๆ)

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

ข้อมูลเพิ่มเติมเกี่ยวกับการปรับแต่ง

Xception มีอยู่ในโมเดลที่ฝึกล่วงหน้ามาตรฐานใน tf.keras.application* อย่าลืมปล่อยน้ำหนักทั้งหมดให้ฝึกได้ในครั้งนี้

pretrained_model = tf.keras.applications.Xception(input_shape=[*IMAGE_SIZE, 3],
                                                  include_top=False)
pretrained_model.trainable = True

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

9b1af213b2b36d47.png

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

ใน Keras อัตราการเรียนรู้จะระบุผ่านการเรียกกลับ ซึ่งคุณสามารถคํานวณอัตราการเรียนรู้ที่เหมาะสมสําหรับแต่ละยุค Keras จะส่งอัตราการเรียนรู้ที่ถูกต้องไปยังเครื่องมือเพิ่มประสิทธิภาพสำหรับแต่ละยุค

def lr_fn(epoch):
  lr = ...
  return lr

lr_callback = tf.keras.callbacks.LearningRateScheduler(lr_fn, verbose=True)

model.fit(..., callbacks=[lr_callback])

วิธีแก้ปัญหา

นี่คือสมุดบันทึกโซลูชัน คุณสามารถใช้ฟีเจอร์นี้หากพบปัญหา

c3df49e90e5a654f.png 07_Keras_Flowers_TPU_xception_fine_tuned_best.ipynb

หัวข้อที่ครอบคลุม

  • 🤔 การกรองเชิงลึกที่แยกได้
  • 🤓 ตารางอัตราการเรียนรู้
  • 😈 การปรับแต่งโมเดลที่ฝึกไว้ล่วงหน้า

โปรดใช้เวลาสักครู่เพื่อทบทวนรายการตรวจสอบนี้

9. ยินดีด้วย

คุณได้สร้างโครงข่ายระบบประสาทเทียมแบบคอนโวลูชัน (Convolutional) ที่ทันสมัยแห่งแรกและได้ฝึกให้มีความแม่นยำมากกว่า 90% ซึ่งทำในการฝึกซ้ำได้ในไม่กี่นาทีด้วย TPU นี่เป็น "Keras on TPU codelabs" 4 รายการสุดท้าย

TPU ในทางปฏิบัติ

TPU และ GPU พร้อมใช้งานบน Cloud AI Platform ดังนี้

สุดท้ายนี้ เราให้ความสำคัญกับความคิดเห็น โปรดแจ้งให้เราทราบ หากคุณพบสิ่งที่ควรปรับปรุงในห้องทดลองนี้ หรือคุณคิดว่าเราควรปรับปรุง คุณแสดงความคิดเห็นได้ผ่านปัญหาเกี่ยวกับ GitHub [ feedback link]

HR.png

Martin Görner ID small.jpg
ผู้เขียน: Martin Görner
Twitter: @martin_gorner

tensorflow logo.jpg
www.tensorflow.org