في 1 أيار (مايو) 2017 ، طرحت على نفسي السؤال التالي: هل يمكنني معرفة علم الكمبيوتر الضروري لبناء جزء البرنامج في سيارة ذاتية القيادة في شهر واحد؟

في 22 مايو 2017 ، بعد 26 ساعة من التعلم والترميز ، اكتشفت أن الإجابة كانت نعم.

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

اليوم ، أبدأ شهرًا جديدًا وتحديًا جديدًا: هل يمكنني معرفة علوم الكمبيوتر اللازمة لبناء جزء البرنامج من سيارة ذاتية القيادة في شهر واحد؟

تحديد النجاح

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

نظرًا لأن الجزء الأكبر من التحدي الفني موجود فعليًا في جزء البرنامج (وأيضًا لأنني لا أمتلك سيارة) ، سأركز بشكل حصري على جزء البرنامج لمواجهة هذا الشهر.

على وجه الخصوص ، أرغب في إنشاء برامج ذاتية التشغيل يمكنها القيام بأمرين:

  1. استنادًا إلى إدخال الفيديو للطريق ، يمكن للبرنامج تحديد كيفية توجيه السيارة بأمان وفعالية.
  2. استنادًا إلى إدخال الفيديو على الطريق ، يمكن للبرنامج تحديد كيفية استخدام آليات تسريع وكبح السيارة بأمان وفعالية.

قد أحاول معالجة كل قطعة من هذه القطع بشكل منفصل أو معًا. لست متأكدا بعد. لست متأكدًا تمامًا من التفاصيل المحددة لكلٍّ من هذه التحديات الفرعية ، لكنني سأدرج هذه التفاصيل بجدية أكبر بعد إجراء بعض الأبحاث الأولية.

قد تكون هناك اعتبارات مهمة أخرى لبرامج السيارة ذاتية القيادة التي لم يتم تضمينها في هذين الجابتين ، ولكن هذه هي العناصر التي سأركز عليها هذا الشهر. من هذه العناصر ، من الواضح أنني أتطلع بشكل رئيسي لمعرفة كيفية استخدام التعلم الآلي / التعلم العميق في حل مشاكل رؤية الكمبيوتر (سأشرح ما يعنيه هذا كله في منشور مستقبلي).

نقطة البداية

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

أولاً ، شهادتي من براون في الرياضيات ، وهو أمر مفيد للغاية لهذا الفرع بالذات من علوم الكمبيوتر. لديّ أيضًا خلفية عامة في علوم الترميز / الكمبيوتر ، والتي ستساعدني بالتأكيد.

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

في الصيف الماضي ، درست أيضًا دورة في الرياضيات حول التعليم العميق (التعلم العميق هو فئة فرعية من التعلم الآلي ... وهي فئة فرعية من الذكاء الاصطناعي ... وهي فئة فرعية من علوم الكمبيوتر). كانت هذه الدورة ممتعة ، لكنها كانت نظرية بحتة وليست عملية.

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

في الأساس ، لدي بعض الخبرة التأسيسية ، لكن ليس لدي خبرة كافية لمعرفة من أين أبدأ (سيتطلب ذلك بعض الأبحاث خلال الأيام القليلة القادمة).

على أي حال ، ليس لدي تقدير معقول لمدى صعوبة هذا الأمر ، لذلك سيكون هذا بالتأكيد شهرًا رائعًا. أنا متحمس للبدء ...

الطريقة الخطية للتعلم

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

نتيجةً لذلك ، يفترض معظم الناس أن أفضل طريق للمضي قدماً هو البدء بالأساسيات ، وبناء أساس عام للمعرفة ، ثم الاستمرار في الوصول إلى مستويات أكثر دقة وأدق من التفاصيل.

أنا أسمي هذا الأسلوب الخطي للتعلم.

إن استخدام الطريقة الخطية لتعلم علوم الكمبيوتر الخاصة بالسيارات ذاتية القيادة يبدو كالتالي:

  1. تعلم حساب التفاضل والتكامل متعدد المتغيرات
  2. تعلم الجبر الخطي
  3. تعلم أساسيات علوم الكمبيوتر الأساسية
  4. تعرف على مفاهيم تعلم الآلة العامة
  5. تعرف على مفاهيم رؤية الكمبيوتر
  6. تعلم كيفية الترميز في Python (لغة ترميز شائعة الاستخدام للتعلم الآلي)
  7. تعرف على كيفية استخدام TensorFlow (مكتبة خاصة بالتعلم الآلي لبرنامج Python)
  8. تعرف على كيفية تطبيق رؤية الكمبيوتر لإنشاء برامج سيارة ذاتية القيادة
  9. تعرف على كيفية كتابة التعليمات البرمجية Python و TensorFlow لإنشاء البرامج ذات الصلة
  10. إلخ…

على الرغم من أن هذه الطريقة قد تنجح في النهاية ، فهي غير فعالة وربما غير فعالة.

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

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

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

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

طريقة التعلم الخامس

بدلاً من ذلك ، أستخدم طريقة مختلفة ، والتي أسميها V- طريقة التعلم.

إليك طريقة عمل طريقة V للتعلم:

  1. أبدأ بمثال محدد وموثق جيدًا لهدفي النهائي
  2. أحاول أن أفهم كيف يعمل هذا المثال
  3. بالنسبة لكل شيء لا أفهمه بشأن المثال ، أبحث في المفاهيم الأساسية
  4. إذا لم أفهم المفاهيم الأساسية ، فسأبحث في المفاهيم الأساسية للمفاهيم الأساسية ، حتى أشعر أنني استنفدت هذا المسار (إما عن طريق الوصول إلى الفهم أو عن طريق الوصول إلى نقطة تناقص الغلة)
  5. في النهاية ، قمت بإغلاق مسارات مختلفة بما يكفي لبدء رؤية الأنماط في المفاهيم الأساسية المهمة
  6. أدرس هذه المفاهيم الأساسية ذات الصلة ، وأعمل ببطء في طريقي إلى سلسلة المعرفة ، حتى أعود على مستوى تفاصيل المثال الأصلي
  7. أخيرًا ، أعد إنتاج المثال بناءً على معرفتي الهرمية الجديدة

أسمي هذا الأسلوب "V-Method" لأنني أبدأ على أدق مستوى من التفصيل ، وأغوص عميقًا في اتجاه المفاهيم الأساسية القابلة للتطبيق مباشرة ، ثم أعمل في طريقي احتياطيًا نحو أرقى مستوى من التفاصيل - مفهوم V

تعد V-Method أكثر فاعلية من الطريقة الخطية ، لأنني قادر على 1. التعلم حسب مدى ملاءمة هدفي النهائي ، 2. تعلم المفاهيم الأساسية في سياق شيء ملموس ، و 3. بناء وتنظيم معرفتي بطريقة هرمية مترابطة.

نتيجة لذلك ، هذه الطريقة أكثر فاعلية وكفاءة وجاذبية.

لذلك ، إليك كيف أخطط لتطبيق V-Method على تحدي هذا الشهر:

  1. ابحث عن نموذج رمز سيارة ذاتية القيادة مفتوح المصدر على Github (يعد Github مستودعًا مشهورًا للرمز ، مما يعني أنه يمكنني العثور على الكثير من مشاريع برامج الأشخاص الآخرين هناك)
  2. العمل طريقي سطرا من خلال التعليمات البرمجية
  3. مقابل كل سطر من التعليمات البرمجية التي لا أفهمها على مستوى حدسي (سيكون معظمها) ، ابدأ في نزولي عبر طبقات المفاهيم الأساسية
  4. حدد الأنماط في ما أبحث عنه باستمرار / ابحث وحدد أهم المفاهيم الأساسية
  5. دراسة هذه المفاهيم الأساسية
  6. اعمل في طريقي احتياطيًا لطبقات المفاهيم الأساسية حتى يمكنني أن أشرح بنفسي كل سطر من التعليمات البرمجية من مشروع Github النموذجي

إذا كان هذا لا يزال مربكًا بعض الشيء ، نأمل أن يبدأ الأمر في جعله أكثر منطقية بمجرد أن أبدأ فعليًا.

خطوتي الأولى هي البحث في جيثب عن مشروع نموذج جيد ...

بالأمس ، قدمت الطريقة الأساسية التي أستخدمها لتعلم مهارات فنية جديدة ، والتي أسميها V-Method. باستخدام هذه الطريقة ، أبدأ دراستي بمثال محدد للغاية (يجب أن يحاكي عن كثب النتيجة النهائية المرجوة) ، واستخدم ذلك كنقطة بداية لتعلم المفاهيم الأساسية ذات الصلة بطريقة ملموسة ومنظمة ومنهجية.

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

العثور على بعض الرموز

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

لذلك ، من هذا ...

الى هذا…

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

الحصول على اقامة

قبل أن أتمكن من تشغيل أي رمز ، كنت بحاجة للتأكد من إعداد جهاز الكمبيوتر الخاص بي مع مكتبات البرامج المناسبة. على وجه الخصوص ، كنت بحاجة إلى تثبيت مكتبات numpy و matplotlib و OpenCV لـ Python.

بعد الحصول على التوجيه في Terminal (سطر الأوامر على Mac) والعثور على بعض التعليمات عبر الإنترنت ، واجهت خطأي الأول ...

بدلاً من محاولة معرفة معنى هذا الخطأ تمامًا أو كيفية إصلاحه بنفسي ، استخدمت تقنية تصحيح الأخطاء الأكثر فعالية التي أعرفها: لقد قمت بنسخ ولصق رسالة الخطأ بالكامل في Google.

لقد نقرت على الرابط الثالث ووجدت هذه الإجابة:

بعد تشغيل هذه الأوامر القليلة (عن طريق نسخها ولصقها في المحطة الطرفية والنقر فوق "Enter") ، يبدو أن كل شيء يعمل بشكل صحيح.

كنت رسميا كل مجموعة (على الأقل حتى الآن).

تشغيل الكود

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

حصلت على هذا الإخراج ...

رائع! لذلك ، هذه الأرقام هي في الأساس التمثيل الرياضي لخطين حارة.

حتى الان جيدة جدا. لكن أين الصور؟

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

وكذلك الصورة مع التراكبات الحمراء ...

للأسف ، لم يخرج الرمز الخاص بي أيًا من هذين ، كما أنه لم يحفظ أي صور في دليلي المحلي.

مرة أخرى ، عدت مرة أخرى إلى Google ، وفتشت "حفظ صورة بيثون" ، على أمل معرفة كيفية حفظ صورة للإخراج.

أخبرتني Google جيدًا باستخدام الدالة cv2.imwrite () ، لذلك فعلت ، وقد عملت. وبعبارة "عمل" ، أعني ... لقد تمكنت من حفظ صورة بمقياس رمادى للصورة مع خطوط حارة مرئية باللون الأبيض.

وهنا آخر ...

و واحدة اخرى…

ماذا الآن؟

هذه بداية جيدة.

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

غدًا ، نظرًا لأن الشفرة تعمل بشكل أو بآخر ، سأحاول الاطلاع على المشروع سطراً والبدء في الكشف عن كيفية عمله بالفعل.

حتى ذلك الحين ، فإن الدرس هو: إذا كنت على استعداد لقبول عدم وجود جميع الإجابات في أغلب الأحيان ، ولكنك على استعداد للتجول عبر Google قليلاً ، يمكنك إحراز تقدم على أي حال.

بالتأكيد ، ليس لدي فهم مفاهيمي قوي حتى الآن ، لكن لدي الآن مثال وظيفي يمكنني استخدامه كنقطة انطلاق.

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

الإخراج من أمس

