إذا لم يكن لديك Python ، ولكن هناك نموذج Keras وجافا

مرحبا بالجميع! في بناء نماذج ML ، تحتل Python اليوم موقعًا رائدًا وتحظى بشعبية كبيرة بين مجتمع متخصصي علوم البيانات [ 1 ].

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

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

ما نلفت الانتباه إلى:

  • ميزات حزم نموذج Keras و Java ؛
  • الاستعداد للعمل مع إطار DeepLearning4j (DL4J باختصار) ؛
  • استيراد نموذج Keras إلى DL4J (بعناية ، يحتوي القسم على رؤى متعددة) - كيفية تسجيل الطبقات ، والقيود التي تفرضها وحدة الاستيراد ، وكيفية التحقق من نتائج عملها.

لماذا تقرأ؟

  • لتوفير الوقت في البداية ، إذا كنت ستواجه مهمة تكامل مماثل ؛
  • لمعرفة ما إذا كان حلنا مناسبًا لك وما إذا كان يمكنك إعادة استخدام تجربتنا.

بديل الصورة

سمة متكاملة على أهمية أطر التعلم العميق [ 2 ].

يمكن العثور على ملخص لأطر التعلم العميقة الأكثر شعبية هنا [ 3 ] وهنا [ 4 ].

كما ترون ، تعتمد معظم هذه الأُطُر على Python و C ++: فهي تستخدم C ++ كنواة لتسريع العمليات الأساسية والحمولة العالية ، و Python كواجهة تفاعلية لتسريع عملية التطوير.

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

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

لتبسيط تطوير حلول الشبكات العصبية في Java ، يتم تطوير إطار DeepLearning4j (DL4J باختصار). يقدم DL4 بالإضافة إلى Java API مجموعة من النماذج المدربة مسبقًا [ 5 ]. بشكل عام ، يصعب منافسة أداة التطوير هذه مع TensorFlow. تتفوق TensorFlow على DL4J مع وثائق أكثر تفصيلًا وعدد من الأمثلة ، والقدرات التقنية ، وأحجام المجتمع ، والتطور السريع. ومع ذلك ، فإن الاتجاه الذي تلتزم به Skymind واعد للغاية. المنافسون المهمون في Java لهذه الأداة لم يظهروا بعد.

مكتبة DL4J هي واحدة من المكتبات القليلة (إن لم تكن الوحيدة) التي تتيح استيراد نماذج Keras ؛ فهي تتوسع في وظائفها مع الطبقات المألوفة في Keras [ 6 ]. تحتوي مكتبة DL4J على دليل يتضمن أمثلة على تطبيق نماذج الشبكات العصبية ML (مثال dl4j). في حالتنا ، فإن التفاصيل الدقيقة لتنفيذ هذه النماذج في جافا ليست مثيرة للاهتمام. سيتم إيلاء اهتمام أكثر تفصيلاً لاستيراد نموذج Keras / TF المدرّب إلى Java باستخدام أساليب DL4J.

الابتداء


قبل أن تبدأ ، تحتاج إلى تثبيت البرامج اللازمة:

  1. إصدار Java 1.7 (إصدار 64 بت) وأعلى.
  2. نظام بناء مشروع اباتشي مخضرم.
  3. IDE للاختيار من بينها: Intellij IDEA ، Eclipse ، Netbeans. يوصي المطورون بالخيار الأول ، إلى جانب مناقشة أمثلة التدريب المتوفرة عليه.
  4. Git (لاستنساخ مشروع على جهاز الكمبيوتر الخاص بك).

يمكن العثور هنا على وصف مفصل مع مثال على الإطلاق [ 7 ] أو في الفيديو [ 8 ].

لاستيراد النموذج ، يقترح مطورو DL4J استخدام وحدة استيراد KerasModelImport (ظهرت في أكتوبر 2016). تدعم الوحدة الوظيفية كلاً من أبنية النماذج من Keras - إنها متسلسلة (تمثيلية في java - MultiLayerNetwork) و Functional (تمثيلي في ComputationGraph فئة java). يتم استيراد النموذج إما بالكامل بتنسيق HDF5 ، أو ملفين منفصلين - وزن النموذج بامتداد h5 وملف json الذي يحتوي على بنية الشبكة العصبية.

