تعلم الآلة باستخدام Node.js باستخدام مكتبة Tensorflow.js

مرحبا بالجميع ، الزملاء!

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

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

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

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

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

ومع ذلك ، بعد بضعة أيام من العرق ، ما زلت فعلت ذلك ! الصيحة!

قبل الانتقال إلى تحليل مفصل للرمز ، دعنا نتحدث عن تطبيقات أخرى لمكتبة TensorFlow.

تينسرفلو

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

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

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

TensorFlow لايت

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

TensorFlow.js

بعد Tensorflow Lite ، تم الإعلان عن TensorFlow.js في مارس 2018. تم تصميم هذا الإصدار من المكتبة ليتم تشغيله في مستعرض ويستند إلى مشروع سابق يسمى deeplearn.js . يوفر WebGL وصول GPU إلى المكتبة. يستخدم المطورون واجهة برمجة تطبيقات JavaScript لتدريب وتحميل وتشغيل النماذج.

تم توسيع TensorFlow.js لاحقًا للعمل مع Node.js ، يتم استخدام الوظيفة الإضافية مكتبة tfjs-node لهذا الغرض.

استيراد النماذج الموجودة إلى TensorFlow.js

يمكن تنفيذ طرازي TensorFlow و Keras الجاهزة باستخدام مكتبة TensorFlow.js. قبل تنفيذ النموذج ، يجب عليك التحويل إلى تنسيق جديد باستخدام هذه الأداة . تتوفر في Github نماذج مُدرَّبة ومحوَّلة مسبقًا لتصنيف الصور وتحديد نقاط التعرُّف واكتشاف الجوار أقرب k.

باستخدام TensorFlow.js مع Node.js

تثبيت مكتبات TensorFlow

يمكن تثبيت TensorFlow.js من سجل NPM .


 npm install @tensorflow/tfjs @tensorflow/tfjs-node // ... npm install @tensorflow/tfjs @tensorflow/tfjs-node-gpu 

تستخدم كلتا الإمتدادات لـ Node.js التبعيات الأصلية ، والتي سيتم تجميعها حسب الطلب.

قم بتنزيل مكتبات TensorFlow

يتم توفير JavaScript API لـ Tensorflow من المكتبة الأساسية. لا يتم توفير واجهات برمجة التطبيقات للإضافات في وحدات الإضافة التي تدعم Node.js.

  const tf = require('@tensorflow/tfjs') //   ( CPU) require('@tensorflow/tfjs-node') //    ( GPU) require('@tensorflow/tfjs-node-gpu') 

تنزيل نماذج TensorFlow

يوفر TensorFlow.js مكتبة NPM ( tfjs-models ) التي تعمل على تبسيط تحميل النماذج المُدرَّبة مسبقًا tfjs-models لتصنيف الصور ، وتحديد الطرود ، واكتشاف الجوار الأقرب لـ k .

نموذج تصنيف صور MobileNet عبارة عن شبكة عصبية عميقة مدربة على التمييز بين 1000 فئة مختلفة من الصور .

في ملف README للمشروع ، يتم استخدام الكود التالي كمثال ، يستخدم لتحميل النموذج.

 import * as mobilenet from '@tensorflow-models/mobilenet'; //   const model = await mobilenet.load(); 

إحدى المشكلات الأولى التي صادفتها هي أن هذا الرمز لا يعمل مع Node.js.

 Error: browserHTTPRequest is not supported outside the web browser. 

بعد فحص الكود المصدري ، نرى أن مكتبة mobilenet عبارة عن tf.Model لفئة tf.Model . عند الاتصال ، تقوم طريقة load() تلقائيًا بتنزيل ملفات النماذج الضرورية الموجودة على عنوان HTTP خارجي وإنشاء نموذج TensorFlow.

لم يدعم ملحق Node.js وقت كتابة هذا التقرير طلبات HTTP لاسترجاع النموذج الديناميكي. كل ما تبقى كان تحميل النماذج يدويًا في نظام الملفات.

ومع ذلك ، بعد قراءة التعليمات البرمجية المصدر للمكتبة ، وجدت حلاً ...

تنزيل النماذج من نظام الملفات

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

 const path = "mobilenet/model.json" const mn = new mobilenet.MobileNet(1, 1); mn.path = `file://${path}` await mn.load() 

رائع ، كل شيء يعمل!

ولكن من أين تأتي ملفات النماذج؟

نماذج MobileNet

