الأختام مقابل الشبكة العصبية 2. أو تشغيل SqueezeNet v.1.1 على Raspberry Zero في الوقت الفعلي (تقريبًا)

مرحبا بالجميع!

بعد كتابة الجزء الأول ، الذي لم يكن جادًا جدًا ولم يكن مفيدًا بشكل خاص من الناحية العملية ، ابتلعني ضميري قليلاً. وقررت أن أنهي ما بدأته. أي اختيار نفس تنفيذ الشبكة العصبية للتشغيل على Rasperry Pi Zero W في الوقت الفعلي (بالطبع ، قدر الإمكان على مثل هذه الأجهزة). لإخراجها من البيانات من واقع الحياة وإلقاء الضوء على النتائج على حبري.

تحذير يوجد كود عملي وعدد قليل من القطط تحت الجرح مقارنة بالجزء الأول. في الصورة ، المهد و سمك القد ، على التوالي.

الصورة

ما الشبكة للاختيار؟


أذكر أنه بسبب ضعف حديد التوت ، فإن اختيار تحقيق الشبكة العصبية صغير. وهي:

1. SqueezeNet.
2. YOLOv3 صغيرة.
3. موبايل نت.
4. ShuffleNet.

ما مدى صحة الاختيار لصالح SqueezeNet في الجزء الأول ؟ .. لتشغيل كل من الشبكات العصبية المذكورة أعلاه على جهازك هو حدث طويل إلى حد ما. لذلك ، وبسبب الشكوك الغامضة ، قررت أن أجعل جوجل إذا كان أحدهم قد طرح مثل هذا السؤال أمامي. اتضح أنه تساءل عن الأمر وحقق فيها بالتفصيل. يمكن لأولئك الذين يرغبون في الرجوع إلى المصدر . سأقتصر على صورة واحدة منه:

الصورة

من الصورة ، يتبع ذلك أن وقت المعالجة لصورة واحدة لنماذج مختلفة مدربة على مجموعة بيانات ImageNet هو الأقل مع SqueezeNet v.1.1. سنتخذ هذا كدليل للعمل. لم يتم تضمين YOLOv3 في المقارنة ، ولكن بقدر ما أتذكر ، فإن YOLO أغلى من MobileNet. على سبيل المثال يجب أن تكون أيضًا أقل سرعة في SqueezeNet.

تنفيذ الشبكة المختارة


يمكن العثور على أوزان وطوبولوجيا SqueezeNet المدربة على مجموعة بيانات ImageNet (إطار عمل Caffe) على GitHub . فقط تحسبًا ، قمت بتنزيل كلا الإصدارين بحيث يمكن مقارنتهما لاحقًا. لماذا ImageNet؟ تحتوي هذه المجموعة من جميع المجموعات المتاحة على الحد الأقصى لعدد الفئات (1000 جهاز كمبيوتر شخصى.) ، لذا تعد نتائج الشبكة العصبية بأنها مثيرة للاهتمام.

هذه المرة سنرى كيف يتعامل Raspberry Zero مع التعرف على الإطار من الكاميرا. ها هو ، العامل الجاد المتواضع في وظيفة اليوم:

الصورة

أخذت شفرة المصدر من مدونة Adrian Rosebrock المذكورة في الجزء الأول كأساس للشفرة ، وبالتحديد من هنا . ولكن كان علي أن أحرثها بشكل كبير:

1. استبدل نموذجك بـ MobileNetSSD على SqueezeNet.
2. أدى تنفيذ البند 1 إلى توسيع عدد الفئات إلى 1000. ولكن في الوقت نفسه ، تمت إزالة وظيفة إبراز الكائنات ذات الإطارات الملونة (وظيفية SSD) ، للأسف.
3. لإزالة استقبال الحجج من خلال سطر الأوامر (لسبب ما ، هذا الإدخال من المعلمات يزعجني).
4. إزالة طريقة VideoStream ، ومعها مكتبة imutils المحبوبة من قبل Adrian. في البداية ، تم استخدام الطريقة للحصول على دفق الفيديو من الكاميرا. ولكن مع توصيل الكاميرا بجهاز Raspberry Zero ، لم تنجح بغباء ، مما يعطي شيئًا مثل "تعليمات غير قانونية".
5. أضف معدل الإطارات (FPS) إلى الصورة المعترف بها ، وأعد كتابة حساب FPS.
6. عمل إطارات حفظ لكتابة هذا المنشور.

على التوت مع نظام التشغيل Rapbian Stretch OS ، Python 3.5.3 وتثبيته من خلال pip3 ، قم بتثبيت OpenCV 3.4.1 ، وتبين ما يلي:

الرمز هنا
import picamera from picamera.array import PiRGBArray import numpy as np import time from time import sleep import datetime as dt import cv2 #    prototxt = 'models/squeezenet_v1.1.prototxt' model = 'models/squeezenet_v1.1.caffemodel' labels = 'models/synset_words.txt' #    rows = open(labels).read().strip().split("\n") classes = [r[r.find(" ") + 1:].split(",")[0] for r in rows] #    print("[INFO] loading model...") net = cv2.dnn.readNetFromCaffe(prototxt, model) print("[INFO] starting video stream...") #   camera = picamera.PiCamera() camera.resolution = (640, 480) camera.framerate = 25 #   camera.start_preview() sleep(1) camera.stop_preview() #     raw rawCapture = PiRGBArray(camera) #   FPS t0 = time.time() #     for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True): #    blob frame = rawCapture.array blob = cv2.dnn.blobFromImage(frame, 1, (224, 224), (104, 117, 124)) #    blob,     net.setInput(blob) preds = net.forward() preds = preds.reshape((1, len(classes))) idxs = int(np.argsort(preds[0])[::-1][:1]) #  FPS FPS = 1/(time.time() - t0) t0 = time.time() #    ,   FPS,    text = "Label: {}, p = {:.2f}%, fps = {:.2f}".format(classes[idxs], preds[0][idxs] * 100, FPS) cv2.putText(frame, text, (5, 25), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) print(text) cv2.imshow("Frame", frame) #     Raspberry fname = 'pic_' + dt.datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + '.jpg' cv2.imwrite(fname, frame) #    SD  key = cv2.waitKey(1) & 0xFF #    `q`    if key == ord("q"): break #   raw       rawCapture.truncate(0) print("[INFO] video stream is terminated") #    cv2.destroyAllWindows() camera.close() 


النتائج


يظهر الرمز على شاشة الشاشة المتصلة بجهاز Raspberry ، وهو الإطار المعترف به التالي في هذا النموذج. في الجزء العلوي من الإطار ، يتم عرض الفئة الأكثر احتمالا فقط.

الصورة

لذلك ، تم تحديد فأرة الكمبيوتر على أنها فأرة ذات احتمالية عالية جدًا. في نفس الوقت ، يتم تحديث الصور بتردد 0.34 إطارًا في الثانية (أي كل ثلاث ثوانٍ تقريبًا). إنه لأمر مزعج قليلاً أن تحمل الكاميرا وتنتظر معالجة الإطار التالي ، ولكن يمكنك العيش. بالمناسبة ، إذا قمت بإزالة الإطار المحفوظ على بطاقة SD ، فستزيد سرعة المعالجة إلى 0.37 ... 0.38 إطارًا في الثانية. بالتأكيد ، هناك طرق أخرى للتفرق. سننتظر ونرى ، على أي حال ، سنترك هذا السؤال للمشاركات التالية.

بشكل منفصل ، أعتذر عن توازن اللون الأبيض. والحقيقة هي أن كاميرا الأشعة تحت الحمراء مع تشغيل الإضاءة الخلفية كانت متصلة بـ Rapberry ، لذلك تبدو معظم الإطارات غريبة نوعًا ما. ولكن كلما زادت قيمة كل شبكة عصبية قيمة. من الواضح أن توازن اللون الأبيض في مجموعة التدريب كان أكثر صحة. بالإضافة إلى ذلك ، قررت إدراج الإطارات الخام فقط ، بحيث يراها القارئ بنفس الطريقة التي يرون بها الشبكة العصبية.

أولاً ، دعنا نقارن عمل إصدارات SqueezeNet 1.0 (على الإطار الأيسر) و 1.1 (على اليمين):

الصورة

يمكن ملاحظة أن الإصدار 1.1 يعمل مرتين وربع أسرع من 1.0 (0.34 إطارًا في الثانية مقابل 0.15). كسب السرعة واضح. لا يستحق إجراء استنتاجات حول دقة التعرف في هذا المثال ، نظرًا لأن الدقة تعتمد بشدة على موضع الكاميرا بالنسبة للكائن والإضاءة والوهج والظلال وما إلى ذلك.

في ضوء ميزة السرعة الهامة هذه v1.1 على v.1.0 في المستقبل ، تم استخدام SqueezeNet v.1.1 فقط. لتقييم أداء النموذج ، قمت بتوجيه الكاميرا إلى أشياء مختلفة جاءت إلى متناول اليد واستلمت الإطارات التالية عند الإخراج:

الصورة

لوحة المفاتيح أسوأ من الماوس. ربما في مجموعة التدريب ، كانت معظم لوحات المفاتيح بيضاء.

الصورة