بصدق ، لم أفهم كيف تم عمل الكود فعليًا ، لذا حاولت اليوم تغيير ذلك.

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

تستخدم هذه الوظيفة الأساسية بعض وظائف المساعد الأخرى المعرّفة في مكان آخر من التعليمات البرمجية ، ولكن هذه الوظائف المساعدة هي في الغالب مجرد طرق أنظف قليلاً لاستهلاك الوظائف المعدة مسبقًا من المكتبات التي قمت بتنزيلها بالأمس (مثل OpenCV ، على سبيل المثال).

def draw_lane_lines (صورة):
imshape = image.shape
    
    # صورة رمادية
    greyscaled_image = تدرج الرمادي (صورة)
    
    # التمويه الضبابي
    blurred_grey_image = gaussian_blur (greyscaled_image ، 5)
    
    # الحافة الكشف عن الحافة
    edges_image = canny (blurred_grey_image ، 50 ، 150)
    
    # قناع حواف الصورة
    الحدود = 0
    القمم = np.array ([[(0، imshape [0]) ، (465 ، 320) ، (475 ، 320) ،
    (imshape [1] ، imshape [0])]] ، dtype = np.int32)
    edges_image_with_mask = region_of_interest (edges_image،
    الرؤوس)
    
    خطوط هوغ #
    رو = 2
    ثيتا = np.pi / 180
    العتبة = 45
    min_line_len = 40
    max_line_gap = 100
    lines_image = hough_lines (edges_image_with_mask، rho، theta،
    الحد الأدنى ، min_line_len ، max_line_gap)
# تحويل Hough من قناة واحدة إلى RGB إلى الإعدادية لالمرجحة
    hough_rgb_image = cv2.cvtColor (lines_image، cv2.COLOR_GRAY2BGR)
 
    # الجمع بين خطوط الصورة مع الصورة الأصلية
    final_image = weighted_img (hough_rgb_image ، صورة)
    
    العودة final_image

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

اليوم ، كان هدفي هو فهم ما قامت به كل من هذه الخطوات السبع ولماذا تم استخدامها.

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

بناءً على بحثي اليوم ، سأحاول الآن شرح التسلسل التالي لأحداث معالجة الصور: صورة الإدخال → 1. الصورة الرمادية ، 2. Gaussian Blur ، 3. كشف حافة الحافة ، 4. قناع الحواف ، 5. الصورة خطوط → خط الانتاج لين

صورة الإدخال

ها هي صورة إدخال البداية.

من المهم أن تتذكر أن الصورة ليست أكثر من مجموعة من وحدات البكسل مرتبة في مستطيل. هذا المستطيل المعين هو 960 بكسل بمقدار 540 بكسل.

قيمة كل بكسل عبارة عن مزيج من الأحمر والأخضر والأزرق ، ويتم تمثيلها بثلاثة أرقام ، حيث يتوافق كل رقم مع قيمة أحد الألوان. يمكن أن تتراوح قيمة كل لون من 0 إلى 255 ، حيث 0 هي الغياب الكامل للون و 255 هي كثافة 100 ٪.

على سبيل المثال ، يتم تمثيل اللون الأبيض كـ (255 ، 255 ، 255) واللون الأسود ممثّل (0 ، 0 ، 0).

لذلك ، يمكن وصف هذه الصورة المدخلة بـ 960 × 540 = 518،400 ثلاثة أضعاف من الأرقام التي تتراوح من (0 ، 0 ، 0) إلى (255 ، 255 ، 255).

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

1. الصورة الرمادية

تتمثل خطوة المعالجة الأولى في تحويل الصورة الملونة إلى تدرج رمادي ، مما يؤدي إلى تقليل مساحة اللون بفعالية من ثلاثة أبعاد إلى بعد واحد. من الأسهل بكثير (وأكثر فاعلية) التعامل مع الصورة ذات بعد واحد فقط: هذا البعد هو "الظلام" أو "شدة" البيكسل ، حيث يمثل 0 اللون الأسود و 255 يمثل اللون الأبيض و 126 يمثل اللون الرمادي المتوسط .

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

على سبيل المثال ، إليك لون من السماء في الصورة الأصلية:

يمكن تمثيله في مساحة RGB (الأحمر والأخضر والأزرق) مثل (120 ، 172 ، 209).

إذا قمت بمتوسط ​​هذه القيم معًا ، فإنني أحصل على (120 + 172 + 209) / 3 = 167 ، أو هذا اللون في مساحة اللون الرمادي.

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

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

طريقة واحدة شائعة ، تسمى التحويل colometric تستخدم هذا المبلغ المرجح: 0.2126 الأحمر + 0.7152 الأخضر + 0.0722 الأزرق.

بعد معالجة الصورة الأصلية من خلال مرشح تدرج الرمادي ، نحصل على هذا الإخراج ...

2. غاوسي طمس

والخطوة التالية هي طمس الصورة باستخدام Gaussian Blur.

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

مرة أخرى ، تعد الرياضيات الضمنية الخاصة بـ Gaussian Blur أساسية جدًا: فالتمويه يأخذ فقط متوسطات أكثر للبكسل (عملية التوسيط هذه هي نوع من الإلتواء kernel ، وهو اسم يتوهم بشكل غير ضروري لما سأقوم بشرحه).

بشكل أساسي ، لإنشاء التمويه ، يجب عليك إكمال الخطوات التالية:

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

تقول هذه العملية بشكل أساسي "اجعل جميع وحدات البكسل أكثر تشابهًا مع وحدات البكسل القريبة" ، والتي تبدو بشكل حدسي غير واضحة.

بالنسبة إلى Gaussian Blur ، نحن نستخدم ببساطة Gaussian Distribution (أي منحنى الجرس) لتحديد الأوزان في الخطوة 3 أعلاه. هذا يعني أنه كلما اقترب البيكسل من البيكسل المحدد ، زاد وزنه.

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

3. حكيم الكشف عن الحافة

الآن وبعد أن أصبح لدينا صورة غير واضحة تدرج الرمادي والغوسي ، سنحاول العثور على جميع الحواف في هذه الصورة.

الحافة هي مجرد مساحة في الصورة حيث توجد قفزة مفاجئة في القيمة.

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

مرة أخرى ، يستخدم مرشح Canny Edge Detection رياضيات بسيطة جدًا للعثور على الحواف:

  1. حدد بكسل في الصورة
  2. حدد قيمة مجموعة البيكسلات الموجودة على اليسار ومجموعة البيكسلات الموجودة على يمين البيكسل المحدد
  3. خذ الفرق بين هاتين المجموعتين (مثل طرح قيمة واحدة من الأخرى).
  4. قم بتغيير قيمة البيكسل المحدد إلى قيمة الفرق المحسوبة في الخطوة 3.
  5. القيام بذلك لجميع بكسل.

لذا ، ادعي أننا ننظر فقط إلى بكسل واحد إلى اليسار وإلى يمين البكسل المحدد ، وتخيل أن هذه هي القيم: (اليسار بكسل ، بكسل المحدد ، بكسل الأيمن) = (133 ، 134 ، 155). بعد ذلك ، نقوم بحساب الفرق بين البكسل الأيمن والأيسر ، 155–133 = 22 ، وتعيين القيمة الجديدة للبكسل المحدد إلى 22.

إذا كانت البيكسل المحدد عبارة عن حافة ، فسيكون الفرق بين البكسل الأيمن والأيسر رقمًا أكبر (أقرب إلى 255) وبالتالي سيظهر باللون الأبيض في الصورة التي تم إخراجها. إذا لم تكن البيكسل المحدد عبارة عن حافة ، فسيكون الفرق قريبًا من 0 وسيظهر باللون الأسود.

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

تسمى هذه الاختلافات التدرجات ، ويمكننا حساب التدرج الكلي باستخدام نظرية فيثاغورس بشكل أساسي لإضافة المساهمات الفردية من التدرجات الرأسية والأفقية. بمعنى آخر ، يمكننا القول أن التدرج الكلي = التدرج العمودي² + التدرج الأفقي².

لذلك ، على سبيل المثال ، دعنا نقول التدرج العمودي = 22 والتدرج الأفقي = 143 ، ثم التدرج الكلي = sqrt (22² + 143²) = ~ 145.

الإخراج يبدو شيء مثل هذا ...

اكتمال مرشح Canny Edge Detection الآن خطوة أخرى.

بدلاً من إظهار كل الحواف فقط ، يحاول مرشح Canny Edge Detection تحديد الحواف المهمة.

للقيام بذلك ، قمنا بتعيين عتبتين: عتبة عالية وعتبة منخفضة. دعنا نقول أن الحد الأعلى هو 200 والحد الأدنى هو 150.

بالنسبة إلى أي تدرج إجمالي له قيمة أكبر من الحد الأعلى البالغ 200 ، يعتبر هذا البيكسل تلقائيًا حافة ويتم تحويله إلى أبيض نقي (255). بالنسبة إلى أي تدرج إجمالي له قيمة أقل من الحد الأدنى البالغ 155 ، يعتبر هذا البيكسل تلقائيًا "ليس حافة" ويتم تحويله إلى أسود نقي (0).

بالنسبة لأي تدرج في الفترة ما بين 150 و 200 ، يتم حساب البيكسل كحافة فقط إذا كان يلمس مباشرة بكسل آخر تم حسابه بالفعل كحافة.

الافتراض هنا هو أنه إذا كانت هذه الحافة الناعمة متصلة بالحافة الصلبة ، فربما تكون جزءًا من نفس الكائن.

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

4. قناع حواف الصورة

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

نحصل على هذا ...

يبدو مثل هذا قناعًا عدوانيًا وغامضًا ، لكن هذا ما هو مكتوب حاليًا في الكود الأصلي. لذلك ، المضي قدما ...

5. خطوط هوغ

الخطوة الأخيرة هي استخدام تحويل Hough للعثور على التعبير الرياضي لخطوط الممرات.

الرياضيات وراء تحويل هوغ أكثر تعقيدًا بقليل من جميع الأشياء المتوسطة المرجحة التي قمنا بها أعلاه ، ولكن بالكاد.

إليك المفهوم الأساسي:

المعادلة لخط هي y = mx + b ، حيث m و b هما ثوابت تمثل ميل الخط وتقاطع y للخط على التوالي.

بشكل أساسي ، لاستخدام تحويل Hough ، نحدد مساحة ثنائية الأبعاد لكل من m و b. تمثل هذه المساحة جميع مجموعات m و b التي نعتقد أنها يمكن أن تولد أفضل خط مناسب لخطوط الممرات.

بعد ذلك ، نتصفح هذه المساحة m و b ، ولكل زوج (m ، b) ، يمكننا تحديد معادلة لسطر معين من النموذج y = mx + b. في هذه المرحلة ، نريد اختبار هذا الخط ، لذلك نجد جميع وحدات البكسل الموجودة على هذا الخط في الصورة ونطلب منهم التصويت إذا كان هذا تخمينًا جيدًا لخط المسار أو لا. صوت البكسل "نعم" إذا كان أبيضًا (مثل جزء من حافة) ويصوت "لا" إذا كان أسود.

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

إليك مخرجات Hough Transform ...

إنني أتخطى الجزء حيث بدلاً من استخدام الصيغة y = mx + b لتمثيل الخط ، يستخدم تحويل Hough بدلاً من ذلك إحداثيات قطبية / نمط مثلثي يستخدم rho و theta كمعلمتين.

هذا التمييز ليس مهمًا للغاية (وفقًا لفهمنا) ، حيث لا يزال يتم تحديد المساحة في بعدين ، والمنطق هو نفسه تمامًا ، ولكن هذا التمثيل المثلثي يساعد في حقيقة أننا لا نستطيع التعبير عن رأسيًا تمامًا خطوط مع المعادلة y = mx + b.