تتكون نماذج TensorFlow.js من نوعين من الملفات: ملف تكوين النموذج المخزن في تنسيق JSON والأوزان النموذجية المخزنة في تنسيق ثنائي. غالبًا ما يتم تجزئة الأوزان النموذجية إلى أجزاء كثيرة لتحسين التخزين المؤقت للمتصفح.

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

 https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v${version}_${alpha}_${size}/ 

تصف معلمات القالب في عنوان URL إصدارات النماذج المدرجة هنا . يتم عرض دقة التصنيف الناتجة أيضًا في نفس الصفحة.

يشير الكود المصدري إلى أنه يمكن تنزيل طرز MobileNet v1 فقط باستخدام tensorflow-models/mobilenet .

يقوم رمز استخراج HTTP بتنزيل ملف model.json من موقع التخزين ، ثم يحدد بشكل متكرر جميع أجزاء النماذج ذات الأوزان المرجعية. هذه ملفات بتنسيق groupX-shard1of1 .

تنزيل النماذج يدويًا

إذا كنت ترغب في حفظ جميع ملفات النماذج في نظام الملفات ، يمكنك القيام بذلك: استخراج ملف تكوين النموذج ، وتحليل بناء جملة جميع الملفات الموزونة المشار إليها في ملف التكوين ، ثم تنزيل كل ملف مرجح يدويًا.
كنت أستخدم وحدة MobileNet V1 ذات قيمة ألفا 1.0 وصورة 224 بكسل . لذلك أحصل على عنوان URL التالي لملف تكوين النموذج.

 https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_1.0_224/model.json 

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

 $ cat model.json | jq -r ".weightsManifest[].paths[0]" group1-shard1of1 group2-shard1of1 group3-shard1of1 ... 

باستخدام أداة sed ، يمكنك بادئة اسم كل عنصر HTTP باستخدام عنوان URL لإنشاء عنوان URL لكل ملف وزن.

 $ cat model.json | jq -r ".weightsManifest[].paths[0]" | sed 's/^/https:\/\/storage.googleapis.com\/tfjs-models\/tfjs\/mobilenet_v1_1.0_224\//' https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_1.0_224/group1-shard1of1 https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_1.0_224/group2-shard1of1 https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_1.0_224/group3-shard1of1 ... 

يسمح لك curl parallel curl بتنزيل كل هذه الملفات على دليلي المحلي.

 cat model.json | jq -r ".weightsManifest[].paths[0]" | sed 's/^/https:\/\/storage.googleapis.com\/tfjs-models\/tfjs\/mobilenet_v1_1.0_224\//' | parallel curl -O 

تصنيف الصورة

يوضح نموذج التعليمات البرمجية هذا المزود بـ TensorFlow.js كيفية إرجاع نتيجة تصنيف الصورة.

 const img = document.getElementById('img'); //   const predictions = await model.classify(img); 

هذا لا يعمل في Node.js بسبب نقص دعم DOM.

تقبل طريقة classify عناصر DOM المختلفة ( canvas ، video ، image ) وتقوم تلقائيًا باستخراج وتحويل بايتات "الصورة" من هذه العناصر إلى فئة tf.Tensor3D ، المستخدمة كمدخل للطراز. بدلا من ذلك ، tf.Tensor3D يمكن أن تنتقل مباشرة.

قررت عدم محاولة استخدام حزمة خارجية لمحاكاة عنصر DOM يدويًا ، لكنني وجدت أن tf.Tensor3D أسهل في التجميع يدويًا .

نحن نولد Tensor3D من الصورة

عند قراءة شفرة المصدر الخاصة بالطريقة المستخدمة لتحويل عناصر DOM إلى فئات Tensor3D ، نجد أن معلمات الإدخال التالية تستخدم لإنشاء فئة Tensor3D.

 const values = new Int32Array(image.height * image.width * numChannels); //     ,    const outShape = [image.height, image.width, numChannels]; const input = tf.tensor3d(values, outShape, 'int32'); 

pixels عبارة عن صفيف ثنائي الأبعاد من النوع (Int32Array) يحتوي على قائمة متسلسلة من قيم القناة لكل بكسل. numChannels هو عدد قيم القناة لكل بكسل.

إنشاء قيم الإدخال لـ JPEG

مكتبة jpeg-js هي أداة فك ترميز / فك تشفير JPEG لـ Node.js مكتوبة بلغة جافا سكريبت. باستخدام هذه المكتبة ، يمكنك استخراج قيم RGB لكل بكسل.

 const pixels = jpeg.decode(buffer, true); 

