TensorFlow.js - ট্রান্সফার লার্নিং ব্যবহার করে অডিও স্বীকৃতি

1. ভূমিকা

এই কোডল্যাবে, আপনি একটি অডিও স্বীকৃতি নেটওয়ার্ক তৈরি করবেন এবং শব্দ করে ব্রাউজারে একটি স্লাইডার নিয়ন্ত্রণ করতে এটি ব্যবহার করবেন। আপনি TensorFlow.js ব্যবহার করবেন, জাভাস্ক্রিপ্টের জন্য একটি শক্তিশালী এবং নমনীয় মেশিন লার্নিং লাইব্রেরি।

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

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

আমরা মেশিন লার্নিং পদগুলির একটি শব্দকোষও তৈরি করেছি যা আপনি এই কোডল্যাবে পাবেন।

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

  • কিভাবে একটি প্রাক-প্রশিক্ষিত স্পিচ কমান্ড স্বীকৃতি মডেল লোড করবেন
  • মাইক্রোফোন ব্যবহার করে কিভাবে রিয়েল-টাইম ভবিষ্যদ্বাণী করা যায়
  • ব্রাউজার মাইক্রোফোন ব্যবহার করে কীভাবে একটি কাস্টম অডিও স্বীকৃতি মডেল প্রশিক্ষণ এবং ব্যবহার করবেন

তো চলুন শুরু করা যাক।

2. প্রয়োজনীয়তা

এই কোডল্যাবটি সম্পূর্ণ করতে আপনার প্রয়োজন হবে:

  1. Chrome এর সাম্প্রতিক সংস্করণ বা অন্য আধুনিক ব্রাউজার।
  2. একটি টেক্সট এডিটর, হয় স্থানীয়ভাবে আপনার মেশিনে বা ওয়েবে কোডপেন বা গ্লিচের মতো কিছুর মাধ্যমে চলছে।
  3. HTML, CSS, JavaScript এবং Chrome DevTools (বা আপনার পছন্দের ব্রাউজার devtools) সম্পর্কে জ্ঞান।
  4. নিউরাল নেটওয়ার্কগুলির একটি উচ্চ-স্তরের ধারণাগত বোঝাপড়া। আপনার যদি পরিচিতি বা রিফ্রেশারের প্রয়োজন হয়, তাহলে 3blue1brown-এর এই ভিডিওটি অথবা Ashi Krishnan-এর Javascript-এ ডিপ লার্নিং-এর এই ভিডিওটি দেখার কথা বিবেচনা করুন।

3. TensorFlow.js এবং অডিও মডেল লোড করুন

একটি সম্পাদকে index.html খুলুন এবং এই সামগ্রী যোগ করুন:

<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/speech-commands"></script>
  </head>
  <body>
    <div id="console"></div>
    <script src="index.js"></script>
  </body>
</html>

প্রথম <script> ট্যাগটি TensorFlow.js লাইব্রেরি আমদানি করে এবং দ্বিতীয়টি <script> পূর্ব-প্রশিক্ষিত স্পিচ কমান্ড মডেল আমদানি করে। <div id="console"> ট্যাগটি মডেলের আউটপুট প্রদর্শন করতে ব্যবহার করা হবে।

4. রিয়েল-টাইমে ভবিষ্যদ্বাণী করুন

এরপরে, একটি কোড এডিটরে index.js ফাইলটি খুলুন/তৈরি করুন এবং নিম্নলিখিত কোডটি অন্তর্ভুক্ত করুন:

let recognizer;

function predictWord() {
 // Array of words that the recognizer is trained to recognize.
 const words = recognizer.wordLabels();
 recognizer.listen(({scores}) => {
   // Turn scores into a list of (score,word) pairs.
   scores = Array.from(scores).map((s, i) => ({score: s, word: words[i]}));
   // Find the most probable word.
   scores.sort((s1, s2) => s2.score - s1.score);
   document.querySelector('#console').textContent = scores[0].word;
 }, {probabilityThreshold: 0.75});
}