على أي حال ، هذا هو السبب في استخدام rho و theta في الكود أعلاه.

الناتج النهائي

ونحن انتهينا.

يخرج البرنامج المعلمتين لوصف سطرين الخط (من المثير للاهتمام ، يتم تحويل هذه النواتج مرة أخرى إلى m ، b parametrization). يوفر البرنامج أيضًا إحداثيات نقاط نهاية كل خط.

خط حارة 1

المنحدر: -0.740605727717 ؛ اعتراض: 664.075746144

النقطة الأولى: (475 ، 311) النقطة الثانية: (960 ، 599)

خط حارة 2

Coef: -0.740605727717؛ اعتراض: 664.075746144

النقطة الأولى: (475 ، 311) النقطة الثانية: (0 ، 664)

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

بالأمس ، قمت بفك قطعة من الشفرة تحدد خطوط الممرات في صور الطريق الأمامية.

مثله…

ربما أكثر إثارة للاهتمام من الصورة ، تولد مجموعة التعليمات البرمجية هذه تمثيلات رياضية لخطوط الممرات باستخدام العمليات الرياضية الأساسية فقط (سلسلة من الوظائف التي تجد متوسطات مرجحة بشكل أساسي):

Lane line 1 = Slope: -0.740605727717؛ اعتراض: 664.075746144

Lane line 2 = Coef: -0.740605727717؛ اعتراض: 664.075746144.

ساعدني التدرب على هذا التمرين على فهم أفضل للميكانيكا الأساسية للسيارة ذاتية القيادة ، والتي لم تعد صوفية بعد الآن.

بناءً على ما جربته حتى الآن ، يبدو أن هناك خطوتين رئيسيتين لإنشاء برنامج سيارة ذاتية القيادة:

الخطوة 1: قم بمعالجة صورة الإدخال في مجموعة من التمثيلات الرقمية المفيدة لبيئة القيادة (مثل خطوط الممرات ، السيارات الأخرى ، إشارات المرور ، المشاة ، إلخ.)

الخطوة 2: قم بتغذية هذا التمثيل الرقمي للعالم في دالة تقوم ، بناءً على هذه المدخلات ، على حساب زاوية التوجيه والتسارع الصحيحة.

أظن أن الوظيفة في الخطوة 2 تتحسن (مع زيادة كميات القدرة الحاسوبية في المستقبل) ، وتصبح المعالجة المسبقة وتصنيف الكائنات في الخطوة 1 أقل أهمية وأقل أهمية.

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

هذا يبدو وكأنه خطة معقولة ، خاصة وأن تقنيات معالجة الصور التي وصفتها بالأمس قد تم اختراعها منذ عقود ، حيث يبدو أن "الوظيفة السحرية" قد أصبحت ممكنة مؤخرًا.

لست متأكدًا مما إذا كان هذا التحليل صحيحًا أم أن هذا المسار هو الأفضل ، لكن هذا هو حدسي الآن استنادًا إلى ما بحثته حتى الآن وعلى التمرين من الأيام القليلة الماضية.

بدءًا من غدًا ، سأبدأ في استكشاف كيفية عمل وظيفة Magic Magic وكيف قد أكون قادرًا على بنائها.

بالأمس ، أدركت أنني بحاجة إلى تحويل تركيزي وتكريس جهودي لبناء بعض إصدارات Magic Function ، وهي الخوارزمية الرياضية التي تقوم بتعيين خرائط لإدخال صور الطريق إلى تعليمات واضحة للقيادة / التوجيه للسيارة ذاتية القيادة.

اليوم ، عثرت على مجموعة بيانات بحجم 223 جيجابايت كانت مفتوحة المصدر من قبل Udacity (وهي شركة تقدم دورات عبر الإنترنت حول مواضيع تقنية ، بما في ذلك السيارات ذاتية القيادة) ، والتي تحتوي على ما أحتاجه بالضبط:

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

على سبيل المثال ، frame: 1479425444933328937؛ زاوية التوجيه: -0.346924703940749

ونتيجة لذلك ، تعد مجموعة البيانات هذه مثالية لإنشاء واختبار Magic Function - يمكنني أن أطلب من Magic Function تخمين زاوية التوجيه استنادًا إلى إطار الفيديو ، ومن ثم يمكنني مقارنة التخمين بزاوية التوجيه الفعلية المسجلة.

إذا كان التخمين بعيدًا عن القيمة الفعلية ، فيمكنني تحديث الوظيفة وإعادة اختبارها. من الناحية النظرية ، يمكنني حينئذٍ استخدام الكمبيوتر لمساعدتي على التكرار في هذه العملية آلاف المرات ، وفي النهاية أجد طريقة معقولة لتوجيه السيارة بدقة.

نظرًا لأنني فقط "نظريًا" أعرف كيفية القيام بذلك الآن ، عدت إلى جيثب اليوم لمعرفة ما إذا كان بإمكاني العثور على أي شخص يستخدم مجموعة بيانات Udacity بهذه الطريقة.

لقد وجدت بعض المشاريع ، وآمل أن أتمكن من تشغيلها بسرعة وعادلة إلى حد ما. بعد حوالي ساعتين من المحاولة ، استمررت في الحصول على أخطاء فادحة في Terminal - وليس حتى من تشغيل التعليمات البرمجية ، ولكن فقط من محاولة إعداد جهاز الكمبيوتر الخاص بي مع المكتبات اللازمة لتشغيل الرمز في المقام الأول.

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

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

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

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

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

عند المغامرة في منطقة ترميز جديدة ، إليك قوس المؤامرة الشائعة: 1. اقضي ساعتين في محاولة كل التباديل المحتمل لإعداد الكود / البيئة لمعرفة ما إذا كانت مجموعة عشوائية ستنجح ، 2. لا شيء يعمل وتدرك أنك بعيدًا انطلاقًا من هدفك مقارنةً بالوقت الذي بدأت فيه (لأنك تعثرت كثيرًا مع الكثير من الأشياء) ، 3. استمر في المحاولة لمدة ساعة أخرى ، 4. بطريقة سحرية ، تتماشى النجوم مع مجموعة من الأشياء التي لا يمكن تفسيرها مما يجعل كل شيء يعمل.

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

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

اليوم ، كنت بالكاد معلقة.

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

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

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

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

غدا ، آمل أن أستيقظ على برنامج يعمل بنجاح.

الليلة الماضية ، بعد الغرق في "حفرة ترميز اليأس" لبضع ساعات ، أخيراً أحرزت بعض التقدم إلى الأمام.

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

بعد عدة ساعات من البحث واللعب ، وجدت ورقة أكاديمية كتبها باحثون في NVIDIA (وهي شركة تصنع أجهزة وبرمجيات السيارات ذاتية القيادة ، من بين أشياء أخرى).

كما هو موضح في ملخص الورقة ، يمكن لنظامهم المبتكر "تعيين بكسلات خام من كاميرا أمامية واحدة مباشرة إلى أوامر التوجيه".

هذا هو بالضبط ما أحتاجه!

ثم وجدت تطبيق TensorFlow لنظام NVIDIA على Github ، وبعد بضع محاولات ، تمكنت بالفعل من "تدريب النموذج" استنادًا إلى بعض بيانات NVIDIA.

(تحديث: هذه ليست في الواقع بيانات NVIDIA ، وإنما هي مجموعة بيانات من إنتاج Sully Chen. لقد جمع البيانات عن طريق النقر على أنبوب كاميرا ويب إلى الزجاج الأمامي لسيارته والتقاط "بيانات محرك الأقراص" من منفذ CAN-BUS في سيارته ).

جانبًا سريعًا لتوضيح بعض المصطلحات: 1. "النموذج" هو الوظيفة التي توضح كيفية تحويل وحدات البكسل إلى تعليمات توجيهية ، و 2. "تدريب النموذج" يعني تحسين هذه الوظيفة بشكل متكرر باستخدام تقنيات التعلم الآلي. سأشرح هذه العملية بمزيد من التفصيل في منشور مستقبلي.

على أي حال ، تحتوي مجموعة بيانات NVIDIA على 25 دقيقة من الفيديو مقسمة إلى إطار على حدة ، حيث يتم تسمية كل إطار بزاوية التوجيه الحقيقية (أي زاوية التوجيه التي كان السائق البشري يستخدمها).

الإطار 45522

في المحطة الطرفية ، قمت بتشغيل البرنامج لتدريب النموذج ، وعلى الرغم من بعض التحذيرات ، فقد بدأ العمل:

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

لتدريب هذا النموذج ، استخدمت 30 فترة مع بضع عشرات من الخطوات لكل فترة.

في لقطة الشاشة ، توضح "الخسارة" مدى دقة النموذج (أو الوظيفة). من الناحية النظرية ، لحساب الخسارة ، تتم مقارنة زاوية التوجيه الحقيقية بزاوية التوجيه التي يتنبأ بها النموذج. كلما زاد الفرق ، زادت الخسارة.

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

وبالتالي ، فإن "تدريب النموذج" هو مجرد "تقليل الخسارة".

إليكم مؤامرة مع خطوات على المحور السيني وفقدان على المحور ص. (في الليلة الماضية ، باستخدام جهاز يسمى Tensorboard ، رسم جهاز الكمبيوتر الخاص بي هذا أثناء التدريب).

في الخطوة 126 ، على سبيل المثال ، كان للخسارة قيمة 5.708.

بينما ، في الخطوة 3،241 ، بعد ما يقرب من ست ساعات ، كان للخسارة قيمة أفضل بكثير عند 0.1615.

الآن وبعد اكتمال التدريب رسمياً ، أصبح الطراز جاهزًا من الناحية النظرية لتوجيه سيارة رائعة للغاية.

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

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

لدي فكرة عن حل بديل ، لكن سيتعين عليك الانتظار حتى الغد.

في غضون ذلك ، يمكنني الاحتفاء بحقيقة أنني (على الأرجح) لدي طراز سيارة ذاتية القيادة ، مدربة بالفعل ، جاهزة للاستخدام. آمل أن أتمكن غدًا من معرفة كيفية استخدامها فعليًا ...

بالأمس ، اكتشفت كيفية تدريب سيارتي ذاتية القيادة ، لكنني كافحت للتأكيد على أن التدريب كان فعالًا بالفعل.

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

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

لحسن الحظ ، قبل بضعة أيام ، اكتشفت كيفية حفظ الإطارات الفردية التي تمت معالجتها في جهازي المحلي.

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

بعد ذلك ، قمت بدمج الإطارات الفردية وتراكب مقاطع الفيديو وتشغيلها. ها هي النتيجة ...

أنا متحمس للغاية بشأن هذا!

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

تتمثل الخطوة التالية في معرفة المزيد حول الكود الأساسي ، وتحسينه للاستخدام العام ، ومن ثم معرفة كيفية عمله على مجموعات بيانات مختلفة (أي على طرق مختلفة). سأبدأ بمجموعة بيانات Udacity.

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

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

اليوم ، سأبحث على وجه التحديد عن "النموذج" ، والذي يمكن اعتباره لحمي الكود: يحدد النموذج كيفية تحويل الصور المدخلة إلى تعليمات التوجيه.

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

سيؤدي هذا إلى إعدادي لمعرفة المواد بطريقة منظمة.

إليك رمز نموذج القيادة الذاتية بالكامل. إنه فقط 50 سطرًا من الشفرات بالإضافة إلى التعليقات والمسافات (وهي عبارة عن مكسرات جميلة ، لأنها تقود سيارة ومواد ...)

