เทคนิคเจไดในการลดเครือข่ายการบิด - การตัดแต่งกิ่ง

เทคนิคเจไดในการลดเครือข่ายการบิด - การตัดแต่งกิ่ง

ก่อนที่คุณจะอีกครั้งคืองานตรวจจับวัตถุ สิ่งสำคัญคือความรวดเร็วในการทำงานด้วยความแม่นยำที่ยอมรับได้ คุณใช้สถาปัตยกรรม YOLOv3 และฝึกฝนเพิ่มเติม ความแม่นยำ (mAp75) มากกว่า 0.95 แต่อัตราการวิ่งยังต่ำอยู่ อึ.

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

การแนะนำ

ที่ที่ทำงานเดิมของฉัน Macroscop ในเมือง Perm ฉันมีนิสัยอย่างหนึ่งคือคอยติดตามเวลาดำเนินการของอัลกอริทึมอยู่เสมอ และตรวจสอบรันไทม์ของเครือข่ายผ่านตัวกรองที่เพียงพอเสมอ โดยปกติแล้วความล้ำสมัยในการผลิตจะไม่ผ่านตัวกรองนี้ ซึ่งนำฉันไปสู่การตัดแต่งกิ่ง

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

เหลือบเข้าสู่ชีววิทยา

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

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

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

ในทำนองเดียวกัน คุณสามารถตัดการโน้มน้าวที่อ่อนแอบางส่วนออกจากโมเดลของคุณได้ ทางเลือกสุดท้าย มัดที่เหลือจะช่วยทดแทนมัดที่ตัดแล้ว

คุณชอบ Transfer Learning หรือคุณกำลังเรียนรู้ตั้งแต่เริ่มต้นหรือไม่?

ตัวเลือกหมายเลขหนึ่ง คุณใช้ Transfer Learning บน Yolov3 Retina, Mask-RCNN หรือ U-Net แต่โดยส่วนใหญ่แล้ว เราไม่จำเป็นต้องจดจำคลาสอ็อบเจ็กต์ 80 คลาสเหมือนใน COCO ในทางปฏิบัติของฉัน ทุกอย่างจำกัดอยู่แค่เกรด 1-2 เท่านั้น อาจมีคนคิดว่าสถาปัตยกรรมสำหรับ 80 คลาสนั้นซ้ำซ้อนที่นี่ สิ่งนี้ชี้ให้เห็นว่าสถาปัตยกรรมจำเป็นต้องทำให้เล็กลง นอกจากนี้ ฉันอยากจะทำเช่นนี้โดยไม่สูญเสียน้ำหนักที่ฝึกไว้ล่วงหน้าที่มีอยู่

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

ในทั้งสองกรณี เครือข่ายสามารถลดลงได้ มีแรงบันดาลใจ ทีนี้เรามาดูกันว่าการตัดแต่งกิ่งคืออะไร

อัลกอริธึมทั่วไป

เราตัดสินใจว่าจะลบชุดข้อมูลออกได้ มันดูค่อนข้างง่าย:

เทคนิคเจไดในการลดเครือข่ายการบิด - การตัดแต่งกิ่ง

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

เทคนิคเจไดในการลดเครือข่ายการบิด - การตัดแต่งกิ่ง

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

เทคนิคเจไดในการลดเครือข่ายการบิด - การตัดแต่งกิ่ง

ดังนั้นอัลกอริธึมจึงชัดเจน ยังคงต้องหาวิธีพิจารณาการโน้มน้าวใจที่ถูกลบ

ค้นหาชุดข้อมูลที่ถูกลบ

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

  1. การวัด L1 ที่เล็กที่สุดหรือการตัดแต่งกิ่งที่มีขนาดต่ำที่สุด. แนวคิดที่ว่าการโน้มน้าวใจด้วยน้ำหนักน้อยมีส่วนช่วยในการตัดสินใจขั้นสุดท้ายเพียงเล็กน้อย
  2. การวัด L1 ที่น้อยที่สุดโดยคำนึงถึงค่าเฉลี่ยและส่วนเบี่ยงเบนมาตรฐาน เราเสริมด้วยการประเมินลักษณะของการจำหน่าย
  3. กำบังการโน้มน้าวใจและไม่รวมการโน้มน้าวใจที่มีอิทธิพลต่อความแม่นยำขั้นสุดท้ายน้อยที่สุด. การระบุการโน้มน้าวใจที่ไม่มีนัยสำคัญที่แม่นยำยิ่งขึ้น แต่ใช้เวลานานและสิ้นเปลืองทรัพยากรมาก
  4. คนอื่น ๆ

