1. ভূমিকা
এই টিউটোরিয়ালে, আমরা একটি TensorFlow.js মডেল তৈরি করব যা একটি কনভোলিউশনাল নিউরাল নেটওয়ার্কের সাহায্যে হাতে লেখা অঙ্কগুলি সনাক্ত করতে পারবে। প্রথমে, আমরা ক্লাসিফায়ারকে হাজার হাজার হাতে লেখা অঙ্কের ছবি এবং তাদের লেবেলগুলি "দেখতে" শেখাবো। তারপর আমরা ক্লাসিফায়ারের নির্ভুলতা মূল্যায়ন করব এমন পরীক্ষার ডেটা ব্যবহার করে যা মডেলটি কখনও দেখেনি।
এই কাজটিকে একটি শ্রেণিবদ্ধকরণ কাজ হিসেবে বিবেচনা করা হয় কারণ আমরা মডেলটিকে ইনপুট ছবিতে একটি বিভাগ (ছবিতে প্রদর্শিত সংখ্যা) নির্ধারণের প্রশিক্ষণ দিচ্ছি। আমরা সঠিক আউটপুট সহ ইনপুটের অনেক উদাহরণ দেখিয়ে মডেলটিকে প্রশিক্ষণ দেব। এটিকে তত্ত্বাবধানে শেখা বলা হয়।
তুমি কী তৈরি করবে
তুমি এমন একটি ওয়েবপেজ তৈরি করবে যা ব্রাউজারে একটি মডেলকে প্রশিক্ষণ দেওয়ার জন্য TensorFlow.js ব্যবহার করবে। একটি নির্দিষ্ট আকারের কালো এবং সাদা চিত্র দেওয়া হলে, ছবিতে কোন সংখ্যাটি প্রদর্শিত হবে তা শ্রেণীবদ্ধ করা হবে। জড়িত পদক্ষেপগুলি হল:
- ডেটা লোড করুন।
- মডেলের স্থাপত্য সংজ্ঞায়িত করুন।
- মডেলটিকে প্রশিক্ষণ দিন এবং প্রশিক্ষণের সময় এর কর্মক্ষমতা পর্যবেক্ষণ করুন।
- কিছু ভবিষ্যদ্বাণী করে প্রশিক্ষিত মডেলটি মূল্যায়ন করুন।
তুমি কি শিখবে
- TensorFlow.js Layers API ব্যবহার করে কনভোলিউশনাল মডেল তৈরির জন্য TensorFlow.js সিনট্যাক্স।
- TensorFlow.js-এ শ্রেণীবিভাগের কাজগুলি প্রণয়ন করা
- tfjs-vis লাইব্রেরি ব্যবহার করে ব্রাউজারে প্রশিক্ষণ কীভাবে পর্যবেক্ষণ করবেন।
তোমার যা লাগবে
- Chrome এর সাম্প্রতিক সংস্করণ অথবা অন্য কোন আধুনিক ব্রাউজারের যা ES6 মডিউল সমর্থন করে।
- একটি টেক্সট এডিটর, যা আপনার মেশিনে স্থানীয়ভাবে চলবে অথবা ওয়েবে কোডপেন বা গ্লিচের মতো কিছুর মাধ্যমে চলবে।
- HTML, CSS, JavaScript, এবং Chrome DevTools (অথবা আপনার পছন্দের ব্রাউজার devtools) সম্পর্কে জ্ঞান থাকতে হবে।
- নিউরাল নেটওয়ার্ক সম্পর্কে উচ্চ স্তরের ধারণাগত ধারণা। যদি আপনার ভূমিকা বা রিফ্রেশারের প্রয়োজন হয়, তাহলে 3blue1brown-এর এই ভিডিওটি অথবা Ashi Krishnan-এর জাভাস্ক্রিপ্টে গভীর শিক্ষার উপর এই ভিডিওটি দেখার কথা বিবেচনা করুন।
আমাদের প্রথম প্রশিক্ষণ টিউটোরিয়ালের উপাদানের সাথেও আপনার স্বাচ্ছন্দ্য বোধ করা উচিত।
2. সেট আপ করুন
একটি HTML পৃষ্ঠা তৈরি করুন এবং জাভাস্ক্রিপ্ট অন্তর্ভুক্ত করুন
নিচের কোডটি একটি html ফাইলে কপি করুন যার নাম
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TensorFlow.js Tutorial</title>
<!-- Import TensorFlow.js -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>
<!-- Import tfjs-vis -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis@1.0.2/dist/tfjs-vis.umd.min.js"></script>
<!-- Import the data file -->
<script src="data.js" type="module"></script>
<!-- Import the main script file -->
<script src="script.js" type="module"></script>
</head>
<body>
</body>
</html>
ডেটা এবং কোডের জন্য জাভাস্ক্রিপ্ট ফাইল তৈরি করুন
- উপরের HTML ফাইলের মতো একই ফোল্ডারে, data.js ফাইল নামে একটি ফাইল তৈরি করুন এবং এই লিঙ্ক থেকে কন্টেন্টটি সেই ফাইলে কপি করুন।
- প্রথম ধাপের মতো একই ফোল্ডারে, script.js নামে একটি ফাইল তৈরি করুন এবং এতে নিম্নলিখিত কোডটি রাখুন।
console.log('Hello TensorFlow');
এটি পরীক্ষা করে দেখুন
এখন যেহেতু তুমি HTML এবং JavaScript ফাইল তৈরি করে ফেলেছো, সেগুলো পরীক্ষা করে দেখো। তোমার ব্রাউজারে index.html ফাইলটি খুলো এবং devtools কনসোলটি খুলো।
যদি সবকিছু ঠিকঠাক কাজ করে, তাহলে দুটি গ্লোবাল ভেরিয়েবল তৈরি করা উচিত। tf হল TensorFlow.js লাইব্রেরির একটি রেফারেন্স, tfvis হল tfjs-vis লাইব্রেরির একটি রেফারেন্স।
আপনার একটি বার্তা দেখা উচিত যেখানে লেখা আছে Hello TensorFlow , যদি তাই হয়, তাহলে আপনি পরবর্তী ধাপে যেতে প্রস্তুত।
3. ডেটা লোড করুন
এই টিউটোরিয়ালে আপনি একজন মডেলকে নীচের চিত্রগুলির মতো চিত্রগুলিতে অঙ্কগুলি চিনতে শেখাবেন। এই চিত্রগুলি MNIST নামক একটি ডেটাসেট থেকে 28x28px গ্রেস্কেল চিত্র।