استيراد tensorflow كما TF
استيراد سكيبي
متغيرة الوزن (الشكل):
  الأولي = tf.truncated_normal (الشكل ، stddev = 0.1)
  إرجاع tf.Variable (الأولي)
متغير bias_variable (الشكل):
  الأولي = tf.constant (0.1 ، الشكل = الشكل)
  إرجاع tf.Variable (الأولي)
def conv2d (x، W، step):
  إرجاع tf.nn.conv2d (x ، W ، خطوات = [1 ، خطوة ، خطوة ، 1] ، الحشو = 'VALID')
x = tf.placeholder (tf.float32 ، الشكل = [بلا ، 66 ، 200 ، 3])
y_ = tf.placeholder (tf.float32 ، الشكل = [لا شيء ، 1])
x_image = x
# الطبقة الأولى تلافيفي
W_conv1 = الوزن_متغير ([5 ، 5 ، 3 ، 24])
b_conv1 = bias_variable ([24])
h_conv1 = tf.nn.relu (conv2d (x_image ، W_conv1 ، 2) + b_conv1)
# طبقة ثانية تلافيفية
W_conv2 = الوزن_متغير ([5 ، 5 ، 24 ، 36])
b_conv2 = bias_variable ([36])
h_conv2 = tf.nn.relu (conv2d (h_conv1 ، W_conv2 ، 2) + b_conv2)
# الطبقة الثالثة تلافيفي
W_conv3 = متغير الوزن ([5 ، 5 ، 36 ، 48])
b_conv3 = bias_variable ([48])
h_conv3 = tf.nn.relu (conv2d (h_conv2، W_conv3، 2) + b_conv3)
# الرابعة طبقة تلافيفية
W_conv4 = الوزن_متغير ([3 ، 3 ، 48 ، 64])
b_conv4 = bias_variable ([64])
h_conv4 = tf.nn.relu (conv2d (h_conv3، W_conv4، 1) + b_conv4)
# الخامس طبقة تلافيفية
W_conv5 = الوزن_متغير ([3 ، 3 ، 64 ، 64])
b_conv5 = bias_variable ([64])
h_conv5 = tf.nn.relu (conv2d (h_conv4، W_conv5، 1) + b_conv5)
#FCL 1
W_fc1 = وزن_متغير ([1152 ، 1164])
b_fc1 = bias_variable ([1164])
h_conv5_flat = tf.reshape (h_conv5 ، [-1 ، 1152])
h_fc1 = tf.nn.relu (tf.matmul (h_conv5_flat، W_fc1) + b_fc1)
keep_prob = tf.placeholder (tf.float32)
h_fc1_drop = tf.nn.dropout (h_fc1 ، keep_prob)
#FCL 2
W_fc2 = الوزن_متغير ([1164 ، 100])
b_fc2 = bias_variable ([100])
h_fc2 = tf.nn.relu (tf.matmul (h_fc1_drop، W_fc2) + b_fc2)
h_fc2_drop = tf.nn.dropout (h_fc2 ، keep_prob)
#FCL 3
W_fc3 = وزن_متغير ([100 ، 50])
b_fc3 = bias_variable ([50])
h_fc3 = tf.nn.relu (tf.matmul (h_fc2_drop، W_fc3) + b_fc3)
h_fc3_drop = tf.nn.dropout (h_fc3 ، keep_prob)
#FCL 4
W_fc4 = وزن_متغير ([50 ، 10])
b_fc4 = bias_variable ([10])
h_fc4 = tf.nn.relu (tf.matmul (h_fc3_drop، W_fc4) + b_fc4)
h_fc4_drop = tf.nn.dropout (h_fc4، keep_prob)
#انتاج
W_fc5 = وزن_متغير ([10 ، 1])
b_fc5 = bias_variable ([1])
y = tf.mul (tf.atan (tf.matmul (h_fc4_drop ، W_fc5) + b_fc5) ، 2)

سطر بسطر تعليق

الآن ، سأنظر في الشفرة المقطوعة وأصف ما أعتقد أن كل قطعة تعني / لا.

استيراد tensorflow كما TF
استيراد سكيبي

أول سطرين واضحان.

نحن نستورد مكتبة TensorFlow (التي سنشير إليها باسم "tf" في مكان آخر في الشفرة) ومكتبة SciPy. TensorFlow هي مكتبة بيثون كتبها غوغل ، والتي ستساعد على تجريد معظم تطبيقات تعلم الآلة على مستوى الأرض. سوف SciPy مساعدة مع الاشياء الرياضيات.

لا شيء جديد للتعلم هنا.

متغيرة الوزن (الشكل):
  الأولي = tf.truncated_normal (الشكل ، stddev = 0.1)
  إرجاع tf.Variable (الأولي)
متغير bias_variable (الشكل):
  الأولي = tf.constant (0.1 ، الشكل = الشكل)
  إرجاع tf.Variable (الأولي)

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

في التعلم الآلي ، يتم تمثيل الوظيفة التي نحاول حلها عادة باسم Wx + b = y ، حيث يتم إعطاء x (قائمة صور المدخلات) و y (قائمة تعليمات التوجيه المقابلة) ، وتريد العثور على أفضل مزيج من W و b لجعل توازن المعادلة.

W و b ليسا في الحقيقة أرقام مفردة ، ولكن بدلاً من ذلك مجموعات من المعاملات. هذه المجموعات متعددة الأبعاد وحجم هذه المجموعات يتوافق مع عدد العقد في شبكة التعلم الآلي. (على الأقل ، هكذا أفهمها الآن).

لذلك ، في التعليمة البرمجية أعلاه ، يمثل الكائن weight_variable W ويمثل الكائن bias_variable b بالمعنى المعمم.

تأخذ هذه الكائنات مدخلات تسمى "الشكل" ، والتي تحدد بشكل أساسي أبعاد W و b.

تبدأ هذه الكائنات W و b مع وظيفة تسمى "طبيعية". أنا متأكد من أن هذا يعني أنه ... عند إنشاء مجموعات من W و b مبدئيًا ، يجب تعيين قيم المعاملات الفردية بشكل عشوائي استنادًا إلى التوزيع العادي (أي منحنى الجرس) بانحراف معياري قدره 0.1. يحدد الانحراف المعياري أكثر أو أقل مدى العشوائية التي نريد أن تكون المعاملات الأولية بها.

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

ما زلت بحاجة إلى تعلمه: أحتاج إلى معرفة المزيد عن بنية Wx + b = y ، ولماذا يتم استخدامها ، وكيف تعمل ، وما إلى ذلك ، لكنني أفهم أساسيات التعليمات البرمجية.

def conv2d (x، W، step):
  إرجاع tf.nn.conv2d (x ، W ، خطوات = [1 ، خطوة ، خطوة ، 1] ، الحشو = 'VALID')

وأعتقد أن هذا الشيء conv2d هو وظيفة تؤدي الإلتواء النواة على بعض المدخلات. تشابك Kernel هي فئة أكثر عمومية لمعالجات الصور التي تعلمتها قبل بضعة أيام.

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

يتم تعريف هذه الخاصية المحددة بواسطة "النواة" ، والتي يبدو أنها محددة باستخدام خطوات = [1 ، خطوة ، خطوة ، 1] من الأعلى. على الرغم من أنني لا أعرف معنى الخطوات أو كيف يعمل هذا بالضبط.

يبدو أن هناك ثلاثة مدخلات إلى وظيفة معالجة الصورة هذه: 1. kernel / strides (لنقول كيف نتعامل مع الصورة) ؛ 2. س (وهي الصورة نفسها) ؛ و 3. W (على ما أظن ، عبارة عن مجموعة من المعاملات التي يتم استخدامها لمزج التلاعب بالصور المختلفة معًا في بعض السعة).

يجب أن أعرف المزيد عن دور W في كل هذا.

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

ما زلت بحاجة لمعرفة: كيف يتم بالضبط تحديد وظيفة الالتواء رياضيا ، وكيف يلعب W دورا في هذا؟

x = tf.placeholder (tf.float32 ، الشكل = [بلا ، 66 ، 200 ، 3])
y_ = tf.placeholder (tf.float32 ، الشكل = [لا شيء ، 1])
x_image = x

هذه الأسطر القليلة التالية تبدو واضحة إلى حد ما. مرة أخرى ، نشير إلى المعادلة Wx + b = y.

نحن هنا نعرّف بشكل أساسي العناصر النائبة للمتغيرات x و y. تقوم العناصر النائبة بتعيين أبعاد المتغيرات (تذكر: تمثل هذه المتغيرات مجموعة من القيم ، وليس فقط رقم واحد).

نحن نقوم بإعداد x لتتوقع استلام صورة ذات أبعاد معينة ، ونقوم بإعداد y لتوقع رقم واحد كإخراج (على سبيل المثال زاوية التوجيه).

ثم نعيد تسمية x إلى "x_image" لتذكير أنفسنا بأن x صورة ، لأن ... لماذا لا.

لا شيء جديد للتعلم هنا.

# الطبقة الأولى تلافيفي
W_conv1 = الوزن_متغير ([5 ، 5 ، 3 ، 24])
b_conv1 = bias_variable ([24])
h_conv1 = tf.nn.relu (conv2d (x_image ، W_conv1 ، 2) + b_conv1)

حسنًا ، نحن الآن في صفنا التلافيفي الأول.

نعرّف W_conv1 ، والذي هو مجرد مثال محدد لمتغير الوزن الذي شرحته أعلاه (مع الشكل [5 ، 5 ، 3 ، 24]). لست متأكدًا من السبب أو السبب في تعيين الشكل بهذه الطريقة بالتحديد.

بعد ذلك نقوم بتعريف b_conv1 ، والذي هو مجرد مثال محدد للمتغير bias_variable الذي أشرحه أعلاه (مع الشكل [24]). من المحتمل أن يطابق هذا الـ 24 الرقم 24 من شكل W_conv1 ، لكنني لست متأكدًا من السبب (بخلاف ذلك سيساعد في جعل عملية مضاعفة المصفوفة).

h_conv1 هو كائن وسيط يطبق دالة الالتفاف على المدخلات x_image و W_conv1 ، ويضيف bconv1 إلى إخراج الالتواء ، ثم يعالج كل شيء من خلال دالة تسمى relu.

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

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

ما زلت بحاجة إلى تعلم: ما هي الطبقة التلافيفية ، وما الذي يفترض أن تفعله ، وكيف تفعل ذلك؟

# طبقة ثانية تلافيفية
W_conv2 = الوزن_متغير ([5 ، 5 ، 24 ، 36])
b_conv2 = bias_variable ([36])
h_conv2 = tf.nn.relu (conv2d (h_conv1 ، W_conv2 ، 2) + b_conv2)
# الطبقة الثالثة تلافيفي
W_conv3 = متغير الوزن ([5 ، 5 ، 36 ، 48])
b_conv3 = bias_variable ([48])
h_conv3 = tf.nn.relu (conv2d (h_conv2، W_conv3، 2) + b_conv3)
# الرابعة طبقة تلافيفية
W_conv4 = الوزن_متغير ([3 ، 3 ، 48 ، 64])
b_conv4 = bias_variable ([64])
h_conv4 = tf.nn.relu (conv2d (h_conv3، W_conv4، 1) + b_conv4)
# الخامس طبقة تلافيفية
W_conv5 = الوزن_متغير ([3 ، 3 ، 64 ، 64])
b_conv5 = bias_variable ([64])
h_conv5 = tf.nn.relu (conv2d (h_conv4، W_conv5، 1) + b_conv5)

ننتقل إلى الحصول على أربع طبقات تلافيفية أخرى ، تعمل بنفس الطريقة تمامًا مثل الطبقة الأولى ، ولكن بدلاً من استخدام x_image كمدخلات ، يستخدمون الإخراج من الطبقة السابقة (أي الشيء h_conv).

