TensorFlow.js: আপনার নিজের "শিক্ষাযোগ্য মেশিন" TensorFlow.js এর সাথে ট্রান্সফার লার্নিং ব্যবহার করে

1. আপনি শুরু করার আগে

TensorFlow.js মডেলের ব্যবহার গত কয়েক বছরে দ্রুতগতিতে বেড়েছে এবং অনেক জাভাস্ক্রিপ্ট ডেভেলপার এখন বিদ্যমান অত্যাধুনিক মডেলগুলি নিতে এবং তাদের শিল্পের জন্য অনন্য কাস্টম ডেটার সাথে কাজ করার জন্য তাদের পুনরায় প্রশিক্ষণ দিতে চাইছে। একটি বিদ্যমান মডেল নেওয়ার কাজ (প্রায়শই একটি বেস মডেল হিসাবে উল্লেখ করা হয়), এবং এটিকে একই রকম কিন্তু ভিন্ন ডোমেনে ব্যবহার করাকে ট্রান্সফার লার্নিং বলা হয়।

সম্পূর্ণ ফাঁকা মডেল থেকে শুরু করে স্থানান্তর শিক্ষার অনেক সুবিধা রয়েছে। আপনি একটি পূর্বের প্রশিক্ষিত মডেল থেকে ইতিমধ্যে শেখা জ্ঞান পুনরায় ব্যবহার করতে পারেন, এবং আপনি যে নতুন আইটেমটি শ্রেণীবদ্ধ করতে চান তার কম উদাহরণ প্রয়োজন। এছাড়াও, পুরো নেটওয়ার্কের পরিবর্তে শুধুমাত্র মডেল আর্কিটেকচারের শেষ কয়েকটি স্তরকে পুনরায় প্রশিক্ষণ দেওয়ার কারণে প্রশিক্ষণ প্রায়শই উল্লেখযোগ্যভাবে দ্রুত হয়। এই কারণে, ট্রান্সফার লার্নিং ওয়েব ব্রাউজার পরিবেশের জন্য খুব উপযুক্ত যেখানে এক্সিকিউশন ডিভাইসের উপর ভিত্তি করে সংস্থানগুলি পরিবর্তিত হতে পারে, কিন্তু সহজ ডেটা অধিগ্রহণের জন্য সেন্সরগুলিতে সরাসরি অ্যাক্সেসও রয়েছে।

এই কোডল্যাবটি আপনাকে দেখায় কিভাবে একটি ফাঁকা ক্যানভাস থেকে একটি ওয়েব অ্যাপ তৈরি করতে হয়, গুগলের জনপ্রিয় " শিক্ষাযোগ্য মেশিন " ওয়েবসাইটটি পুনরায় তৈরি করে৷ ওয়েবসাইটটি আপনাকে একটি কার্যকরী ওয়েব অ্যাপ তৈরি করতে দেয় যা যেকোনো ব্যবহারকারী তাদের ওয়েবক্যাম থেকে কয়েকটি উদাহরণের চিত্র সহ একটি কাস্টম অবজেক্ট চিনতে ব্যবহার করতে পারে। ওয়েবসাইটটি উদ্দেশ্যমূলকভাবে ন্যূনতম রাখা হয়েছে যাতে আপনি এই কোডল্যাবের মেশিন লার্নিং দিকগুলিতে ফোকাস করতে পারেন। মূল Teachable Machine ওয়েবসাইটের মতো, তবে, UX উন্নত করতে আপনার বিদ্যমান ওয়েব ডেভেলপার অভিজ্ঞতা প্রয়োগ করার প্রচুর সুযোগ রয়েছে।

পূর্বশর্ত

এই কোডল্যাবটি ওয়েব ডেভেলপারদের জন্য লেখা হয়েছে যারা TensorFlow.js প্রি-মেড মডেল এবং বেসিক API ব্যবহারের সাথে কিছুটা পরিচিত এবং যারা TensorFlow.js-এ ট্রান্সফার লার্নিং শুরু করতে চান।

  • TensorFlow.js, HTML5, CSS, এবং JavaScript-এর সাথে প্রাথমিক পরিচিতি এই ল্যাবের জন্য ধরে নেওয়া হয়।

আপনি যদি Tensorflow.js-এ নতুন হয়ে থাকেন, তাহলে প্রথমে এই বিনামূল্যের জিরো টু হিরো কোর্সটি নেওয়ার কথা বিবেচনা করুন , যা মেশিন লার্নিং বা TensorFlow.js-এর সাথে কোনো ব্যাকগ্রাউন্ড অনুমান করে না এবং ছোট ধাপে আপনার যা জানা দরকার তা শেখায়।

আপনি কি শিখবেন

  • TensorFlow.js কি এবং কেন আপনার পরবর্তী ওয়েব অ্যাপে এটি ব্যবহার করা উচিত।
  • কীভাবে একটি সরলীকৃত HTML/CSS/JS ওয়েবপেজ তৈরি করবেন যা শিক্ষনীয় মেশিন ব্যবহারকারীর অভিজ্ঞতার প্রতিলিপি করে।
  • কিভাবে TensorFlow.js ব্যবহার করবেন একটি প্রাক-প্রশিক্ষিত বেস মডেল লোড করতে, বিশেষ করে MobileNet, ইমেজ ফিচার তৈরি করতে যা ট্রান্সফার লার্নিংয়ে ব্যবহার করা যেতে পারে।
  • আপনি চিনতে চান এমন একাধিক শ্রেণীর ডেটার জন্য ব্যবহারকারীর ওয়েবক্যাম থেকে কীভাবে ডেটা সংগ্রহ করবেন।
  • কীভাবে একটি মাল্টি-লেয়ার পারসেপ্ট্রন তৈরি এবং সংজ্ঞায়িত করা যায় যা চিত্রের বৈশিষ্ট্যগুলি নেয় এবং সেগুলি ব্যবহার করে নতুন বস্তুকে শ্রেণিবদ্ধ করতে শেখে।

আসুন হ্যাকিং করা যাক...

আপনি কি প্রয়োজন হবে

  • একটি Glitch.com অ্যাকাউন্ট অনুসরণ করার জন্য পছন্দ করা হয়, অথবা আপনি এমন একটি ওয়েব পরিবেশন পরিবেশ ব্যবহার করতে পারেন যা আপনি সম্পাদনা করতে এবং নিজে চালাতে পারেন৷

2. TensorFlow.js কি?

54e81d02971f53e8.png

TensorFlow.js হল একটি ওপেন সোর্স মেশিন লার্নিং লাইব্রেরি যা জাভাস্ক্রিপ্ট যে কোন জায়গায় চালাতে পারে। এটি পাইথনে লেখা মূল TensorFlow লাইব্রেরির উপর ভিত্তি করে তৈরি করা হয়েছে এবং জাভাস্ক্রিপ্ট ইকোসিস্টেমের জন্য এই ডেভেলপার অভিজ্ঞতা এবং API-এর সেট পুনরায় তৈরি করা।

এটা কোথায় ব্যবহার করা যেতে পারে?

জাভাস্ক্রিপ্টের বহনযোগ্যতার কারণে, আপনি এখন 1টি ভাষায় লিখতে পারেন এবং নিচের সমস্ত প্ল্যাটফর্মে সহজেই মেশিন লার্নিং করতে পারেন:

  • ভ্যানিলা জাভাস্ক্রিপ্ট ব্যবহার করে ওয়েব ব্রাউজারে ক্লায়েন্ট সাইড
  • সার্ভার সাইড এবং এমনকি IoT ডিভাইস যেমন Raspberry Pi Node.js ব্যবহার করে
  • ইলেক্ট্রন ব্যবহার করে ডেস্কটপ অ্যাপ
  • React Native ব্যবহার করে নেটিভ মোবাইল অ্যাপ

TensorFlow.js এই প্রতিটি পরিবেশের মধ্যে একাধিক ব্যাকএন্ডকেও সমর্থন করে (প্রকৃত হার্ডওয়্যার ভিত্তিক পরিবেশ যা এটি কার্যকর করতে পারে যেমন CPU বা WebGL এর মধ্যে। এই প্রসঙ্গে একটি "ব্যাকএন্ড" মানে সার্ভার সাইড এনভায়রনমেন্ট নয় - এক্সিকিউশনের জন্য ব্যাকএন্ড WebGL-এ ক্লায়েন্ট সাইড হতে পারে উদাহরণস্বরূপ) সামঞ্জস্য নিশ্চিত করতে এবং জিনিসগুলি দ্রুত চলমান রাখতে। বর্তমানে TensorFlow.js সমর্থন করে:

  • ডিভাইসের গ্রাফিক্স কার্ডে (GPU) WebGL এক্সিকিউশন - GPU ত্বরণ সহ বড় মডেল (3MB এর বেশি) চালানোর এটি দ্রুততম উপায়।
  • CPU-তে ওয়েব অ্যাসেম্বলি (WASM) এক্সিকিউশন - উদাহরণস্বরূপ পুরানো প্রজন্মের মোবাইল ফোন সহ ডিভাইস জুড়ে CPU কর্মক্ষমতা উন্নত করতে। গ্রাফিক্স প্রসেসরে বিষয়বস্তু আপলোড করার ওভারহেডের কারণে ওয়েবজিএল-এর তুলনায় WASM-এর সাথে CPU-তে আসলে WASM-এর সাথে দ্রুত কার্যকর করতে পারে এমন ছোট মডেলগুলির জন্য এটি আরও উপযুক্ত।
  • সিপিইউ এক্সিকিউশন - ফলব্যাক অন্য কোনো পরিবেশে পাওয়া উচিত নয়। এটি তিনটির মধ্যে সবচেয়ে ধীর তবে সর্বদা আপনার জন্য রয়েছে।

দ্রষ্টব্য: আপনি এই ব্যাকএন্ডগুলির মধ্যে একটিকে জোর করে বেছে নিতে পারেন যদি আপনি জানেন যে আপনি কোন ডিভাইসে কাজ করবেন, অথবা আপনি যদি এটি নির্দিষ্ট না করেন তবে আপনি কেবল TensorFlow.js কে আপনার জন্য সিদ্ধান্ত নিতে দিতে পারেন।

ক্লায়েন্ট সাইড সুপার পাওয়ার

ক্লায়েন্ট মেশিনে ওয়েব ব্রাউজারে TensorFlow.js চালানোর ফলে বেশ কিছু সুবিধা হতে পারে যা বিবেচনা করার মতো।

গোপনীয়তা

আপনি 3য় পক্ষের ওয়েব সার্ভারে কখনও ডেটা না পাঠিয়ে ক্লায়েন্ট মেশিনে ডেটা প্রশিক্ষণ এবং শ্রেণিবদ্ধ করতে পারেন। এমন কিছু সময় থাকতে পারে যেখানে স্থানীয় আইন মেনে চলার জন্য এটির প্রয়োজন হতে পারে, যেমন GDPR, অথবা কোনো ডেটা প্রক্রিয়া করার সময় যা ব্যবহারকারী তাদের মেশিনে রাখতে চান এবং তৃতীয় পক্ষের কাছে পাঠানো হয়নি।

গতি

যেহেতু আপনাকে দূরবর্তী সার্ভারে ডেটা পাঠাতে হবে না, অনুমান (ডেটা শ্রেণীবদ্ধ করার কাজ) দ্রুত হতে পারে। আরও ভাল, আপনার ডিভাইসের সেন্সর যেমন ক্যামেরা, মাইক্রোফোন, জিপিএস, অ্যাক্সিলোমিটার এবং আরও অনেক কিছুতে আপনার সরাসরি অ্যাক্সেস আছে ব্যবহারকারী আপনাকে অ্যাক্সেস দেওয়ার অনুমতি দেয়।

পৌঁছান এবং স্কেল করুন

এক ক্লিকে বিশ্বের যে কেউ আপনার পাঠানো একটি লিঙ্কে ক্লিক করতে পারে, তাদের ব্রাউজারে ওয়েব পৃষ্ঠা খুলতে পারে এবং আপনি যা তৈরি করেছেন তা ব্যবহার করতে পারেন। মেশিন লার্নিং সিস্টেম ব্যবহার করার জন্য CUDA ড্রাইভার সহ একটি জটিল সার্ভার সাইড লিনাক্স সেটআপের প্রয়োজন নেই এবং আরও অনেক কিছু।