আমরা আপনার জন্য তৈরি একটি বিশেষ স্প্রাইট ফাইল (~১০MB) থেকে এই ছবিগুলি লোড করার জন্য কোড প্রদান করেছি যাতে আমরা প্রশিক্ষণ অংশে মনোযোগ দিতে পারি।
ডেটা কীভাবে লোড করা হয় তা বুঝতে data.js ফাইলটি পড়তে দ্বিধা করবেন না। অথবা এই টিউটোরিয়ালটি শেষ করার পরে, ডেটা লোড করার জন্য আপনার নিজস্ব পদ্ধতি তৈরি করুন।
প্রদত্ত কোডটিতে একটি ক্লাস MnistData রয়েছে যার দুটি পাবলিক পদ্ধতি রয়েছে:
-
nextTrainBatch(batchSize): প্রশিক্ষণ সেট থেকে ছবি এবং তাদের লেবেলের একটি এলোমেলো ব্যাচ ফেরত দেয়। -
nextTestBatch(batchSize): টেস্ট সেট থেকে ছবি এবং তাদের লেবেলের একটি ব্যাচ ফেরত দেয়।
MnistData ক্লাস ডেটা বদলানো এবং স্বাভাবিক করার গুরুত্বপূর্ণ ধাপগুলিও করে।
মোট ৬৫,০০০টি ছবি আছে, আমরা মডেলটিকে প্রশিক্ষণ দেওয়ার জন্য ৫৫,০০০টি পর্যন্ত ছবি ব্যবহার করব, ১০,০০০টি ছবি সংরক্ষণ করব যা আমরা কাজ শেষ করার পরে মডেলটির কর্মক্ষমতা পরীক্ষা করার জন্য ব্যবহার করতে পারব। এবং আমরা ব্রাউজারেই সব কিছু করব!
আসুন ডেটা লোড করি এবং পরীক্ষা করি যে এটি সঠিকভাবে লোড হয়েছে।
আপনার script.js ফাইলে নিম্নলিখিত কোডটি যোগ করুন।
import {MnistData} from './data.js';
async function showExamples(data) {
// Create a container in the visor
const surface =
tfvis.visor().surface({ name: 'Input Data Examples', tab: 'Input Data'});
// Get the examples
const examples = data.nextTestBatch(20);
const numExamples = examples.xs.shape[0];
// Create a canvas element to render each example
for (let i = 0; i < numExamples; i++) {
const imageTensor = tf.tidy(() => {
// Reshape the image to 28x28 px
return examples.xs
.slice([i, 0], [1, examples.xs.shape[1]])
.reshape([28, 28, 1]);
});
const canvas = document.createElement('canvas');
canvas.width = 28;
canvas.height = 28;
canvas.style = 'margin: 4px;';
await tf.browser.toPixels(imageTensor, canvas);
surface.drawArea.appendChild(canvas);
imageTensor.dispose();
}
}
async function run() {
const data = new MnistData();
await data.load();
await showExamples(data);
}
document.addEventListener('DOMContentLoaded', run);
পৃষ্ঠাটি রিফ্রেশ করুন এবং কয়েক সেকেন্ড পরে আপনি বাম দিকে একটি প্যানেল দেখতে পাবেন যেখানে বেশ কয়েকটি ছবি রয়েছে।