لست متأكدًا من الكيفية التي قررنا بها استخدام خمس طبقات وكيف تختلف أشكال كل W_conv ولماذا.

ما زلت بحاجة إلى تعلم: لماذا خمس طبقات ، وكيف يمكننا اختيار الأشكال لكل منها؟

#FCL 1
W_fc1 = وزن_متغير ([1152 ، 1164])
b_fc1 = bias_variable ([1164])
h_conv5_flat = tf.reshape (h_conv5 ، [-1 ، 1152])
h_fc1 = tf.nn.relu (tf.matmul (h_conv5_flat، W_fc1) + b_fc1)
keep_prob = tf.placeholder (tf.float32)
h_fc1_drop = tf.nn.dropout (h_fc1 ، keep_prob)
#FCL 2
W_fc2 = الوزن_متغير ([1164 ، 100])
b_fc2 = bias_variable ([100])
h_fc2 = tf.nn.relu (tf.matmul (h_fc1_drop، W_fc2) + b_fc2)
h_fc2_drop = tf.nn.dropout (h_fc2 ، keep_prob)
#FCL 3
W_fc3 = وزن_متغير ([100 ، 50])
b_fc3 = bias_variable ([50])
h_fc3 = tf.nn.relu (tf.matmul (h_fc2_drop، W_fc3) + b_fc3)
h_fc3_drop = tf.nn.dropout (h_fc3 ، keep_prob)
#FCL 4
W_fc4 = وزن_متغير ([50 ، 10])
b_fc4 = bias_variable ([10])
h_fc4 = tf.nn.relu (tf.matmul (h_fc3_drop، W_fc4) + b_fc4)
h_fc4_drop = tf.nn.dropout (h_fc4، keep_prob)

بعد ذلك ، لدينا أربعة FCLs ، والتي أعتقد أنها تمثل "طبقات متصلة بالكامل".

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

على أي حال ، سيتعين عليّ أن أتعمق في هذا الأمر.

ما زلت بحاجة إلى تعلم: ما هو FCL ، وما يحدث في كل خطوة من خطوات FCL؟

#انتاج
W_fc5 = وزن_متغير ([10 ، 1])
b_fc5 = bias_variable ([1])
y = tf.mul (tf.atan (tf.matmul (h_fc4_drop ، W_fc5) + b_fc5) ، 2)

أخيرًا ، نأخذ مخرجات الطبقة FCL النهائية ، ونقوم ببعض التلاعب بالمثلثات المجنونة ، ثم نخرج زاوية التوجيه المتوقعة.

يبدو أن هذه الخطوة هي "جعل الرياضيات تنجح" ، لكنني لست متأكدًا.

ما زلت بحاجة إلى تعلم: كيف ولماذا يتم حساب الإخراج بهذه الطريقة؟

منجز.

استغرق ذلك وقتًا أطول من المتوقع - في الغالب لأنني كنت قادرًا على تحليل أكثر مما كنت أتوقع.

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

يبدو أن الشيء المهم الوحيد الذي يجب أن نعرفه كمنشئي نماذج هو كيفية ضبط عمق (مثل عدد الطبقات) للنموذج ، وأشكال كل طبقة ، وأنواع الطبقات.

في اعتقادي أن هذا قد يكون فنًا أكثر من كونه علمًا ، لكنه على الأرجح فن متعلم.

سأبدأ في البحث في أسئلتي المفتوحة غدًا.

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

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

على وجه الخصوص ، شاهدت مجموعة من مقاطع الفيديو من قناة Computerphile على YouTube ، وهي شخصيًا قناتي المفضلة حول موضوعات متعلقة بعلوم الكمبيوتر.

إليكم فيديو Computerphile على الشبكات العصبية التلافيفية ...

وإليكم أول فيديو Computerphile في سلسلة حول تلوين النواة ...

على الرغم من كونه أقل صلة بتحدي هذا الشهر ، إلا أن Computerphile لديها قناة شقيقة على YouTube تسمى Numberphile ، والتي تناقش موضوعات في نظرية الأعداد والرياضيات بشكل عام.

إليك أحد مقاطع الفيديو Numberphile المفضلة - إنه يتميز بطريقة رائعة للغاية لتقدير قيمة pi.

على أي حال ، لقد استمتعت باستراحة اليوم ، وسأعود إلى العمل غدًا.

قبل يومين ، مررت بلحظة رمز سيارة القيادة الذاتية وحددت الأسئلة المفتوحة التي لدي حول كيفية عملها.

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

في الأساس ، إليك الأشياء المهمة التي يجب معرفتها:

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

فيما يتعلق بالمرتبة رقم 4 ، في ورقة نفيديا ، التي تصف نظام التعلم العميق الذي أستخدمه ، يوضحون أن "الطبقات التلافيفية صُممت لأداء استخراج المعالم وتم اختيارهم تجريبياً من خلال سلسلة من التجارب التي تباينت تكوينات الطبقات".

إليكم الأمر التالي: سر إنشاء شبكة عصبية تلافيفية فعالة هو تجربة مجموعة من مجموعات مختلفة من المكونات المستخدمة عادة ومعرفة ما هو الأفضل.

في الأساس ، طالما أنك تفهم المكونات الأساسية ، فإن بناء سيارة فعالة ذاتية القيادة (نفيديا مستقلة بنسبة 98٪) ليس أكثر من مجرد "تخمين وتحقق". (يمكن القول أنه إذا كنا نريد الحصول على السيارة من 98 ٪ إلى 100 ٪ مستقلة ، يجب علينا أن نفعل أكثر قليلا من التخمين والتحقق ، وهذا صحيح اليوم ، ولكن ربما نصبح أقل حقيقة مع مرور الوقت كما كنا تطبيق متزايد أكثر قوة المعالجة لهذه المشكلة).

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

أتوقع أنه خلال 18-24 شهرًا ، وصلنا إلى مستوى من التجريد حيث يمكن إنشاء سيارة ذاتية القيادة في سطر واحد من الكود - وهو ما أعتقد أنه يعني أن تحدي التعلم هذا الشهر لن يمضي قدمًا جيدًا.

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

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

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

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

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

كانت الخطوة الأولى هي تهيئة مجموعة بيانات Udacity ، بحيث يمكن معالجتها بواسطة طراز السيارة ذاتية القيادة.

بخلاف مجموعة بيانات NVIDIA ، التي تحتوي على مقطع فيديو مقسم بشكل جيد إلى إطارات مرقمة بالتسلسل (0.jpg ، 1.jpg ، 2.jpg ، 3.jpg ، وما إلى ذلك) ، فإن مجموعة بيانات Udacity عبارة عن مجموعة من الصور ذات الأرقام المربكة: هناك فجوات غريبة غير متسقة الحجم بين الأرقام ، وتبدأ مجموعة البيانات في العد في 1479425441182877835.

من المحتمل أن يكون لدى Udacity بعض الأساس المنطقي لمخطط الترقيم هذا ، لكن لا يبدو لي أن أعرف ماهية هذا الأساس المنطقي.

لذلك ، كانت خطوتي الأولى هي إعادة تسمية كل هذه الملفات لتتوافق مع نظام الترقيم على غرار NVIDIA (على سبيل المثال ، ابدأ من الصفر وعد من جانب آخر).

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

بعد حوالي 12 دقيقة من الشعيرية ، تمكنت من كتابة نص بيثون صغير لإعادة تسمية جميع ملفات Udacity.

استيراد نظام التشغيل
إعادة تسمية def (الدليل):
أنا = 0
من أجل file_name في os.listdir (الدليل):
      new_file_name = str (i) + '.jpg'
      old_file_name = file_name
os.rename (old_file_name ، new_file_name)
أنا + 1
PATH = os.path.abspath ('/ Users / maxdeutsch / Desktop / nvidia / udacity_data')
إعادة تسمية (PATH)

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

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

للأسف ، الأداء سيء للغاية: إذا اتبعت هذه السيارة ذاتية القيادة هذه الإرشادات في الواقع ، فسوف تتعطل فورًا تقريبًا.

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

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

من الواضح أن النموذج المدرّب على مجموعة بيانات NVIDIA غير مناسب لمجموعة بيانات Udacity.

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

إليك إطار ثابت من مجموعة بيانات NVIDIA:

وهنا لا يزال من مجموعة بيانات Udacity:

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

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

كانت مهمة اليوم هي إعادة صياغة مجموعة بيانات Udacity بحيث يمكن استخدامها للتدريب.

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

من هذا…

الى هذا…

بعد إعداد الصور ، احتجت بعد ذلك إلى إنشاء ملف نصي يسمى "data.txt" لمجموعة بيانات Udacity ، والتي تسرد زاوية التوجيه الصحيحة بجوار اسم الصورة المطابقة.

إليك ما يبدو عليه ملف data.txt الخاص بـ NVIDIA:

ليست هذه هي الشاشة الأكثر جاذبية ، نظرًا لأن أول 22 زاوية توجيه صفرية.

ومع ذلك ، تم تجميع بيانات Udacity في جدول بيانات مثل هذا:

لذلك ، لإنشاء ملف data.txt لمجموعة بيانات Udacity ، كنت بحاجة لإنجاز أمرين: 1. أعد تسمية frame_ids لتتوافق مع نظام ترقيم الأمس ؛ 2. معرفة كيفية تحويل جدول بيانات إلى ملف نصي دون أي تنسيق على غرار الجدول.

بدلاً من استخدام برنامج نصي Python ، حاولت معرفة كيفية القيام بالخطوتين في صفحات Google (من المحتمل وجود طريقة أكثر فاعلية).

أولاً ، قمت بكتابة تسلسل صغير من الأرقام المتتالية ، ثم قمت بسحب التسلسل لملء الخلايا الأخرى البالغ عددها 5000 خلية.

بعد ذلك ، استخدمت الدالتين المدمجتين TO_TEXT و CONCATENATE لتحويل الأعداد الصحيحة إلى سلاسل ثم وصل سلسلة هذه السلاسل مع امتداد الملف .jpg.

On to Step 2 - تحويل الجدول إلى مستند نصي غير منسق.

لقد استخدمت CONCATENATE مرة أخرى لدمج أسماء الصور وزوايا التوجيه في خلية واحدة (مع فاصل مسافة واحدة).

بعد ذلك ، قمت بتسلسل كل خلية باستخدام الحرف (10) ، وهو رمز الحرف لفواصل الأسطر. وأخيرا ، متسلسل جميع الخلايا في خلية واحدة.

قمت بنسخ محتويات هذه الخلية المنفردة في مستند نصي ، وكان ملف data.txt الخاص بي جاهزًا للذهاب.

الشيء الغريب هو أن أرقام زاوية توجيه Udacity تبدو مختلفة تمامًا عن أرقام زاوية توجيه NVIDIA.

يبدو أن الشركات تستخدم تمثيلات زاوية توجيه مختلفة تمامًا ، لكنني لست متأكدًا تمامًا من كيفية ارتباط الطريقتين رياضيا.

قد أكون قادرًا على تدريب النموذج بنجاح دون اكتشاف هذه العلاقة الرياضية ، لكنني متشكك في هذه الحالة.

سوف أستكشف هذا الأمر غدًا ، ثم ابدأ في تدريب النموذج على بيانات Udacity.

بالأمس ، انتهيت من تهيئة مجموعة البيانات الجديدة ، لذلك ، عندما وصلت إلى المنزل من العمل اليوم ، كنت مستعدًا لبدء تدريب النموذج.

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