لبداية سريعة ، أعد مطورو DL4J تحليلًا تدريجيًا لمثال بسيط على مجموعة بيانات Fisher iris لنموذج من النوع Sequential [ 9 ]. تم النظر في مثال تدريبي آخر من منظور استيراد النماذج بطريقتين (1: بتنسيق HDF5 الكامل ؛ 2: في ملفات منفصلة - أوزان النموذج (امتداد h5) والهندسة المعمارية (امتداد json)) ، متبوعة بمقارنة نتائج نماذج Python و Java [ 10 ]. هذا يختتم مناقشة القدرات العملية لوحدة الاستيراد.

يوجد أيضًا TF في Java ، ولكنه في حالة تجريبية ولا يقدم المطورون أي ضمانات لتشغيله المستقر [ 11 ]. هناك مشاكل في الإصدار ، و TF في Java به واجهة برمجة تطبيقات غير مكتملة - ولهذا السبب لن يتم النظر في هذا الخيار هنا.

ميزات طراز Keras / TF الأصلي:


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

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

ميزات النموذج:

1. نوع النموذج - وظيفي (شبكة مع المتفرعة) ؛

2. يتم تحديد معلمات التدريب (حجم الدُفعة ، عدد العصور) صغيرة: حجم الدُفعة - 100 ، عدد العصور - 10 ، خطوات لكل عصر - 10 ؛

3. 13 طبقات ، ويرد ملخص للطبقات في الشكل:

بديل الصورة

وصف طبقة قصيرة
  1. input_1 - طبقة الإدخال ، تقبل موترًا ثنائي الأبعاد (يمثله مصفوفة) ؛
  2. lambda_1 - طبقة المستخدم ، في حالتنا ، تجعل الحشو في TF للموتر بنفس القيم الرقمية ؛
  3. embedding_1 - ينشئ Embedding (تمثيل متجه) لتسلسل إدخال البيانات النصية (يحول الموتر ثنائي الأبعاد إلى ثلاثي الأبعاد) ؛
  4. conv1d_1 - طبقة تلافيفية أحادية اللون ؛
  5. lstm_2 - طبقة LSTM (بعد طبقة التضمين (رقم 3)) ؛
  6. lstm_1 - طبقة LSTM (بعد طبقة conv1d (رقم 4)) ؛
  7. lambda_2 هي طبقة المستخدم حيث يتم اقتطاع الموتر بعد الطبقة lstm_2 (رقم 5) (العملية المقابلة للحشو في الطبقة lambda_1 (رقم 2)) ؛
  8. lambda_3 هي طبقة المستخدم حيث يتم اقتطاع الموتر بعد طبقات lstm_1 (رقم 6) و conv1d_1 (رقم 4) (العملية المقابلة للحشو في طبقة lambda_1 (رقم 2)) ؛
  9. concatenate_1 - الربط بين الطبقات (رقم 7) و (رقم 8) ؛
  10. dense_1 - طبقة متصلة بالكامل من 8 خلايا عصبية ووظيفة التنشيط الخطي الأسي "elu" ؛
  11. batch_normalization_1 - طبقة التطبيع ؛
  12. dense_2 - طبقة متصلة تمامًا من 1 من الخلايا العصبية وتفعيل السيني "السيني" ؛
  13. lambda_4 - طبقة المستخدم حيث يتم تنفيذ ضغط الطبقة السابقة (الضغط في TF).

4. فقدان الوظيفة - binary_crossentropy

loss= frac1N sum1N(ytrue cdotlog(ypred)+(1ytrue) سجلcdot(1ypred))



5. متري جودة النموذج - الوسط التوافقي (مقياس F)

F=2 fracPrecision timesRecallPrecision+Recall


في حالتنا ، فإن مسألة مقاييس الجودة ليست مهمة مثل صحة الاستيراد. يتم تحديد صحة الاستيراد عن طريق مصادفة النتائج في نماذج Python و Java NN التي تعمل في وضع الاستدلال.

استيراد طرازات Keras في DL4J:


الإصدارات المستخدمة: Tensorflow 1.5.0 و Keras 2.2.5. في حالتنا ، تم تحميل النموذج من Python ككل بواسطة ملف HDF5.

# saving model model1.save('model1_functional.h5') 

عند استيراد نموذج إلى DL4J ، لا توفر وحدة الاستيراد طرق API لتمرير معلمات إضافية: اسم وحدة tensorflow (من حيث تم استيراد الوظائف عند إنشاء النموذج).