نتيجة لذلك ، حصلنا على Uint8Array مع قيم القناة الأربعة ( RGBA ) لكل بكسل ( width * height ). يستخدم نموذج MobileNet ثلاث قنوات ألوان فقط ( RGB ) للتصنيف ، ويتم تجاهل قناة ألفا. يحول هذا الكود صفيفًا من أربع قنوات إلى إصدار حقيقي من ثلاث قنوات.

  const numChannels = 3; const numPixels = image.width * image.height; const values = new Int32Array(numPixels * numChannels); for (let i = 0; i < numPixels; i++) { for (let channel = 0; channel < numChannels; ++channel) { values[i * numChannels + channel] = pixels[i * 4 + channel]; } } 

متطلبات الإدخال لنماذج MobileNet

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

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

لدى TensorFlow.js طرق مكتبة لتبسيط هذه العملية ، ولكن الأفضل من ذلك ، هناك tfjs-models/mobilenet خاصة بـ tfjs-models/mobilenet تحل هذه المشكلة تلقائيًا !

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

الحصول على التوقعات

تتعلم نماذج MobileNet في Tensorflow التعرف على الكائنات من أهم 1000 فئة من مجموعة بيانات ImageNet . عند إخراج النموذج ، أعطِ قيمًا احتمالية تميز ما هي فرص العثور على هذه الكائنات في الصورة المصنفة.

توجد قائمة كاملة بالفصول المدربة للنموذج المستخدم في هذا الملف .

تقدم tfjs-models/mobilenet طريقة classify في فئة MobileNet ، والتي تُرجع أعلى X من الفئات الأكثر ترجيحًا ، استنادًا إلى ما يظهر في الصورة.

 const predictions = await mn_model.classify(input, 10); 

predictions هي مجموعة من فئات X والاحتمالات في التنسيق التالي.

  { className: 'panda', probability: 0.9993536472320557 } 

مثال

لذلك ، اكتشفنا كيفية استخدام مكتبة TensorFlow.js ونماذج MobileNet في Node.js ، وننظر الآن في كيفية تصنيف هذا البرنامج النصي للصورة المحددة كوسيطة سطر أوامر.

شفرة المصدر

احفظ ملف البرنامج النصي واصف الحزمة في الملفات المحلية.

 { "name": "tf-js", "version": "1.0.0", "main": "script.js", "license": "MIT", "dependencies": { "@tensorflow-models/mobilenet": "^0.2.2", "@tensorflow/tfjs": "^0.12.3", "@tensorflow/tfjs-node": "^0.1.9", "jpeg-js": "^0.3.4" } } 

 const tf = require('@tensorflow/tfjs') const mobilenet = require('@tensorflow-models/mobilenet'); require('@tensorflow/tfjs-node') const fs = require('fs'); const jpeg = require('jpeg-js'); const NUMBER_OF_CHANNELS = 3 const readImage = path => { const buf = fs.readFileSync(path) const pixels = jpeg.decode(buf, true) return pixels } const imageByteArray = (image, numChannels) => { const pixels = image.data const numPixels = image.width * image.height; const values = new Int32Array(numPixels * numChannels); for (let i = 0; i < numPixels; i++) { for (let channel = 0; channel < numChannels; ++channel) { values[i * numChannels + channel] = pixels[i * 4 + channel]; } } return values } const imageToInput = (image, numChannels) => { const values = imageByteArray(image, numChannels) const outShape = [image.height, image.width, numChannels]; const input = tf.tensor3d(values, outShape, 'int32'); return input } const loadModel = async path => { const mn = new mobilenet.MobileNet(1, 1); mn.path = `file://${path}` await mn.load() return mn } const classify = async (model, path) => { const image = readImage(path) const input = imageToInput(image, NUMBER_OF_CHANNELS) const mn_model = await loadModel(model) const predictions = await mn_model.classify(input) console.log('classification results:', predictions) } if (process.argv.length !== 4) throw new Error('incorrect arguments: node script.js <MODEL> <IMAGE_FILE>') classify(process.argv[2], process.argv[3]) 

اختبار

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

npm install

قم بتنزيل نموذج ملف JPEG للتصنيف

wget http://bit.ly/2JYSal9 -O panda.jpg



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

node script.js mobilenet/model.json panda.jpg

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

  classification results: [ { className: 'giant panda, panda, panda bear, coon bear', probability: 0.9993536472320557 } ] 

تم تصنيف الصورة بشكل صحيح على أنها تحتوي على باندا مع احتمال 99.93 ٪!

الخاتمة

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

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

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


All Articles