أمامك مرة أخرى مهمة الكشف عن الأشياء. الأولوية - سرعة العمل بدقة مقبولة. تأخذ هندسة YOLOv3 وتدربها أكثر. الدقة (mAp75) أكبر من 0.95. لكن سرعة الجري لا تزال منخفضة. هراء.
اليوم سوف نتجاوز التكميم. وتحت الخفض ، ضع في اعتبارك نموذج التقليم - قطع الأجزاء الزائدة من الشبكة لتسريع الاستدلال دون فقدان الدقة. بوضوح - أين وكم وكيف تقطع. دعنا نتعرف على كيفية القيام بذلك يدويًا وأين يمكنك أتمتة. في النهاية يوجد مستودع على keras.
مقدمة
في مكان عملي الأخير ، Macroscop في بيرم ، اكتسبت عادة واحدة - لمراقبة وقت تنفيذ الخوارزميات دائمًا. ويجب دائمًا التحقق من وقت تشغيل الشبكة من خلال عامل تصفية الكفاية. عادة لا يمر أحدث الإنتاج في هذا المرشح ، مما أدى بي إلى التقليم.
التقليم هو موضوع قديم تمت مناقشته في محاضرات ستانفورد في عام 2017. الفكرة الرئيسية هي تقليل حجم الشبكة المدربة دون فقدان الدقة عن طريق إزالة العقد المختلفة. يبدو رائعًا ، لكن نادرًا ما أسمع عن استخدامه. ربما ، لا توجد تطبيقات كافية ، ولا توجد مقالات باللغة الروسية ، أو ببساطة يفكر الجميع في تقليم المعرفة وصمت.
لكن لتفكيكها
نظرة في علم الأحياء
أحبه عندما تنظر الأفكار التي تأتي من علم الأحياء إلى التعلم العميق. هم ، مثل التطور ، يمكن الوثوق بهم (هل تعلم أن ReLU مشابه جدًا لـ وظيفة تنشيط الخلايا العصبية في الدماغ?)
عملية التقليم النموذجية قريبة أيضًا من علم الأحياء. يمكن مقارنة تفاعل الشبكة هنا مع ليونة الدماغ. هناك بعض الأمثلة الشيقة في الكتاب. نورمان دويدج:
عقل امرأة ولدت بنصف واحد فقط ، أعاد برمجة نفسه لأداء وظائف النصف المفقود
أطلق الرجل النار على الجزء المسؤول عن الرؤية في دماغه. بمرور الوقت ، تولت أجزاء أخرى من الدماغ هذه الوظائف. (لا تحاول التكرار)
لذا من نموذجك ، يمكنك قطع بعض التلافيف الضعيفة. في الحالات القصوى ، ستساعد الحزم المتبقية في استبدال الحزم المقطوعة.
هل تحب نقل التعلم أم أنك تتعلم من الصفر؟
الخيار رقم واحد. أنت تستخدم نقل التعلم على Yolov3. Retina أو Mask-RCNN أو U-Net. ولكن في أغلب الأحيان ، لا نحتاج إلى التعرف على 80 فئة كائن كما هو الحال في COCO. في ممارستي ، يقتصر كل شيء على 1-2 فصول. يمكن افتراض أن الهندسة المعمارية لـ 80 فئة زائدة عن الحاجة هنا. ينشأ الفكر أن العمارة بحاجة إلى تقليل. علاوة على ذلك ، أود القيام بذلك دون فقدان الأوزان الموجودة مسبقًا.
الخيار الثاني. ربما لديك الكثير من موارد البيانات والحوسبة ، أو تحتاج فقط إلى بنية فائقة التخصيص. لا يهم. لكنك تتعلم الشبكة من الصفر. الترتيب المعتاد - ننظر إلى بنية البيانات ، ونختار بنية مفرطة من حيث القوة ، ونقوم بدفع المتسربين من إعادة التدريب. رأيت 0.6 متسربين يا كارل.
في كلتا الحالتين ، يمكن تقليل الشبكة. ترقية. الآن دعنا نبدأ في معرفة نوع تشذيب الختان
خوارزمية عامة
قررنا أنه يمكننا إزالة التلافيف. يبدو بسيطًا جدًا:
تعد إزالة أي التفاف أمرًا مرهقًا للشبكة ، مما يؤدي عادةً إلى زيادة بعض الأخطاء. من ناحية أخرى ، تعد هذه الزيادة في الخطأ مؤشرًا على مدى صحة إزالة التلافيف (على سبيل المثال ، تشير الزيادة الكبيرة إلى أننا نقوم بشيء خاطئ). لكن الزيادة الصغيرة مقبولة تمامًا وغالبًا ما يتم التخلص منها عن طريق إعادة التدريب على الضوء اللاحق باستخدام LR صغير. إضافة خطوة إعادة التدريب:
الآن نحن بحاجة إلى معرفة متى نريد إيقاف حلقة التعلم <-> التقليم. قد تكون هناك خيارات غريبة هنا عندما نحتاج إلى تقليل الشبكة إلى حجم معين وسرعة التشغيل (على سبيل المثال ، للأجهزة المحمولة). ومع ذلك ، فإن الخيار الأكثر شيوعًا هو الاستمرار في الحلقة حتى يصبح الخطأ أكبر من المسموح به. إضافة شرط:
لذلك ، تصبح الخوارزمية واضحة. يبقى معرفة كيفية تحديد التلافيف المراد إزالتها.
البحث عن الحزم المحذوفة
نحن بحاجة لإزالة بعض التلافيف. التسرع إلى الأمام و "إطلاق النار" فكرة سيئة ، على الرغم من أنها ستنجح. ولكن نظرًا لوجود رأس ، يمكنك التفكير ومحاولة اختيار التلافيف "الضعيفة" للحذف. هناك عدة خيارات:
لكل خيار الحق في الحياة وميزات تنفيذه. هنا نعتبر المتغير بأصغر مقياس L1
عملية يدوية لـ YOLOv3
تحتوي العمارة الأصلية على كتل متبقية. ولكن بغض النظر عن مدى روعتها بالنسبة للشبكات العميقة ، فإنها تتداخل معنا قليلاً. تكمن الصعوبة في أنه لا يمكنك حذف التسويات بمؤشرات مختلفة في هذه الطبقات:
لذلك ، نختار الطبقات التي يمكننا من خلالها إزالة التسويات بحرية:
لنقم الآن ببناء دورة عمل:
تحميل التنشيطات
معرفة مقدار القطع
اقطعها
تعلم 10 فترات مع LR = 1e-4
اختبارات
يعد تفريغ مجموعات التحديثات مفيدًا لتقييم مقدار ما يمكننا إزالته في خطوة معينة. تحميل أمثلة:
نرى أن 5٪ تقريبًا من التلافيف في كل مكان لها معيار L1 منخفض جدًا ويمكننا إزالتها. في كل خطوة ، يتكرر هذا التفريغ ويتم إجراء تقييم للطبقات ومقدار القطع التي يمكن قطعها.
تتناسب العملية برمتها مع 4 خطوات (هنا وفي كل مكان أرقام RTX 2060 Super):
خطوة
الخريطة 75
عدد المعلمات ، مليون
حجم الشبكة ، ميغابايت
من الأصل ،٪
وقت التشغيل ، مللي
شرط القطع
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% ولا تفقد الدقة.
أتمتة لأبسط البنى
بالنسبة إلى أبسط معماريات الشبكة (بدون إضافة شرطية وكتل متطابقة ومتبقية) ، من الممكن تمامًا التركيز على معالجة جميع الطبقات التلافيفية وأتمتة عملية قطع التلافيف.
لقد نفذت هذا الخيار هنا.
الأمر بسيط: لديك فقط وظيفة الخسارة ، والمحسن ومولدات الدُفعات:
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 ألف):
سرعة الجري عرضة للتقلبات العادية ولم تتغير كثيرًا. هناك تفسير لذلك:
يتغير عدد التلافيف من مناسب (32 ، 64 ، 128) إلى غير مناسب لبطاقات الفيديو - 27 ، 51 ، إلخ. قد أكون مخطئا هنا ، لكن من المحتمل أن يكون الأمر كذلك.
الهندسة ليست واسعة ، لكنها متسقة. بتقليل العرض ، لا نلمس العمق. وبالتالي ، نقوم بتقليل الحمل ، لكن لا نغير السرعة.
لذلك ، تم التعبير عن التحسن في انخفاض حمل CUDA أثناء التشغيل بنسبة 20-30 ٪ ، ولكن ليس في انخفاض وقت التشغيل
نتائج
دعونا نفكر. لقد درسنا خيارين للتقليم - لـ YOLOv2 (عندما تضطر إلى العمل بيديك) وللشبكات ذات البنى الأبسط. يمكن ملاحظة أنه في كلتا الحالتين من الممكن تحقيق تقليل في حجم الشبكة والتسريع دون فقدان الدقة. نتائج:
تصغير الحجم
قم بتشغيل التسريع
تقليل حمل CUDA
نتيجة لذلك ، التوافق البيئي (نحن نحسن الاستخدام المستقبلي لموارد الحوسبة. في مكان ما يبتهج المرء جريتا ثونبرج)
الزائدة الدودية
بعد خطوة التقليم ، يمكنك أيضًا تعديل التكميم (على سبيل المثال ، باستخدام TensorRT)