async function app() {
 recognizer = speechCommands.create('BROWSER_FFT');
 await recognizer.ensureModelLoaded();
 predictWord();
}

app();

5. ভবিষ্যদ্বাণী পরীক্ষা করুন

আপনার ডিভাইসে একটি মাইক্রোফোন আছে তা নিশ্চিত করুন। এটা লক্ষনীয় যে এটি একটি মোবাইল ফোনেও কাজ করবে! ওয়েবপেজ চালানোর জন্য, একটি ব্রাউজারে index.html খুলুন। আপনি যদি স্থানীয় ফাইল থেকে কাজ করেন, মাইক্রোফোন অ্যাক্সেস করতে আপনাকে একটি ওয়েব সার্ভার শুরু করতে হবে এবং http://localhost:port/ ব্যবহার করতে হবে।

পোর্ট 8000 এ একটি সাধারণ ওয়েব সার্ভার শুরু করতে:

python -m SimpleHTTPServer

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

এই শব্দগুলির মধ্যে একটি কথা বলুন। এটা সঠিকভাবে আপনার শব্দ পেতে? probabilityThreshold সাথে খেলুন যা নিয়ন্ত্রণ করে কত ঘন ঘন মডেলটি ফায়ার করে – 0.75 এর মানে হল যে মডেলটি যখন 75% এর বেশি আত্মবিশ্বাসী হয় যে এটি একটি প্রদত্ত শব্দ শুনেছে তখন আগুন জ্বলবে।

স্পিচ কমান্ড মডেল এবং এর API সম্পর্কে আরও জানতে, Github-এ README.md দেখুন।

6. তথ্য সংগ্রহ করুন

এটিকে মজাদার করতে, স্লাইডার নিয়ন্ত্রণ করতে পুরো শব্দের পরিবর্তে ছোট শব্দ ব্যবহার করা যাক!

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

  1. প্রথমে আমাদের ডেটা সংগ্রহ করতে হবে। <div id="console"> এর আগে <body> ট্যাগের ভিতরে এটি যোগ করে অ্যাপে একটি সাধারণ UI যোগ করুন:
<button id="left" onmousedown="collect(0)" onmouseup="collect(null)">Left</button>
<button id="right" onmousedown="collect(1)" onmouseup="collect(null)">Right</button>
<button id="noise" onmousedown="collect(2)" onmouseup="collect(null)">Noise</button>
  1. এটি index.js এ যোগ করুন:
// One frame is ~23ms of audio.
const NUM_FRAMES = 3;
let examples = [];

function collect(label) {
 if (recognizer.isListening()) {
   return recognizer.stopListening();
 }
 if (label == null) {
   return;
 }
 recognizer.listen(async ({spectrogram: {frameSize, data}}) => {
   let vals = normalize(data.subarray(-frameSize * NUM_FRAMES));
   examples.push({vals, label});
   document.querySelector('#console').textContent =
       `${examples.length} examples collected`;
 }, {
   overlapFactor: 0.999,
   includeSpectrogram: true,
   invokeCallbackOnNoiseAndUnknown: true
 });
}

function normalize(x) {
 const mean = -100;
 const std = 10;
 return x.map(x => (x - mean) / std);
}
  1. app() ) থেকে predictWord() সরান:
async function app() {
 recognizer = speechCommands.create('BROWSER_FFT');
 await recognizer.ensureModelLoaded();
 // predictWord() no longer called.
}

ভেঙ্গে ফেলছে

এই কোডটি প্রথমে অপ্রতিরোধ্য হতে পারে, তাই আসুন এটি ভেঙে ফেলি।

আমরা আমাদের UI-তে তিনটি বোতাম যুক্ত করেছি "বাম", "ডান" এবং "গোলমাল" লেবেলযুক্ত, তিনটি কমান্ডের সাথে সম্পর্কিত যা আমরা আমাদের মডেলকে চিনতে চাই। এই বোতাম টিপলে আমাদের নতুন যোগ করা collect() ফাংশন বলা হয়, যা আমাদের মডেলের জন্য প্রশিক্ষণের উদাহরণ তৈরি করে।

