البداية
بدأ كل شيء عندما وجدت تطبيقًا. في سوق أبل ، من المفترض أنه كان قادراً على تحديد مدى نضوج ميلون المياه. كان البرنامج ... غريب. مجرد التفكير في الأمر: بدلاً من طرق استخدام المفاصل الخاصة بك ، كان من المفترض أن تصل إلى ميلون المياه مع اي فون الخاص بك! ومع ذلك ، فقد قررت تكرار هذه الوظيفة على منصة Andtoid.
أدوات الاختيار
هناك طرق قليلة لحل المشكلة التي نواجهها ، وكان عليّ أن أبذل جهودًا معينة لتجنب المشكلة السهلة. وهو ، فورييه يحول ، wavelets ومحرر الإشارة. أردت أن أتعلم الشبكات العصبية بعد كل شيء.
اخترت Keras كمكتبة NN ، وهي أداة رائعة من Google ، وهي عبارة عن مجمّع حول TensorFlow و Theano. إذا كنت مبتدئًا ، فهذه بالتأكيد أفضل أداة. من ناحية ، تعد Keras أداة قوية ، تم تحسينها من خلال السرعة والذاكرة والأجهزة (وهي تعمل مع وحدات معالجة الرسومات). من ناحية أخرى - يخفي جميع الموظفين المملين عن المستخدم ، مما يسمح بالتركيز على المهمة نفسها. مريحة جدا.
ترتبط Keras والشبكات العصبية عمومًا بيثون ، وهي اللغة التي تشبه الأفعى العملاقة ... لا تمانع. على أي حال ، يحتاج المرء إلى معرفة بيثون من أجل العمل في مجال التعلم العميق. لحسن الحظ ، إنها لغة سهلة يمكن تعلمها بسرعة كبيرة.
بالإضافة إلى Python ، ستحتاج إلى عدد قليل من المكتبات الإضافية ، ولكن إتقانها سهل - حتى بالمقارنة مع Python نفسها. ستحتاج إلى تجربة (ضحلة) مع NumPy و PyPlot وربما اثنين من المكتبات الأخرى.
أخيرًا ، تجدر الإشارة إلى أننا لن نحتاج إلى مجموعات GPU: يمكن حل مشكلتنا على وحدة معالجة مركزية واحدة ، بطيئة ، ولكن ليس بطيئة للغاية.
خطة العمل
بادئ ذي بدء ، نحن بحاجة إلى إنشاء شبكة عصبية ، باستخدام Python و Keras ، في بيئة Ubuntu. يمكن للمرء القيام بذلك في Windows ، ولكن الوقت الذي تقضيه في تكوين الأشياء يجب أن يكون كافياً لتعلم Ubuntu بدلاً من ذلك.
والخطوة التالية هي لكتابة البرنامج. أخطط للقيام بذلك على Java لنظام Android. سيكون نموذجًا أوليًا ، بمعنى أنه سيكون له واجهة المستخدم ، لكن ليس هناك NN - حتى الآن.
لماذا يتعين علينا كتابة برنامج وهمية؟ هذه هي الخدعة: أي احتياجات التعلم العميق تحتاج إلى تعلمها. كم عدد ملونات الماء التي يجب عليّ اختبارها (بكلتا معاني هذه الكلمة) لتزويد NN بكمية كافية من البيانات> مائة؟ أكثر من ذلك؟
سنستخدم برنامج الدمية هنا: سأضعه على Google Play ، وسأمنحه (حسناً ، أجبر جميع أصدقائي على تثبيته) وجمع البيانات منه ... أين؟
والخطوة التالية هي كتابة برنامج بجانب الخادم ، واحد يستقبل البيانات من عميل Android الخاص بنا. هذه مهمة بسيطة للغاية ، استغرقت مني حوالي عشرين دقيقة للكتابة ، لكنها لا تزال ، إنها خطوة منفصلة.
أخيرًا ، عندما يكون لدينا بيانات كافية ، يمكننا تعليم NN.
ثم نحتاج إلى نقل NN الناتج إلى Java ولإصدار نسخة جديدة من برنامجنا ، لاستبدال نسخة "وهمية".
الربح. لا ، انتظر. البرنامج مجاني. فقط التجربة.
خلق nn
إن العمل باستخدام إشارة صوتية ، وهو ما يطرح بالتأكيد ميلون الماء بالتأكيد ، يعني إما شبكات عصبية متكررة أو ما يسمى بشبكة سي إن إن واحدة. نظرًا لأن استخدام شبكات CNN أسهل - وبالنسبة للإشارات القصيرة - أفضل ، سنستخدمها. فكرة NN التلافيفية هي "انزلاق" "نافذة الاستشعار" على مجموعة من البيانات لدينا (والتي هي إشارة صوتية). ونتيجة لذلك ، بدلاً من تحليل جميع البيانات في وقت واحد ، فإننا نبحث عن الأنماط الفرعية المحلية. كل طبقة التالية من NN تعمل مع أنماط حصلت عليها الطبقة السابقة ، وتبحث عن أنماط مستوى أعلى.
لتسهيل الأمر ، تخيل أنه يتعين علينا تحديد موقع طيور النورس في صورة المحيط. نقوم بتمرير "نافذة" صغيرة عبر الصورة ، ونبحث عن نمط "يشبه علامة" بيضاء. الآن ، كانت هذه الشبكة العصبية التلافيفية ثنائية الأبعاد ، مثل الإشارة أحادية البعد ، 1D CNN هو خيار منطقي.
كان NN الهيكل التالي:
model = Sequential() model.add(Conv1D(filters=32, kernel_size=512, strides=3, padding='valid', use_bias=False, input_shape=(nSampleSize, 1), name='c1d', activation='relu')) model.add(Activation('relu', input_shape=(nSampleSize, 1))) model.add(MaxPooling1D(pool_size=(2))) model.add(Conv1D(32, (3))) model.add(Activation('relu')) model.add(MaxPooling1D(pool_size=(2))) model.add(Conv1D(64, (3))) model.add(Activation('relu')) model.add(MaxPooling1D(pool_size=(2))) model.add(Flatten()) model.add(Dense(64)) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(nNumOfOutputs))
يحتوي NN على ناتجين (يتنبأ بقيمتين: الحلاوة والنضوج. يمكن أن تكون الحلاوة 0 (ليست حلوة) و 1 (عادية) و 2 (ممتازة). أما بالنسبة للنضوج ، فيمكن أن تكون 0 (صلبة جدًا) و 1 (جيدة ) و 2 - لينة جدا ، مثل القطن مع الرمال.
لإنشاء هذه التصنيفات (المخرجات) ، نحتاج إلى بيانات أعدها البشر ، وسيتم مناقشة الطريقة التي يتم بها ذلك لاحقًا ، في فصل عن برنامج Android. الهدف من NN الخاص بنا هو التنبؤ باستخدام تقديرات سمعية ، باستخدام عينة سمعية.
كتابة البرنامج
كما ذكرت ، سيكون هناك نسختان من البرنامج: "دمية" و "نهائي". يقوم أحدهم بإجراء تنبؤات عشوائية (وسيتم تحذير المستخدم حيال ذلك). لأنها تفعل ذلك ، فهي تسجل العينات الصوتية وترسلها إلى الخادم الخاص بنا إلى جانب تقديرات المستخدم لجودة حقيقية من الماء. بمعنى آخر ، يقوم البرنامج ببساطة بجمع البيانات.
فيما يلي صفحة من النسخة النهائية للبرنامج ، وهي مجانية.
ماذا يفعل:
1. عند الضغط على زر "الميكروفون" ، يبدأ التسجيل. المستخدم لديه خمس ثوان لضرب الماء ميلون ثلاث مرات ، إنه يشبه إلى حد كبير يطرق الباب. ثم يمكنك الضغط على زر "البطيخ" للحصول على "التنبؤ".

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

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

كتابة برنامج جانب الخادم
إنه أمر سهل حقًا ، لذا من الأفضل أن أنشر الكود المصدري. يقوم برنامج "catches" ، بتعيين أسماء فريدة ووضعها في مجلد يمكن لمالك الموقع الوصول إليه فقط.
<?php if (is_uploaded_file($_FILES['file']['tmp_name'])) { $uploads_dir = './melonaire/'; $tmp_name = $_FILES['file']['tmp_name']; $pic_name = $_FILES['file']['name']; $filename = md5(date('Ymd H:i:s:u')); move_uploaded_file($tmp_name, $uploads_dir.$filename); } else { echo "File not uploaded successfully."; } ?>
تدريب nn
نحن تقسيم البيانات إلى التدريب (70 ٪) والاختبار (30 ٪). تتلاقى الشبكة العصبية بشكل جيد ، ولا مفاجآت هنا. ملاحظة للمبتدئين: لا تنسَ تطبيع بيانات الإدخال ، فهي ستوفر عليك الكثير من الوقت والأعصاب. شيء مثل هذا:
for file_name in os.listdir(path): nSweetness, nRipeness, arr_loaded = loadData(file_name) arr_data.append(arr_loaded / max(abs(arr_loaded)))
ترقية إلى جافا
هناك عدة طرق لتوصيل NN من Python إلى Java. في الآونة الأخيرة ، جعلت Google هذه العملية مريحة للغاية ، لذلك إذا قررت دراسة الكتب المدرسية ، فتأكد من أنها غير متقادمة. إليكم كيف فعلت ذلك:
from keras.models import Model from keras.models import load_model from keras.layers import * import os import sys import tensorflow as tf
لاحظ السطر الأخير: في كود Java ، ستحتاج إلى اسم طبقات المدخلات والمخرجات في NN. بيان "الطباعة" يعرضها لنا.
بعد ذلك ، نضع الملف الذي تم تصديره إلى مجلد "الأصول" لمشروع Android Studio (اسم الملف هو coordted.pb ، لا تسأل) ، أضف المكتبة (
هنا ،
هنا أو أفضل ،
هنا tensorflowinferenceinterface ، و ... هذا كل شيء.
هذا كل شيء. عندما فعلت ذلك لأول مرة ، كنت أتوقع مشاكل ، لكن ... كل شيء يعمل للتو.
هذه هي الدعوة إلى NN الخاص بنا من كود Java:
protected Void doInBackground(Void... params) { try {
هنا "m_arrInput" - صفيف يحتوي على عنصرين ، مع تنبؤنا (حلاوة ونضج) ، في نطاق من 0 إلى 1.
استنتاج
أعتقد أنه من المفترض أن أشكر جمهوري على الاهتمام والتعبير عن الأمل في أنه كان مثيراً للاهتمام. بدلاً من ذلك ، أتمنى لك المزيد من ملونات المياه الحلوة ، وآمل أن ترسلوا لي عينات صوتية جديدة ، كما تأكلونها (ملونات ، لا عينات ، هاه!)
البرنامج مجاني ، بالطبع.