แต่ละตัวเลือกมีสิทธิ์ในการมีชีวิตและคุณสมบัติการใช้งานของตัวเอง ที่นี่เราจะพิจารณาตัวเลือกที่มีการวัด L1 ที่เล็กที่สุด

กระบวนการด้วยตนเองสำหรับ YOLOv3

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

เทคนิคเจไดในการลดเครือข่ายการบิด - การตัดแต่งกิ่ง

ดังนั้น เรามาเลือกเลเยอร์ที่เราสามารถลบการกระทบยอดได้อย่างอิสระ:

เทคนิคเจไดในการลดเครือข่ายการบิด - การตัดแต่งกิ่ง

ตอนนี้เรามาสร้างวงจรการทำงานกันดีกว่า:

  1. กำลังอัพโหลดการเปิดใช้งาน
  2. ตัดสินใจว่าจะตัดขนาดไหน
  3. ตัดออก
  4. เรียนรู้ 10 ยุคด้วย LR=1e-4
  5. การทดสอบ

การขนถ่ายการโน้มน้าวใจมีประโยชน์ในการประมาณจำนวนส่วนที่เราสามารถเอาออกได้ในขั้นตอนหนึ่ง ตัวอย่างการขนถ่าย:

เทคนิคเจไดในการลดเครือข่ายการบิด - การตัดแต่งกิ่ง

เราเห็นว่าเกือบทุกที่ 5% ของการโน้มน้าวใจมี L1-norm ต่ำมากและเราสามารถลบมันออกได้ ในแต่ละขั้นตอน การขนถ่ายนี้จะถูกทำซ้ำ และทำการประเมินว่าชั้นใดและจำนวนเท่าใดที่สามารถตัดออกได้

กระบวนการทั้งหมดเสร็จสิ้นใน 4 ขั้นตอน (ตัวเลขที่นี่และทุกที่สำหรับ RTX 2060 Super):

ขั้นตอน mAp75 จำนวนพารามิเตอร์ ล้าน ขนาดเครือข่าย, MB ตั้งแต่เริ่มต้น % รันไทม์, นางสาว สภาพการเข้าสุหนัต
0 0.9656 60 241 100 180 -
1 0.9622 55 218 91 175 5% ของทั้งหมด
2 0.9625 50 197 83 168 5% ของทั้งหมด
3 0.9633 39 155 64 155 15% สำหรับเลเยอร์ที่มีการโน้มน้าวใจมากกว่า 400 ครั้ง
4 0.9555 31 124 51 146 10% สำหรับเลเยอร์ที่มีการโน้มน้าวใจมากกว่า 100 ครั้ง

มีการเพิ่มผลเชิงบวกอย่างหนึ่งในขั้นตอนที่ 2 - ขนาดแบตช์ 4 ที่พอดีกับหน่วยความจำ ซึ่งช่วยเร่งกระบวนการฝึกอบรมเพิ่มเติมได้อย่างมาก
ในขั้นตอนที่ 4 กระบวนการหยุดลงเนื่องจาก แม้แต่การฝึกอบรมเพิ่มเติมในระยะยาวก็ไม่ได้เพิ่ม mAp75 ให้เป็นค่าเดิม
ด้วยเหตุนี้ เราจึงสามารถเร่งการอนุมานได้เร็วขึ้น ลด 15%, ลดขนาดลงโดย ลด 35% และไม่แพ้อย่างแน่นอน

ระบบอัตโนมัติสำหรับสถาปัตยกรรมที่เรียบง่าย

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

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

import pruning
from keras.optimizers import Adam
from keras.utils import Sequence

train_batch_generator = BatchGenerator...
score_batch_generator = BatchGenerator...

opt = Adam(lr=1e-4)
pruner = pruning.Pruner("config.json", "categorical_crossentropy", opt)

pruner.prune(train_batch, valid_batch)

หากจำเป็น คุณสามารถเปลี่ยนพารามิเตอร์การกำหนดค่าได้:

{
    "input_model_path": "model.h5",
    "output_model_path": "model_pruned.h5",
    "finetuning_epochs": 10, # the number of epochs for train between pruning steps
    "stop_loss": 0.1, # loss for stopping process
    "pruning_percent_step": 0.05, # part of convs for delete on every pruning step
    "pruning_standart_deviation_part": 0.2 # shift for limit pruning part
}

นอกจากนี้ ยังมีการใช้ข้อจำกัดตามค่าเบี่ยงเบนมาตรฐานอีกด้วย เป้าหมายคือการจำกัดส่วนที่ถูกนำออก ไม่รวมการโน้มน้าวใจด้วยการวัด L1 ที่ "เพียงพอ" แล้ว:

เทคนิคเจไดในการลดเครือข่ายการบิด - การตัดแต่งกิ่ง

ดังนั้นเราจึงอนุญาตให้คุณลบเฉพาะการโน้มน้าวที่อ่อนแอจากการแจกแจงที่คล้ายกับอันที่ถูกต้องและไม่ส่งผลกระทบต่อการลบออกจากการแจกแจงที่คล้ายกับอันซ้าย:

เทคนิคเจไดในการลดเครือข่ายการบิด - การตัดแต่งกิ่ง

เมื่อการกระจายเข้าใกล้ปกติ คุณสามารถเลือกค่าสัมประสิทธิ์การตัดแต่งกิ่ง_มาตรฐาน_ส่วนเบี่ยงเบนได้จาก:

เทคนิคเจไดในการลดเครือข่ายการบิด - การตัดแต่งกิ่ง
ฉันขอแนะนำสมมติฐานของ 2 ซิกมา หรือคุณสามารถเพิกเฉยต่อคุณลักษณะนี้ได้ โดยปล่อยให้ค่า < 1.0

ผลลัพธ์คือกราฟขนาดเครือข่าย การสูญเสีย และรันไทม์ของเครือข่ายสำหรับการทดสอบทั้งหมด ปรับให้เป็นมาตรฐานเป็น 1.0 ตัวอย่างเช่น ที่นี่ขนาดเครือข่ายลดลงเกือบ 2 เท่าโดยไม่สูญเสียคุณภาพ (เครือข่าย Convolutional ขนาดเล็กที่มีน้ำหนัก 100):

เทคนิคเจไดในการลดเครือข่ายการบิด - การตัดแต่งกิ่ง

ความเร็วในการวิ่งขึ้นอยู่กับความผันผวนตามปกติและแทบจะไม่เปลี่ยนแปลง มีคำอธิบายสำหรับสิ่งนี้:

  1. จำนวนการโน้มน้าวใจเปลี่ยนจากสะดวก (32, 64, 128) เป็นไม่สะดวกที่สุดสำหรับการ์ดแสดงผล - 27, 51 เป็นต้น ฉันอาจจะผิดที่นี่ แต่น่าจะมีผลกระทบมากที่สุด
  2. สถาปัตยกรรมไม่กว้างแต่มีความสม่ำเสมอ การลดความกว้างจะไม่ส่งผลต่อความลึก ดังนั้นเราจึงลดภาระแต่ไม่เปลี่ยนความเร็ว

ดังนั้น การปรับปรุงจึงแสดงให้เห็นในการลดภาระ CUDA ในระหว่างการรันลง 20-30% แต่ไม่ลดเวลาในการรัน

ผลของการ

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

  • การลดขนาด
  • การเร่งความเร็ว
  • การลดภาระ CUDA
  • ส่งผลให้เป็นมิตรต่อสิ่งแวดล้อม (เราเพิ่มประสิทธิภาพการใช้ทรัพยากรคอมพิวเตอร์ในอนาคต ที่ไหนสักแห่งที่มีความสุข เกรต้า ธันเบิร์ก)

ภาคผนวก

  • หลังจากขั้นตอนการตัดแต่งกิ่ง คุณจะเพิ่มการหาปริมาณได้ (เช่น ด้วย TensorRT)
  • Tensorflow ให้ความสามารถสำหรับ การตัดแต่งกิ่งต่ำ. ได้ผล
  • ที่เก็บ ฉันต้องการที่จะพัฒนาและยินดีที่จะช่วยเหลือ

ที่มา: will.com

เพิ่มความคิดเห็น