collect() recognizer.listen() আউটপুটের সাথে একটি label যুক্ত করে। যেহেতু includeSpectrogram সত্য recognizer.listen() , 43 ফ্রেমে বিভক্ত অডিওর 1 সেকেন্ডের জন্য রও স্পেকট্রোগ্রাম (ফ্রিকোয়েন্সি ডেটা) দেয়, তাই প্রতিটি ফ্রেম অডিওর ~23ms হয়:

recognizer.listen(async ({spectrogram: {frameSize, data}}) => {
...
}, {includeSpectrogram: true});

যেহেতু আমরা স্লাইডার নিয়ন্ত্রণ করতে শব্দের পরিবর্তে ছোট শব্দ ব্যবহার করতে চাই, তাই আমরা শুধুমাত্র শেষ 3টি ফ্রেম (~70ms) বিবেচনা করছি:

let vals = normalize(data.subarray(-frameSize * NUM_FRAMES));

এবং সংখ্যাগত সমস্যা এড়াতে, আমরা 0 এর গড় এবং 1 এর আদর্শ বিচ্যুতিতে ডেটাকে স্বাভাবিক করি। এই ক্ষেত্রে, বর্ণালীগ্রামের মানগুলি সাধারণত -100 এর কাছাকাছি বড় ঋণাত্মক সংখ্যা এবং 10 এর বিচ্যুতি হয়:

const mean = -100;
const std = 10;
return x.map(x => (x - mean) / std);

অবশেষে, প্রতিটি প্রশিক্ষণের উদাহরণে 2টি ক্ষেত্র থাকবে:

  • label ****: 0, 1, এবং 2 যথাক্রমে "বাম", "ডান" এবং "শব্দ" এর জন্য।
  • vals ****: 696 সংখ্যা ফ্রিকোয়েন্সি তথ্য ধারণ করে (স্পেকট্রোগ্রাম)

এবং আমরা examples ভেরিয়েবলে সমস্ত ডেটা সংরক্ষণ করি:

examples.push({vals, label});

7. টেস্ট ডেটা সংগ্রহ

একটি ব্রাউজারে index.html খুলুন, এবং আপনি 3টি কমান্ডের সাথে সম্পর্কিত 3টি বোতাম দেখতে পাবেন৷ আপনি যদি স্থানীয় ফাইল থেকে কাজ করেন, মাইক্রোফোন অ্যাক্সেস করতে আপনাকে একটি ওয়েব সার্ভার শুরু করতে হবে এবং http://localhost:port/ ব্যবহার করতে হবে।

পোর্ট 8000 এ একটি সাধারণ ওয়েব সার্ভার শুরু করতে:

python -m SimpleHTTPServer

প্রতিটি কমান্ডের উদাহরণ সংগ্রহ করতে, 3-4 সেকেন্ডের জন্য প্রতিটি বোতাম টিপুন এবং ধরে রাখার সময় বারবার (বা ক্রমাগত) একটি সামঞ্জস্যপূর্ণ শব্দ করুন। প্রতিটি লেবেলের জন্য আপনার ~150টি উদাহরণ সংগ্রহ করা উচিত। উদাহরণস্বরূপ, আমরা "বাম" এর জন্য আঙ্গুল ছিঁড়তে পারি, "ডান" এর জন্য শিস দিতে পারি এবং "গোলমাল" এর জন্য নীরবতা এবং কথা বলার মধ্যে বিকল্প।