খরচ

কোনো সার্ভার মানেই আপনার HTML, CSS, JS, এবং মডেল ফাইলগুলি হোস্ট করার জন্য একটি CDN এর জন্য আপনাকে অর্থপ্রদান করতে হবে। একটি CDN-এর খরচ একটি সার্ভার (সম্ভাব্যভাবে একটি গ্রাফিক্স কার্ড সংযুক্ত) 24/7 চালানোর চেয়ে অনেক সস্তা।

সার্ভার সাইড বৈশিষ্ট্য

TensorFlow.js-এর Node.js বাস্তবায়নের কাজে লাগানো নিম্নলিখিত বৈশিষ্ট্যগুলিকে সক্ষম করে।

সম্পূর্ণ CUDA সমর্থন

সার্ভারের দিকে, গ্রাফিক্স কার্ডের ত্বরণের জন্য, আপনাকে অবশ্যই NVIDIA CUDA ড্রাইভার ইনস্টল করতে হবে যাতে TensorFlow গ্রাফিক্স কার্ডের সাথে কাজ করতে সক্ষম হয় (WebGL ব্যবহার করে এমন ব্রাউজার থেকে আলাদা - কোন ইনস্টলের প্রয়োজন নেই)। তবে সম্পূর্ণ CUDA সমর্থনের সাথে আপনি গ্রাফিক্স কার্ডের নিম্ন স্তরের ক্ষমতাগুলিকে সম্পূর্ণরূপে লাভ করতে পারেন, যার ফলে দ্রুত প্রশিক্ষণ এবং অনুমান সময় হয়। Python TensorFlow ইমপ্লিমেন্টেশনের সাথে পারফরম্যান্স সমানভাবে রয়েছে কারণ তারা উভয়ই একই C++ ব্যাকএন্ড শেয়ার করে।

মডেলের আকার

গবেষণা থেকে আধুনিক মডেলের জন্য, আপনি খুব বড় মডেলের সাথে কাজ করতে পারেন, হয়তো গিগাবাইট আকারের। প্রতি ব্রাউজার ট্যাবে মেমরি ব্যবহারের সীমাবদ্ধতার কারণে এই মডেলগুলি বর্তমানে ওয়েব ব্রাউজারে চালানো যাবে না। এই বৃহত্তর মডেলগুলি চালানোর জন্য আপনি আপনার নিজের সার্ভারে Node.js ব্যবহার করতে পারেন হার্ডওয়্যার স্পেসিফিকেশনের সাথে এই ধরনের মডেলটি দক্ষতার সাথে চালানোর জন্য।

আইওটি

Node.js Raspberry Pi এর মত জনপ্রিয় একক বোর্ড কম্পিউটারে সমর্থিত, যার মানে হল আপনি এই ধরনের ডিভাইসেও TensorFlow.js মডেলগুলি চালাতে পারেন।

গতি

Node.js জাভাস্ক্রিপ্টে লেখা হয় যার মানে এটি শুধুমাত্র সময় সংকলন থেকে উপকৃত হয়। এর মানে হল যে আপনি প্রায়শই Node.js ব্যবহার করার সময় পারফরম্যান্স লাভ দেখতে পারেন কারণ এটি রানটাইমে অপ্টিমাইজ করা হবে, বিশেষ করে আপনি যে কোনো প্রিপ্রসেসিং করছেন। এর একটি দুর্দান্ত উদাহরণ এই কেস স্টাডিতে দেখা যায় যা দেখায় যে কীভাবে Hugging Face তাদের প্রাকৃতিক ভাষা প্রক্রিয়াকরণ মডেলের জন্য 2x পারফরম্যান্স বুস্ট পেতে Node.js ব্যবহার করেছে৷

এখন আপনি TensorFlow.js এর মূল বিষয়গুলি বুঝতে পেরেছেন, যেখানে এটি চলতে পারে এবং কিছু সুবিধা, আসুন এটির সাথে দরকারী জিনিসগুলি করা শুরু করি!

3. ট্রান্সফার লার্নিং

ট্রান্সফার লার্নিং আসলে কি?

ট্রান্সফার লার্নিং একটি ভিন্ন কিন্তু একই জিনিস শিখতে সাহায্য করার জন্য ইতিমধ্যেই শেখা হয়েছে এমন জ্ঞান নেওয়া জড়িত।

আমরা মানুষ সব সময় এই কাজ. আপনার মস্তিষ্কে আজীবন অভিজ্ঞতা রয়েছে যা আপনি নতুন জিনিসগুলিকে চিনতে সাহায্য করতে ব্যবহার করতে পারেন যা আপনি আগে কখনও দেখেননি। উদাহরণস্বরূপ এই উইলো গাছটি নিন:

e28070392cd4afb9.png

আপনি বিশ্বের কোথায় আছেন তার উপর নির্ভর করে এমন সম্ভাবনা রয়েছে যে আপনি এই ধরণের গাছ আগে দেখেননি।

তবুও যদি আমি আপনাকে নীচের নতুন ছবিতে কোনও উইলো গাছ আছে কিনা তা আমাকে বলতে বলি, আপনি সম্ভবত সেগুলিকে খুব দ্রুত খুঁজে পেতে পারেন, যদিও সেগুলি একটি ভিন্ন কোণে, এবং আমি আপনাকে দেখানো আসলটির থেকে কিছুটা আলাদা৷

d9073a0d5df27222.png

আপনার মস্তিষ্কে ইতিমধ্যেই একগুচ্ছ নিউরন রয়েছে যেগুলি গাছের মতো বস্তুগুলিকে কীভাবে শনাক্ত করতে হয় তা জানে এবং অন্যান্য নিউরনগুলি যা দীর্ঘ সরল রেখা খুঁজে পেতে ভাল। আপনি একটি উইলো গাছকে দ্রুত শ্রেণীবদ্ধ করতে সেই জ্ঞানটি পুনরায় ব্যবহার করতে পারেন, যা একটি গাছের মতো বস্তু যার অনেকগুলি লম্বা সোজা উল্লম্ব শাখা রয়েছে।

একইভাবে, যদি আপনার কাছে একটি মেশিন লার্নিং মডেল থাকে যা ইতিমধ্যেই একটি ডোমেনে প্রশিক্ষিত হয়, যেমন ছবি শনাক্ত করা, আপনি একটি ভিন্ন কিন্তু সম্পর্কিত কাজ সম্পাদন করতে এটি পুনরায় ব্যবহার করতে পারেন।

আপনি MobileNet এর মত একটি উন্নত মডেলের সাথে একই কাজ করতে পারেন, যা একটি খুব জনপ্রিয় গবেষণা মডেল যা 1000টি বিভিন্ন ধরনের অবজেক্টে ইমেজ রিকগনিশন করতে পারে। কুকুর থেকে গাড়ি পর্যন্ত, এটিকে ইমেজনেট নামে পরিচিত একটি বিশাল ডেটাসেটে প্রশিক্ষণ দেওয়া হয়েছিল যাতে লক্ষ লক্ষ লেবেলযুক্ত চিত্র রয়েছে।

এই অ্যানিমেশনে, আপনি এই MobileNet V1 মডেলের বিশাল সংখ্যক স্তর দেখতে পারেন:

7d4e1e35c1a89715.gif

এর প্রশিক্ষণের সময়, এই মডেলটি শিখেছে কীভাবে সাধারণ বৈশিষ্ট্যগুলি বের করতে হয় যা এই 1000টি বস্তুর জন্য গুরুত্বপূর্ণ, এবং এই ধরনের বস্তুগুলি সনাক্ত করতে এটি ব্যবহার করে এমন অনেক নিম্ন স্তরের বৈশিষ্ট্যগুলি এমন নতুন বস্তু সনাক্ত করতে কার্যকর হতে পারে যা এটি আগে কখনও দেখেনি। সর্বোপরি, সবকিছুই শেষ পর্যন্ত শুধু লাইন, টেক্সচার এবং আকারের সংমিশ্রণ।

আসুন একটি প্রথাগত কনভোলিউশনাল নিউরাল নেটওয়ার্ক (সিএনএন) আর্কিটেকচার (মোবাইলনেটের অনুরূপ) দেখে নেওয়া যাক এবং দেখুন কিভাবে ট্রান্সফার লার্নিং এই প্রশিক্ষিত নেটওয়ার্ককে নতুন কিছু শিখতে সাহায্য করতে পারে। নীচের চিত্রটি একটি সিএনএন-এর আদর্শ মডেল আর্কিটেকচার দেখায় যা এই ক্ষেত্রে 0 থেকে 9 পর্যন্ত হাতে লেখা অঙ্কগুলি চিনতে প্রশিক্ষিত ছিল:

baf4e3d434576106.png

যদি আপনি একটি বিদ্যমান প্রশিক্ষিত মডেলের প্রাক-প্রশিক্ষিত নিম্ন স্তরের স্তরগুলিকে বাম দিকে দেখানো এইভাবে আলাদা করতে পারেন, ডানদিকে প্রদর্শিত মডেলের শেষের কাছাকাছি শ্রেণিবিন্যাসের স্তরগুলি থেকে (কখনও কখনও মডেলের শ্রেণিবিন্যাস প্রধান হিসাবে উল্লেখ করা হয়), আপনি প্রশিক্ষিত মূল ডেটার উপর ভিত্তি করে যে কোনও প্রদত্ত চিত্রের জন্য আউটপুট বৈশিষ্ট্যগুলি তৈরি করতে নিম্ন স্তরের স্তরগুলি ব্যবহার করতে পারেন। এখানে শ্রেণীবিন্যাস প্রধান সরানো একই নেটওয়ার্ক আছে:

369a8a9041c6917d.png

আপনি যে নতুন জিনিসটি চিনতে চাচ্ছেন তা ধরে নিলে পূর্বের মডেলটি শিখেছে এমন আউটপুট বৈশিষ্ট্যগুলিও ব্যবহার করতে পারে, তাহলে একটি নতুন উদ্দেশ্যে সেগুলি পুনরায় ব্যবহার করার একটি ভাল সুযোগ রয়েছে।

উপরের চিত্রে, এই অনুমানমূলক মডেলটি অঙ্কের উপর প্রশিক্ষিত ছিল, তাই হয়তো অঙ্ক সম্পর্কে যা শিখেছি তা a, b, এবং c এর মতো অক্ষরগুলিতেও প্রয়োগ করা যেতে পারে।

সুতরাং এখন আপনি একটি নতুন শ্রেণিবিন্যাস হেড যোগ করতে পারেন যা a, b, বা c এর পরিবর্তে ভবিষ্যদ্বাণী করার চেষ্টা করে, যেমন দেখানো হয়েছে:

db97e5e60ae73bbd.png

এখানে নিম্ন স্তরের স্তরগুলি হিমায়িত এবং প্রশিক্ষিত নয়, শুধুমাত্র নতুন শ্রেণীবিভাগ প্রধান বাম দিকে প্রাক-প্রশিক্ষিত চপ আপ মডেল থেকে প্রদত্ত বৈশিষ্ট্যগুলি থেকে শিখতে নিজেকে আপডেট করবে।

এটি করার কাজটিকে ট্রান্সফার লার্নিং বলা হয় এবং পর্দার আড়ালে শিক্ষনীয় মেশিন এটিই করে।

আপনি আরও দেখতে পারেন যে শুধুমাত্র নেটওয়ার্কের একেবারে শেষে মাল্টি-লেয়ার পারসেপ্ট্রনকে প্রশিক্ষিত করার মাধ্যমে, এটি আপনাকে স্ক্র্যাচ থেকে পুরো নেটওয়ার্ককে প্রশিক্ষণ দেওয়ার চেয়ে অনেক দ্রুত প্রশিক্ষণ দেয়।