يتم تعريف الهاتف الخلوي جيدًا إذا قمت بتشغيل الشاشة. لا تحسب الخلية ذات الشاشة المقفلة الشبكة العصبية على أنها خلية.

الصورة

يتم تعريف الكوب الفارغ بشكل مقبول تمامًا على أنه فنجان قهوة. كل شيء يسير على ما يرام حتى الآن.

الصورة

المقص هو أسوأ حالا ؛ يتم تعريفهم بعناد بواسطة الشبكة على أنه مشبك شعر. ومع ذلك ، الدخول إلى شجرة التفاح إن لم يكن البقعة)

دعونا نعقد المهمة


دعونا نحاول وضع شيء صعب على الشبكة العصبية للخنزير . لقد صادفت للتو لعبة أطفال محلية الصنع. أعتقد أن معظم القراء يتعرفون عليها كقطّة لعبة. أتساءل ما الذي سيعتبره ذكائنا الاصطناعي البدائي.

الصورة

في الإطار الموجود على اليسار ، مسح ضوء الأشعة تحت الحمراء جميع الشرائط من القماش. ونتيجة لذلك ، تم تعريف اللعبة على أنها قناع الأكسجين مع احتمال لائق جدا. لما لا؟ يشبه شكل اللعبة بالفعل قناع الأكسجين.

في الإطار الموجود على اليمين ، غطيت أصابعي بتمييز IR ، لذلك ظهرت الخطوط على اللعبة ، وأصبح توازن اللون الأبيض أكثر تصديقًا. في الواقع ، هذا هو الإطار الوحيد الذي يبدو أكثر أو أقل طبيعية في هذا المنشور. لكن الشبكة العصبية لديها الكثير من التفاصيل في الصورة الخلط. حددت اللعبة على أنها قميص من النوع الثقيل. يجب أن أقول أن هذا أيضًا لا يبدو وكأنه "إصبع في السماء". ضرب إذا لم يكن في "شجرة التفاح" ، ثم على الأقل في بستان التفاح).

حسنًا ، لقد اقتربنا بسلاسة من ذروة عملنا. الفائز الفائز في المعركة ، المكرس بالتفصيل في المنشور الأول ، يدخل الحلبة. ويخرج دماغ شبكتنا العصبية بسهولة من الإطارات الأولى.

الصورة

من الغريب أن القط لا يغير موضعه عمليًا ، ولكن في كل مرة يتم تحديده بشكل مختلف. ومن هذا المنظور ، يشبه إلى حد كبير الظربان. في المركز الثاني هو تشابه الهامستر. لنحاول تغيير الزاوية.

الصورة

نعم ، إذا قمت بتصوير القطة من الأعلى ، فسيتم تحديدها بشكل صحيح ، ولكن إذا قمت فقط بتغيير موضع جسم القط في الإطار قليلاً ، بالنسبة للشبكة العصبية يصبح كلبًا - من قشور سيبيريا وقذرة (Eskimo sled dog) ، على التوالي.

الصورة

وهذا التحديد جميل حيث يتم تعريف كلب من سلالات مختلفة على كل إطار منفصل للقط. والسلالات لا تتكرر)

الصورة

بالمناسبة ، هناك أوضاع الشبكات العصبية يصبح من الواضح أن هذا لا يزال قطة ، وليس كلبًا. أي أن SqueezeNet v.1.1 تمكنت من إثبات نفسها حتى على مثل هذا الشيء الذي يصعب تحليله. نظرًا لنجاح الشبكة العصبية في التعرف على الأشياء في بداية الاختبار والتعرف على القطة كقط في النهاية ، نعلن هذه المرة عن التعادل القتالي القوي)

حسنًا ، هذا كل شيء. أدعو الجميع لتجربة الكود المقترح على توت العليق وأي كائنات ظهرت في عرض كائنات حية وغير حية. سأكون ممتنًا بشكل خاص لأولئك الذين يقيسون FPS على Rapberry Pi B +. أعدك بتضمين النتائج في هذا المنشور مع الإشارة إلى الشخص الذي أرسل البيانات. أعتقد أنه يجب أن يتحول إلى أكثر من 1 FPS!

آمل أن تكون بعض المعلومات من هذا المنشور مفيدة لأغراض ترفيهية أو تعليمية ، وقد يأتي شخص بأفكار جديدة.

أتمنى لك أسبوع عمل جيد! ونراكم قريبا)

الصورة

UPD1: على Raspberry Pi 3B + ، يعمل البرنامج النصي أعلاه على تردد 2 مع FPS صغير.

UPD2: في RPi 3B + مع Movidius NCS ، يعمل النص في 6 FPS.

Source: https://habr.com/ru/post/ar429400/


All Articles