আপনি আরও উদাহরণ সংগ্রহ করার সাথে সাথে পৃষ্ঠায় দেখানো কাউন্টারটি উপরে যেতে হবে। কনসোলের ভেরিয়েবলের examples console.log() কল করে ডেটা পরিদর্শন করতে নির্দ্বিধায়৷ এই মুহুর্তে লক্ষ্য হল ডেটা সংগ্রহ প্রক্রিয়া পরীক্ষা করা। পরে আপনি পুরো অ্যাপটি পরীক্ষা করার সময় ডেটা পুনরায় সংগ্রহ করবেন।

8. একটি মডেল প্রশিক্ষণ

  1. index.html এ বডিতে " নয়েজ " বোতামের ঠিক পরে একটি " ট্রেন " বোতাম যোগ করুন:
<br/><br/>
<button id="train" onclick="train()">Train</button>
  1. index.js- এ বিদ্যমান কোডে নিম্নলিখিত যোগ করুন:
const INPUT_SHAPE = [NUM_FRAMES, 232, 1];
let model;

async function train() {
 toggleButtons(false);
 const ys = tf.oneHot(examples.map(e => e.label), 3);
 const xsShape = [examples.length, ...INPUT_SHAPE];
 const xs = tf.tensor(flatten(examples.map(e => e.vals)), xsShape);

 await model.fit(xs, ys, {
   batchSize: 16,
   epochs: 10,
   callbacks: {
     onEpochEnd: (epoch, logs) => {
       document.querySelector('#console').textContent =
           `Accuracy: ${(logs.acc * 100).toFixed(1)}% Epoch: ${epoch + 1}`;
     }
   }
 });
 tf.dispose([xs, ys]);
 toggleButtons(true);
}

function buildModel() {
 model = tf.sequential();
 model.add(tf.layers.depthwiseConv2d({
   depthMultiplier: 8,
   kernelSize: [NUM_FRAMES, 3],
   activation: 'relu',
   inputShape: INPUT_SHAPE
 }));
 model.add(tf.layers.maxPooling2d({poolSize: [1, 2], strides: [2, 2]}));
 model.add(tf.layers.flatten());
 model.add(tf.layers.dense({units: 3, activation: 'softmax'}));
 const optimizer = tf.train.adam(0.01);
 model.compile({
   optimizer,
   loss: 'categoricalCrossentropy',
   metrics: ['accuracy']
 });
}

function toggleButtons(enable) {
 document.querySelectorAll('button').forEach(b => b.disabled = !enable);
}

function flatten(tensors) {
 const size = tensors[0].length;
 const result = new Float32Array(tensors.length * size);
 tensors.forEach((arr, i) => result.set(arr, i * size));
 return result;
}
  1. অ্যাপ লোড হলে buildModel() কল করুন:
async function app() {
 recognizer = speechCommands.create('BROWSER_FFT');
 await recognizer.ensureModelLoaded();
 // Add this line.
 buildModel();
}

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

ভেঙ্গে ফেলছে

একটি উচ্চ স্তরে আমরা দুটি জিনিস করছি: buildModel() মডেল আর্কিটেকচারকে সংজ্ঞায়িত করে এবং train() সংগৃহীত ডেটা ব্যবহার করে মডেলটিকে প্রশিক্ষণ দেয়।

মডেল আর্কিটেকচার

মডেলটিতে 4টি স্তর রয়েছে: একটি রূপান্তরমূলক স্তর যা অডিও ডেটা প্রক্রিয়া করে (স্পেকট্রোগ্রাম হিসাবে উপস্থাপিত), একটি সর্বাধিক পুল স্তর, একটি সমতল স্তর এবং একটি ঘন স্তর যা 3টি ক্রিয়াকে মানচিত্র করে:

model = tf.sequential();
 model.add(tf.layers.depthwiseConv2d({
   depthMultiplier: 8,
   kernelSize: [NUM_FRAMES, 3],
   activation: 'relu',
   inputShape: INPUT_SHAPE
 }));
 model.add(tf.layers.maxPooling2d({poolSize: [1, 2], strides: [2, 2]}));
 model.add(tf.layers.flatten());
 model.add(tf.layers.dense({units: 3, activation: 'softmax'}));