কিন্তু আপনি কিভাবে একটি মডেলের উপ-অংশগুলিতে আপনার হাত পেতে পারেন? খুঁজে বের করতে পরবর্তী বিভাগে যান।

4. টেনসরফ্লো হাব - বেস মডেল

ব্যবহার করার জন্য একটি উপযুক্ত বেস মডেল খুঁজুন

MobileNet-এর মতো আরও উন্নত এবং জনপ্রিয় গবেষণা মডেলের জন্য, আপনি TensorFlow হাবে যেতে পারেন, এবং তারপরে TensorFlow.js-এর জন্য উপযুক্ত মডেলগুলির জন্য ফিল্টার করতে পারেন যেগুলি এখানে দেখানোর মতো ফলাফল পেতে MobileNet v3 আর্কিটেকচার ব্যবহার করে :

c5dc1420c6238c14.png

মনে রাখবেন যে এই ফলাফলগুলির মধ্যে কিছু "ইমেজ শ্রেণীবিভাগ" (প্রতিটি মডেল কার্ডের ফলাফলের উপরের বাম দিকে বিশদ বিবরণ) টাইপের এবং অন্যগুলি "চিত্র বৈশিষ্ট্য ভেক্টর" টাইপের।

এই ইমেজ ফিচার ভেক্টর ফলাফলগুলি মূলত MobileNet-এর প্রাক-কাপ করা সংস্করণ যা আপনি চূড়ান্ত শ্রেণীবিভাগের পরিবর্তে চিত্র বৈশিষ্ট্য ভেক্টর পেতে ব্যবহার করতে পারেন।

এই ধরনের মডেলগুলিকে প্রায়শই "বেস মডেল" বলা হয়, যেটি আপনি একটি নতুন শ্রেণীবিভাগ প্রধান যোগ করে এবং আপনার নিজস্ব ডেটা দিয়ে প্রশিক্ষণের মাধ্যমে পূর্ববর্তী বিভাগে দেখানো একই পদ্ধতিতে স্থানান্তর শিক্ষা সম্পাদন করতে ব্যবহার করতে পারেন।

পরের জিনিসটি পরীক্ষা করার জন্য আগ্রহের একটি প্রদত্ত বেস মডেলের জন্য TensorFlow.js ফর্ম্যাটে মডেলটি প্রকাশ করা হয়েছে৷ আপনি যদি এই বৈশিষ্ট্য ভেক্টর MobileNet v3 মডেলগুলির একটির জন্য পৃষ্ঠাটি খোলেন তবে আপনি JS ডকুমেন্টেশন থেকে দেখতে পাবেন যে এটি ডকুমেন্টেশনের উদাহরণ কোড স্নিপেটের উপর ভিত্তি করে একটি গ্রাফ মডেল আকারে যা tf.loadGraphModel() ব্যবহার করে।

f97d903d2e46924b.png

এটিও লক্ষ করা উচিত যে আপনি যদি গ্রাফ বিন্যাসের পরিবর্তে স্তর বিন্যাসে একটি মডেল খুঁজে পান তবে আপনি প্রশিক্ষণের জন্য কোন স্তরগুলিকে হিমায়িত করতে হবে এবং কোনটি আনফ্রিজ করতে হবে তা চয়ন করতে পারেন৷ একটি নতুন কাজের জন্য একটি মডেল তৈরি করার সময় এটি খুব শক্তিশালী হতে পারে, যা প্রায়ই "স্থানান্তর মডেল" হিসাবে উল্লেখ করা হয়। আপাতত, যাইহোক, আপনি এই টিউটোরিয়ালের জন্য ডিফল্ট গ্রাফ মডেল টাইপ ব্যবহার করবেন, যেটি বেশিরভাগ TF হাব মডেল হিসাবে স্থাপন করা হয়। লেয়ার মডেলগুলির সাথে কাজ করার বিষয়ে আরও জানতে, জিরো থেকে হিরো TensorFlow.js কোর্সটি দেখুন।

স্থানান্তর শিক্ষার সুবিধা

স্ক্র্যাচ থেকে পুরো মডেল আর্কিটেকচার প্রশিক্ষণের পরিবর্তে ট্রান্সফার লার্নিং ব্যবহার করার সুবিধা কী?

প্রথমত, প্রশিক্ষণের সময় হল একটি ট্রান্সফার শেখার পদ্ধতি ব্যবহার করার একটি মূল সুবিধা কারণ আপনার কাছে ইতিমধ্যেই তৈরি করার জন্য একটি প্রশিক্ষিত বেস মডেল রয়েছে।

দ্বিতীয়ত, আপনি যে নতুন জিনিসের শ্রেণীবিভাগ করার চেষ্টা করছেন তার অনেক কম উদাহরণ দেখিয়ে আপনি দূরে যেতে পারেন যা ইতিমধ্যেই সংঘটিত প্রশিক্ষণের কারণে।

আপনি যে জিনিসটি শ্রেণীবদ্ধ করতে চান তার উদাহরণ ডেটা সংগ্রহ করার জন্য আপনার কাছে সীমিত সময় এবং সংস্থান থাকলে এটি সত্যিই দুর্দান্ত, এবং এটিকে আরও শক্তিশালী করতে আরও প্রশিক্ষণের ডেটা সংগ্রহ করার আগে দ্রুত একটি প্রোটোটাইপ তৈরি করতে হবে।

কম ডেটার প্রয়োজনীয়তা এবং একটি ছোট নেটওয়ার্ককে প্রশিক্ষণের গতির প্রেক্ষিতে, স্থানান্তর শেখার কম সম্পদ নিবিড়। এটি ব্রাউজার পরিবেশের জন্য খুব উপযুক্ত করে তোলে, সম্পূর্ণ মডেল প্রশিক্ষণের জন্য ঘন্টা, দিন বা সপ্তাহের পরিবর্তে একটি আধুনিক মেশিনে মাত্র দশ সেকেন্ড সময় নেয়।

ঠিক আছে! এখন আপনি ট্রান্সফার লার্নিং এর সারমর্ম জানেন, এটি আপনার নিজস্ব শিক্ষণযোগ্য মেশিনের সংস্করণ তৈরি করার সময়। চল শুরু করি!

5. কোড সেট আপ করুন

আপনি কি প্রয়োজন হবে

  • একটি আধুনিক ওয়েব ব্রাউজার।
  • HTML, CSS, JavaScript এবং Chrome DevTools এর প্রাথমিক জ্ঞান (কনসোল আউটপুট দেখা)।

কোডিং করা যাক

থেকে শুরু করার জন্য বয়লারপ্লেট টেমপ্লেটগুলি Glitch.com বা Codepen.io- এর জন্য তৈরি করা হয়েছে। আপনি এই কোড ল্যাবের জন্য আপনার বেস স্টেট হিসাবে যেকোন একটি টেমপ্লেটকে ক্লোন করতে পারেন, শুধুমাত্র একটি ক্লিকে।

Glitch-এ, এটিকে কাঁটাচামচ করতে " রিমিক্স এই" বোতামটি ক্লিক করুন এবং আপনি সম্পাদনা করতে পারেন এমন ফাইলগুলির একটি নতুন সেট তৈরি করুন৷

বিকল্পভাবে, কোডপেনে, স্ক্রিনের নীচের নীচে ডানদিকে " ফর্ক" ক্লিক করুন।

এই খুব সাধারণ কঙ্কাল আপনাকে নিম্নলিখিত ফাইলগুলি সরবরাহ করে:

  • HTML পৃষ্ঠা (index.html)
  • স্টাইলশীট (style.css)
  • আমাদের জাভাস্ক্রিপ্ট কোড লেখার জন্য ফাইল (script.js)

আপনার সুবিধার জন্য, TensorFlow.js লাইব্রেরির জন্য HTML ফাইলে একটি যোগ করা হয়েছে। এটি এই মত দেখায়:

index.html

<!-- Import TensorFlow.js library -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js" type="text/javascript"></script>

বিকল্প: আপনার পছন্দের ওয়েবডিটর ব্যবহার করুন বা স্থানীয়ভাবে কাজ করুন

আপনি যদি কোডটি ডাউনলোড করতে চান এবং স্থানীয়ভাবে কাজ করতে চান, বা অন্য কোনও অনলাইন সম্পাদকে, শুধুমাত্র একই ডিরেক্টরিতে উপরে নাম দেওয়া 3টি ফাইল তৈরি করুন এবং আমাদের গ্লিচ বয়লারপ্লেট থেকে কোডটি কপি করে প্রতিটিতে পেস্ট করুন৷

6. অ্যাপ এইচটিএমএল বয়লারপ্লেট

আমি কোথা থেকে শুরু করব?

সমস্ত প্রোটোটাইপের জন্য কিছু মৌলিক HTML ভারা প্রয়োজন যাতে আপনি আপনার ফলাফলগুলি রেন্ডার করতে পারেন৷ এটা এখন সেট আপ. আপনি যোগ করতে যাচ্ছেন:

  • পৃষ্ঠার জন্য একটি শিরোনাম।
  • কিছু বর্ণনামূলক লেখা।
  • একটি স্ট্যাটাস অনুচ্ছেদ।
  • ওয়েবক্যাম ফিড একবার প্রস্তুত হওয়ার জন্য একটি ভিডিও।
  • ক্যামেরা চালু করতে, ডেটা সংগ্রহ করতে বা অভিজ্ঞতা পুনরায় সেট করতে বেশ কয়েকটি বোতাম।
  • TensorFlow.js এবং JS ফাইলের জন্য আমদানি করে আপনি পরে কোড করবেন।

index.html খুলুন এবং উপরের বৈশিষ্ট্যগুলি সেট আপ করতে নিম্নলিখিত সহ বিদ্যমান কোডটি পেস্ট করুন:

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Transfer Learning - TensorFlow.js</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Import the webpage's stylesheet -->
    <link rel="stylesheet" href="/style.css">
  </head>  
  <body>
    <h1>Make your own "Teachable Machine" using Transfer Learning with MobileNet v3 in TensorFlow.js using saved graph model from TFHub.</h1>
    
    <p id="status">Awaiting TF.js load</p>
    
    <video id="webcam" autoplay muted></video>
    
    <button id="enableCam">Enable Webcam</button>
    <button class="dataCollector" data-1hot="0" data-name="Class 1">Gather Class 1 Data</button>
    <button class="dataCollector" data-1hot="1" data-name="Class 2">Gather Class 2 Data</button>
    <button id="train">Train &amp; Predict!</button>
    <button id="reset">Reset</button>

    <!-- Import TensorFlow.js library -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.11.0/dist/tf.min.js" type="text/javascript"></script>

    <!-- Import the page's JavaScript to do some stuff -->
    <script type="module" src="/script.js"></script>
  </body>
</html>

এটি ভেংগে ফেল

আপনার যোগ করা কিছু মূল জিনিস হাইলাইট করতে উপরের কিছু HTML কোড ভেঙে দেওয়া যাক।

  • আপনি পৃষ্ঠার শিরোনামের জন্য একটি <h1> ট্যাগ যোগ করেছেন একটি <p> ট্যাগের সাথে একটি 'স্থিতি' আইডি সহ, যেখানে আপনি তথ্য মুদ্রণ করবেন, কারণ আপনি আউটপুট দেখার জন্য সিস্টেমের বিভিন্ন অংশ ব্যবহার করেন।
  • আপনি 'ওয়েবক্যাম'-এর একটি আইডি সহ একটি <video> উপাদান যোগ করেছেন, যেখানে আপনি পরে আপনার ওয়েবক্যাম স্ট্রিম রেন্ডার করবেন।
  • আপনি 5টি <button> উপাদান যোগ করেছেন। প্রথমটি, 'enableCam'-এর আইডি দিয়ে, ক্যামেরাকে সক্ষম করে। পরবর্তী দুটি বোতামে 'ডেটাকলেক্টর'-এর একটি শ্রেণী রয়েছে, যা আপনাকে যে বস্তুগুলিকে চিনতে চান তার উদাহরণ চিত্র সংগ্রহ করতে দেয়। আপনি পরে যে কোডটি লিখবেন তা এমনভাবে ডিজাইন করা হবে যাতে আপনি এই বোতামগুলির যেকোনো সংখ্যা যোগ করতে পারেন এবং সেগুলি স্বয়ংক্রিয়ভাবে কাজ করবে।

