كيف أنا Keras في إطلاق C ++

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


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


بيان المشكلة.


في هذه العملية ، كنت بحاجة إلى تشغيل نموذج مدرب في تطبيق C++ (Unreal Engune 4) . ولكن هذا هو الحظ السيئ: اليوم لا يوجد عملياً طريقة لتشغيل طراز Keras في C ++.


خيار الاتصال Python من C++ لم يكن جيدًا بالنسبة لي. كان هناك خيار آخر لتحويل نموذج Keras إلى نموذج TensorFlow ثم إنشاء TensoFflow للصلبان واستدعاء TF API من رمز C ++.


هذه العملية من التحول موصوفة جيدا في هذه المقالة . ولكن الصعوبات تنشأ أيضا مع هذا. أولاً ، يمر Bzzel عبر Bzzel . والإطار نفسه هو شيء غريب الأطوار ورفض التجمع تحت UE4 . ثانياً ، TF نفسها شيء كبير إلى حد ما ، لكنني أردت شيئًا أكثر وزنًا وإنتاجية. لا أستطيع إلا أن أقول أنه في الأماكن المفتوحة لجيثب تم العثور على مشروع نصف عمل ، مع الوظيفة التي احتاجها. لكنه لم يدعم الإصدارات الحالية من Python Keras . ولم تنجح محاولات إعادة تشكيلها: تعطل تطبيق C ++ بسبب خطأ Core Dump . كان من المعتاد أن أكتب التنفيذ الخاص بي ...


نحن نكتب مكتبتنا!


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


وتلبية ذلك: Keras2cpp!


الجزء الأول من المكتبة هو وحدة بيثون لحفظ النموذج المدرّب في نسق ثنائي خاص به.


لا يوجد شيء معقد في هذه العملية. نقرأ فقط نموذج Keras شيئًا فشيئًا في ملف: أولاً ، ثم ، ثم بالتنسيق float .


الآن دعنا ننتقل إلى تطبيق C ++ اللذيذ.


المستخدم لديه 2 كيان tensor model .


Tensor - يعيد توزيع البيانات التي تعمل بها الشبكة العصبية وهو عبارة عن تطبيق للكمبيوتر من tensor. المدعومة حاليا البعد الأقصى في 4 أبعاد. يتم تخزين البعد لكل البعد في std::vector<int> dims_; ويكون وزن كل عنصر tensor في std::vector<int> data_; . من بين الطرق المتاحة ، يمكن تمييز void Print() و Tensor Select(int row) . بقية العمليات التي يمكنك رؤيتها في الكود المصدري. بعد كتابة الرياضيات عن التنسورات ، بدأت في تطبيق النماذج.


الطراز - عبارة عن مجموعة من الطبقات التي يتم فيها تحديد العمليات على التنسورات ومصفوفة الوزن. 2 وظائف متاحة للمستخدم virtual bool LoadModel(const std::string& filename); وتطبيق virtual bool Apply(Tensor* in, Tensor* out); .


هنا مثال رمز كامل.


python_model.py:


 import numpy as np from keras import Sequential from keras.layers import Dense #create random data test_x = np.random.rand(10, 10).astype('f') test_y = np.random.rand(10).astype('f') model = Sequential([ Dense(1, input_dim=10) ]) model.compile(loss='mse', optimizer='adam') #train model by 1 iteration model.fit(test_x, test_y, epochs=1, verbose=False) #predict data = np.array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]) prediction = model.predict(data) print(prediction) #save model from keras2cpp import export_model export_model(model, 'example.model') 

cpp_mpdel.cc:


 #include "keras_model.h" int main() { // Initialize model. KerasModel model; model.LoadModel("example.model"); // Create a 1D Tensor on length 10 for input data. Tensor in(10); in.data_ = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}; // Run prediction. Tensor out; model.Apply(&in, &out); out.Print(); return 0; } 

هذا كل ما أعتقد. استمتع باستخدامه ، وسأذهب إلى صديقتي الحبيبة C # و Python لكتابة المزيد من الشبكات العصبية.


PS


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


مستودع جيثب
المصدر

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


All Articles