মডেলটির ইনপুট আকৃতি হল [NUM_FRAMES, 232, 1] যেখানে প্রতিটি ফ্রেমে 23ms অডিও রয়েছে যাতে 232 নম্বর থাকে যা বিভিন্ন ফ্রিকোয়েন্সির সাথে মিলে যায় (232টি বেছে নেওয়া হয়েছিল কারণ এটি মানুষের ভয়েস ক্যাপচার করার জন্য প্রয়োজনীয় ফ্রিকোয়েন্সি বালতিগুলির পরিমাণ)। এই কোডল্যাবে, আমরা 3 ফ্রেম লম্বা নমুনা ব্যবহার করছি (~70ms নমুনা) যেহেতু আমরা স্লাইডার নিয়ন্ত্রণ করতে পুরো শব্দ বলার পরিবর্তে শব্দ করছি।

প্রশিক্ষণের জন্য প্রস্তুত করার জন্য আমরা আমাদের মডেলটি কম্পাইল করি:

const optimizer = tf.train.adam(0.01);
 model.compile({
   optimizer,
   loss: 'categoricalCrossentropy',
   metrics: ['accuracy']
 });

আমরা অ্যাডাম অপ্টিমাইজার ব্যবহার করি, একটি সাধারণ অপ্টিমাইজার যা গভীর শিক্ষায় ব্যবহৃত হয় এবং ক্ষতির জন্য categoricalCrossEntropy , শ্রেণীবিভাগের জন্য ব্যবহৃত স্ট্যান্ডার্ড লস ফাংশন। সংক্ষেপে, এটি পরিমাপ করে যে ভবিষ্যদ্বাণী করা সম্ভাব্যতাগুলি (একটি শ্রেণী প্রতি একটি সম্ভাব্যতা) প্রকৃত শ্রেণীতে 100% সম্ভাব্যতা এবং অন্যান্য সমস্ত শ্রেণীর জন্য 0% সম্ভাবনা থেকে কতদূর। আমরা নিরীক্ষণের জন্য একটি মেট্রিক হিসাবে accuracy প্রদান করি, যা আমাদের প্রশিক্ষণের প্রতিটি যুগের পরে মডেলটি সঠিক হওয়ার শতকরা উদাহরণ দেবে।

প্রশিক্ষণ

প্রশিক্ষণটি 16 ব্যাচের আকার ব্যবহার করে ডেটার উপর 10 বার (যুগ) যায় (এক সময়ে 16টি উদাহরণ প্রক্রিয়াকরণ) এবং UI-তে বর্তমান নির্ভুলতা দেখায়:

await model.fit(xs, ys, {
   batchSize: 16,
   epochs: 10,
   callbacks: {
     onEpochEnd: (epoch, logs) => {
       document.querySelector('#console').textContent =
           `Accuracy: ${(logs.acc * 100).toFixed(1)}% Epoch: ${epoch + 1}`;
     }
   }
 });

9. রিয়েল-টাইমে স্লাইডার আপডেট করুন

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

<br/><br/>
<button id="listen" onclick="listen()">Listen</button>
<input type="range" id="output" min="0" max="10" step="0.1">

এবং index.js এ নিম্নলিখিত:

async function moveSlider(labelTensor) {
 const label = (await labelTensor.data())[0];
 document.getElementById('console').textContent = label;
 if (label == 2) {
   return;
 }
 let delta = 0.1;
 const prevValue = +document.getElementById('output').value;
 document.getElementById('output').value =
     prevValue + (label === 0 ? -delta : delta);
}