উল্লেখ্য যে এই বোতামগুলিতে ডেটা-1 হট নামে একটি বিশেষ ব্যবহারকারী-সংজ্ঞায়িত বৈশিষ্ট্যও রয়েছে, যার প্রথম শ্রেণীর জন্য 0 থেকে পূর্ণসংখ্যার মান শুরু হয়। এটি এমন একটি সংখ্যাসূচক সূচক যা আপনি একটি নির্দিষ্ট শ্রেণীর ডেটা উপস্থাপন করতে ব্যবহার করবেন। সূচীটি আউটপুট ক্লাসগুলিকে স্ট্রিংয়ের পরিবর্তে একটি সংখ্যাসূচক উপস্থাপনা সহ সঠিকভাবে এনকোড করতে ব্যবহার করা হবে, কারণ ML মডেলগুলি শুধুমাত্র সংখ্যার সাথে কাজ করতে পারে।

এছাড়াও একটি ডেটা-নাম বৈশিষ্ট্য রয়েছে যাতে আপনি এই শ্রেণীর জন্য ব্যবহার করতে চান এমন মানব পাঠযোগ্য নাম রয়েছে, যা আপনাকে 1 হট এনকোডিং থেকে একটি সংখ্যাসূচক সূচক মানের পরিবর্তে ব্যবহারকারীকে আরও অর্থপূর্ণ নাম প্রদান করতে দেয়৷

অবশেষে, আপনার কাছে একটি ট্রেন এবং রিসেট বোতাম রয়েছে যা একবার ডেটা সংগ্রহ করার পরে প্রশিক্ষণ প্রক্রিয়া শুরু করতে বা যথাক্রমে অ্যাপটি পুনরায় সেট করতে।

  • আপনি 2টি <script> আমদানিও যোগ করেছেন। একটি TensorFlow.js এর জন্য এবং অন্যটি script.js এর জন্য যা আপনি শীঘ্রই সংজ্ঞায়িত করবেন৷

7. শৈলী যোগ করুন

এলিমেন্ট ডিফল্ট

সঠিকভাবে রেন্ডার নিশ্চিত করতে আপনি এইমাত্র যোগ করেছেন এমন HTML উপাদানগুলির জন্য শৈলী যোগ করুন। এখানে কিছু শৈলী রয়েছে যা সঠিকভাবে অবস্থান এবং আকারের উপাদানগুলিতে যোগ করা হয়েছে। খুব বিশেষ কিছু না. আপনি অবশ্যই আরও ভাল ইউএক্স তৈরি করতে পরে এটিতে যোগ করতে পারেন, যেমন আপনি শিক্ষণীয় মেশিন ভিডিওতে দেখেছেন।

style.css

body {
  font-family: helvetica, arial, sans-serif;
  margin: 2em;
}

h1 {
  font-style: italic;
  color: #FF6F00;
}


video {
  clear: both;
  display: block;
  margin: 10px;
  background: #000000;
  width: 640px;
  height: 480px;
}

button {
  padding: 10px;
  float: left;
  margin: 5px 3px 5px 10px;
}

.removed {
  display: none;
}

#status {
  font-size:150%;
}

দারুণ! যে সব আপনার প্রয়োজন. আপনি যদি এখনই আউটপুটটির পূর্বরূপ দেখেন তবে এটি দেখতে এরকম কিছু হওয়া উচিত:

81909685d7566dcb.png

8. জাভাস্ক্রিপ্ট: কী ধ্রুবক এবং শ্রোতা

কী ধ্রুবক সংজ্ঞায়িত করুন

প্রথমে, কিছু মূল ধ্রুবক যোগ করুন যা আপনি পুরো অ্যাপ জুড়ে ব্যবহার করবেন। এই ধ্রুবকগুলির সাথে script.js এর বিষয়বস্তু প্রতিস্থাপন করে শুরু করুন:

script.js

const STATUS = document.getElementById('status');
const VIDEO = document.getElementById('webcam');
const ENABLE_CAM_BUTTON = document.getElementById('enableCam');
const RESET_BUTTON = document.getElementById('reset');
const TRAIN_BUTTON = document.getElementById('train');
const MOBILE_NET_INPUT_WIDTH = 224;
const MOBILE_NET_INPUT_HEIGHT = 224;
const STOP_DATA_GATHER = -1;
const CLASS_NAMES = [];

এগুলি কীসের জন্য তা ভেঙে দেওয়া যাক:

  • STATUS শুধুমাত্র অনুচ্ছেদ ট্যাগের একটি রেফারেন্স ধারণ করে যেখানে আপনি স্ট্যাটাস আপডেট লিখবেন।
  • VIDEO HTML ভিডিও উপাদানের একটি রেফারেন্স রয়েছে যা ওয়েবক্যাম ফিড রেন্ডার করবে।
  • ENABLE_CAM_BUTTON , RESET_BUTTON , এবং TRAIN_BUTTON HTML পৃষ্ঠা থেকে সমস্ত কী বোতামের DOM রেফারেন্স দখল করে৷
  • MOBILE_NET_INPUT_WIDTH এবং MOBILE_NET_INPUT_HEIGHT যথাক্রমে MobileNet মডেলের প্রত্যাশিত ইনপুট প্রস্থ এবং উচ্চতা সংজ্ঞায়িত করে৷ এটিকে ফাইলের শীর্ষের কাছে একটি ধ্রুবক হিসাবে সংরক্ষণ করার মাধ্যমে, আপনি যদি পরে একটি ভিন্ন সংস্করণ ব্যবহার করার সিদ্ধান্ত নেন, তবে এটি বিভিন্ন স্থানে এটি প্রতিস্থাপন করার পরিবর্তে একবার মানগুলিকে আপডেট করা সহজ করে তোলে।
  • STOP_DATA_GATHER এ সেট করা আছে - 1। এটি একটি রাষ্ট্রীয় মান সঞ্চয় করে যাতে আপনি জানতে পারেন যে ব্যবহারকারী কখন ওয়েবক্যাম ফিড থেকে ডেটা সংগ্রহ করতে একটি বোতামে ক্লিক করা বন্ধ করেছে। এই নম্বরটিকে আরও অর্থপূর্ণ নাম দেওয়ার মাধ্যমে, এটি কোডটিকে পরে আরও পাঠযোগ্য করে তোলে।
  • CLASS_NAMES একটি লুকআপ হিসাবে কাজ করে এবং সম্ভাব্য শ্রেণীর পূর্বাভাসের জন্য মানুষের পঠনযোগ্য নাম ধারণ করে। এই অ্যারে পরে পপুলেট করা হবে.

ঠিক আছে, এখন আপনার কাছে মূল উপাদানগুলির উল্লেখ রয়েছে, এটি কিছু ইভেন্ট শ্রোতাদের সাথে যুক্ত করার সময়।

মূল ঘটনা শ্রোতা যোগ করুন

দেখানো হিসাবে কী বোতামে ক্লিক ইভেন্ট হ্যান্ডলার যোগ করে শুরু করুন:

script.js

ENABLE_CAM_BUTTON.addEventListener('click', enableCam);
TRAIN_BUTTON.addEventListener('click', trainAndPredict);
RESET_BUTTON.addEventListener('click', reset);


function enableCam() {
  // TODO: Fill this out later in the codelab!
}


function trainAndPredict() {
  // TODO: Fill this out later in the codelab!
}


function reset() {
  // TODO: Fill this out later in the codelab!
}

ENABLE_CAM_BUTTON - ক্লিক করার সময় enableCam ফাংশন কল করে।

TRAIN_BUTTON - ক্লিক করলে ট্রেন এবং প্রেডিক্টে কল করে।

RESET_BUTTON - ক্লিক করলে কল রিসেট হয়।

অবশেষে এই বিভাগে আপনি document.querySelectorAll() ব্যবহার করে 'dataCollector'-এর ক্লাস আছে এমন সমস্ত বোতাম খুঁজে পেতে পারেন। এটি নথি থেকে পাওয়া উপাদানগুলির একটি অ্যারে প্রদান করে যা মেলে:

script.js

let dataCollectorButtons = document.querySelectorAll('button.dataCollector');
for (let i = 0; i < dataCollectorButtons.length; i++) {
  dataCollectorButtons[i].addEventListener('mousedown', gatherDataForClass);
  dataCollectorButtons[i].addEventListener('mouseup', gatherDataForClass);
  // Populate the human readable names for classes.
  CLASS_NAMES.push(dataCollectorButtons[i].getAttribute('data-name'));
}


function gatherDataForClass() {
  // TODO: Fill this out later in the codelab!
}

কোড ব্যাখ্যা:

তারপরে আপনি পাওয়া বোতামগুলির মাধ্যমে পুনরাবৃত্তি করুন এবং প্রতিটির সাথে 2 জন ইভেন্ট শ্রোতাকে সংযুক্ত করুন৷ একটি 'মাউসডাউন' এর জন্য এবং একটি 'মাউসআপ' এর জন্য। এটি আপনাকে যতক্ষণ বোতাম টিপছে ততক্ষণ নমুনা রেকর্ড করতে দেয়, যা ডেটা সংগ্রহের জন্য দরকারী।

উভয় ইভেন্টই একটি gatherDataForClass ফাংশন বলে যা আপনি পরে সংজ্ঞায়িত করবেন।

এই মুহুর্তে, আপনি HTML বোতাম অ্যাট্রিবিউট ডেটা-নাম থেকে CLASS_NAMES অ্যারেতে পাওয়া মানুষের পঠনযোগ্য শ্রেণির নামগুলিকেও পুশ করতে পারেন।

এর পরে, কিছু ভেরিয়েবল যোগ করুন মূল জিনিসগুলি সংরক্ষণ করতে যা পরে ব্যবহার করা হবে।

script.js

let mobilenet = undefined;
let gatherDataState = STOP_DATA_GATHER;
let videoPlaying = false;
let trainingDataInputs = [];
let trainingDataOutputs = [];
let examplesCount = [];
let predict = false;

এর মধ্যে দিয়ে হাঁটা যাক.

প্রথমত, লোড করা মোবাইলনেট মডেল সংরক্ষণ করার জন্য আপনার কাছে একটি পরিবর্তনশীল mobilenet রয়েছে। প্রাথমিকভাবে এটি অনির্ধারিত সেট করুন।

এরপরে, আপনার কাছে gatherDataState নামে একটি ভেরিয়েবল আছে। যদি একটি 'dataCollector' বোতাম টিপানো হয়, তাহলে এটি পরিবর্তন করে সেই বোতামের 1 হট আইডি হবে, যেমনটি HTML-এ সংজ্ঞায়িত করা হয়েছে, যাতে আপনি জানতে পারেন যে আপনি সেই মুহূর্তে কোন শ্রেণীর ডেটা সংগ্রহ করছেন। প্রাথমিকভাবে, এটি STOP_DATA_GATHER এ সেট করা হয়েছে যাতে আপনি পরে যে ডেটা সংগ্রহের লুপটি লিখবেন সেটি কোনো বোতাম টিপলে কোনো ডেটা সংগ্রহ করবে না।

videoPlaying ওয়েবক্যাম স্ট্রীম সফলভাবে লোড হয়েছে এবং চালানো হয়েছে এবং ব্যবহারের জন্য উপলব্ধ কিনা তা ট্র্যাক রাখে। প্রাথমিকভাবে, এটি false হিসাবে সেট করা হয়েছে কারণ আপনি ENABLE_CAM_BUTTON.

এর পরে, 2টি অ্যারে, trainingDataInputs এবং trainingDataOutputs সংজ্ঞায়িত করুন। এগুলি সংগৃহীত প্রশিক্ষণ ডেটা মানগুলি সঞ্চয় করে, যখন আপনি MobileNet বেস মডেল দ্বারা উত্পন্ন ইনপুট বৈশিষ্ট্যগুলির জন্য 'dataCollector' বোতামে ক্লিক করেন এবং যথাক্রমে আউটপুট ক্লাস নমুনা করা হয়।