৪. আমাদের কাজটি ধারণা করুন
আমাদের ইনপুট ডেটা দেখতে এরকম।

আমাদের লক্ষ্য হলো এমন একটি মডেলকে প্রশিক্ষণ দেওয়া যা একটি ছবি নেবে এবং সম্ভাব্য ১০টি শ্রেণীর (০-৯ সংখ্যা) প্রতিটির জন্য একটি স্কোর ভবিষ্যদ্বাণী করতে শিখবে।
প্রতিটি ছবি ২৮ পিক্সেল প্রস্থ এবং ২৮ পিক্সেল উঁচু এবং এতে ১টি রঙের চ্যানেল রয়েছে কারণ এটি একটি গ্রেস্কেল ছবি। তাই প্রতিটি ছবির আকৃতি [28, 28, 1] ।
মনে রাখবেন যে আমরা এক থেকে দশটি ম্যাপিং করি, সেইসাথে প্রতিটি ইনপুট উদাহরণের আকৃতিও করি, কারণ এটি পরবর্তী বিভাগের জন্য গুরুত্বপূর্ণ।
৫. মডেল আর্কিটেকচারের সংজ্ঞা দাও
এই বিভাগে আমরা মডেল আর্কিটেকচার বর্ণনা করার জন্য কোড লিখব। মডেল আর্কিটেকচার হল "মডেলটি যখন কার্যকর হবে তখন কোন ফাংশনগুলি চলবে" , অথবা বিকল্পভাবে "আমাদের মডেলটি তার উত্তরগুলি গণনা করার জন্য কোন অ্যালগরিদম ব্যবহার করবে" তা বলার একটি অভিনব উপায়।
মেশিন লার্নিংয়ে আমরা একটি আর্কিটেকচার (বা অ্যালগরিদম) সংজ্ঞায়িত করি এবং প্রশিক্ষণ প্রক্রিয়াটিকে সেই অ্যালগরিদমের পরামিতিগুলি শিখতে দিই।
আপনার ফাংশনে নিম্নলিখিত ফাংশনটি যোগ করুন
মডেল আর্কিটেকচার সংজ্ঞায়িত করার জন্য script.js ফাইল
function getModel() {
const model = tf.sequential();
const IMAGE_WIDTH = 28;
const IMAGE_HEIGHT = 28;
const IMAGE_CHANNELS = 1;
// In the first layer of our convolutional neural network we have
// to specify the input shape. Then we specify some parameters for
// the convolution operation that takes place in this layer.
model.add(tf.layers.conv2d({
inputShape: [IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS],
kernelSize: 5,
filters: 8,
strides: 1,
activation: 'relu',
kernelInitializer: 'varianceScaling'
}));
// The MaxPooling layer acts as a sort of downsampling using max values
// in a region instead of averaging.
model.add(tf.layers.maxPooling2d({poolSize: [2, 2], strides: [2, 2]}));
// Repeat another conv2d + maxPooling stack.
// Note that we have more filters in the convolution.
model.add(tf.layers.conv2d({
kernelSize: 5,
filters: 16,
strides: 1,
activation: 'relu',
kernelInitializer: 'varianceScaling'
}));
model.add(tf.layers.maxPooling2d({poolSize: [2, 2], strides: [2, 2]}));
// Now we flatten the output from the 2D filters into a 1D vector to prepare
// it for input into our last layer. This is common practice when feeding
// higher dimensional data to a final classification output layer.
model.add(tf.layers.flatten());
// Our last layer is a dense layer which has 10 output units, one for each
// output class (i.e. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9).
const NUM_OUTPUT_CLASSES = 10;
model.add(tf.layers.dense({
units: NUM_OUTPUT_CLASSES,
kernelInitializer: 'varianceScaling',
activation: 'softmax'
}));
// Choose an optimizer, loss function and accuracy metric,
// then compile and return the model
const optimizer = tf.train.adam();
model.compile({
optimizer: optimizer,
loss: 'categoricalCrossentropy',
metrics: ['accuracy'],
});
return model;
}
আসুন আমরা এটিকে আরও একটু বিস্তারিতভাবে দেখি।
কনভলিউশন
model.add(tf.layers.conv2d({
inputShape: [IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS],
kernelSize: 5,
filters: 8,
strides: 1,
activation: 'relu',
kernelInitializer: 'varianceScaling'
}));
এখানে আমরা একটি ক্রমিক মডেল ব্যবহার করছি।
আমরা ঘন স্তরের পরিবর্তে একটি conv2d স্তর ব্যবহার করছি। কনভলিউশন কীভাবে কাজ করে তার সমস্ত বিবরণে আমরা যেতে পারব না, তবে এখানে কয়েকটি সংস্থান রয়েছে যা অন্তর্নিহিত ক্রিয়াকলাপ ব্যাখ্যা করে:
- চিত্র কার্নেলগুলি দৃশ্যত ব্যাখ্যা করা হয়েছে
- ভিজ্যুয়াল রিকগনিশনের জন্য কনভোলিউশনাল নিউরাল নেটওয়ার্ক
conv2d এর জন্য কনফিগারেশন অবজেক্টের প্রতিটি আর্গুমেন্ট ভেঙে ফেলা যাক:
-
inputShape। মডেলের প্রথম স্তরে প্রবাহিত ডেটার আকৃতি। এই ক্ষেত্রে, আমাদের MNIST উদাহরণগুলি হল 28x28-পিক্সেল কালো-সাদা ছবি। চিত্র ডেটার জন্য ক্যানোনিকাল ফর্ম্যাট হল[row, column, depth], তাই এখানে আমরা[28, 28, 1]এর একটি আকৃতি কনফিগার করতে চাই। প্রতিটি মাত্রায় পিক্সেলের সংখ্যার জন্য 28টি সারি এবং কলাম এবং 1টির গভীরতা কারণ আমাদের চিত্রগুলিতে কেবল 1টি রঙিন চ্যানেল রয়েছে। মনে রাখবেন যে আমরা ইনপুট আকারে ব্যাচের আকার নির্দিষ্ট করি না। স্তরগুলি ব্যাচ আকারের অজ্ঞেয়বাদী হিসাবে ডিজাইন করা হয়েছে যাতে অনুমানের সময় আপনি যেকোনো ব্যাচ আকারের একটি টেনসর পাস করতে পারেন। -
kernelSize। ইনপুট ডেটাতে প্রয়োগ করার জন্য স্লাইডিং কনভোলিউশনাল ফিল্টার উইন্ডোর আকার। এখানে, আমরা5এর একটিkernelSizeসেট করেছি, যা একটি বর্গাকার, 5x5 কনভোলিউশনাল উইন্ডো নির্দিষ্ট করে। -
filters। ইনপুট ডেটাতে প্রয়োগ করার জন্যkernelSizeআকারের ফিল্টার উইন্ডোর সংখ্যা। এখানে, আমরা ডেটাতে 8টি ফিল্টার প্রয়োগ করব। -
strides। স্লাইডিং উইন্ডোর "স্টেপ সাইজ" - অর্থাৎ, প্রতিবার ছবির উপর দিয়ে যাওয়ার সময় ফিল্টারটি কত পিক্সেল স্থানান্তর করবে। এখানে, আমরা 1 এর স্ট্রাইড নির্দিষ্ট করি, যার অর্থ হল ফিল্টারটি 1 পিক্সেলের ধাপে ছবির উপর দিয়ে স্লাইড করবে। -
activation। কনভলিউশন সম্পূর্ণ হওয়ার পরে ডেটাতে প্রয়োগ করার জন্য অ্যাক্টিভেশন ফাংশন । এই ক্ষেত্রে, আমরা একটি রেক্টিফাইড লিনিয়ার ইউনিট (ReLU) ফাংশন প্রয়োগ করছি, যা ML মডেলগুলিতে একটি খুব সাধারণ অ্যাক্টিভেশন ফাংশন। -
kernelInitializer। মডেল ওয়েটগুলিকে এলোমেলোভাবে ইনিশিয়ালাইজ করার জন্য ব্যবহার করা পদ্ধতি, যা গতিবিদ্যা প্রশিক্ষণের জন্য খুবই গুরুত্বপূর্ণ। আমরা এখানে ইনিশিয়ালাইজেশনের বিশদে যাব না, তবেVarianceScaling(এখানে ব্যবহৃত) সাধারণত একটি ভাল ইনিশিয়ালাইজার পছন্দ ।
আমাদের তথ্য উপস্থাপনাকে সমতল করা
model.add(tf.layers.flatten());
ছবিগুলো উচ্চ মাত্রিক তথ্য, এবং কনভলিউশন অপারেশনের ফলে সেগুলোতে প্রবেশ করা তথ্যের আকার বৃদ্ধি পায়। আমাদের চূড়ান্ত শ্রেণীবিভাগ স্তরে পাঠানোর আগে আমাদের ডেটাগুলিকে একটি দীর্ঘ অ্যারেতে সমতল করতে হবে। ঘন স্তরগুলি (যা আমরা আমাদের চূড়ান্ত স্তর হিসাবে ব্যবহার করি) শুধুমাত্র tensor1d ব্যবহার করে, তাই এই ধাপটি অনেক শ্রেণীবিভাগের কাজে সাধারণ।
আমাদের চূড়ান্ত সম্ভাব্যতা বন্টন গণনা করুন
const NUM_OUTPUT_CLASSES = 10;
model.add(tf.layers.dense({
units: NUM_OUTPUT_CLASSES,
kernelInitializer: 'varianceScaling',
activation: 'softmax'
}));
আমরা ১০টি সম্ভাব্য ক্লাসের সম্ভাব্যতা বন্টন গণনা করার জন্য একটি সফটম্যাক্স অ্যাক্টিভেশন সহ একটি ঘন স্তর ব্যবহার করব। সর্বোচ্চ স্কোর সহ ক্লাসটি হবে পূর্বাভাসিত অঙ্ক।
একটি অপ্টিমাইজার এবং ক্ষতি ফাংশন নির্বাচন করুন
const optimizer = tf.train.adam();
model.compile({
optimizer: optimizer,
loss: 'categoricalCrossentropy',
metrics: ['accuracy'],
});
আমরা একটি অপ্টিমাইজার , লস ফাংশন এবং মেট্রিক্স নির্দিষ্ট করে মডেলটি কম্পাইল করি যা আমরা ট্র্যাক রাখতে চাই।
আমাদের প্রথম টিউটোরিয়ালের বিপরীতে, এখানে আমরা আমাদের লস ফাংশন হিসেবে categoricalCrossentropy ব্যবহার করি। নাম থেকেই বোঝা যাচ্ছে যে এটি তখন ব্যবহৃত হয় যখন আমাদের মডেলের আউটপুট একটি সম্ভাব্যতা বন্টন হয়। categoricalCrossentropy আমাদের মডেলের শেষ স্তর দ্বারা উৎপন্ন সম্ভাব্যতা বন্টন এবং আমাদের সত্যিকারের লেবেল দ্বারা প্রদত্ত সম্ভাব্যতা বন্টনের মধ্যে ত্রুটি পরিমাপ করে।
উদাহরণস্বরূপ, যদি আমাদের সংখ্যাটি সত্যিই 7 প্রতিনিধিত্ব করে তবে আমাদের নিম্নলিখিত ফলাফল থাকতে পারে
সূচক | 0 | ১ | ২ | ৩ | ৪ | ৫ | ৬ | ৭ | ৮ | ৯ |
ট্রু লেবেল | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ১ | 0 | 0 |
ভবিষ্যদ্বাণী | ০.১ | ০.০১ | ০.০১ | ০.০১ | ০.২০ | ০.০১ | ০.০১ | ০.৬০ | ০.০৩ | ০.০২ |
শ্রেণীবদ্ধ ক্রস এনট্রপি একটি একক সংখ্যা তৈরি করবে যা নির্দেশ করবে যে ভবিষ্যদ্বাণী ভেক্টরটি আমাদের প্রকৃত লেবেল ভেক্টরের সাথে কতটা মিল।
লেবেলগুলির জন্য এখানে ব্যবহৃত ডেটা উপস্থাপনাকে ওয়ান-হট এনকোডিং বলা হয় এবং এটি শ্রেণিবিন্যাস সমস্যায় সাধারণ। প্রতিটি শ্রেণীর প্রতিটি উদাহরণের জন্য একটি সম্ভাব্যতা যুক্ত থাকে। যখন আমরা ঠিক জানি যে এটি কী হওয়া উচিত তখন আমরা সেই সম্ভাব্যতা 1 এবং অন্যগুলি 0 তে সেট করতে পারি। ওয়ান-হট এনকোডিং সম্পর্কে আরও তথ্যের জন্য এই পৃষ্ঠাটি দেখুন।
আমরা যে অন্য মেট্রিকটি পর্যবেক্ষণ করব তা হল accuracy , যা একটি শ্রেণীবিভাগের সমস্যার জন্য হল সমস্ত ভবিষ্যদ্বাণীর মধ্যে সঠিক ভবিষ্যদ্বাণীর শতাংশ।
৬. মডেলকে প্রশিক্ষণ দিন
নিচের ফাংশনটি আপনার script.js ফাইলে কপি করুন।
async function train(model, data) {
const metrics = ['loss', 'val_loss', 'acc', 'val_acc'];
const container = {
name: 'Model Training', tab: 'Model', styles: { height: '1000px' }
};
const fitCallbacks = tfvis.show.fitCallbacks(container, metrics);
const BATCH_SIZE = 512;
const TRAIN_DATA_SIZE = 5500;
const TEST_DATA_SIZE = 1000;
const [trainXs, trainYs] = tf.tidy(() => {
const d = data.nextTrainBatch(TRAIN_DATA_SIZE);
return [
d.xs.reshape([TRAIN_DATA_SIZE, 28, 28, 1]),
d.labels
];
});
const [testXs, testYs] = tf.tidy(() => {
const d = data.nextTestBatch(TEST_DATA_SIZE);
return [
d.xs.reshape([TEST_DATA_SIZE, 28, 28, 1]),
d.labels
];
});
return model.fit(trainXs, trainYs, {
batchSize: BATCH_SIZE,
validationData: [testXs, testYs],
epochs: 10,
shuffle: true,
callbacks: fitCallbacks
});
}
তারপর আপনার কোডে নিম্নলিখিত কোডটি যোগ করুন
ফাংশন run ।
const model = getModel();
tfvis.show.modelSummary({name: 'Model Architecture', tab: 'Model'}, model);
await train(model, data);
পৃষ্ঠাটি রিফ্রেশ করুন এবং কয়েক সেকেন্ড পরে আপনি প্রশিক্ষণের অগ্রগতির প্রতিবেদনকারী কিছু গ্রাফ দেখতে পাবেন।