function listen() {
 if (recognizer.isListening()) {
   recognizer.stopListening();
   toggleButtons(true);
   document.getElementById('listen').textContent = 'Listen';
   return;
 }
 toggleButtons(false);
 document.getElementById('listen').textContent = 'Stop';
 document.getElementById('listen').disabled = false;

 recognizer.listen(async ({spectrogram: {frameSize, data}}) => {
   const vals = normalize(data.subarray(-frameSize * NUM_FRAMES));
   const input = tf.tensor(vals, [1, ...INPUT_SHAPE]);
   const probs = model.predict(input);
   const predLabel = probs.argMax(1);
   await moveSlider(predLabel);
   tf.dispose([input, probs, predLabel]);
 }, {
   overlapFactor: 0.999,
   includeSpectrogram: true,
   invokeCallbackOnNoiseAndUnknown: true
 });
}

ভেঙ্গে ফেলছে

রিয়েল-টাইম ভবিষ্যদ্বাণী

listen() মাইক্রোফোন শোনে এবং রিয়েল টাইম ভবিষ্যদ্বাণী করে। কোডটি collect() পদ্ধতির সাথে খুব মিল, যা কাঁচা স্পেকট্রোগ্রামকে স্বাভাবিক করে এবং শেষ NUM_FRAMES ফ্রেমগুলি ছাড়া বাকিগুলিকে বাদ দেয়৷ শুধুমাত্র পার্থক্য হল যে আমরা একটি ভবিষ্যদ্বাণী পেতে প্রশিক্ষিত মডেলকেও কল করি:

const probs = model.predict(input);
const predLabel = probs.argMax(1);
await moveSlider(predLabel);

model.predict(input) এর আউটপুট হল আকৃতির একটি টেনসর [1, numClasses] যা ক্লাসের সংখ্যার উপর একটি সম্ভাব্যতা বন্টন প্রতিনিধিত্ব করে। আরও সহজভাবে, এটি সম্ভাব্য প্রতিটি আউটপুট ক্লাসের জন্য আত্মবিশ্বাসের একটি সেট যার যোগফল 1। টেনসরের বাইরের মাত্রা 1 কারণ এটি ব্যাচের আকার (একটি একক উদাহরণ)।

সম্ভাব্যতা বণ্টনকে একটি একক পূর্ণসংখ্যাতে রূপান্তর করার জন্য যা সর্বাধিক সম্ভাব্য শ্রেণীর প্রতিনিধিত্ব করে, আমরা probs.argMax(1) বলি যা সর্বোচ্চ সম্ভাব্যতার সাথে শ্রেণি সূচক প্রদান করে। আমরা অক্ষ প্যারামিটার হিসাবে একটি "1" পাস করি কারণ আমরা শেষ মাত্রা, numClasses এর উপর argMax গণনা করতে চাই।

স্লাইডার আপডেট করা হচ্ছে

moveSlider() স্লাইডারের মান হ্রাস করে যদি লেবেলটি 0 ("বাম") হয়, লেবেলটি 1 ("ডান") হলে এটিকে বৃদ্ধি করে এবং লেবেলটি 2 ("শব্দ") হলে উপেক্ষা করে।

নিষ্পত্তি টেনসর

GPU মেমরি পরিষ্কার করার জন্য আউটপুট টেনসরে tf.dispose() কে ম্যানুয়ালি কল করা আমাদের জন্য গুরুত্বপূর্ণ। ম্যানুয়াল tf.dispose() এর বিকল্প হল tf.tidy() এ ফাংশন কলগুলিকে মোড়ানো, কিন্তু এটি async ফাংশনের সাথে ব্যবহার করা যাবে না।

   tf.dispose([input, probs, predLabel]);

10. চূড়ান্ত অ্যাপ পরীক্ষা করুন

আপনার ব্রাউজারে index.html খুলুন এবং 3টি কমান্ডের সাথে সম্পর্কিত 3টি বোতামের সাহায্যে আপনি আগের বিভাগে যেমন ডেটা সংগ্রহ করেছিলেন। তথ্য সংগ্রহ করার সময় 3-4 সেকেন্ডের জন্য প্রতিটি বোতাম টিপুন এবং ধরে রাখতে ভুলবেন না।

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

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

http://js.tensorflow.org/-এ আরও টিউটোরিয়াল দেখুন।