একটি চূড়ান্ত অ্যারে, examplesCount, তারপরে প্রতিটি ক্লাসের জন্য কতগুলি উদাহরণ রয়েছে তা ট্র্যাক রাখার জন্য সংজ্ঞায়িত করা হয় একবার আপনি সেগুলি যোগ করা শুরু করেন।

অবশেষে, আপনার predict নামক একটি পরিবর্তনশীল আছে যা আপনার পূর্বাভাস লুপ নিয়ন্ত্রণ করে। এটি প্রাথমিকভাবে false হিসাবে সেট করা হয়েছে। এটি পরবর্তীতে true না হওয়া পর্যন্ত কোনো ভবিষ্যদ্বাণী করা যাবে না।

এখন যেহেতু সমস্ত মূল ভেরিয়েবল সংজ্ঞায়িত করা হয়েছে, চলুন এবং প্রি-কাপ আপ MobileNet v3 বেস মডেলটি লোড করি যা শ্রেণীবিভাগের পরিবর্তে চিত্র বৈশিষ্ট্য ভেক্টর প্রদান করে।

9. MobileNet বেস মডেল লোড করুন

প্রথমে, নীচে দেখানো হিসাবে loadMobileNetFeatureModel নামে একটি নতুন ফাংশন সংজ্ঞায়িত করুন। এটি অবশ্যই একটি অ্যাসিঙ্ক ফাংশন হতে হবে কারণ একটি মডেল লোড করার কাজটি অ্যাসিঙ্ক্রোনাস:

script.js

/**
 * Loads the MobileNet model and warms it up so ready for use.
 **/
async function loadMobileNetFeatureModel() {
  const URL = 
    'https://tfhub.dev/google/tfjs-model/imagenet/mobilenet_v3_small_100_224/feature_vector/5/default/1';
  
  mobilenet = await tf.loadGraphModel(URL, {fromTFHub: true});
  STATUS.innerText = 'MobileNet v3 loaded successfully!';
  
  // Warm up the model by passing zeros through it once.
  tf.tidy(function () {
    let answer = mobilenet.predict(tf.zeros([1, MOBILE_NET_INPUT_HEIGHT, MOBILE_NET_INPUT_WIDTH, 3]));
    console.log(answer.shape);
  });
}

// Call the function immediately to start loading.
loadMobileNetFeatureModel();

এই কোডে আপনি URL টি সংজ্ঞায়িত করেন যেখানে TFHub ডকুমেন্টেশন থেকে লোড করার জন্য মডেলটি অবস্থিত।

তারপরে আপনি await tf.loadGraphModel() ব্যবহার করে মডেলটি লোড করতে পারেন, fromTFHub বিশেষ বৈশিষ্ট্যটিকে true সেট করার কথা মনে রেখে আপনি এই Google ওয়েবসাইট থেকে একটি মডেল লোড করছেন৷ এটি শুধুমাত্র TF হাবে হোস্ট করা মডেল ব্যবহার করার জন্য একটি বিশেষ ক্ষেত্রে যেখানে এই অতিরিক্ত সম্পত্তি সেট করতে হবে।

একবার লোডিং সম্পূর্ণ হলে আপনি একটি বার্তা সহ STATUS উপাদানের innerText সেট করতে পারেন যাতে আপনি দৃশ্যত দেখতে পারেন এটি সঠিকভাবে লোড হয়েছে এবং আপনি ডেটা সংগ্রহ শুরু করতে প্রস্তুত৷

এখন শুধু মডেলটিকে ওয়ার্ম আপ করা বাকি। এই ধরনের বড় মডেলগুলির সাথে, আপনি প্রথমবার মডেলটি ব্যবহার করার সময়, সবকিছু সেট আপ করতে একটু সময় নিতে পারে৷ তাই এটি মডেলের মধ্য দিয়ে শূন্য অতিক্রম করতে সাহায্য করে যাতে ভবিষ্যতে কোনো অপেক্ষা না করা যায় যেখানে সময় আরও জটিল হতে পারে।

আপনি tf.zeros() ব্যবহার করতে পারেন tf.tidy() এ মোড়ানো নিশ্চিত করতে টেনসর সঠিকভাবে নিষ্পত্তি করা হয়েছে, ব্যাচের আকার 1 এবং সঠিক উচ্চতা এবং প্রস্থ যা আপনি শুরুতে আপনার ধ্রুবকগুলিতে সংজ্ঞায়িত করেছেন। অবশেষে, আপনি রঙের চ্যানেলগুলিও নির্দিষ্ট করুন, যেটি এই ক্ষেত্রে 3 যেমন মডেলটি আরজিবি ছবি আশা করে।

এর পরে, এই মডেলটি তৈরি করা ছবির বৈশিষ্ট্যগুলির আকার বুঝতে সাহায্য করার জন্য answer.shape() ব্যবহার করে ফেরত টেনসরের ফলের আকৃতি লগ করুন।

এই ফাংশনটি সংজ্ঞায়িত করার পরে, আপনি পৃষ্ঠা লোডে মডেল ডাউনলোড শুরু করতে অবিলম্বে এটিকে কল করতে পারেন।

আপনি যদি এখনই আপনার লাইভ প্রিভিউ দেখেন, তাহলে কিছুক্ষণ পর আপনি দেখতে পাবেন স্ট্যাটাস টেক্সট পরিবর্তন হয়ে "TF.js লোডের অপেক্ষায়" থেকে "MobileNet v3 সফলভাবে লোড হয়েছে!" নিচে দেখানো হয়েছে। চালিয়ে যাওয়ার আগে এটি কাজ করে তা নিশ্চিত করুন।

a28b734e190afff.png

এই মডেলটি যে আউটপুট বৈশিষ্ট্যগুলি তৈরি করে তার মুদ্রিত আকার দেখতে আপনি কনসোল আউটপুটটিও পরীক্ষা করতে পারেন। MobileNet মডেলের মাধ্যমে শূন্য চালানোর পরে, আপনি [1, 1024] মুদ্রিত আকার দেখতে পাবেন। প্রথম আইটেমটি শুধুমাত্র 1 এর ব্যাচের আকার, এবং আপনি দেখতে পাচ্ছেন এটি আসলে 1024 বৈশিষ্ট্য প্রদান করে যা আপনাকে নতুন অবজেক্ট শ্রেণীবদ্ধ করতে সাহায্য করতে ব্যবহার করা যেতে পারে।

10. নতুন মডেল হেড সংজ্ঞায়িত করুন

এখন আপনার মডেল হেডকে সংজ্ঞায়িত করার সময় এসেছে, যা মূলত একটি খুব ন্যূনতম মাল্টি-লেয়ার পারসেপ্ট্রন।

script.js

let model = tf.sequential();
model.add(tf.layers.dense({inputShape: [1024], units: 128, activation: 'relu'}));
model.add(tf.layers.dense({units: CLASS_NAMES.length, activation: 'softmax'}));

model.summary();

// Compile the model with the defined optimizer and specify a loss function to use.
model.compile({
  // Adam changes the learning rate over time which is useful.
  optimizer: 'adam',
  // Use the correct loss function. If 2 classes of data, must use binaryCrossentropy.
  // Else categoricalCrossentropy is used if more than 2 classes.
  loss: (CLASS_NAMES.length === 2) ? 'binaryCrossentropy': 'categoricalCrossentropy', 
  // As this is a classification problem you can record accuracy in the logs too!
  metrics: ['accuracy']  
});

এর এই কোড মাধ্যমে পদচারণা করা যাক. আপনি একটি tf.sequential মডেল সংজ্ঞায়িত করে শুরু করুন যেখানে আপনি মডেল স্তর যুক্ত করবেন।

এর পরে, এই মডেলটিতে ইনপুট স্তর হিসাবে একটি ঘন স্তর যুক্ত করুন। মোবাইলনেট v3 বৈশিষ্ট্যগুলি থেকে আউটপুটগুলি এই আকারের হওয়ায় এটির একটি ইনপুট আকার 1024 রয়েছে৷ আপনি মডেলের মধ্য দিয়ে অতিক্রম করার পর আগের ধাপে এটি আবিষ্কার করেছেন। এই স্তরটিতে 128টি নিউরন রয়েছে যা ReLU অ্যাক্টিভেশন ফাংশন ব্যবহার করে।

আপনি যদি অ্যাক্টিভেশন ফাংশন এবং মডেল স্তরগুলিতে নতুন হন, তাহলে এই বৈশিষ্ট্যগুলি পর্দার আড়ালে কী করে তা বোঝার জন্য এই কর্মশালার শুরুতে বিস্তারিত কোর্সটি নেওয়ার কথা বিবেচনা করুন

পরবর্তী স্তরটি যোগ করার জন্য আউটপুট স্তর। আপনি ভবিষ্যদ্বাণী করার চেষ্টা করছেন এমন ক্লাসের সংখ্যার সমান হওয়া উচিত নিউরনের সংখ্যা। এটি করার জন্য আপনি CLASS_NAMES.length ব্যবহার করতে পারেন যে আপনি কতগুলি ক্লাস শ্রেণীবদ্ধ করার পরিকল্পনা করছেন, যা ব্যবহারকারী ইন্টারফেসে পাওয়া ডেটা সংগ্রহ বোতামের সংখ্যার সমান। যেহেতু এটি একটি শ্রেণিবিন্যাসের সমস্যা, আপনি এই আউটপুট স্তরে softmax অ্যাক্টিভেশন ব্যবহার করেন, যা রিগ্রেশনের পরিবর্তে শ্রেণিবিন্যাসের সমস্যা সমাধানের জন্য একটি মডেল তৈরি করার চেষ্টা করার সময় ব্যবহার করা আবশ্যক।

কনসোলে নতুন সংজ্ঞায়িত মডেলের ওভারভিউ প্রিন্ট করতে এখন একটি model.summary() প্রিন্ট করুন।

অবশেষে, মডেলটি কম্পাইল করুন যাতে এটি প্রশিক্ষণের জন্য প্রস্তুত হয়। এখানে অপ্টিমাইজারটি adam এ সেট করা হয়েছে, এবং CLASS_NAMES.length 2 এর সমান হলে ক্ষতি হয় binaryCrossentropy হবে, অথবা শ্রেণীবদ্ধ করার জন্য 3 বা তার বেশি শ্রেণী থাকলে এটি categoricalCrossentropy ব্যবহার করবে। নির্ভুলতা মেট্রিকগুলিও অনুরোধ করা হয়েছে যাতে ডিবাগিংয়ের উদ্দেশ্যে সেগুলি পরে লগগুলিতে নিরীক্ষণ করা যায়৷

কনসোলে আপনি এই মত কিছু দেখতে হবে:

22eaf32286fea4bb.png

উল্লেখ্য যে এটিতে 130 হাজারের বেশি প্রশিক্ষণযোগ্য পরামিতি রয়েছে। তবে এটি নিয়মিত নিউরনের একটি সাধারণ ঘন স্তর হওয়ায় এটি বেশ দ্রুত প্রশিক্ষণ দেবে।

প্রোজেক্টটি সম্পূর্ণ হওয়ার পরে করার জন্য একটি কার্যকলাপ হিসাবে, আপনি প্রথম স্তরে নিউরনের সংখ্যা পরিবর্তন করার চেষ্টা করতে পারেন যাতে আপনি এখনও শালীন কর্মক্ষমতা পেয়ে এটি কতটা কম করতে পারেন। প্রায়শই মেশিন লার্নিংয়ের সাথে কিছু স্তরের ট্রায়াল এবং ত্রুটি থাকে যা আপনাকে সম্পদের ব্যবহার এবং গতির মধ্যে সর্বোত্তম ট্রেড অফ দেওয়ার জন্য সর্বোত্তম প্যারামিটার মানগুলি খুঁজে পায়।

11. ওয়েবক্যাম সক্রিয় করুন