بشكل عام ، يعمل DL4J فقط مع وظائف Keras ، يتم تقديم قائمة شاملة في قسم استيراد Keras [ 6 ] ، لذلك إذا تم إنشاء النموذج على Keras باستخدام طرق من TF (كما في حالتنا) ، فلن تتمكن وحدة الاستيراد من التعرف عليها.

إرشادات عامة لاستيراد نموذج


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

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

باستخدام وظيفة TF الخسارة


لإثبات أنه عند الاستيراد إلى Java ، يجب أن تكون وظيفة فقد النموذج المدرّب من Keras ، فنحن نستخدم log_loss من tensorflow (كأكثر ما يشبه وظيفة custom_loss). حصلنا على الخطأ التالي في وحدة التحكم:

 Exception in thread "main" org.deeplearning4j.nn.modelimport.keras.exceptions.UnsupportedKerasConfigurationException: Unknown Keras loss function log_loss. 

استبدال أساليب TF مع Keras


في حالتنا ، يتم استخدام وظائف وحدة TF مرتين ، وفي جميع الحالات ، توجد فقط في طبقات lambda.

طبقات Lambda هي طبقات مخصصة تُستخدم لإضافة دالة عشوائية.

نموذجنا يحتوي فقط على 4 طبقات لامدا. الحقيقة هي أنه في Java من الضروري تسجيل طبقات lambda هذه يدويًا من خلال KerasLayer.registerLambdaLayer (وإلا فقد حصل خطأ [ 12 ]). في هذه الحالة ، يجب أن تكون الوظيفة المعرفة داخل طبقة lambda وظيفة من مكتبات Java المقابلة. في Java ، لا توجد أمثلة على تسجيل هذه الطبقات ، بالإضافة إلى وثائق شاملة لهذا ؛ مثال هنا [ 13 ]. تم استعارة الاعتبارات العامة من الأمثلة [ 14 ، 15 ].

ضع في اعتبارك تسجيل جميع طبقات lambda للنموذج في Java:

1) طبقة Lambda لإضافة الثوابت إلى الموتر (المصفوفة) عددًا محدودًا من المرات على طول الاتجاهات المعطاة (في حالتنا ، اليسار واليمين):

يتم توصيل مدخلات هذه الطبقة بإدخال النموذج.

1.1) طبقة بايثون:

 padding = keras.layers.Lambda(lambda x: tf.pad(x, paddings=[[0, 0], [10, 10]], constant_values=1))(embedding) 

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

الجدول مع مثال على الموتر التعسفي 2x2
كان 2X2لقد أصبح 2x22
[[ 1 ، 2 ] ،
[ 3 ، 4 ]]
[[37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 1 ، 2 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37] ،
[37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 3 ، 4 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37 ، 37]]


1.2) طبقة جافا:

 KerasLayer.registerLambdaLayer("lambda_1", new SameDiffLambdaLayer() { @Override public SDVariable defineLayer(SameDiff sameDiff, SDVariable sdVariable) { return sameDiff.nn().pad(sdVariable, new int[][]{ { 0, 0 }, { 10, 10 }}, 1); } @Override public InputType getOutputType(int layerIndex, InputType inputType) { return InputType.feedForward(20); } }); 

في جميع طبقات lambda المسجلة في Java ، يتم إعادة تعريف وظيفتين:
الوظيفة الأولى "definelayer" هي المسؤولة عن الطريقة المستخدمة (وليس على الإطلاق حقيقة واضحة: لا يمكن استخدام هذه الطريقة إلا من خلال nn () backend) ؛ getOutputType مسؤول عن إخراج الطبقة المسجلة ، الوسيطة هي معلمة رقمية (هنا 20 ، ولكن بشكل عام يُسمح بأي قيمة عدد صحيح). يبدو غير متناسق ، لكنه يعمل مثل هذا.

2) طبقة لامدا لتشذيب الموتر (المصفوفة) على طول اتجاهات معينة (في حالتنا ، اليسار واليمين):

في هذه الحالة ، تدخل طبقة LSTM مدخلات طبقة lambda.

2.1) طبقة بايثون:

 slicing_lstm = keras.layers.Lambda(lambda x: x[:, 10:-10])(lstm) 

