ট্রেনিং এর পদ্ধতি
Last updated
Last updated
আমরা যেটা করতে পারি – নিউরনটার তিনটা ইনপুটে আমাদের প্রথম উদাহরণের তিনটা ভ্যালু দেবো আর আউপুট প্রান্তে সেই উদাহরণ মোতাবেক সঠিক আউপুটটা রাখবো। এরপর ইনপুট লাইন (গ্রাফ কনসেপ্টে Edge) গুলোতে কিছু Weight (ভ্যালু) সেট করবো। এরপর প্রত্যেকটা ইনপুট ভ্যালুর সাথে ওই Edge এর ভ্যালু তথা Weight গুন করে নিউরন-বডি/Soma বা Node এ একটা Weighted Sum জমা করবো। এক্ষেত্রে এই Node টী হচ্ছে আমাদের আউপুট নোড। যাই হোক, এই নোডে জমা হওয়া ভ্যালুর পরিমাণ কিন্তু 1 এর অনেক বেশি বা 0 এর চেয়ে কম হতে পারে। কিন্তু আমরা তো চাই, ভ্যালুটা 1 আর 0 এর মাঝা মাঝি থাকুক যাতে করে আমরা আমাদের আগে থেকেই সেট করা আউপুট ভ্যালু (যেমন – প্রথম উদাহরণ মোতাবেক 0) –এর সাথে তুলনা করতে পারি। তাই আউটপুট নোডে জমা হওয়া ভ্যালুকে আমরা গণিতের একটা স্পেশাল গ্যারাকলে ফেলে কোন না কোন ভাবে 1 ও 0 এর মাঝেই রাখবো। এটাকে বলে Activation Function (নিচেই আমরা এর চেহারা এবং ব্যবহার দেখবো)। এরপর সেই ক্যালকূলেটেড ভ্যালু এবং প্রথম উদাহরণ মোতাবেক আউটপুটের ভ্যালুর মধ্যে তুলনা করে আমরা ভুলের পরিমাণ দেখবো।
অর্থাৎ প্রথম ট্রেনিং হচ্ছে – ইনপুট দিলাম 0 0 1 এবং আউটপুট যেন হয় 0. কিন্তু ধরি Edge গুলোতে সেট করা আমাদের র্যান্ডম ওয়েট গুলো কন্সিডার করে ওয়েটেড সাম থেকে অ্যাক্টিভেশন ফাংশনের মাধ্যমে ভ্যালু পেলাম 0.9
তার মানে ট্রেনিং এর মাথা মুণ্ড কিছুই হয় নি। এরপর আমরা যা করতে পারি সেটা হল, সেই ওয়েট গুলোকে একটু চেঞ্জ (Adjust) করে দেখতে পারি। অর্থাৎ প্রথম লাইনে (Edge) যে ভ্যালু ছিল সেটাকে একটু বাড়িয়ে, আবার দ্বিতীয় লাইনের ওয়েটকে একটু কমিয়ে আবারও Activation Function এর আউটপুট দেখতে পারি। এবার যদি দেখি যে এর মান আসলো 0.4 তার মানে আউটপুটের সাথে মিল আসতেছে। আবারও একটু ওয়েট গুলোকে অ্যাডজাস্ট করে Activation Function এর আউটপুট দেখতে পারি। এবার যদি দেখি যে এর মান আসলো 0.1 তার মানে প্রথম ট্রেনিং সেট মোতাবেক যে 0 পাওয়ার চেষ্টা সেটা মোটামুটি সফল।
অর্থাৎ প্রথম ডাটা সেট (একটা Row যার ইনপুট/ভ্যারিয়েবল 0 0 1 এবং আউটপুট/লেবেল 0) এর জন্য আমাদের নিউরনের ট্রেনিং সম্পন্ন। অর্থাৎ, নিউরনটি তার ওয়েট গুলোকে অ্যাডজাস্ট করে এমন একটা অবস্থায় নিয়ে এসেছে যে এর তিনটি ইনপুটে 0 0 1 দিলে আউটপুটে 0 এর কাছাকাছি একটা ভ্যালু আসে। এরপর আবার নিউরনকে দ্বিতীয় ট্রেনিং ডাটা সেট দেয়া হল। এবার তার কাজ হচ্ছে নতুন তিনটি ইনপুট 1 1 1 এবং এর জানা আউটপুট 1 এর সাপেক্ষে নিজের Edge গুলোর ওয়েট এমনভাবে অ্যাডজাস্ট করা, যাতে করে ওয়েটেড সাম এবং Activation Function এর কাজের পর আউটপুট মোটামুটি 1 এর কাছাকাছি আসে।
কিন্তু খেয়াল রাখতে হবে যে আগের ট্রেনিং সেটের ব্যাপারটাও যাতে ঠিক থাকে। অর্থাৎ, দ্বিতীয় ট্রেনিং সেটের জন্য ওয়েট অ্যাডজাস্ট করে ইনপুট আউটপুট মিলাতে গিয়ে যেন প্রথম ট্রেনিং সেটের বারোটা না বেজে যায়। তার মানে তাকে খুবি ধীরে সুস্থে এবং ক্ষুদ্র ক্ষুদ্র পরিমাণে ওয়েটের ভ্যালু অ্যাডজাস্ট করতে হবে যাতে 0 0 1 দিলেও 0 এর মত মান আসে আবার 1 1 1 দিলেও যাতে 1 এর মত মান আসে। তো, বোঝাই যাচ্ছে যে, একবার দুইবার অ্যাডজাস্ট করে এই কাজ হাসিল করা সম্ভব না। বার বার এরর চেক করে বার বার ওয়েট অ্যাডজাস্ট করে করে দেখতে হবে। মাথা গরম করার কিছু নাই, নিচে আবারও আমরা এসব কথা বার্তা আরেকবার ধাপে ধাপে দেখবো।
তবে বুঝতে পারছি যে ঠিক কি কি কাজ আমাদের করতে হবে একটা ট্রেনিং সাইকেল সম্পন্ন করতে হলেঃ
এক) ট্রেনিং ডাটা টেবিল থেকে একটা সেট নিয়ে ইনপুট গুলো দেবো। এইজ গুলোতে কিছু র্যান্ডম ওয়েট (ভ্যালু) সেট করবো। কিছু গুন আর যোগ করে এবং স্পেশাল একটা ফাংশনের মাধ্যমে এর আউটপুট বের করবো।
দুই) এরর এর পরিমাণ বের করবো অর্থাৎ – এই ধাপের আউটপুট এবং আসলেই ট্রেনিং সেট মোতাবেক আসল আউটপুটের পার্থক্য দেখবো।
তিন) এরর এর গতবিধি মোতাবেক ওয়েটগুলোকে খুব অল্প পরিমাণে অ্যাডজাস্ট করবো
চার) উপরের তিনটি ধাপকে হাজার হাজার বার রিপিট করাবো
এভাবে সামনের দিকে ক্যালকুলেশন এগিয়ে নিয়ে (Forward Propogation) এরর সাথে তুলনা করে আবার পিছনে ফিরে এসে (Back Propogation) ভ্যালু (ইনপুট ভ্যালু না কিন্তু। ওয়েট বা আপনার সেট করা ভ্যালু) গুলোকে অ্যাডজাস্ট করে আবার আউটপুটের সাথে তুলনা করার যে চক্র তাকে বলে Back Propogation.
এক নাম্বার ধাপের কাজ করি – প্রত্যেকটা ইনপুটের সাথে প্রত্যেক লাইনের ওয়েট গুন করে যোগফল বের করার সূত্র হবে নিচের মতঃ
এর পর এই যোগফলকে 1 ও 0 এর মাঝা মাঝি রাখার জন্য গণিতের একটা স্পেশাল ফাংশন যার নাম Sigmid Function (এখানে এটাই আমাদের Activation Function. এরকম আরও আছে।) সেটাকে ব্যবহার করতে পারি। এই ফাংশনের কাজ হচ্ছে – একে ইনপুট হিসেবে যে মাণই দেয়া হোক না কেন, আউটপুট আসবে 1 থেকে শুনের মধ্যেই। এটাই তো দরকার 🙂 যাই হোক ফাংশনের ম্যাথেমেটিক্যাল রিপ্রেজেন্টেশন এবং গ্রাফটা দেখতে নিচের মত
তো আমরা আমাদের ওয়েটেড সাম কে এই ফাংশনের সাহায্যে 1 ও 0 এর মধ্যে এনে ফেলতে পারি। Sigmoid Function নিয়ে পড়ার জায়গা এটা না। দরকার হলে আলাদা করে দেখে ফিরে আসতে পারেন এই পোস্টে।
দ্বিতীয় ধাপে – এরর এর পরিমাণ বের করবো। এটা খুবি সহজ কাজ। প্রত্যেকটি ইনপুট কম্বিনেশনের জন্য আউটপুট থেকে এই নিউরাল নেটওয়ার্কের হিসেব করা আউটপুটকে বিয়োগ দিতে হবে।
তৃতীয় ধাপে – আমরা এররের উপর ভিত্তি করে ওয়েট অ্যাডজাস্ট করবো। কিন্তু কি পরিমাণে অ্যাডজাস্ট করবো? এক্ষেত্রেও আমরা একটা ফর্মুলা “Error Weighted Derivative” ব্যবহার করতে পারি। সূত্রটা দেখতে নিচের মতোঃ
সূত্রে বিভিন্ন ফ্যাক্টরের প্রয়োজনীয়তা নিয়ে প্রশ্ন আসতেই পারে। বিষয়টা সহজ – যেহেতু আমরা এরর সমানুপাতে ওয়েট অ্যাড জাস্ট করবো তাই এটাকে লাগছে। আবার সাথে আমরা ইনপুটকেও নিচ্ছি যাতে করে ইনপুট যদি 0 হয় তাহলে ওয়েট অ্যাডজাস্ট করবো না (ডান পাশে শুন্য আসবে)। আসলে ইনপুট শুন্য হলে অ্যাডজাস্ট করে লাভও নাই। ওই Edge এর মাণ এমনিতেই শূন্য আসবে। তিন নাম্বার ফ্যাক্টরটা গুরুত্বপূর্ণ যা কিনা একটি ভ্যালুর জন্য (এক্ষেত্রে আমাদের ক্যালকুলেট করা আউটপুট) প্রাপ্ত Sigmoid Curve এর Gradient (ঢাল)। সূত্রের ডান পাশে এই ফ্যাক্টর এর তাৎপর্য এরকম – Sigmoid Curve এর মাধ্যমে আমরা নিউরনের আউপুট হিসেবে করছি। যদি এই আউটপুটের মাণ খুব বেশি পজিটিভ বা খুব বেশি নেগেটিভ হয় তার মাণে নিউরনটি ট্রেনিং সেটের আউটপুট ভ্যালুর দিকে ঝুঁকতে খুবি আত্মবিশ্বাসী তথা ওয়েট অ্যাডজাস্ট করার খুব একটা দরকার নাই। অন্যদিকে আমরা Sigmoid Function এর গ্রাফ থেকে দেখতে পারি যে – ভ্যালু যত বেশি, এই Curve এর Gradient বা ঢাল তত কম। তাই এই ফ্যাক্টরকে ডান পাশে রাখলে এবং আউটপুট খুব বেশি পজিটিভ/নেগেটিভ আসলে এই ফ্যাক্টরের মাণও কম আসতেছে আর তাই বাম পাশে অ্যাডজাস্টের পরিমাণও কম হচ্ছে। বুদ্ধি 🙂
যাই হোক Sigmoid Curve এর Gradient বের করার সহজ সূত্র হচ্ছেঃ
অর্থাৎ Adjust weight by সমীকরণ দাড়ায়ঃ