আপনি আগে সংজ্ঞায়িত enableCam() ফাংশনটি বের করার সময় এখন। নিচে দেখানো হিসাবে hasGetUserMedia() নামে একটি নতুন ফাংশন যোগ করুন এবং তারপরে পূর্বে সংজ্ঞায়িত enableCam() ফাংশনের বিষয়বস্তু নীচের সংশ্লিষ্ট কোড দিয়ে প্রতিস্থাপন করুন।

script.js

function hasGetUserMedia() {
  return !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia);
}

function enableCam() {
  if (hasGetUserMedia()) {
    // getUsermedia parameters.
    const constraints = {
      video: true,
      width: 640, 
      height: 480 
    };

    // Activate the webcam stream.
    navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
      VIDEO.srcObject = stream;
      VIDEO.addEventListener('loadeddata', function() {
        videoPlaying = true;
        ENABLE_CAM_BUTTON.classList.add('removed');
      });
    });
  } else {
    console.warn('getUserMedia() is not supported by your browser');
  }
}

প্রথমে, hasGetUserMedia() নামে একটি ফাংশন তৈরি করুন যাতে ব্রাউজারটি getUserMedia() সমর্থন করে কিনা তা যাচাই করার জন্য মূল ব্রাউজার API-এর বৈশিষ্ট্যগুলির অস্তিত্ব পরীক্ষা করে।

enableCam() ফাংশনে hasGetUserMedia() ফাংশনটি ব্যবহার করুন যা আপনি উপরে সংজ্ঞায়িত করেছেন এটি সমর্থিত কিনা তা পরীক্ষা করতে। যদি এটি না হয়, কনসোলে একটি সতর্কতা মুদ্রণ করুন।

যদি এটি এটি সমর্থন করে, তাহলে আপনার getUserMedia() কলের জন্য কিছু সীমাবদ্ধতা নির্ধারণ করুন, যেমন আপনি শুধুমাত্র ভিডিও স্ট্রিম চান, এবং আপনি ভিডিওর width 640 পিক্সেল আকারে এবং height 480 পিক্সেল হতে পছন্দ করেন৷ কেন? ঠিক আছে, এর থেকে বড় একটি ভিডিও পাওয়ার খুব বেশি বিন্দু নেই কারণ এটিকে মোবাইলনেট মডেলে খাওয়ানোর জন্য 224 বাই 224 পিক্সেলের আকার পরিবর্তন করতে হবে। আপনি একটি ছোট রেজোলিউশনের অনুরোধ করে কিছু কম্পিউটিং সংস্থানও সংরক্ষণ করতে পারেন। বেশিরভাগ ক্যামেরা এই আকারের রেজোলিউশন সমর্থন করে।

এরপরে, উপরে বিস্তারিত constraints সহ navigator.mediaDevices.getUserMedia() কে কল করুন এবং তারপরে stream ফিরে আসার জন্য অপেক্ষা করুন। একবার stream ফেরত দিলে আপনি আপনার VIDEO উপাদানটিকে এটির srcObject মান হিসাবে সেট করে stream চালানোর জন্য পেতে পারেন।

stream কখন লোড হয়েছে এবং সফলভাবে বাজছে তা জানতে আপনার VIDEO উপাদানটিতে একটি ইভেন্ট লিসেনার যোগ করা উচিত।

একবার স্টিম লোড হয়ে গেলে, আপনি videoPlaying সত্যে সেট করতে পারেন এবং ENABLE_CAM_BUTTON সরিয়ে ফেলতে পারেন যাতে এটিকে আবার ক্লিক করা থেকে রোধ করতে এর ক্লাসকে " removed " তে সেট করে৷

এখন আপনার কোড চালান, সক্ষম ক্যামেরা বোতামে ক্লিক করুন এবং ওয়েবক্যামে অ্যাক্সেসের অনুমতি দিন। যদি এটি আপনার প্রথমবার হয়, তাহলে আপনাকে পৃষ্ঠার ভিডিও উপাদানে দেখানো হিসাবে নিজেকে রেন্ডার করা দেখতে হবে:

b378eb1affa9b883.png

ঠিক আছে, এখন dataCollector বোতাম ক্লিকের সাথে মোকাবিলা করার জন্য একটি ফাংশন যোগ করার সময়।

12. ডেটা সংগ্রহ বোতাম ইভেন্ট হ্যান্ডলার

এখন gatherDataForClass(). কোডল্যাবের শুরুতে dataCollector বোতামগুলির জন্য আপনি আপনার ইভেন্ট হ্যান্ডলার ফাংশন হিসাবে এটি নির্ধারণ করেছেন।

script.js

/**
 * Handle Data Gather for button mouseup/mousedown.
 **/
function gatherDataForClass() {
  let classNumber = parseInt(this.getAttribute('data-1hot'));
  gatherDataState = (gatherDataState === STOP_DATA_GATHER) ? classNumber : STOP_DATA_GATHER;
  dataGatherLoop();
}

প্রথমে, বর্তমানে ক্লিক করা বাটনে data-1hot অ্যাট্রিবিউট চেক করুন attribute-এর নামের সাথে this.getAttribute() কল করে, এই ক্ষেত্রে data-1hot প্যারামিটার হিসেবে। যেহেতু এটি একটি স্ট্রিং, আপনি parseInt() ব্যবহার করে এটিকে একটি পূর্ণসংখ্যাতে কাস্ট করতে পারেন এবং এই ফলাফলটি classNumber.

এরপরে, সেই অনুযায়ী gatherDataState ভেরিয়েবল সেট করুন। যদি বর্তমান gatherDataState STOP_DATA_GATHER এর সমান হয় (যা আপনি -1 সেট করেছেন), তাহলে তার মানে আপনি বর্তমানে কোনো ডেটা সংগ্রহ করছেন না এবং এটি একটি mousedown ইভেন্ট যা ফায়ার করেছে। আপনি এইমাত্র পাওয়া classNumber হিসাবে gatherDataState সেট করুন।

অন্যথায়, এর মানে হল যে আপনি বর্তমানে ডেটা সংগ্রহ করছেন এবং যে ইভেন্টটি গুলি করা হয়েছে সেটি একটি mouseup ইভেন্ট ছিল এবং আপনি এখন সেই ক্লাসের জন্য ডেটা সংগ্রহ করা বন্ধ করতে চান৷ আপনি শীঘ্রই সংজ্ঞায়িত করা ডেটা সংগ্রহের লুপটি শেষ করতে এটিকে আবার STOP_DATA_GATHER অবস্থায় সেট করুন৷

অবশেষে, dataGatherLoop(), যা আসলে ক্লাস ডেটা রেকর্ডিং করে।

13. তথ্য সংগ্রহ

এখন, dataGatherLoop() ফাংশন সংজ্ঞায়িত করুন। এই ফাংশনটি ওয়েবক্যাম ভিডিও থেকে চিত্রের নমুনা নেওয়ার জন্য, মোবাইলনেট মডেলের মাধ্যমে তাদের পাস করার জন্য এবং সেই মডেলের (1024 বৈশিষ্ট্য ভেক্টর) আউটপুটগুলি ক্যাপচার করার জন্য দায়ী।

এটি তখন সেই বোতামের gatherDataState ID সহ সেগুলিকে সঞ্চয় করে যা বর্তমানে চাপা হচ্ছে যাতে আপনি জানেন যে এই ডেটা কোন শ্রেণীর প্রতিনিধিত্ব করে।

এর মধ্য দিয়ে চলুন:

script.js

function dataGatherLoop() {
  if (videoPlaying && gatherDataState !== STOP_DATA_GATHER) {
    let imageFeatures = tf.tidy(function() {
      let videoFrameAsTensor = tf.browser.fromPixels(VIDEO);
      let resizedTensorFrame = tf.image.resizeBilinear(videoFrameAsTensor, [MOBILE_NET_INPUT_HEIGHT, 
          MOBILE_NET_INPUT_WIDTH], true);
      let normalizedTensorFrame = resizedTensorFrame.div(255);
      return mobilenet.predict(normalizedTensorFrame.expandDims()).squeeze();
    });

    trainingDataInputs.push(imageFeatures);
    trainingDataOutputs.push(gatherDataState);
    
    // Intialize array index element if currently undefined.
    if (examplesCount[gatherDataState] === undefined) {
      examplesCount[gatherDataState] = 0;
    }
    examplesCount[gatherDataState]++;

    STATUS.innerText = '';
    for (let n = 0; n < CLASS_NAMES.length; n++) {
      STATUS.innerText += CLASS_NAMES[n] + ' data count: ' + examplesCount[n] + '. ';
    }
    window.requestAnimationFrame(dataGatherLoop);
  }
}

videoPlaying সত্য হলেই আপনি শুধুমাত্র এই ফাংশনটির এক্সিকিউশন চালিয়ে যেতে যাচ্ছেন, যার অর্থ হল ওয়েবক্যাম সক্রিয়, এবং gatherDataState STOP_DATA_GATHER এর সমান নয় এবং ক্লাস ডেটা সংগ্রহের জন্য একটি বোতাম বর্তমানে চাপা হচ্ছে৷

এরপরে, আপনার কোডটি একটি tf.tidy() তে মোড়ানো কোডে যেকোনও তৈরি করা টেনসরের নিষ্পত্তি করুন। এই tf.tidy() কোড এক্সিকিউশনের ফলাফল imageFeatures নামক একটি ভেরিয়েবলে সংরক্ষণ করা হয়।

আপনি এখন tf.browser.fromPixels() ব্যবহার করে ওয়েবক্যাম VIDEO একটি ফ্রেম ধরতে পারেন। চিত্র ডেটা ধারণকারী ফলাফল টেনসর videoFrameAsTensor নামক একটি ভেরিয়েবলে সংরক্ষণ করা হয়।

এরপর, MobileNet মডেলের ইনপুটের জন্য সঠিক আকারের হতে videoFrameAsTensor ভেরিয়েবলের আকার পরিবর্তন করুন। আপনি যে টেনসরটিকে প্রথম প্যারামিটার হিসাবে পুনরায় আকার দিতে চান তার সাথে একটি tf.image.resizeBilinear() কল ব্যবহার করুন এবং তারপরে এমন একটি আকৃতি যা নতুন উচ্চতা এবং প্রস্থকে সংজ্ঞায়িত করে যা আপনি ইতিমধ্যে তৈরি করা ধ্রুবকগুলির দ্বারা সংজ্ঞায়িত করেছেন৷ পরিশেষে, আকার পরিবর্তন করার সময় কোনো প্রান্তিককরণ সমস্যা এড়াতে তৃতীয় প্যারামিটারটি পাস করে সারিবদ্ধ কোণগুলিকে সত্যে সেট করুন। এই আকার পরিবর্তনের ফলাফল resizedTensorFrame নামক একটি ভেরিয়েবলে সংরক্ষণ করা হয়।

নোট করুন যে এই আদিম আকার পরিবর্তন চিত্রটিকে প্রসারিত করে, কারণ আপনার ওয়েবক্যাম চিত্রটি আকারে 640 বাই 480 পিক্সেল, এবং মডেলটির জন্য 224 বাই 224 পিক্সেলের একটি বর্গাকার চিত্র প্রয়োজন৷

এই ডেমোর উদ্দেশ্যে এটি সূক্ষ্ম কাজ করা উচিত। যাইহোক, একবার আপনি এই কোডল্যাবটি সম্পূর্ণ করার পরে, আপনি পরে তৈরি করতে পারেন এমন কোনও উত্পাদন সিস্টেমের জন্য আরও ভাল ফলাফলের জন্য পরিবর্তে এই চিত্র থেকে একটি বর্গক্ষেত্র কাটাতে চেষ্টা করতে পারেন।

এর পরে, ইমেজ ডেটা স্বাভাবিক করুন। tf.browser.frompixels() ব্যবহার করার সময় ইমেজ ডেটা সর্বদা 0 থেকে 255 এর মধ্যে থাকে, তাই আপনি কেবলমাত্র resizedTensorFrame কে 255 দ্বারা ভাগ করতে পারেন যাতে সমস্ত মান 0 এবং 1 এর পরিবর্তে থাকে, যা MobileNet মডেল ইনপুট হিসাবে আশা করে।