الجدول مع مثال الموتر التعسفي 2x22x5
كان 2x22x5لقد أصبح 2x2x5
[[[1 ، 2 ، 3 ، 4 ، 5] ، [1 ، 2 ، 3 ، 4 ، 5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1 ، 2،3،4،5] ، [1،2،3،4،5] ، [ 1 ، 2 ، 3 ، 4 ، 5 ] ، [ 1 ، 2 ، 3 ، 4 ، 5 ] ، [1،2 ، 3،4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3 ، 4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3،4] ، 5] ، [1،2،3،4،5]] ،

[[1،2،3،4،5]، [1،2،3،4،5]، [1،2،3،4،5]، [1،2،3،4،5]، [ 1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1 ، 2،3،4،5] ، [1،2،3،4،5] ، [ 1 ، 2 ، 3 ، 4 ، 5 ] ، [ 1 ، 2 ، 3 ، 4 ، 5 ] ، [1،2 ، 3،4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3 ، 4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3،4،5] ، [1،2،3،4 ، 5] ، [1،2،3،4،5]]]
[[[ 1 ، 2 ، 3 ، 4 ، 5 ] ، [ 1 ، 2 ، 3 ، 4 ، 5 ]] ،
[[ 1 ، 2 ، 3 ، 4 ، 5 ] ، [ 1 ، 2 ، 3 ، 4 ، 5 ]]]


2.2) طبقة جافا:

 KerasLayer.registerLambdaLayer("lambda_2", new SameDiffLambdaLayer() { @Override public SDVariable defineLayer(SameDiff sameDiff, SDVariable sdVariable) { return sameDiff.stridedSlice(sdVariable, new int[]{ 0, 0, 10 }, new int[]{ (int)sdVariable.getShape()[0], (int)sdVariable.getShape()[1], (int)sdVariable.getShape()[2]-10}, new int[]{ 1, 1, 1 }); } @Override public InputType getOutputType(int layerIndex, InputType inputType) { return InputType.recurrent(60); } }); 

في حالة هذه الطبقة ، تغيرت المعلمة InputType من feedforward (20) إلى المتكررة (60). في الوسيطة المتكررة ، يمكن أن يكون الرقم أي عدد صحيح (غير صفري) ، لكن مجموعته مع الوسيطة المتكررة لطبقة lambda التالية يجب أن تعطي 160 (أي في الطبقة التالية ، يجب أن تكون الوسيطة 100). الرقم 160 يرجع إلى حقيقة أن الموتر ذو البعد (بلا ، لا شيء ، 160) يجب أن يستقبل عند تسلسل الإدخال للطبقة.

الوسائط الأولى 2 هي متغيرات ، اعتمادًا على حجم سلسلة الإدخال.

3) طبقة لامدا لتشذيب الموتر (المصفوفة) على طول الاتجاهات المعينة (في حالتنا ، اليسار واليمين):

مدخلات هذه الطبقة هي طبقة LSTM ، وأمامها الطبقة conv1_d

3.1) طبقة بايثون:

 slicing_convolution = keras.layers.Lambda(lambda x: x[:,10:-10])(lstm_conv) 

هذه العملية مماثلة تماما للعملية في الفقرة 2.1.

3.2) طبقة جافا:

 KerasLayer.registerLambdaLayer("lambda_3", new SameDiffLambdaLayer() { @Override public SDVariable defineLayer(SameDiff sameDiff, SDVariable sdVariable) { return sameDiff.stridedSlice(sdVariable, new int[]{ 0, 0, 10 }, new int[]{ (int)sdVariable.getShape()[0], (int)sdVariable.getShape()[1], (int)sdVariable.getShape()[2]-10}, new int[]{ 1, 1, 1 }); } @Override public InputType getOutputType(int layerIndex, InputType inputType) { return InputType.recurrent(100); } }); 

تكرر طبقة lambda هذه طبقة lambda السابقة باستثناء المعلمة المتكررة (100). لماذا يتم أخذ "100" في وصف الطبقة السابقة.

في النقطتين 2 و 3 ، توجد طبقات lambda بعد طبقات LSTM ، لذلك يتم استخدام النوع المتكرر. ولكن إذا لم يكن هناك طبقة LSTM قبل طبقة lambda ، ولكن conv1d_1 ، فلا يزال من الضروري ضبط المتكرر (يبدو غير متسق ، لكنه يعمل هكذا).

4) طبقة لامدا لضغط الطبقة السابقة:

مدخلات هذه الطبقة هي طبقة متصلة بالكامل.

4.1) طبقة بايثون:

  squeeze = keras.layers.Lambda(lambda x: tf.squeeze( x, axis=-1))(dense) 