عادةً ما تحصل على هذا النوع من الخطأ عندما يتوقع البرنامج قائمة بالأشياء أطول من قائمة الأشياء الفعلية.

نظرًا لأن مجموعة بيانات NVIDIA أطول / أكبر من مجموعة بيانات Udacity ، فكنت أحسب أن قيمة طول القائمة يجب أن تكون مضغوطة ، ويمكنني ضبط هذه القيمة وفقًا لذلك.

ومع ذلك ، بعد الاطلاع على الشفرة ، لم أتمكن من العثور على المشكلة. كل شيء بدا وكأنه يجب أن تعمل.

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

قمت بتشغيل البرنامج باستخدام عبارات الطباعة ، وحصلت على هذا الإخراج:

تم تكرار البرنامج بنجاح من خلال جميع سطور البيانات الفعلية ، ثم بدا أنه حاول تحليل سطر إضافي من البيانات غير موجود.

لذا ، فتحت ملف data.txt ، وأنا متأكد بما فيه الكفاية ... لقد نسخت بطريق الخطأ بعض الأسطر الفارغة في نهاية الملف.

لقد حذفت هذه الأسطر الثلاثة الفارغة وأعد تشغيل البرنامج في الجهاز الطرفي.

نجحت ، وبدأ النموذج التدريب.

بينما يتدرب النموذج (سنقوم بتسجيله غدًا) ، اعتقدت أنني سأشارك جانبًا سريعًا وممتعًا:

اليوم ، أثناء انتقالي إلى العمل ، مررت بسيارة ذاتية القيادة من Google / Waymo بالقرب من محطة القطار Mountain View.

بعد ذلك ، في بيتي للتنقل ، على بعد بضعة صفوف من الأبنية من شقتي ، رأيت اثنين من Ubers ذاتية القيادة على التوالي.

فيما يلي صورة أوضح قليلاً عن الرصاص Uber: يبدو أنه يتم تشغيله حاليًا من قِبل الإنسان ، على الأرجح لأغراض التدريب. سيارة جوجل كانت تقود نفسها.

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

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

كان اليوم مجموعة حزينة من الأخطاء وحواجز الطرق (مع عدم وجود نهاية سعيدة). بينما حاولت أن أفدي نفسي ، ظللت أعمق وأعمق أسفل فتحة الأرانب.

بدأت أمس - قمت بإعادة تهيئة بيانات Udacity بنجاح وبدأت في تدريب طراز السيارة ذاتية القيادة.

بعد الانتهاء من التدريب ، ألقيت نظرة سريعة على الرسم البياني للخسارة (يقيس الخسارة "دقة" النموذج - كلما انخفضت الخسارة ، كان النموذج أفضل ... للجزء الأكبر).

بعد 30 فترة تدريب ، لم تنخفض الخسارة إلى ما دون 1.00 ، حيث ، عندما قمت بتدريب النموذج على بيانات NVIDIA ، انخفضت الخسارة بشكل ملحوظ إلى ما دون 1.00 ، وصولًا إلى 0.16 تقريبًا.

لست متأكدًا من سبب توقع حدوث شيء مختلف - لم تكن مجموعة بيانات Udacity التي استخدمتها سوى 1/8 بحجم مجموعة بيانات NVIDIA.

كان هذا غلطتي الأولى: لقد استخدمت بطريق الخطأ مجموعة بيانات الاختبار لتدريب النموذج. بدلاً من ذلك ، كان ينبغي أن أستخدم مجموعة البيانات التدريبية الأكبر بكثير ، ثم اختبرت النموذج المدرّب على مجموعة بيانات الاختبار.

ليست مشكلة كبيرة: ذهبت إلى صفحة Udacity Github وقمت بتنزيل مجموعة البيانات الأكبر للتدريب. أو على الأقل حاولت ذلك.

في منتصف التنزيل ، كان جهاز الكمبيوتر الخاص بي مروعًا تمامًا.

اتضح أن قرص التخزين / بدء التشغيل المحلي الخاص بالكمبيوتر كان ممتلئًا تمامًا. ممتلئ حتى أن جهاز الكمبيوتر الخاص بي رفض تشغيل أي برامج. حتى الباحث تم تحطمها بشكل غير متوقع.

لقد قمت بتوصيل محرك الأقراص الصلبة الخارجي الخاص بي ، وبدأت في نقل مستندات "كل شهر" إلى "ماستر" من الجهاز المحلي.

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

على أي حال ، فقد تحطمت الأشهر الستة الأولى من وثائق M2M على 132 جيجابايت ، وكان 70.8 منها على جهازي المحلي ، لذلك ، بمجرد انتهاء عملية النقل ، تمكنت من نقل 70 جيجابايت من المواد المحلية إلى Trash.

بعد ذلك ، عند محاولة تفريغ سلة المهملات ، تجمد جهاز الكمبيوتر الخاص بي ...

بعد إعادة تشغيل جهاز الكمبيوتر الخاص بي عدة مرات ، أفرغت Trash أخيرًا ، وبعد 30 دقيقة ، عدت للعمل.

مع وجود مساحة الآن على جهاز الكمبيوتر الخاص بي ، عدت إلى صفحة Udacity Github لتنزيل مجموعة بيانات التدريب.

تم ضغط مجموعة البيانات التدريبية فعليًا بسيل ، لذلك كنت بحاجة إلى تثبيت BitTorrent لتنزيل مجموعة البيانات.

بعد تنزيل السيل ، فككت الملف. توقعت أن أرى مجموعة من صور JPEG وملف data.txt كما رأينا من قبل ، ولكن بدلاً من ذلك ، رأيت هذا ...

على ما يبدو ، اعتقد Udacity أنه سيكون من الجيد تجميع البيانات في ملفات .bag. لم أسمع من قبل ملفات .bag من قبل ، لكن يبدو أنها الطريقة الأصلية التي تقوم بها السيارات ذاتية القيادة (أو غيرها من "الروبوتات" بحفظ البيانات).

لذلك ، كنت بحاجة لمعرفة كيفية استخراج ملفات JPEG و CSV من ملفات .bag الفردية.

هناك مكتبة تسمى ROS (نظام التشغيل Robot) اللازمة للعمل مع ملفات .bag ، لذلك حاولت تثبيتها.

ولكن ، هذا ما وجدته في صفحة تثبيت ROS ...

بمعنى آخر ، فإن الأشخاص الذين يصنعون ROS يقولون بشكل أساسي "هذا لن ينجح. سوف تفشل. آسف."

وكانوا على حق ، لقد فشلوا.

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

في هذه المرحلة ، اضطررت إلى التوقف ليلاً.

غدا ، آمل أن أتمكن من إحراز بعض التقدم إلى الأمام.

بالأمس ، واجهت صعوبة بالغة: كنت أحاول تحويل ملفات ROSbag من Udacity إلى ملفات JPEG و CSV ، لذلك يمكنني استخدام البيانات لتدريب سيارتي ذاتية القيادة ، لكنني لم أكن محظوظًا.

في النهاية ، اكتشفت أن نظام التشغيل Robot غير متوافق مع Mac ، وبالتالي ، لا يمكنني استخراج الملفات بشكل صحيح محليًا على جهاز الكمبيوتر الخاص بي.

اليوم ، بعد الكثير من التجربة والخطأ ، تمكنت من معرفة كيفية تشغيل Ubuntu 14.04 و ROS على جهاز افتراضي باستخدام VirtualBox.

بعد المزيد من التجربة والخطأ ، اكتشفت كيفية استخدام الجهاز الظاهري لاستخراج محتويات ملفات ROSbag ...

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

بدلاً من ذلك ، تشتمل مجموعة بيانات Udacity على حوالي 33000 إطارًا من مقاطع فيديو القيادة من ثلاث زوايا مختلفة للكاميرا وجميع البيانات الخاصة بالتوجيه والكبح والخانق ونظام تحديد المواقع العالمي ، إلخ.

ضمن CSV للتوجيه ، على سبيل المثال ، تتضمن البيانات ، ليس فقط الطابع الزمني والزاوية ، ولكن أيضًا عزم الدوران (قوة الدوران على العجلة) والسرعة (سرعة الدوران).

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

بالأمس ، تصدعت مجموعة بيانات Udacity ...

لذلك ، كانت الخطة اليوم هي إعادة صياغة / إعداد البيانات ، ثم البدء في تدريب طراز السيارة ذاتية القيادة.

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

لإعداد البيانات ، كنت بحاجة لإنشاء ملف data.txt يبدو كالتالي:

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

بدا هذا واضحًا بما فيه الكفاية - لكن كانت هناك مشكلة:

عندما فتحت ملف steering.csv ، لم تطابق أي من الطوابع الزمنية في الملف الطوابع الزمنية لإطارات JPEG. اعتقدت أنني ربما تطل على شيء ...

لذلك ، ذهبت من خلال JPEGs ونسخ أول أرقام الزوجين الإطار.

بعد ذلك ، قمت بشكل منفرد بالبحث في ملف CSV عن أرقام الإطارات هذه ، لكنها لم تكن موجودة ...

كانت هذه مشكلة.

إذا لم أتمكن من مطابقة الصور مع بيانات القيادة ، تصبح مجموعة البيانات عديمة الفائدة تمامًا.

لحسن الحظ ، كان لدي فكرة غير رائعة عن فتح ملفات CSV الأخرى في مجموعة بيانات Udacity (فقط لمعرفة ماذا كان هناك) ، وفي النهاية فتحت ملف interpolated.csv ، والذي يتميز بجميع البيانات في مكان واحد ويتطابق مع كل هذا البيانات إلى الطوابع الزمنية على الصور تماما.

لذلك ، كنت مرة أخرى في الحظ.

لقد استخرجت البيانات التي أحتاجها ، وأنشأت ملف data.txt ، وبدأت في تدريب النموذج.

هذا سيستغرق على الأرجح طوال الليل ، لذلك سوف نتحقق منه غدًا.

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

بدأت قيمة الخسارة (المقياس الذي يتناسب بشكل غير مباشر مع دقة النموذج) عند 6.14783.

بعد عدة ساعات ، انتهى النموذج من التدريب ، مما قلل الخسارة إلى 0.000377398 فقط.

إليكم مؤامرة الخسارة بمرور الوقت:

هذا الانخفاض في الخسارة ملفت للنظر.

والأكثر إثارة للدهشة هو الفرق في الخسارة عند استخدام 5000 نقطة بيانات (كما فعلت قبل بضعة أيام) ، مع خسارة مقدارها 1.00 دولار تقريبًا ، وعند استخدام نقاط بيانات Udacity البالغة 33000 نقطة ، وخسارة تبلغ حوالي 0.000377398.

بمعنى آخر ، بزيادة حجم مجموعة البيانات بعامل ~ 7 ، تم تقليل الخسارة بمعامل ~ 2500. من الواضح أن هذه ليست علاقة خطية: مع وجود بيانات أكثر قليلاً ، يصبح النموذج أفضل بشكل يبعث على السخرية.

وهذا هو السبب وراء قدرة Google على توفير كل / معظم خوارزميات التعلم الآلي والمكتبات عبر TensorFlow: كمية البيانات هي الفرق ، وجوجل لديها أكثر من غيرها (من البحث والبريد الإلكتروني والصور ومقاطع فيديو يوتيوب ، إلخ)

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

اليوم ساعدني حقًا في تقدير قيمة البيانات كميزة تنافسية.

الحديث عن البيانات ... لقد وصلت إلى علامة بارزة في إنشاء مجموعة البيانات الخاصة بي: اليوم يصادف اليوم المائتين على التوالي الذي كتبت فيه مدونة منشورة كجزء من مشروع "شهر إلى ماجستير" الخاص بي.