অবশেষে, কোডের tf.tidy() বিভাগে, mobilenet.predict() কল করে লোড করা মডেলের মাধ্যমে এই স্বাভাবিক টেনসরটি পুশ করুন, যেখানে আপনি expandDims() ব্যবহার করে normalizedTensorFrame টেনসরফ্রেমের প্রসারিত সংস্করণটি পাস করেন যাতে এটি একটি ব্যাচ হয়। 1, যেমন মডেলটি প্রক্রিয়াকরণের জন্য ইনপুটের একটি ব্যাচ আশা করে।

ফলাফলটি ফিরে আসার পরে, আপনি অবিলম্বে সেই প্রত্যাবর্তিত ফলাফলে squeeze() কল করতে পারেন যাতে এটিকে একটি 1D টেনসরে ফিরিয়ে আনতে হয়, যা আপনি তারপরে ফিরে আসেন এবং imageFeatures ভেরিয়েবলে বরাদ্দ করেন যা tf.tidy() থেকে ফলাফলটি ক্যাপচার করে।

এখন যেহেতু আপনার কাছে MobileNet মডেল থেকে imageFeatures রয়েছে, আপনি সেগুলিকে আগে সংজ্ঞায়িত করা trainingDataInputs অ্যারেতে পুশ করে রেকর্ড করতে পারেন।

আপনি এই ইনপুটটি কী প্রতিনিধিত্ব করে তা রেকর্ড করতে পারেন বর্তমান gatherDataState trainingDataOutputs অ্যারেতে পুশ করেও।

নোট করুন যে gatherDataState ভেরিয়েবলটি বর্তমান ক্লাসের সংখ্যাসূচক আইডিতে সেট করা হবে যেটির জন্য আপনি ডেটা রেকর্ড করছেন যখন পূর্বে সংজ্ঞায়িত gatherDataForClass() ফাংশনে বোতামটি ক্লিক করা হয়েছিল।

এই মুহুর্তে আপনি প্রদত্ত ক্লাসের জন্য আপনার কাছে থাকা উদাহরণগুলির সংখ্যা বৃদ্ধি করতে পারেন। এটি করার জন্য, প্রথমে পরীক্ষা করুন যে examplesCount অ্যারের মধ্যে সূচকটি আগে শুরু করা হয়েছে কি না। যদি এটি অনির্ধারিত হয়, তবে একটি প্রদত্ত শ্রেণীর সংখ্যাসূচক আইডির জন্য কাউন্টার শুরু করতে এটিকে 0 এ সেট করুন এবং তারপরে আপনি বর্তমান gatherDataState জন্য examplesCount বৃদ্ধি করতে পারেন।

এখন ওয়েব পৃষ্ঠায় STATUS উপাদানের পাঠ্য আপডেট করুন যাতে প্রতিটি ক্লাসের বর্তমান গণনাগুলি ক্যাপচার করা হয়। এটি করার জন্য, CLASS_NAMES অ্যারের মাধ্যমে লুপ করুন, এবং examplesCount এ একই সূচকে ডেটা গণনার সাথে মিলিত মানব পাঠযোগ্য নামটি মুদ্রণ করুন।

পরিশেষে, একটি প্যারামিটার হিসাবে পাস করা dataGatherLoop সহ window.requestAnimationFrame() কে কল করুন, এই ফাংশনটিকে পুনরায় কল করার জন্য। বোতামের mouseup শনাক্ত না হওয়া পর্যন্ত এটি ভিডিও থেকে ফ্রেমের নমুনা করতে থাকবে, এবং gatherDataState STOP_DATA_GATHER, এই সময়ে ডেটা সংগ্রহের লুপ শেষ হবে।

আপনি যদি এখন আপনার কোডটি চালান, তাহলে আপনি সক্ষম ক্যামেরা বোতামটি ক্লিক করতে সক্ষম হবেন, ওয়েবক্যামটি লোড হওয়ার জন্য অপেক্ষা করুন এবং তারপরে প্রতিটি ডেটা সংগ্রহের বোতামে ক্লিক করুন এবং ধরে রাখুন ডেটার প্রতিটি শ্রেণীর উদাহরণ সংগ্রহ করতে৷ এখানে আপনি আমাকে যথাক্রমে আমার মোবাইল ফোন এবং আমার হাতের জন্য ডেটা সংগ্রহ করতে দেখছেন।

541051644a45131f.gif

আপনি স্ট্যাটাস টেক্সট আপডেট করা দেখতে পাবেন কারণ এটি উপরের স্ক্রীন ক্যাপচারে দেখানো সমস্ত টেনসর মেমরিতে সংরক্ষণ করে।

14. ট্রেন এবং ভবিষ্যদ্বাণী

পরবর্তী ধাপ হল আপনার বর্তমানে খালি trainAndPredict() ফাংশনের জন্য কোড প্রয়োগ করা, যেখানে স্থানান্তর শেখা হয়। আসুন কোডটি দেখে নেওয়া যাক:

script.js

async function trainAndPredict() {
  predict = false;
  tf.util.shuffleCombo(trainingDataInputs, trainingDataOutputs);
  let outputsAsTensor = tf.tensor1d(trainingDataOutputs, 'int32');
  let oneHotOutputs = tf.oneHot(outputsAsTensor, CLASS_NAMES.length);
  let inputsAsTensor = tf.stack(trainingDataInputs);
  
  let results = await model.fit(inputsAsTensor, oneHotOutputs, {shuffle: true, batchSize: 5, epochs: 10, 
      callbacks: {onEpochEnd: logProgress} });
  
  outputsAsTensor.dispose();
  oneHotOutputs.dispose();
  inputsAsTensor.dispose();
  predict = true;
  predictLoop();
}

function logProgress(epoch, logs) {
  console.log('Data for epoch ' + epoch, logs);
}

প্রথমে, নিশ্চিত করুন যে আপনি predict false সেট করে যেকোনও বর্তমান ভবিষ্যদ্বাণী করা বন্ধ করেছেন৷

এরপর, আপনার ইনপুট এবং আউটপুট অ্যারেগুলিকে tf.util.shuffleCombo() ব্যবহার করে শাফেল করুন যাতে প্রশিক্ষণে কোনো সমস্যা না হয়।

আপনার আউটপুট অ্যারে, trainingDataOutputs, int32 টাইপের tensor1d হতে রূপান্তর করুন যাতে এটি একটি হট এনকোডিং- এ ব্যবহারের জন্য প্রস্তুত। এটি outputsAsTensor নামের একটি ভেরিয়েবলে সংরক্ষণ করা হয়।

এনকোড করার জন্য ক্লাসের সর্বাধিক সংখ্যা সহ এই outputsAsTensor ভেরিয়েবলের সাথে tf.oneHot() ফাংশনটি ব্যবহার করুন, যা শুধুমাত্র CLASS_NAMES.length । আপনার একটি হট এনকোডেড আউটপুট এখন oneHotOutputs নামক একটি নতুন টেনসরে সংরক্ষণ করা হয়েছে।

উল্লেখ্য যে বর্তমানে trainingDataInputs হল রেকর্ড করা টেনসরের একটি অ্যারে। প্রশিক্ষণের জন্য এগুলি ব্যবহার করার জন্য আপনাকে নিয়মিত 2D টেনসর হতে টেনসরের অ্যারে রূপান্তর করতে হবে।

এটি করার জন্য TensorFlow.js লাইব্রেরির মধ্যে একটি দুর্দান্ত ফাংশন রয়েছে যাকে বলা হয় tf.stack() ,

যা টেনসরের একটি অ্যারে নেয় এবং আউটপুট হিসাবে একটি উচ্চমাত্রিক টেনসর তৈরি করতে তাদের একসাথে স্ট্যাক করে। এক্ষেত্রে একটি টেনসর 2 ডি ফিরে আসে, এটি 1 টি মাত্রিক ইনপুটগুলির একটি ব্যাচ যা প্রতিটি 1024 দৈর্ঘ্যে রেকর্ড করা বৈশিষ্ট্যযুক্ত দৈর্ঘ্যে থাকে, যা আপনার প্রশিক্ষণের জন্য প্রয়োজন।

এরপরে, কাস্টম মডেল হেডকে প্রশিক্ষণ দেওয়ার জন্য await model.fit() । উদাহরণস্বরূপ ইনপুট এবং টার্গেট আউটপুটগুলি যথাক্রমে ব্যবহার করার জন্য প্রশিক্ষণের ডেটা উপস্থাপন করতে এখানে আপনি আপনার inputsAsTensor ভেরিয়েবলটি oneHotOutputs সাথে পাস করুন। তৃতীয় প্যারামিটারের জন্য কনফিগারেশন অবজেক্টে, true shuffle সেট করুন, 5 এর batchSize ব্যবহার করুন, epochs 10 এ সেট করা আছে এবং তারপরে logProgress ফাংশনে onEpochEnd জন্য একটি callback নির্দিষ্ট করুন যা আপনি শীঘ্রই সংজ্ঞায়িত করবেন।

অবশেষে, মডেলটি এখন প্রশিক্ষিত হওয়ায় আপনি তৈরি টেনারগুলি নিষ্পত্তি করতে পারেন। তারপরে আপনি ভবিষ্যদ্বাণীগুলি আবার স্থান নেওয়ার অনুমতি দেওয়ার জন্য predict true দিকে ফিরিয়ে দিতে পারেন এবং তারপরে লাইভ ওয়েবক্যাম চিত্রগুলির পূর্বাভাস দেওয়া শুরু করার জন্য predictLoop() ফাংশনটিকে কল করুন।

আপনি প্রশিক্ষণের অবস্থাকে লগ করতে logProcess() ফাংশনটিও সংজ্ঞায়িত করতে পারেন, যা উপরে model.fit() এ ব্যবহৃত হয় এবং এটি প্রতিটি রাউন্ড প্রশিক্ষণের পরে সান্ত্বনার জন্য ফলাফলগুলি মুদ্রণ করে।

আপনি বেশিরভাগ ওখানেই থাকেন! ভবিষ্যদ্বাণী করার জন্য predictLoop() ফাংশন যুক্ত করার সময়।

কোর পূর্বাভাস লুপ

এখানে আপনি মূল পূর্বাভাস লুপটি প্রয়োগ করেন যা একটি ওয়েবক্যাম থেকে ফ্রেমগুলি নমুনা দেয় এবং ব্রাউজারে রিয়েল টাইম ফলাফল সহ প্রতিটি ফ্রেমে কী রয়েছে তা অবিচ্ছিন্নভাবে ভবিষ্যদ্বাণী করে।

কোডটি পরীক্ষা করা যাক:

script.js

function predictLoop() {
  if (predict) {
    tf.tidy(function() {
      let videoFrameAsTensor = tf.browser.fromPixels(VIDEO).div(255);
      let resizedTensorFrame = tf.image.resizeBilinear(videoFrameAsTensor,[MOBILE_NET_INPUT_HEIGHT, 
          MOBILE_NET_INPUT_WIDTH], true);

      let imageFeatures = mobilenet.predict(resizedTensorFrame.expandDims());
      let prediction = model.predict(imageFeatures).squeeze();
      let highestIndex = prediction.argMax().arraySync();
      let predictionArray = prediction.arraySync();

      STATUS.innerText = 'Prediction: ' + CLASS_NAMES[highestIndex] + ' with ' + Math.floor(predictionArray[highestIndex] * 100) + '% confidence';
    });

    window.requestAnimationFrame(predictLoop);
  }
}

প্রথমত, পরীক্ষা করুন যে predict সত্য, যাতে কোনও মডেল প্রশিক্ষিত হওয়ার পরে এবং এটি ব্যবহারের জন্য উপলব্ধ হওয়ার পরে কেবল ভবিষ্যদ্বাণীগুলি তৈরি করা হয়।