আসুন এটি আরও একটু বিস্তারিতভাবে দেখি।
মেট্রিক্স পর্যবেক্ষণ করুন
const metrics = ['loss', 'val_loss', 'acc', 'val_acc'];
এখানে আমরা সিদ্ধান্ত নেব যে আমরা কোন মেট্রিক্সগুলি পর্যবেক্ষণ করব। আমরা প্রশিক্ষণ সেটের ক্ষতি এবং নির্ভুলতা পর্যবেক্ষণ করব, সেইসাথে বৈধতা সেটের ক্ষতি এবং নির্ভুলতা (যথাক্রমে val_loss এবং val_acc) পর্যবেক্ষণ করব। আমরা নীচে বৈধতা সেট সম্পর্কে আরও আলোচনা করব।
টেনসর হিসেবে ডেটা প্রস্তুত করা
const BATCH_SIZE = 512;
const TRAIN_DATA_SIZE = 5500;
const TEST_DATA_SIZE = 1000;
const [trainXs, trainYs] = tf.tidy(() => {
const d = data.nextTrainBatch(TRAIN_DATA_SIZE);
return [
d.xs.reshape([TRAIN_DATA_SIZE, 28, 28, 1]),
d.labels
];
});
const [testXs, testYs] = tf.tidy(() => {
const d = data.nextTestBatch(TEST_DATA_SIZE);
return [
d.xs.reshape([TEST_DATA_SIZE, 28, 28, 1]),
d.labels
];
});
এখানে আমরা দুটি ডেটাসেট তৈরি করি, একটি প্রশিক্ষণ সেট যা আমরা মডেলটিকে প্রশিক্ষণ দেব এবং একটি বৈধতা সেট যা আমরা প্রতিটি যুগের শেষে মডেলটিকে পরীক্ষা করব, তবে বৈধতা সেটের ডেটা প্রশিক্ষণের সময় মডেলটিকে কখনই দেখানো হয় না।
আমরা যে ডেটা ক্লাসটি প্রদান করেছি তা ইমেজ ডেটা থেকে টেনসর পাওয়া সহজ করে তোলে। কিন্তু আমরা এখনও মডেলে ফিড করার আগে টেনসরগুলিকে মডেল দ্বারা প্রত্যাশিত আকারে, [num_examples, image_width, image_height, channels] তে পুনরায় আকার দিই। প্রতিটি ডেটাসেটের জন্য আমাদের ইনপুট (Xs) এবং লেবেল (Ys) উভয়ই থাকে।
return model.fit(trainXs, trainYs, {
batchSize: BATCH_SIZE,
validationData: [testXs, testYs],
epochs: 10,
shuffle: true,
callbacks: fitCallbacks
});
আমরা প্রশিক্ষণ লুপ শুরু করার জন্য model.fit কল করি। আমরা একটি validationData প্রোপার্টিও পাস করি যা নির্দেশ করে যে প্রতিটি যুগের পরে মডেলটি কোন ডেটা ব্যবহার করে নিজেকে পরীক্ষা করবে (কিন্তু প্রশিক্ষণের জন্য ব্যবহার করা হবে না)।
যদি আমরা আমাদের প্রশিক্ষণের তথ্যে ভালো করি কিন্তু আমাদের বৈধতা তথ্যে না করি, তাহলে এর অর্থ হল মডেলটি সম্ভবত প্রশিক্ষণের তথ্যের সাথে অতিরিক্ত মানানসই এবং পূর্বে দেখা না যাওয়া ইনপুটগুলিতে ভালভাবে সাধারণীকরণ করবে না।
৭. আমাদের মডেল মূল্যায়ন করুন
যাচাইকরণের নির্ভুলতা আমাদের মডেলটি এমন ডেটাতে কতটা ভালো করবে তার একটি ভালো অনুমান প্রদান করে যা তারা আগে দেখেনি (যদি সেই ডেটা কোনওভাবে বৈধতা সেটের সাথে সাদৃশ্যপূর্ণ হয়)। তবে আমরা বিভিন্ন শ্রেণীর পারফরম্যান্সের আরও বিস্তারিত বিশ্লেষণ চাইতে পারি।
tfjs-vis-এ কয়েকটি পদ্ধতি রয়েছে যা আপনাকে এতে সাহায্য করতে পারে।
আপনার script.js ফাইলের নীচে নিম্নলিখিত কোডটি যোগ করুন।
const classNames = ['Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine'];
function doPrediction(model, data, testDataSize = 500) {
const IMAGE_WIDTH = 28;
const IMAGE_HEIGHT = 28;
const testData = data.nextTestBatch(testDataSize);
const testxs = testData.xs.reshape([testDataSize, IMAGE_WIDTH, IMAGE_HEIGHT, 1]);
const labels = testData.labels.argMax(-1);
const preds = model.predict(testxs).argMax(-1);
testxs.dispose();
return [preds, labels];
}
async function showAccuracy(model, data) {
const [preds, labels] = doPrediction(model, data);
const classAccuracy = await tfvis.metrics.perClassAccuracy(labels, preds);
const container = {name: 'Accuracy', tab: 'Evaluation'};
tfvis.show.perClassAccuracy(container, classAccuracy, classNames);
labels.dispose();
}
async function showConfusion(model, data) {
const [preds, labels] = doPrediction(model, data);
const confusionMatrix = await tfvis.metrics.confusionMatrix(labels, preds);
const container = {name: 'Confusion Matrix', tab: 'Evaluation'};
tfvis.render.confusionMatrix(container, {values: confusionMatrix, tickLabels: classNames});
labels.dispose();
}
এই কোডটি কী করছে?
- ভবিষ্যদ্বাণী করে।
- নির্ভুলতার মেট্রিক্স গণনা করে।
- মেট্রিক্স দেখায়
আসুন প্রতিটি ধাপ ঘনিষ্ঠভাবে দেখে নেওয়া যাক।
ভবিষ্যদ্বাণী করুন
function doPrediction(model, data, testDataSize = 500) {
const IMAGE_WIDTH = 28;
const IMAGE_HEIGHT = 28;
const testData = data.nextTestBatch(testDataSize);
const testxs = testData.xs.reshape([testDataSize, IMAGE_WIDTH, IMAGE_HEIGHT, 1]);
const labels = testData.labels.argMax(-1);
const preds = model.predict(testxs).argMax(-1);
testxs.dispose();
return [preds, labels];
}
প্রথমে আমাদের কিছু ভবিষ্যদ্বাণী করতে হবে। এখানে আমরা ৫০০টি ছবি নেব এবং সেগুলোতে কোন সংখ্যাটি আছে তা ভবিষ্যদ্বাণী করব (আপনি পরে আরও বড় ছবি পরীক্ষা করার জন্য এই সংখ্যাটি বাড়িয়ে নিতে পারেন)।
উল্লেখযোগ্যভাবে, argmax ফাংশনটি আমাদের সর্বোচ্চ সম্ভাব্যতা শ্রেণীর সূচক দেয়। মনে রাখবেন যে মডেলটি প্রতিটি শ্রেণীর জন্য একটি সম্ভাব্যতা আউটপুট করে। এখানে আমরা সর্বোচ্চ সম্ভাব্যতা খুঁজে বের করি এবং এটিকে পূর্বাভাস হিসাবে ব্যবহার করি।
আপনি হয়তো লক্ষ্য করেছেন যে আমরা একসাথে ৫০০টি উদাহরণের উপর ভবিষ্যদ্বাণী করতে পারি। TensorFlow.js ভেক্টরাইজেশনের এই ক্ষমতা প্রদান করে।
প্রতি শ্রেণীর নির্ভুলতা দেখান
async function showAccuracy() {
const [preds, labels] = doPrediction();
const classAccuracy = await tfvis.metrics.perClassAccuracy(labels, preds);
const container = { name: 'Accuracy', tab: 'Evaluation' };
tfvis.show.perClassAccuracy(container, classAccuracy, classNames);
labels.dispose();
}
ভবিষ্যদ্বাণী এবং লেবেলের একটি সেট দিয়ে আমরা প্রতিটি শ্রেণীর জন্য নির্ভুলতা গণনা করতে পারি।
একটি বিভ্রান্তি ম্যাট্রিক্স দেখান
async function showConfusion() {
const [preds, labels] = doPrediction();
const confusionMatrix = await tfvis.metrics.confusionMatrix(labels, preds);
const container = { name: 'Confusion Matrix', tab: 'Evaluation' };
tfvis.render.confusionMatrix(container, {values: confusionMatrix, tickLabels: classNames});
labels.dispose();
}
একটি কনফিউশন ম্যাট্রিক্স প্রতি ক্লাসের নির্ভুলতার অনুরূপ, কিন্তু ভুল শ্রেণীবিভাগের ধরণগুলি দেখানোর জন্য এটিকে আরও ভেঙে দেয়। এটি আপনাকে দেখতে দেয় যে মডেলটি কোনও নির্দিষ্ট জোড়া ক্লাস সম্পর্কে বিভ্রান্ত হচ্ছে কিনা।
মূল্যায়ন প্রদর্শন করুন
মূল্যায়ন দেখানোর জন্য আপনার রান ফাংশনের নীচে নিম্নলিখিত কোডটি যুক্ত করুন।
await showAccuracy(model, data);
await showConfusion(model, data);
আপনি নিচের মত দেখতে একটি ডিসপ্লে দেখতে পাবেন।

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