مجموعتي من الإدخالات اليومية يبلغ الآن حوالي 85000 كلمة. ربما ، بمجرد انتهائي من جميع المنشورات الـ 365 ، سأكتشف شيئًا مثيرًا للاهتمام يتعلق بمجموعة البيانات هذه ...

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

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

هناك عدد قليل من الأشياء ملاحظة:

  • في الأصل ، اعتقدت أن هناك مجموعتي بيانات Udacity: مجموعة بيانات تدريب (استخدمتها بالأمس) وبيانات اختبار (استخدمتها عن طريق الخطأ للتدريب قبل بضعة أيام). اليوم ، أدركت أن مجموعة بيانات الاختبار هي في الواقع مجموعة فرعية من مجموعة التدريب ، لذلك قررت بدلاً من ذلك استخدام بعض بيانات Nvidia للاختبار. الشيء المهم هنا هو أن النموذج تم تدريبه على مجموعة بيانات Udacity واختباره على أرض جديدة تمامًا من مجموعة بيانات Nvidia. بمعنى آخر ، يعمل النموذج جيدًا على الطرق خارج مجموعة التدريب الخاصة به (هذا مهم جدًا إذا كنت تريد سيارة ذاتية القيادة عالميًا).
  • من أجل محاكاة مخرجات نموذج Udacity بشكل صحيح ، كنت بحاجة إلى القيام بأمرين: 1. قم بتعيين بيانات Udacity إلى مجموعة من القيم القابلة للاستخدام بواسطة محاكي Nvidia (يستخدم نموذج Nvidia الدرجات كوحدات ، بينما تتراوح مجموعة بيانات Udacity من -1 إلى 1) ، و 2. قم بإجراء بعض المعالجة المسبقة الثانوية لمجموعة اختبار Nvidia (أي الاقتصاص) لاختبار نموذج Udacity.
  • أثناء الاختبار ، قدم البرنامج النصي صورًا لعجلة القيادة تدور استنادًا إلى زاوية التوجيه المتوقعة ، وبعد ذلك قمت بتراكب هذه الإطارات أعلى لقطات Nvidia الأصلية غير المقطوعة للحصول على عرض أوسع قليلاً.
  • بعد مرور 40 ثانية تقريبًا على الفيديو ، تتوقف السيارة تمامًا ، ثم تقوم بدورها الصحيح. يبدو أن السيارة تبدأ في الدوران قبل أن تشير الصور المرئية إلى أنه من المفترض أن تسير في الاتجاه الصحيح (يمكن أن تسير السيارة مباشرة بعد كل شيء) ، لذلك لست متأكدًا من كيفية حدوث ذلك. لا تحتوي مجموعة بيانات Udacity على أي معرفة بهذا المنعطف بعينه. التفسير الوحيد المعقول هو أن النموذج قد تم إدراكه في خط السير ، أو أن النموذج هو مجرد مسند أكثر من إنسان. وفي كلتا الحالتين ، كان هذا مفاجأة بعض الشيء ، ولكن رائع أن نرى.

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

خلال معظم هذا الشهر ، كنت أركز على إنشاء أداة تحديد زاوية التوجيه لسيارتي ذاتية القيادة.

ومع ذلك ، لإنهاء سيارتي ، من المهم أن أفهم كيفية إنشاء نظام للتحكم في دواسة الوقود / دواسة الوقود وفرامل السيارة (أي "الدواسات").

رغم أن هذا قد يبدو بمثابة تحدٍ جديد تمامًا ، فقد اتضح أنه يمكنني بناء نظام دواسة الخاص بي دون كتابة أي كود جديد للخطوط.

بعد كل شيء ، تم بناء نموذج التوجيه الخاص بي على 1. عرض الكمبيوتر على مجموعة من الصور ، 2. تعيين قيمة رقمية لكل صورة ، 3. مطالبة الكمبيوتر لمعرفة كيفية ارتباط بكسلات الصور بالقيم الرقمية ، 4 استخدام هذه العلاقة للتنبؤ بالقيمة الرقمية المخصصة للصور الأخرى.

في حالة مسند التوجيه ، تمثل هذه القيمة الرقمية زاوية التوجيه. ولكن ، يمكن أن يمثل بسهولة مقدار الكبح أو الكبح.

وبالتالي ، لبناء نظام الدواسة ، كل ما أحتاج إليه هو إعادة تعيين قيمة رقمية لكل صورة تتوافق مع مقدار الخانق الصحيح أو مقدار الكبح الصحيح ، ثم اطلب من الكمبيوتر (بنفس الطريقة الدقيقة) تحديد العلاقة بين البيكسلات والقيم الرقمية.

هذا ما فعلته.

على سبيل المثال ، في حالة دواسة الوقود ، قمت بإعداد data.txt مع 10000 صورة متطابقة مع مقدار الخانق المقابل لها ، ثم قمت بتشغيل هذا الملف من خلال نفس نموذج تعلم الآلة نفسه.

وكما هو متوقع ، تعلم النموذج بمرور الوقت ، وقلل من الخسارة ، وحدد طريقة فعالة للتنبؤ بحجم الخانق.

فعلت الشيء نفسه بالنسبة لنظام الكبح.

بمعنى آخر ، نموذج التعلم الآلي الذي كنت أستخدمه عام تمامًا. لا يهم إذا كانت المدخلات عبارة عن زوايا توجيهية أو قيم دواسة الوقود أو قيم الكبح. النموذج لا يميز.

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

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

في هذا الشهر ، تحدّيت نفسي لبناء جزء البرنامج من سيارة ذاتية القيادة. على وجه الخصوص ، أردت أن أبني شيئين رئيسيين: 1. نظام توجيه السيارة و 2. نظام دواسة السيارة (أي دواسة الوقود والفرامل).

قبل يومين ، انتهيت من بناء نظام التوجيه - الذي يمكنه التنبؤ بدقة بزاوية التوجيه بناءً على تغذية فيديو أمامية للطريق.

لكي يُعتبر نظام التوجيه ناجحًا ، حددت هدفين فرعيين:

  1. كنت بحاجة إلى تكييف واستخدام طراز السيارة ذاتية القيادة في مجموعة بيانات لم يتم تصميمها خصيصًا لها. منذ أن استخدمت نموذجًا يستند إلى ورقة بحث NVIDIA تم تطبيقها على مجموعة بيانات مقدمة من Udacity ، فقد استوفيت متطلبات هذا الهدف الفرعي.
  2. ثانياً ، كنت بحاجة لتدريب النموذج على مجموعة بيانات واحدة (أي مجموعة من الطرق) ، ولديها أداء جيد على مجموعة بيانات مختلفة تمامًا (مثل مجموعة من الطرق الجديدة). منذ أن قمت بتدريب النموذج على مجموعة بيانات Udacity ، ثم قمت باختبار النموذج بنجاح على مجموعة بيانات NVIDIA ، فقد استوفيت أيضًا متطلبات هذا الهدف الفرعي.

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

مع تجميع كل هذه القطع ، فإن تحدي هذا الشهر قد اكتمل رسميًا!

بالأمس ، أكملت تحدي هذا الشهر ، حيث نجحت في بناء جزء البرنامج من سيارة ذاتية القيادة.

الآن ، السؤال هو ... ما الذي يجب عمله / بناءه من أجل إخراج سيارتي فعليًا من شوارع كاليفورنيا؟

أفضل إجابة تأتي من جورج هوتز - الذي كان رائدًا في حركة السيارات ذاتية القيادة.

منذ 18 شهرًا ، نشر بلومبرج مقطع فيديو عن هوتز البالغ من العمر 26 عامًا ، والذي بنى سيارة تعمل بكامل طاقتها (أكثر أو أقل) في مرآب سيارته:

في الفيديو ، يوضح جورج أنه يحتاج فقط إلى بناء شيئين لإنشاء السيارة: 1. نظام يمكنه إخراج تعليمات القيادة استنادًا إلى بيانات الإدخال ، و 2. نظام يمكنه التحكم في المشغلات المادية للسيارة (أي عجلة القيادة ، خنق ، الفرامل) على أساس المدخلات الرقمية.

في بداية هذا الشهر ، دعوت # 1 "جزء البرنامج" و # 2 "الجزء الأجهزة" ، مع التركيز طاقاتي على البرنامج. لذا ، بعد إكمال # 1 ، لإنهاء تطوير سيارتي ، سأحتاج إلى معالجة # 2.

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

لا أعرف أنني أعرف الكثير عن السيارات ، ولكن هذا شعور ودود للغاية (طالما أن لدي إمكانية الوصول إلى الإنترنت ويوتيوب). إذا كان لديّ شهر آخر ، والأهم من ذلك سيارة ، فستكون هذه هي الخطوة الطبيعية التالية.

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

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

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

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

في فبراير 2017 ، هبطت backflip. إذا كان الأمر بدلاً من فبراير 2020 ، فلن يحدث فرقًا.

في ديسمبر 2016 ، تعلمت رسم صور واقعية. إذا كان الأمر بدلاً من ذلك في ديسمبر 2036 ، فلن يحدث فرقًا.

في هذا الشهر ، مايو 2017 ، قمت ببناء جزء البرنامج من سيارة ذاتية القيادة. إذا كان هذا هو مايو 2020 ، فسيكون هذا التحدي مختلفًا تمامًا.

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

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

في الأساس ، ما أقوله هو أن تحدي هذا الشهر لن يكون تحديًا خلال بضع سنوات.

ليست هذه مشكلة كبيرة ، ولكن من المثير للاهتمام التفكير في مدى تقادم المهارات وكيف يصبح "الطليعة" بسرعة "وسط ممل".

ربما ، ينبغي علي التفكير في تحدي أداء هذا الشهر ، حيث يكون الأداء "الهاوي العادي يبني برمجيات ذاتية القيادة في عالم لا يزال الناس يقودون فيه السيارات". بعد ذلك ، قد تظل مجموعة منشورات هذا الشهر أكثر ملاءمة / اهتمامًا بمرور الوقت. بعد كل شيء ، الفن مكاسب عادة في القيمة مع مرور الوقت.

على أي حال ، مجرد ملاحظة اعتقدت أنها تستحق المشاركة.

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

أثناء وجودي في سياتل ، سأستمر في كتابة مشاركاتي اليومية (حيث لا يزال لدي الكثير لأفكر فيه فيما يتعلق بعملياتي وتقنيات / رؤى تعليمية) ، لكنني لا أعتزم العمل على أي برامج أخرى .

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

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

الهدف الأكثر تحديدًا هو الأفضل.

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

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

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

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

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

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

بعد كل شيء ، كانت سيارتي ذاتية القيادة تعتمد على شفرة المصدر المفتوح لشخص آخر (والتي قمت بتكييفها وتعميمها بشكل خفيف). يستند هذا الكود المفتوح المصدر إلى ورقة كتبها فريق أبحاث السيارة ذاتية القيادة في NVIDIA. استند هذا النموذج من البحث على التقنيات الرياضية (backpropagation ، وما إلى ذلك) التي تم اختراعها خارج مختبر NVIDIA ، وخاصة في مراكز البحوث الجامعية. ويمكنني الاستمرار ...

هذه التقنيات الرياضية مبنية على أساس رؤى أساسية من حساب التفاضل والتكامل ، والتي اخترعت منذ مئات السنين ، وهلم جرا.

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

لا يزال بإمكاني الاستمرار ... لكن ذلك لن يحدث.

إذاً ، بالعودة إلى السؤال: ما الذي أنجزته شخصيًا هذا الشهر؟ هذا ليس واضحًا تمامًا.

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

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

كلاهما صحيح.