এরপরে, আপনি dataGatherLoop() ফাংশনে যেমন করেছেন ঠিক তেমন বর্তমান চিত্রের জন্য চিত্রের বৈশিষ্ট্যগুলি পেতে পারেন। মূলত, আপনি tf.browser.from pixels() ব্যবহার করে ওয়েবক্যাম থেকে একটি ফ্রেম ধরেন, এটিকে স্বাভাবিক করুন, আকারে 224 দ্বারা 224 দ্বারা আকার পরিবর্তন করুন এবং তারপরে ফলস্বরূপ চিত্রের বৈশিষ্ট্যগুলি পেতে মোবাইলনেট মডেলের মাধ্যমে সেই ডেটা পাস করুন।

তবে এখন, আপনি প্রশিক্ষিত মডেলের predict() ফাংশনটির মাধ্যমে সবেমাত্র পাওয়া ফলাফলের imageFeatures পাস করে আপনার নতুন প্রশিক্ষিত মডেল হেড ব্যবহার করতে পারেন। তারপরে আপনি আবার 1 টি মাত্রিক তৈরি করতে ফলাফলের টেনসরটি চেপে ধরতে পারেন এবং এটি prediction নামে একটি পরিবর্তনশীলকে বরাদ্দ করতে পারেন।

এই prediction সাহায্যে আপনি সূচকটি খুঁজে পেতে পারেন যা argMax() ব্যবহার করে সর্বোচ্চ মান রয়েছে এবং তারপরে সর্বাধিক মূল্যবান উপাদানের অবস্থানটি আবিষ্কার করতে জাভাস্ক্রিপ্টে অন্তর্নিহিত ডেটা পেতে arraySync() ব্যবহার করে এই ফলস্বরূপ টেনসরকে একটি অ্যারে রূপান্তর করুন। এই মানটি highestIndex নামে ভেরিয়েবলে সংরক্ষণ করা হয়।

আপনি সরাসরি prediction টেনসারে arraySync() কে কল করে একইভাবে প্রকৃত পূর্বাভাসের আত্মবিশ্বাসের স্কোরগুলিও পেতে পারেন।

prediction ডেটা সহ STATUS পাঠ্য আপডেট করার জন্য আপনার এখন প্রয়োজনীয় সমস্ত কিছু রয়েছে। শ্রেণীর জন্য মানব পঠনযোগ্য স্ট্রিং পেতে আপনি কেবল CLASS_NAMES অ্যারেতে highestIndex সন্ধান করতে পারেন এবং তারপরে predictionArray থেকে আত্মবিশ্বাসের মানটি ধরতে পারেন। এটি শতাংশ হিসাবে আরও পঠনযোগ্য করে তুলতে, কেবল 100 এবং math.floor() ফলাফল দ্বারা গুণ করুন।

শেষ অবধি, আপনি আপনার ভিডিও স্ট্রিমে রিয়েল টাইম শ্রেণিবিন্যাস পেতে, predictionLoop() কে আবারও প্রস্তুত করার জন্য window.requestAnimationFrame() ব্যবহার করতে পারেন। আপনি যদি নতুন ডেটা সহ কোনও নতুন মডেল প্রশিক্ষণ দিতে চান তবে predict false হিসাবে সেট না হওয়া পর্যন্ত এটি অব্যাহত রয়েছে।

যা আপনাকে ধাঁধার চূড়ান্ত টুকরোটিতে নিয়ে আসে। রিসেট বোতামটি প্রয়োগ করা।

15. রিসেট বোতামটি প্রয়োগ করুন

প্রায় শেষ! ধাঁধাটির চূড়ান্ত অংশটি শুরু করার জন্য একটি রিসেট বোতামটি প্রয়োগ করা। আপনার বর্তমানে খালি reset() ফাংশনের জন্য কোডটি নীচে রয়েছে। এগিয়ে যান এবং এটি নিম্নলিখিত হিসাবে আপডেট করুন:

script.js

/**
 * Purge data and start over. Note this does not dispose of the loaded 
 * MobileNet model and MLP head tensors as you will need to reuse 
 * them to train a new model.
 **/
function reset() {
  predict = false;
  examplesCount.length = 0;
  for (let i = 0; i < trainingDataInputs.length; i++) {
    trainingDataInputs[i].dispose();
  }
  trainingDataInputs.length = 0;
  trainingDataOutputs.length = 0;
  STATUS.innerText = 'No data collected';
  
  console.log('Tensors in memory: ' + tf.memory().numTensors);
}

প্রথমে, false predict সেট করে কোনও চলমান পূর্বাভাস লুপগুলি বন্ধ করুন। এরপরে, এর দৈর্ঘ্য 0 এ সেট করে examplesCount অ্যারেতে সমস্ত সামগ্রী মুছুন, যা একটি অ্যারে থেকে সমস্ত সামগ্রী সাফ করার একটি সহজ উপায়।

এখন সমস্ত বর্তমান রেকর্ডড trainingDataInputs মধ্য দিয়ে যান এবং আবার মেমরি মুক্ত করার জন্য এর মধ্যে থাকা প্রতিটি টেনসারের মধ্যে আপনি dispose() নিশ্চিত করুন, কারণ জাভাস্ক্রিপ্ট আবর্জনা সংগ্রাহক দ্বারা টেনারগুলি পরিষ্কার করা হয়নি।

এটি হয়ে গেলে আপনি এখন নিরাপদে অ্যারের দৈর্ঘ্য 0 এ trainingDataInputs এবং trainingDataOutputs অ্যারে উভয়কেও সাফ করার জন্য সেট করতে পারেন।

অবশেষে STATUS পাঠ্যটি বুদ্ধিমান কিছুতে সেট করুন এবং স্যানিটি চেক হিসাবে স্মৃতিতে বাম টেনারগুলি মুদ্রণ করুন।

নোট করুন যে মোবাইলনেট মডেল এবং আপনি যে মাল্টি-লেয়ার পার্সেপট্রন সংজ্ঞায়িত করেছেন তা উভয়ই নিষ্পত্তি করা হয়নি বলে স্মৃতিতে এখনও কয়েক শতাধিক টেনার থাকবে। আপনি যদি এই পুনরায় সেট করার পরে আবার প্রশিক্ষণের সিদ্ধান্ত নেন তবে আপনাকে নতুন প্রশিক্ষণ ডেটা দিয়ে তাদের পুনরায় ব্যবহার করতে হবে।

16. আসুন এটি চেষ্টা করে দেখুন

আপনার শিক্ষণযোগ্য মেশিনের নিজস্ব সংস্করণটি পরীক্ষা করার সময় এসেছে!

লাইভ পূর্বরূপের দিকে যান, ওয়েবক্যাম সক্ষম করুন, আপনার ঘরের কোনও অবজেক্টের জন্য 1 ম শ্রেণির জন্য কমপক্ষে 30 টি নমুনা সংগ্রহ করুন এবং তারপরে কোনও আলাদা অবজেক্টের জন্য 2 ক্লাস 2 এর জন্য একই কাজ করুন, ট্রেনে ক্লিক করুন এবং অগ্রগতি দেখতে কনসোল লগটি পরীক্ষা করুন। এটি বেশ দ্রুত প্রশিক্ষণ দেওয়া উচিত:

BF1AC3CC5B15740.gif

একবার প্রশিক্ষিত হয়ে গেলে, লাইভ ভবিষ্যদ্বাণীগুলি পেতে ক্যামেরায় অবজেক্টগুলি দেখান যা শীর্ষের কাছাকাছি ওয়েব পৃষ্ঠায় স্ট্যাটাস পাঠ্য অঞ্চলে মুদ্রিত হবে। যদি আপনার সমস্যা হয় তবে আপনি কোনও কিছুর অনুলিপি মিস করেছেন কিনা তা দেখতে আমার সমাপ্ত ওয়ার্কিং কোডটি পরীক্ষা করুন

17. অভিনন্দন

অভিনন্দন! আপনি ব্রাউজারে লাইভ টেনসরফ্লো.জেএস ব্যবহার করে আপনার প্রথম স্থানান্তর শেখার উদাহরণটি সম্পন্ন করেছেন।

এটি চেষ্টা করে দেখুন, এটি বিভিন্ন বস্তুর উপর পরীক্ষা করুন, আপনি লক্ষ্য করতে পারেন যে কিছু জিনিস অন্যের চেয়ে স্বীকৃতি দেওয়া আরও কঠিন, বিশেষত যদি সেগুলি অন্য কোনও কিছুর সাথে সমান হয়। এগুলি আলাদা করে বলতে সক্ষম হতে আপনার আরও ক্লাস বা প্রশিক্ষণের ডেটা যুক্ত করতে হবে।

রিক্যাপ

এই কোডল্যাবটিতে আপনি শিখেছেন:

  1. কী স্থানান্তর শেখার, এবং একটি সম্পূর্ণ মডেল প্রশিক্ষণের ক্ষেত্রে এর সুবিধাগুলি।
  2. টেনসরফ্লো হাব থেকে পুনরায় ব্যবহারের জন্য কীভাবে মডেল পাবেন।
  3. স্থানান্তর শেখার জন্য উপযুক্ত একটি ওয়েব অ্যাপ্লিকেশন কীভাবে সেট আপ করবেন।
  4. চিত্রের বৈশিষ্ট্যগুলি তৈরি করতে কীভাবে একটি বেস মডেল লোড এবং ব্যবহার করবেন।
  5. কীভাবে একটি নতুন ভবিষ্যদ্বাণী হেডকে প্রশিক্ষণ দেওয়া যায় যা ওয়েবক্যামের চিত্র থেকে কাস্টম অবজেক্টগুলি সনাক্ত করতে পারে।
  6. রিয়েল টাইমে ডেটা শ্রেণিবদ্ধ করতে কীভাবে ফলাফল মডেলগুলি ব্যবহার করবেন।

এরপর কি?

এখন আপনার শুরু করার জন্য একটি কার্যনির্বাহী বেস রয়েছে, আপনি কী কাজ করছেন এমন একটি বাস্তব বিশ্বের ব্যবহারের ক্ষেত্রে এই মেশিন লার্নিং মডেল বয়লারপ্লেটটি প্রসারিত করতে আপনি কোন সৃজনশীল ধারণাগুলি নিয়ে আসতে পারেন? আপনি বর্তমানে আপনার কোম্পানির লোকদের ট্রেন মডেলগুলিতে তাদের প্রতিদিনের কাজের ক্ষেত্রে গুরুত্বপূর্ণ বিষয়গুলিকে শ্রেণিবদ্ধ করার জন্য সহায়তা করার জন্য যে শিল্পে কাজ করছেন তা আপনি বিপ্লব করতে পারেন? সম্ভাবনা সীমাহীন।

আরও এগিয়ে যাওয়ার জন্য, এই সম্পূর্ণ কোর্সটি নিখরচায় নেওয়ার বিষয়টি বিবেচনা করুন , যা আপনাকে দেখায় যে কীভাবে আপনার বর্তমানে এই কোডেল্যাবটিতে থাকা 2 টি মডেল দক্ষতার জন্য 1 একক মডেল হিসাবে একত্রিত করবেন।

এছাড়াও আপনি যদি মূল টিচেবল মেশিন অ্যাপ্লিকেশনটির পিছনে তত্ত্বের চারপাশে আরও কৌতূহলী হন তবে এই টিউটোরিয়ালটি দেখুন।

আপনি আমাদের সাথে যা করেন তা ভাগ করুন

অন্যান্য সৃজনশীল ব্যবহারের ক্ষেত্রেও আপনি আজ যা তৈরি করেছেন তা সহজেই প্রসারিত করতে পারেন এবং আমরা আপনাকে বাক্সের বাইরে ভাবতে এবং হ্যাকিং চালিয়ে যেতে উত্সাহিত করি।

আপনার প্রকল্পের জন্য আমাদের টেনসরফ্লো ব্লগ বা এমনকি ভবিষ্যতের ইভেন্টগুলিতে বৈশিষ্ট্যযুক্ত হওয়ার জন্য আপনার প্রকল্পের সুযোগের জন্য #MADEWITHTFJS হ্যাশট্যাগ ব্যবহার করে আমাদের সোশ্যাল মিডিয়ায় ট্যাগ করতে ভুলবেন না। আমরা আপনি কী করেন তা দেখতে আমরা পছন্দ করব।

চেক আউট ওয়েবসাইট