الجدول مع مثال الموتر التعسفي 2x4x1
كان 2 × 4 × 1أصبح 2x4
[[[ [1] ، [2] ، [3] ، [4]] ،

[ [1] ، [2] ، [3] ، [4] ]]
[[ 1 ، 2 ، 3 ، 4 ] ،
[ 1 ، 2 ، 3 ، 4 ]]


4.2) طبقة جافا:

 KerasLayer.registerLambdaLayer("lambda_4", new SameDiffLambdaLayer() { @Override public SDVariable defineLayer(SameDiff sameDiff, SDVariable sdVariable) { return sameDiff.squeeze(sdVariable, -1); } @Override public InputType getOutputType(int layerIndex, InputType inputType) { return InputType.feedForward(15); } }); 

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

تحميل النموذج المستورد


يتم تحميل النموذج من خلال وحدة ComputationGraph:

 ComputationGraph model = org.deeplearning4j.nn.modelimport.keras.KerasModelImport.importKerasModelAndWeights("/home/user/Models/model1_functional.h5"); 

إخراج البيانات إلى وحدة تحكم Java


في Java ، على وجه الخصوص في DL4J ، تتم كتابة التنسورات في شكل صفائف من مكتبة Nd4j عالية الأداء ، والتي يمكن اعتبارها نظيرًا لمكتبة Numpy في Python.

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

على سبيل المثال ، لدينا 4 أحرف مشفرة بالفهرس: 1 ، 3 ، 4 ، 8.

كود في جافا:

 INDArray myArray = Nd4j.zeros(1,4); // one row 4 column array myArray.putScalar(0,0,1); myArray.putScalar(0,1,3); myArray.putScalar(0,2,4); myArray.putScalar(0,3,8); INDArray output = model.outputSingle(myArray); System.out.println(output); 

ستعرض وحدة التحكم الاحتمالات لكل عنصر إدخال.

النماذج المستوردة


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

نموذج بيثون:

بديل الصورة

نموذج جافا:

بديل الصورة

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

1) طبقة تطبيع التصحيح لا تعمل بعد الطبقات العودية. تم فتح العدد على جيثب لمدة عام تقريبًا [ 16 ]. على سبيل المثال ، إذا أضفت هذه الطبقة إلى النموذج (بعد طبقة الاتصال) ، فسوف نحصل على الخطأ التالي:

 Exception in thread "main" java.lang.IllegalStateException: Invalid input type: Batch norm layer expected input of type CNN, CNN Flat or FF, got InputTypeRecurrent(160) for layer index -1, layer name = batch_normalization_1 

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

2) بعد طبقة متصلة بالكامل ، يؤدي تعيين طبقة Flatten إلى حدوث خطأ. تم ذكر خطأ مشابه في Stackoverflow [ 17 ]. لمدة ستة أشهر ، لا توجد ردود فعل.

بالتأكيد هذا ليس كل القيود التي يمكنك مواجهتها عند العمل مع DL4J.
وقت التشغيل النهائي للنموذج هنا [ 18 ].

استنتاج


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

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

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

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

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

مراجع

  1. أفضل 5 لغات برمجة لحقل الذكاء الاصطناعي
  2. درجات القوة في إطار التعلم العميق 2018
  3. مقارنة بين برامج التعلم العميق
  4. أفضل 9 أطر في عالم الذكاء الاصطناعي
  5. DeepLearning4j. النماذج المتاحة
  6. DeepLearning4j. استيراد نموذج Keras. الميزات المدعومة.
  7. Deeplearning4j. التشغيل السريع
  8. محاضرة 0: البدء مع DeepLearning4j
  9. Deeplearing4j: استيراد طراز Keras
  10. محاضرة 7 | استيراد نموذج Keras
  11. تثبيت TensorFlow لجافا
  12. باستخدام طبقات Keras
  13. DeepLearning4j: فئة KerasLayer
  14. DeepLearning4j: SameDiffLambdaLayer.java
  15. DeepLearning4j: KerasLambdaTest.java
  16. DeepLearning4j: BatchNorm مع RecurrentInputType
  17. StackOverFlow: مشكلة في فتح نموذج keras في java مع deeplearning4j (https://deeplearning4j.org/)
  18. جيثب: كود كامل للنموذج المعني
  19. Skymind: مقارنة بين أطر الذكاء الاصطناعى

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


All Articles