لذلك ، هل أقوم بالفعل بصنع سيارة ذاتية القيادة؟ هل يمكنك القول أن شركات مثل OnePlus أو Xiaomi تقوم ببناء هواتف ذكية ، حتى لو تم تصميم البرنامج بواسطة Google ومكونات الأجهزة الخاصة بي مثل Samsung و Foxconn وغيرها؟

هل يعتبر "التجمع" بمثابة "بناء" ، وهل يعتبر "التجميع" بمثابة "تعلم"؟

أود أن أقول نعم ، لكنني لا أعتقد أن الأمر مهم.

الأمر الأكثر إثارة للاهتمام هو: في بعض الأحيان ، تكون الأشياء التي تبدو صعبة أو يتعذر الوصول إليها في الواقع أكثر ملاءمة للمبتدئين مما تبدو. وبالتالي ، كان الفرق بين "بناء سيارة ذاتية القيادة" وليس اعتقادي أنه يمكنني معرفة ذلك ومحاولة القيام بذلك.

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

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

أعتقد أن هذه نتيجة أكثر إثارة للاهتمام على أي حال.

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

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

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

أحد الأسئلة الشائعة التي أسمعها ردا على الراحة العامة لدي هو: "ألا تفضل أن تكون مسيطرًا على حياتك؟ حتى لو كان استخدام السيارة المستقلة بالكامل أكثر أمانًا من الناحية الإحصائية ، ألا تريد أن تعرف أنك فعلت كل ما بوسعك شخصيًا لإبقائه على قيد الحياة؟ "

نوعا ما. لكن ، بصدق ، بما أنني لا أملك سيارة ، وأثق بالفعل في الغرباء (سائقي Uber / Lyft) في حياتي ، لست متأكدًا من أنني أمتلك حاليًا هذه السيطرة على أي حال.

وكإضافة قصيرة: منذ يومين ، نشرت MIT ورقة بحثية سنوية حول الحالة الحالية لاهتمام المستهلكين بالسيارات ذاتية القيادة ، وقال 48 ٪ من المشاركين البالغ عددهم 3000 مشارك في الدراسة إنهم لن يشتروا أبدًا سيارة تقود نفسها تمامًا.

ليس ذلك فحسب ، بل قال 40٪ من الأطفال الذين تتراوح أعمارهم بين 25 و 34 عامًا أنهم سيكونون مرتاحين لسيارة بدون سائق بالكامل ، ومع ذلك ، قال 20٪ فقط من نفس المجموعة نفس الشيء هذا العام.

من المثير للاهتمام أن نرى أنه ، بينما يتعلم عامة الناس المزيد عن السيارات ذاتية القيادة ، تتضاءل راحتهم.

بصراحة ، بعد قراءة ورقة معهد ماساتشوستس للتكنولوجيا ، قد أتفق مع عامة الناس (على الأقل ، اعتبارًا من اليوم ... لكنني ما زلت متفائلًا جدًا).

أقوم حاليًا بزيارة أحد الأصدقاء في سياتل ، والذي يمنحني وقتًا صعبًا حول المنشور الذي كتبته قبل يومين:

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

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

في منشور الجمعة ، أوافق على أن التحدي المتصوَّر (المتمثل في إنشاء آلية قيادة ذاتية) لم يكن في الواقع التحدي ، لكن هذا لا يعني أنه لم يكن هناك تحدٍ على الإطلاق.

في الحقيقة ، أنا أزعم أن التحدي الملموس ليس في الواقع هو التحدي الحقيقي.

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

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

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

هذا ليس مفاجئًا - معظم هندسة البرمجيات لا تبني بالضرورة مكونات جديدة تمامًا. عادةً ، يكتشف كيفية أخذ مجموعة من المكونات الموجودة مسبقًا ، وتناسبها جميعًا معًا ، ويكون لها وظيفة الإخراج كما هو متوقع.

في رأيي ، فإن هندسة البرمجيات تشبه إلى حد كبير إجراء عملية زرع الأعضاء: لا تكمن الحيلة في العثور على العضو البديل (على الرغم من أن هذا لا يزال عملية طويلة). الحيلة هي جعل الجسم لا يرفض العضو الجديد.

وبالمثل ، تنطوي هندسة البرمجيات على تحديين رئيسيين: 1. العثور على "العضو" (أي مثال على المكون الذي تريد بناءه) ، 2. دمج هذا "العضو" في الجسم الكلي (أي ضمان تهيئة بيئة التطوير الخاصة بك بشكل صحيح ؛ توصيل المكون بالمكونات والخدمات الأخرى بحيث يتفاعل بشكل صحيح مع بقية المشروع ؛ تعديل المكون بحيث يتصرف بالطريقة المتوقعة / المطلوبة).

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

بشكل عام ، لم يكن التحدي المتصور يمثل تحديًا ، لكن لا يزال هناك الكثير من الاحتكاك.

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

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

ولكن من الواضح أن هذه الانحرافات تكون في كثير من الأحيان بمثابة اللحم الفعلي لتحدي التعلم ، وإذا تم كسرها ، فقم بإطلاق أكبر قدر من التقدم نحو الهدف.

كما يوضح ريان هوليداي: "العقبة هي الطريق"

عقباتك لا تمنعك من السعي لتحقيق هدفك ، ولكن في الواقع ، حدد السعي وراء ذلك.

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

غداً ، أخطط لاستعراض سجلات ممارساتي وحساب المدة التي قضيتها في تحدي هذا الشهر.

لكن قبل أن أفعل ذلك ، من المهم الإشارة إلى كيف قضيت وقتي هذا الشهر ، وعلى الأخص كيف تم توزيع وقتي.

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

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

مرحلتي التعلم:

  1. مرحلة الاكتشاف - في هذه المرحلة ، تتمثل مهمة المتعلم في استكشاف الحقل واكتشاف أفضل المسار وتصميم التمارين بما يتماشى مع هذا المسار الأفضل.
  2. مرحلة التدريب - في هذه المرحلة ، تعرف المتعلمة بالفعل ما تحتاج إلى ممارسته ، وتقضي كل وقتها في تركيز تدريبها بشكل متعمد ومكثف على هذا المسار الأفضل.

يتطلب كل التعلم هاتين المرحلتين ، ولكن هذه المراحل قد تتفاعل بشكل مختلف ضمن أنواع مختلفة من التعلم.

نوعان من التعلم:

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

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

ومع ذلك ، خلال تحدي هذا الشهر ، لم يكن لديّ رفاهية طريق محدد بوضوح. بخلاف دورة Udacity التي تبلغ 2400 دولار عبر الإنترنت (والتي لم أكن مستعدًا لدفع ثمنها) ، لم تكن هناك خطة واضحة يمكنني اتباعها لبناء سيارة ذاتية القيادة. بدلاً من ذلك ، كنت بحاجة لاستكشاف الكثير من الطرق المسدودة والدوارات ، قبل أن أجد طريقي.

نتيجةً لذلك ، استمرت جلساتي هذا الشهر عادة بضع ساعات على الأقل ، ولكنها كانت أقل من حيث الكمية.

إذا حاولت بناء سيارة ذاتية القيادة خلال جلسات مدتها 45 دقيقة يوميًا ، لما نجحت أبدًا. كنت بحاجة إلى إعادة هيكلة وإعادة توزيع وقتي لتناسب نوع التعلم الذي ظهر هذا الشهر (أي التعلم المتزامن).

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

نظرًا لأن نهاية شهر مايو تقريبًا ، فقد حان الوقت للنظر إلى الوراء لمعرفة مقدار الوقت الذي قضيته في تحدي هذا الشهر.

تم توزيع معظم وقتي على تسع جلسات أطول ، من الأطوال التالية: 1.5 ساعة ، ساعتان ، 2.5 ساعة ، 1.5 ساعة ، 1 ساعة ، 3.5 ساعة ، 2.5 ساعة ، 1.5 ساعة ، 1 ساعة ، 3 ساعات.

قضيت أيضًا ساعة أخرى خلال أربع جلسات مدة كل منها 15 دقيقة ، وخمس ساعات أخرى في البحث والقراءة والكتابة (وهذا ما أحسبه في الحالات التي استخدم فيها كأداة تعليمية على وجه التحديد).

لذلك ، إجمالاً ، أمضيت 26 ساعة في بناء سيارتي ذاتية القيادة.

قبل حساب هذا المجموع ، كنت أتوقع شيئًا ما بين 35 و 40 ساعة ، لذلك كنت مندهشًا جدًا من هذه النتيجة. لكن الأمر منطقي الآن: كان هناك العديد من الأيام التي شعرت فيها أنني كنت أستثمر الوقت ، لكنني في الواقع إما أترك جهاز الكمبيوتر الخاص بي يعمل من تلقاء نفسه أو يكتب منشورًا يوميًا أكثر تفصيلًا من المعتاد (أي لا أعمل في الواقع على تحدي نفسه).

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

"الطريق" في حد ذاته لم يستغرق وقتًا طويلاً.

اليوم هو اليوم الأخير من تحدي السيارة ذاتية القيادة ، وأود أن أتناول أحد الأسئلة الكبيرة التي تلقيتها على مدار الشهر: "أعتقد أن لديك شيئًا هنا ... كيف ستجني الأموال من هذا؟"

إنه أمر غريب لأن أحداً لم يطلب مني ذلك عندما علمت أن أحفظ مجموعة من البطاقات أو أنزل خلفية.

لذا ، فإن هذه المشاركة الأخيرة هي ردي على ذلك (على الرغم من أنني لست متأكدًا من أنني أجيب على السؤال مباشرة) ...

يجد معظم البالغين العاملين صعوبة في تخصيص وقت لتعلم مهارات جديدة. وأولئك الذين يجدون الوقت عادة ما يركزون على اكتساب قدرات ذات توجه مهني.

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

لا حرج في هذا الدافع. في الواقع ، أنا بالتأكيد أشجع التعلم بدوافع وظيفية دون تعلم على الإطلاق. ولكن هناك مشكلة في المهارات المهنية: فهي لا تظل مهمة أو مثيرة للاهتمام لفترة طويلة.

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

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

بفضل المهارات التي اكتسبتها هذا الشهر ، يمكنني أن أفعل الكثير من الأشياء المثيرة للاهتمام تجاريا.

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

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

ربما أفرط في إثارة الطابع الدرامي ، لكن بالمقارنة مع المهارات ذات التوجه التجاري ، أميل إلى تفضيل الكثير من المهارات الخالدة - المهارات التي يمكن الاستمتاع بها والعمل عليها باستمرار إلى الأبد.

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

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

إذا لم يكن الأمر كذلك ، فربما يستحق الأمر التفكير.

ليس لأنني أعتقد أن التعلم الخالد أفضل نوعًا ما أو "نخبة أكثر" أو أي شيء من هذا القبيل. أعتقد أنه أمر ممتع. وفي بعض الأحيان ، لا نعطي أنفسنا الفرصة للتسلية لأننا لا نعتقد أنها عملية.

ولكن يبدو أن العملية قصيرة الأجل وتتغير باستمرار على أي حال ، لذلك أشجعك على استثمار القليل من الوقت في بعض المرح غير العملي.

هذا المنشور جزء من مشروع التعلم السريع لمدة عام ، من شهر إلى ماجستير.

إذا كنت تريد المتابعة مع مشاركاتي اليومية ، فتأكد من متابعة هذا الحساب المتوسط.

للمحتوى الحصري على التعلم السريع والانضباط وتصميم أسلوب الحياة ، اشترك في نشرتي الإخبارية مرة واحدة في كل مرة.

إذا كنت قد استمتعت بهذا التفصيل المفصل ، فأخبرني بالنقر فوق القلب أدناه. دائما موضع تقدير كبير.