টেনসরফ্লো, কেরাস এবং গভীর শিক্ষা, পিএইচডি ছাড়াই

1. সংক্ষিপ্ত বিবরণ

এই টিউটোরিয়ালটি Tensorflow 2.2 এর জন্য আপডেট করা হয়েছে!

74f6fbd758bf19e6.png সম্পর্কে

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

এই কোডল্যাবটি MNIST ডেটাসেট ব্যবহার করে, যা 60,000 লেবেলযুক্ত সংখ্যার একটি সংগ্রহ যা প্রায় দুই দশক ধরে পিএইচডিদের প্রজন্মকে ব্যস্ত রেখেছে। আপনি 100 লাইনেরও কম পাইথন / টেনসরফ্লো কোড দিয়ে সমস্যার সমাধান করতে পারবেন।

তুমি কি শিখবে

  • নিউরাল নেটওয়ার্ক কী এবং কীভাবে এটি প্রশিক্ষণ দেওয়া যায়
  • tf.keras ব্যবহার করে কিভাবে একটি মৌলিক ১-স্তর নিউরাল নেটওয়ার্ক তৈরি করবেন
  • কীভাবে আরও স্তর যোগ করবেন
  • শেখার হারের সময়সূচী কীভাবে সেট করবেন
  • কনভোলিউশনাল নিউরাল নেটওয়ার্ক কীভাবে তৈরি করবেন
  • নিয়মিতকরণ কৌশলগুলি কীভাবে ব্যবহার করবেন: ড্রপআউট, ব্যাচ স্বাভাবিকীকরণ
  • অতিরিক্ত ফিটিং কী?

তোমার যা লাগবে

শুধু একটি ব্রাউজার। এই কর্মশালাটি সম্পূর্ণরূপে Google Colaboratory দিয়ে চালানো যেতে পারে।

প্রতিক্রিয়া

এই ল্যাবে যদি কিছু ভুল দেখেন অথবা আপনার মনে হয় এটি উন্নত করা উচিত, তাহলে আমাদের জানান। আমরা GitHub সমস্যাগুলির [ প্রতিক্রিয়া লিঙ্ক ] মাধ্যমে প্রতিক্রিয়া পরিচালনা করি।

২. গুগল কোলাবোরেটরি দ্রুত শুরু

এই ল্যাবটি Google Colaboratory ব্যবহার করে এবং আপনার পক্ষ থেকে কোনও সেটআপের প্রয়োজন নেই। আপনি এটি একটি Chromebook থেকে চালাতে পারেন। অনুগ্রহ করে নীচের ফাইলটি খুলুন এবং Colab নোটবুকগুলির সাথে নিজেকে পরিচিত করার জন্য সেলগুলি কার্যকর করুন।

c3df49e90e5a654f.png সম্পর্কে Welcome to Colab.ipynb

নীচে অতিরিক্ত নির্দেশাবলী:

একটি GPU ব্যাকএন্ড নির্বাচন করুন

hsy7H7O5qJNvKcRnHRiZoyh0IznlzmrO60wR1B6pqtfdc8Ie7gLsXC0f670zsPzGsNy3Q AJuZefYv9CwTHmjiMyywG2pTpnMCE6Slkf3K1BeVmfpsYVw6omItm1ZneqdE31F8re-dA

Colab মেনুতে, Runtime > Change runtime type নির্বাচন করুন এবং তারপর GPU নির্বাচন করুন। প্রথম এক্সিকিউশনে রানটাইমের সাথে সংযোগ স্বয়ংক্রিয়ভাবে হয়ে যাবে, অথবা আপনি উপরের ডানদিকের কোণায় "Connect" বোতামটি ব্যবহার করতে পারেন।

নোটবুক সম্পাদন

evlBKSO15ImjocdEcsIo8unzEe6oDGYnKFe8CoHS_7QiP3sDbrs2jB6lbyitEtE7Gt_1UsCdU5dJA-_2IgBWh9ofYf4yVDE740PwJ6kiQwuXNOLkgktzzf0E_k5VN5mq29ZXI5wb7Q

একটি কক্ষে ক্লিক করে এবং Shift-ENTER ব্যবহার করে একের পর এক কক্ষ সম্পাদন করুন। আপনি Runtime > Run all ব্যবহার করে সম্পূর্ণ নোটবুকটিও চালাতে পারেন।

সুচিপত্র

OXeYYbtKdLCNnw_xovSMeMwSdD7CL_w25EfhnpRhhhO44bYp3zZpU72J5tKaSuo8wpas0GK5B2sTBlIMiFmdGxFRQ9NmwJ7JIRYy5XtpWKQCPdxQVRPy_0J_LshGIKjtw8P9fXozaA

সকল নোটবুকের একটি সূচিপত্র থাকে। আপনি বাম দিকের কালো তীর ব্যবহার করে এটি খুলতে পারেন।

লুকানো কোষ

GXTbXUO8xpPFKiGc6Q-cFwFHxHvOa105hHg3vk77EDpStyhU4AQMN3FYenbiBusHXUSk-yGXbRDcK-Cwx18XbDtyqB5WRr3_2jhnLvFxW8a7H_4cGvVDKrEMto_QxhfTeO0hwmrfng

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

৩. একটি নিউরাল নেটওয়ার্ক প্রশিক্ষণ দিন

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

c3df49e90e5a654f.png সম্পর্কে keras_01_mnist.ipynb

নোটবুকটি চালানোর সময়, ভিজ্যুয়ালাইজেশনের উপর মনোযোগ দিন। ব্যাখ্যার জন্য নীচে দেখুন।

প্রশিক্ষণ তথ্য

আমাদের হাতে লেখা সংখ্যার একটি ডেটাসেট আছে যা লেবেল করা হয়েছে যাতে আমরা জানতে পারি প্রতিটি ছবি কী প্রতিনিধিত্ব করে, অর্থাৎ 0 থেকে 9 এর মধ্যে একটি সংখ্যা। নোটবুকে, আপনি একটি অংশ দেখতে পাবেন:

ad83f98e56054737.png সম্পর্কে

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

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

প্রশিক্ষণ

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

3f7b405649301ea.png সম্পর্কে

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

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

X-অক্ষটি সমগ্র ডেটাসেটের "যুগ" বা পুনরাবৃত্তির সংখ্যা প্রতিনিধিত্ব করে।

ভবিষ্যদ্বাণী

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

c0699216ba0effdb.png সম্পর্কে

আপনি দেখতে পাচ্ছেন, এই প্রাথমিক মডেলটি খুব একটা ভালো নয় কিন্তু তবুও কিছু সংখ্যা সঠিকভাবে চিনতে পারে। এর চূড়ান্ত যাচাইকরণের নির্ভুলতা প্রায় 90% যা আমরা যে সরলীকৃত মডেল দিয়ে শুরু করছি তার জন্য খুব একটা খারাপ নয়, তবে এর অর্থ হল এটি 10,000 এর মধ্যে 1000টি যাচাইকরণ সংখ্যা মিস করে। এটি অনেক বেশি যা প্রদর্শিত হতে পারে, যার কারণে মনে হচ্ছে সমস্ত উত্তর ভুল (লাল)।

টেনসর

ডেটা ম্যাট্রিক্সে সংরক্ষণ করা হয়। একটি 28x28 পিক্সেল গ্রেস্কেল ছবি একটি 28x28 দ্বি-মাত্রিক ম্যাট্রিক্সের সাথে মানানসই। কিন্তু একটি রঙিন ছবির জন্য, আমাদের আরও মাত্রা প্রয়োজন। প্রতি পিক্সেলে 3টি রঙের মান রয়েছে (লাল, সবুজ, নীল), তাই মাত্রা সহ একটি ত্রিমাত্রিক টেবিল প্রয়োজন হবে [28, 28, 3]। এবং 128টি রঙিন ছবির একটি ব্যাচ সংরক্ষণ করতে, মাত্রা সহ একটি চার-মাত্রিক টেবিল প্রয়োজন [128, 28, 28, 3]।

এই বহুমাত্রিক টেবিলগুলিকে "টেনসর" বলা হয় এবং তাদের মাত্রার তালিকা হল তাদের "আকৃতি"

৪. [তথ্য]: নিউরাল নেটওয়ার্ক ১০১

সংক্ষেপে

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

জাদুকরী.png

স্তরের ক্রম হিসাবে নির্মিত মডেলগুলির জন্য Keras Sequential API অফার করে। উদাহরণস্বরূপ, তিনটি ঘন স্তর ব্যবহার করে একটি চিত্র শ্রেণিবদ্ধকারী Keras এ এভাবে লেখা যেতে পারে:

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[28, 28, 1]),
    tf.keras.layers.Dense(200, activation="relu"),
    tf.keras.layers.Dense(60, activation="relu"),
    tf.keras.layers.Dense(10, activation='softmax') # classifying into 10 classes
])

# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy']) # % of correct answers

# train the model
model.fit(dataset, ... )

688858c21e3beff2.png সম্পর্কে

একটি একক ঘন স্তর

MNIST ডেটাসেটে হাতে লেখা সংখ্যাগুলি হল 28x28 পিক্সেল গ্রেস্কেল ছবি। এগুলিকে শ্রেণীবদ্ধ করার সবচেয়ে সহজ পদ্ধতি হল 1-স্তর নিউরাল নেটওয়ার্কের জন্য ইনপুট হিসাবে 28x28=784 পিক্সেল ব্যবহার করা।

স্ক্রিন শট 2016-07-26 12.32.24.png

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

উপরের ছবিটি ১০টি আউটপুট নিউরন সহ একটি ১-স্তরের নিউরাল নেটওয়ার্কের প্রতিনিধিত্ব করে কারণ আমরা অঙ্কগুলিকে ১০টি শ্রেণীতে (০ থেকে ৯) শ্রেণীবদ্ধ করতে চাই।

ম্যাট্রিক্স গুণনের মাধ্যমে

এখানে একটি নিউরাল নেটওয়ার্ক স্তর, যা চিত্রের সংগ্রহ প্রক্রিয়াকরণ করে, একটি ম্যাট্রিক্স গুণ দ্বারা কীভাবে প্রতিনিধিত্ব করা যেতে পারে:

অনুসরণ

ওয়েট ম্যাট্রিক্স W-এর ওজনের প্রথম কলাম ব্যবহার করে, আমরা প্রথম ছবির সমস্ত পিক্সেলের ওজনযুক্ত যোগফল গণনা করি। এই যোগফলটি প্রথম নিউরনের সাথে মিলে যায়। ওজনের দ্বিতীয় কলাম ব্যবহার করে, আমরা দ্বিতীয় নিউরনের জন্য একই কাজ করি এবং দশম নিউরন পর্যন্তও করি। এরপর আমরা বাকি ৯৯টি ছবির জন্যও একই কাজ করতে পারি। যদি আমরা X-কে আমাদের ১০০টি ছবি ধারণকারী ম্যাট্রিক্স বলি, তাহলে ১০০টি ছবির উপর গণনা করা আমাদের ১০টি নিউরনের জন্য সমস্ত ওজনযুক্ত যোগফল কেবল XW, একটি ম্যাট্রিক্স গুণ।

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

অবশেষে আমরা একটি অ্যাক্টিভেশন ফাংশন প্রয়োগ করি, উদাহরণস্বরূপ "সফটম্যাক্স" (নীচে ব্যাখ্যা করা হয়েছে) এবং ১০০টি ছবিতে প্রয়োগ করা ১-স্তরের নিউরাল নেটওয়ার্ক বর্ণনাকারী সূত্রটি পাই:

স্ক্রিন শট ২০১৬-০৭-২৬ ১৬.০২.৩৬.png

কেরাসে

কেরাসের মতো উচ্চ-স্তরের নিউরাল নেটওয়ার্ক লাইব্রেরিগুলির সাথে, আমাদের এই সূত্রটি বাস্তবায়নের প্রয়োজন হবে না। তবে, এটি বোঝা গুরুত্বপূর্ণ যে একটি নিউরাল নেটওয়ার্ক স্তর কেবল গুণ এবং যোগের একটি গুচ্ছ। কেরাসে, একটি ঘন স্তর লেখা হবে:

tf.keras.layers.Dense(10, activation='softmax')

গভীরে যাও

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

fba0638cc213a29.png

নিউরনের সংখ্যা ছাড়াও, একমাত্র পার্থক্য হবে সক্রিয়করণ ফাংশনের পছন্দ।

অ্যাক্টিভেশন ফাংশন: রিলু, সফটম্যাক্স এবং সিগময়েড

আপনি সাধারণত শেষ স্তরটি ছাড়া সকল স্তরের জন্য "relu" অ্যাক্টিভেশন ফাংশন ব্যবহার করবেন। একটি শ্রেণিবদ্ধকরণে শেষ স্তরটি "softmax" অ্যাক্টিভেশন ব্যবহার করবে।

644f4213a4ee70e5.png সম্পর্কে

আবার, একটি "নিউরন" তার সমস্ত ইনপুটের একটি ওজনযুক্ত যোগফল গণনা করে, "বায়াস" নামক একটি মান যোগ করে এবং অ্যাক্টিভেশন ফাংশনের মাধ্যমে ফলাফলটি ফিড করে।

রেক্টিফাইড লিনিয়ার ইউনিটের জন্য সবচেয়ে জনপ্রিয় অ্যাক্টিভেশন ফাংশনটিকে "RELU" বলা হয়। এটি একটি খুব সহজ ফাংশন যা আপনি উপরের গ্রাফে দেখতে পাচ্ছেন।

নিউরাল নেটওয়ার্কে ঐতিহ্যবাহী অ্যাক্টিভেশন ফাংশন ছিল "সিগময়েড" কিন্তু "রেলু"-এর প্রায় সর্বত্রই উন্নত কনভারজেন্স বৈশিষ্ট্য রয়েছে বলে প্রমাণিত হয়েছে এবং এখন এটি পছন্দনীয়।

41fc82288c4aff5d.png সম্পর্কে

শ্রেণীবিভাগের জন্য সফটম্যাক্স অ্যাক্টিভেশন

আমাদের নিউরাল নেটওয়ার্কের শেষ স্তরে ১০টি নিউরন রয়েছে কারণ আমরা হাতে লেখা অঙ্কগুলিকে ১০টি শ্রেণীতে (০,..৯) শ্রেণীবদ্ধ করতে চাই। এটি ০ থেকে ১ এর মধ্যে ১০টি সংখ্যা আউটপুট করবে যা এই অঙ্কটি ০, ১, ২ ইত্যাদি হওয়ার সম্ভাবনাকে প্রতিনিধিত্ব করবে। এর জন্য, শেষ স্তরে, আমরা "softmax" নামক একটি অ্যাক্টিভেশন ফাংশন ব্যবহার করব।

একটি ভেক্টরের উপর সফটম্যাক্স প্রয়োগ করা হয় প্রতিটি উপাদানের সূচক গ্রহণ করে এবং তারপর ভেক্টরটিকে স্বাভাবিক করে তোলার মাধ্যমে, সাধারণত এটিকে তার "L1" আদর্শ (অর্থাৎ পরম মানের যোগফল) দিয়ে ভাগ করে যাতে স্বাভাবিক মানগুলি 1 পর্যন্ত যোগ হয় এবং সম্ভাব্যতা হিসাবে ব্যাখ্যা করা যায়।

অ্যাক্টিভেশনের আগে শেষ স্তরের আউটপুটকে কখনও কখনও "logits" বলা হয়। যদি এই ভেক্টরটি L = [L0, L1, L2, L3, L4, L5, L6, L7, L8, L9] হয়, তাহলে:

ef0d98c0952c262d.png সম্পর্কেd51252f75894479e.gif সম্পর্কে

ক্রস-এনট্রপি ক্ষতি

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

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

6dbba1bce3cadc36.png সম্পর্কে

গ্রেডিয়েন্ট ডিসেন্ট

নিউরাল নেটওয়ার্ককে "প্রশিক্ষণ" দেওয়ার অর্থ আসলে ওজন এবং পক্ষপাত সামঞ্জস্য করার জন্য প্রশিক্ষণ চিত্র এবং লেবেল ব্যবহার করা যাতে ক্রস-এনট্রপি লস ফাংশন কমানো যায়। এটি কীভাবে কাজ করে তা এখানে।

ক্রস-এনট্রপি হল ওজন, পক্ষপাত, প্রশিক্ষণ চিত্রের পিক্সেল এবং এর পরিচিত শ্রেণীর একটি ফাংশন।

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

গ্রেডিয়েন্ট ডিসেন্ট২.png

মিনি-ব্যাচিং এবং মোমেন্টাম

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

এই কৌশল, যাকে কখনও কখনও "স্টোকাস্টিক গ্রেডিয়েন্ট ডিসেন্ট" বলা হয়, এর আরেকটি, আরও বাস্তবসম্মত সুবিধা রয়েছে: ব্যাচগুলির সাথে কাজ করার অর্থ বৃহত্তর ম্যাট্রিক্সগুলির সাথে কাজ করা এবং এগুলি সাধারণত GPU এবং TPU গুলিতে অপ্টিমাইজ করা সহজ।

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

cc544924671fa208.png সম্পর্কে

চিত্র: একটি স্যাডল পয়েন্ট। গ্রেডিয়েন্ট 0 কিন্তু সব দিকে এটি সর্বনিম্ন নয়। (ছবি অ্যাট্রিবিউশন উইকিমিডিয়া: নিকোগুয়ারো - নিজস্ব কাজ, CC BY 3.0 )

সমাধান হল অপ্টিমাইজেশন অ্যালগরিদমে কিছু গতি যোগ করা যাতে এটি থেমে না গিয়ে স্যাডল পয়েন্ট অতিক্রম করতে পারে।

শব্দকোষ

ব্যাচ বা মিনি-ব্যাচ : প্রশিক্ষণ সর্বদা প্রশিক্ষণ ডেটা এবং লেবেলের ব্যাচগুলিতে সঞ্চালিত হয়। এটি করলে অ্যালগরিদম একত্রিত হতে সাহায্য করে। "ব্যাচ" মাত্রা সাধারণত ডেটা টেনসরের প্রথম মাত্রা। উদাহরণস্বরূপ, আকৃতির একটি টেনসর [100, 192, 192, 3] তে 192x192 পিক্সেলের 100টি ছবি থাকে যার প্রতি পিক্সেল (RGB) তিনটি মান থাকে।

ক্রস-এনট্রপি লস : একটি বিশেষ লস ফাংশন যা প্রায়শই শ্রেণিবদ্ধকরণে ব্যবহৃত হয়।

ঘন স্তর : নিউরনের একটি স্তর যেখানে প্রতিটি নিউরন পূর্ববর্তী স্তরের সমস্ত নিউরনের সাথে সংযুক্ত থাকে।

বৈশিষ্ট্য : একটি নিউরাল নেটওয়ার্কের ইনপুটগুলিকে কখনও কখনও "বৈশিষ্ট্য" বলা হয়। একটি ডেটাসেটের কোন অংশগুলি (অথবা অংশগুলির সংমিশ্রণ) একটি নিউরাল নেটওয়ার্কে ফিড করা উচিত তা নির্ধারণ করার শিল্পকে "বৈশিষ্ট্য প্রকৌশল" বলা হয়।

লেবেল : "ক্লাস" বা তত্ত্বাবধানে থাকা শ্রেণীবিভাগ সমস্যার সঠিক উত্তরের আরেকটি নাম

শেখার হার : প্রশিক্ষণ লুপের প্রতিটি পুনরাবৃত্তিতে ওজন এবং পক্ষপাত আপডেট করা গ্রেডিয়েন্টের ভগ্নাংশ।

লগিট : অ্যাক্টিভেশন ফাংশন প্রয়োগের আগে নিউরনের একটি স্তরের আউটপুটগুলিকে "লগিট" বলা হয়। এই শব্দটি "লজিস্টিক ফাংশন" অর্থাৎ "সিগময়েড ফাংশন" থেকে এসেছে যা আগে সবচেয়ে জনপ্রিয় অ্যাক্টিভেশন ফাংশন ছিল। "লজিস্টিক ফাংশনের আগে নিউরন আউটপুট" কে সংক্ষিপ্ত করে "লগিট" করা হয়েছিল।

ক্ষতি : সঠিক উত্তরের সাথে নিউরাল নেটওয়ার্ক আউটপুট তুলনা করার ত্রুটি ফাংশন

নিউরন : এর ইনপুটগুলির ওজনযুক্ত যোগফল গণনা করে, একটি পক্ষপাত যোগ করে এবং একটি অ্যাক্টিভেশন ফাংশনের মাধ্যমে ফলাফল ফিড করে।

এক-গরম এনকোডিং : ৫ এর মধ্যে ৩য় শ্রেণী ৫টি উপাদানের ভেক্টর হিসেবে এনকোড করা হয়েছে, ৩য়টি ছাড়া বাকি সকল শূন্য, যা ১।

relu : সংশোধিত রৈখিক একক। নিউরনের জন্য একটি জনপ্রিয় সক্রিয়করণ ফাংশন।

সিগময়েড : আরেকটি অ্যাক্টিভেশন ফাংশন যা আগে জনপ্রিয় ছিল এবং এখনও বিশেষ ক্ষেত্রে কার্যকর।

সফটম্যাক্স : একটি বিশেষ অ্যাক্টিভেশন ফাংশন যা একটি ভেক্টরের উপর কাজ করে, বৃহত্তম উপাদান এবং অন্যান্য সকল উপাদানের মধ্যে পার্থক্য বৃদ্ধি করে এবং ভেক্টরকে 1 এর যোগফলে স্বাভাবিক করে তোলে যাতে এটি সম্ভাব্যতার ভেক্টর হিসাবে ব্যাখ্যা করা যায়। শ্রেণিবদ্ধকরণের শেষ ধাপ হিসেবে ব্যবহৃত হয়।

টেনসর : একটি "টেনসর" একটি ম্যাট্রিক্সের মতো কিন্তু এর মাত্রার একটি নির্দিষ্ট সংখ্যক থাকে। একটি 1-মাত্রিক টেনসর হল একটি ভেক্টর। একটি 2-মাত্রিক টেনসর হল একটি ম্যাট্রিক্স। এবং তারপরে আপনার 3, 4, 5 বা তার বেশি মাত্রার টেনসর থাকতে পারে।

৫. আসুন কোডে ঝাঁপিয়ে পড়ি।

আবার পড়াশোনার খাতায় ফিরে আসি এবং এবার, কোডটি পড়ি।

c3df49e90e5a654f.png সম্পর্কে keras_01_mnist.ipynb

এই নোটবুকের সমস্ত ঘর ঘুরে দেখা যাক।

"পরামিতি" ঘর

ব্যাচের আকার, প্রশিক্ষণ পর্বের সংখ্যা এবং ডেটা ফাইলের অবস্থান এখানে সংজ্ঞায়িত করা হয়েছে। ডেটা ফাইলগুলি একটি Google ক্লাউড স্টোরেজ (GCS) বাকেটে হোস্ট করা হয় যার কারণে তাদের ঠিকানা gs:// দিয়ে শুরু হয়।

"আমদানি" সেল

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

" ভিজ্যুয়ালাইজেশন ইউটিলিটি [আমাকে চালান]****" সেল

এই ঘরে অরুচিকর ভিজ্যুয়ালাইজেশন কোড রয়েছে। এটি ডিফল্টভাবে ধসে পড়ে তবে আপনি এটি খুলতে পারেন এবং সময় পেলে কোডটি দেখতে পারেন এটিতে ডাবল-ক্লিক করে।

" tf.data.Dataset: ফাইলগুলি বিশ্লেষণ করুন এবং প্রশিক্ষণ এবং বৈধতা ডেটাসেট প্রস্তুত করুন " সেল

এই সেলটি ডেটা ফাইল থেকে MNIST ডেটাসেট লোড করার জন্য tf.data.Dataset API ব্যবহার করেছে। এই সেলটিতে খুব বেশি সময় ব্যয় করার প্রয়োজন নেই। যদি আপনি tf.data.Dataset API সম্পর্কে আগ্রহী হন, তাহলে এখানে একটি টিউটোরিয়াল রয়েছে যা এটি ব্যাখ্যা করে: TPU-গতির ডেটা পাইপলাইন । আপাতত, মূল বিষয়গুলি হল:

MNIST ডেটাসেট থেকে প্রাপ্ত ছবি এবং লেবেল (সঠিক উত্তর) 4টি ফাইলে নির্দিষ্ট দৈর্ঘ্যের রেকর্ডে সংরক্ষণ করা হয়। ডেডিকেটেড ফিক্সড রেকর্ড ফাংশন ব্যবহার করে ফাইলগুলি লোড করা যেতে পারে:

imagedataset = tf.data.FixedLengthRecordDataset(image_filename, 28*28, header_bytes=16)

আমাদের কাছে এখন ইমেজ বাইটের একটি ডেটাসেট আছে। সেগুলোকে ইমেজে ডিকোড করতে হবে। আমরা এটি করার জন্য একটি ফাংশন সংজ্ঞায়িত করি। ইমেজটি কম্প্রেস করা হয় না তাই ফাংশনটির কোনও কিছু ডিকোড করার প্রয়োজন হয় না ( decode_raw মূলত কিছুই করে না)। এরপর ইমেজটি 0 এবং 1 এর মধ্যে ফ্লোটিং পয়েন্ট মানগুলিতে রূপান্তরিত হয়। আমরা এখানে এটিকে 2D ইমেজ হিসাবে পুনরায় আকার দিতে পারি কিন্তু আসলে আমরা এটিকে 28*28 আকারের পিক্সেলের একটি সমতল অ্যারে হিসাবে রাখি কারণ আমাদের প্রাথমিক ঘন স্তরটি এটাই প্রত্যাশা করে।

def read_image(tf_bytestring):
    image = tf.io.decode_raw(tf_bytestring, tf.uint8)
    image = tf.cast(image, tf.float32)/256.0
    image = tf.reshape(image, [28*28])
    return image

আমরা .map ব্যবহার করে ডেটাসেটে এই ফাংশনটি প্রয়োগ করি এবং চিত্রগুলির একটি ডেটাসেট পাই:

imagedataset = imagedataset.map(read_image, num_parallel_calls=16)

আমরা লেবেলের জন্য একই ধরণের পঠন এবং ডিকোডিং করি এবং আমরা ছবি এবং লেবেল একসাথে .zip :

dataset = tf.data.Dataset.zip((imagedataset, labelsdataset))

আমাদের কাছে এখন জোড়ার একটি ডেটাসেট আছে (ছবি, লেবেল)। আমাদের মডেল এটাই আশা করে। আমরা এখনও প্রশিক্ষণ ফাংশনে এটি ব্যবহার করার জন্য পুরোপুরি প্রস্তুত নই:

dataset = dataset.cache()
dataset = dataset.shuffle(5000, reshuffle_each_iteration=True)
dataset = dataset.repeat()
dataset = dataset.batch(batch_size)
dataset = dataset.prefetch(tf.data.experimental.AUTOTUNE)

tf.data.Dataset API-তে ডেটাসেট প্রস্তুত করার জন্য প্রয়োজনীয় সকল ইউটিলিটি ফাংশন রয়েছে:

.cache RAM-তে ডেটাসেট ক্যাশে করে। এটি একটি ছোট ডেটাসেট তাই এটি কাজ করবে। .shuffle 5000 টি উপাদানের একটি বাফার দিয়ে এটিকে শাফেল করে। প্রশিক্ষণের ডেটা ভালভাবে শাফেল করা গুরুত্বপূর্ণ। .repeat পুনরাবৃত্তি করুন। আমরা এটিতে একাধিকবার প্রশিক্ষণ দেব (একাধিক যুগ)। .batch একাধিক ছবি এবং লেবেলকে একসাথে একটি মিনি-ব্যাচে টেনে আনে। অবশেষে, .prefetch GPU-তে বর্তমান ব্যাচটি প্রশিক্ষণের সময় পরবর্তী ব্যাচ প্রস্তুত করতে CPU ব্যবহার করতে পারে।

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

সেল "কেরাস মডেল"

আমাদের সকল মডেলই হবে স্তরের সোজা ক্রম, তাই আমরা tf.keras.Sequential স্টাইল ব্যবহার করে এগুলি তৈরি করতে পারি। প্রাথমিকভাবে এখানে, এটি একটি একক ঘন স্তর। এতে ১০টি নিউরন রয়েছে কারণ আমরা হাতে লেখা অঙ্কগুলিকে ১০টি শ্রেণীতে শ্রেণীবদ্ধ করছি। এটি "সফটম্যাক্স" অ্যাক্টিভেশন ব্যবহার করে কারণ এটি একটি শ্রেণিবিন্যাসকারীর শেষ স্তর।

একটি Keras মডেলের তার ইনপুটগুলির আকৃতিও জানা প্রয়োজন। tf.keras.layers.Input ব্যবহার করে এটি সংজ্ঞায়িত করা যেতে পারে। এখানে, ইনপুট ভেক্টরগুলি হল 28*28 দৈর্ঘ্যের পিক্সেল মানের সমতল ভেক্টর।

model = tf.keras.Sequential(
  [
    tf.keras.layers.Input(shape=(28*28,)),
    tf.keras.layers.Dense(10, activation='softmax')
  ])

model.compile(optimizer='sgd',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# print model layers
model.summary()

# utility callback that displays training curves
plot_training = PlotTraining(sample_rate=10, zoom=1)

মডেলটি কেরাসে model.compile ফাংশন ব্যবহার করে কনফিগার করা হয়। এখানে আমরা বেসিক অপ্টিমাইজার 'sgd' (Stochastic Gradient Descent) ব্যবহার করি। একটি ক্লাসিফিকেশন মডেলের জন্য একটি ক্রস-এনট্রপি লস ফাংশন প্রয়োজন, যা কেরাসে 'categorical_crossentropy' নামে পরিচিত। অবশেষে, আমরা মডেলটিকে 'accuracy' মেট্রিক গণনা করতে বলি, যা সঠিকভাবে শ্রেণীবদ্ধ চিত্রের শতাংশ।

Keras খুব সুন্দর model.summary() ইউটিলিটি অফার করে যা আপনার তৈরি মডেলের বিশদ বিবরণ প্রিন্ট করে। আপনার দয়ালু প্রশিক্ষক PlotTraining ইউটিলিটি ("ভিজ্যুয়ালাইজেশন ইউটিলিটি" সেলে সংজ্ঞায়িত) যোগ করেছেন যা প্রশিক্ষণের সময় বিভিন্ন প্রশিক্ষণ কার্ভ প্রদর্শন করবে।

"মডেলটি প্রশিক্ষণ দিন এবং যাচাই করুন" সেল

এখানেই প্রশিক্ষণ অনুষ্ঠিত হয়, model.fit কল করে এবং প্রশিক্ষণ এবং বৈধতা ডেটাসেট উভয়ই পাস করে। ডিফল্টরূপে, Keras প্রতিটি যুগের শেষে বৈধতার একটি রাউন্ড চালায়।

model.fit(training_dataset, steps_per_epoch=steps_per_epoch, epochs=EPOCHS,
          validation_data=validation_dataset, validation_steps=1,
          callbacks=[plot_training])

কেরাসে, কলব্যাক ব্যবহার করে প্রশিক্ষণের সময় কাস্টম আচরণ যোগ করা সম্ভব। এই কর্মশালার জন্য গতিশীলভাবে আপডেট করা প্রশিক্ষণ পরিকল্পনাটি এভাবেই বাস্তবায়িত হয়েছিল।

"পূর্বাভাস কল্পনা করুন" ঘর

মডেলটি প্রশিক্ষিত হয়ে গেলে, আমরা model.predict() কল করে এটি থেকে ভবিষ্যদ্বাণী পেতে পারি:

probabilities = model.predict(font_digits, steps=1)
predicted_labels = np.argmax(probabilities, axis=1)

এখানে আমরা স্থানীয় ফন্ট থেকে রেন্ডার করা মুদ্রিত সংখ্যার একটি সেট প্রস্তুত করেছি, একটি পরীক্ষা হিসেবে। মনে রাখবেন যে নিউরাল নেটওয়ার্ক তার চূড়ান্ত "সফটম্যাক্স" থেকে 10টি সম্ভাব্যতার একটি ভেক্টর ফেরত দেয়। লেবেলটি পেতে, আমাদের খুঁজে বের করতে হবে কোন সম্ভাব্যতা সবচেয়ে বেশি। numpy লাইব্রেরি থেকে np.argmax এটি করে।

axis=1 প্যারামিটার কেন প্রয়োজন তা বোঝার জন্য, অনুগ্রহ করে মনে রাখবেন যে আমরা ১২৮টি ছবির একটি ব্যাচ প্রক্রিয়া করেছি এবং সেইজন্য মডেলটি ১২৮টি সম্ভাব্যতার ভেক্টর প্রদান করে। আউটপুট টেনসরের আকৃতি হল [128, 10]। আমরা প্রতিটি ছবির জন্য প্রদত্ত ১০টি সম্ভাব্যতার উপর ভিত্তি করে argmax গণনা করছি, অর্থাৎ axis=1 (প্রথম অক্ষ হল 0)।

এই সহজ মডেলটি ইতিমধ্যেই 90% সংখ্যা চিনতে পারে। খারাপ না, তবে এখন আপনি এটি উল্লেখযোগ্যভাবে উন্নত করবেন।

396c54ef66fad27f.png সম্পর্কে

৬. স্তর যোগ করা

godeep.png সম্পর্কে

স্বীকৃতির নির্ভুলতা উন্নত করার জন্য আমরা নিউরাল নেটওয়ার্কে আরও স্তর যুক্ত করব।

স্ক্রিন শট 2016-07-27 15.36.55.png

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

41fc82288c4aff5d.png সম্পর্কে

উদাহরণস্বরূপ, আপনার মডেলটি দেখতে এরকম হতে পারে (কমা ভুলে যাবেন না, tf.keras.Sequential কমা দ্বারা পৃথক স্তরের একটি তালিকা নেয়):

model = tf.keras.Sequential(
  [
      tf.keras.layers.Input(shape=(28*28,)),
      tf.keras.layers.Dense(200, activation='sigmoid'),
      tf.keras.layers.Dense(60, activation='sigmoid'),
      tf.keras.layers.Dense(10, activation='softmax')
  ])

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

5236f91ba6e07d85.png সম্পর্কে

মনে হচ্ছে ক্ষতিটাও মাথাচাড়া দিয়ে উঠেছে। কিছু একটা ঠিক নেই।

৭. গভীর নেটওয়ার্কের জন্য বিশেষ যত্ন

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

দেখা যাচ্ছে যে অনেক স্তর বিশিষ্ট গভীর স্নায়ু নেটওয়ার্ক (আজ ২০, ৫০, এমনকি ১০০টিও) সত্যিই ভালোভাবে কাজ করতে পারে, যদি তাদের একত্রিত করার জন্য কয়েকটি গাণিতিক নোংরা কৌশল ব্যবহার করা হয়। এই সহজ কৌশলগুলির আবিষ্কার ২০১০-এর দশকে গভীর শিক্ষার নবজাগরণের অন্যতম কারণ।

RELU সক্রিয়করণ

relu.png সম্পর্কে

সিগময়েড অ্যাক্টিভেশন ফাংশনটি আসলে ডিপ নেটওয়ার্কগুলিতে বেশ সমস্যাযুক্ত। এটি 0 এবং 1 এর মধ্যে সমস্ত মানকে স্কোয়াশ করে এবং যখন আপনি বারবার এটি করেন, তখন নিউরন আউটপুট এবং তাদের গ্রেডিয়েন্ট সম্পূর্ণরূপে অদৃশ্য হয়ে যেতে পারে। ঐতিহাসিক কারণে এটি উল্লেখ করা হয়েছিল, তবে আধুনিক নেটওয়ার্কগুলি RELU (রেক্টিফাইড লিনিয়ার ইউনিট) ব্যবহার করে যা দেখতে এইরকম:

1abce89f7143a69c.png সম্পর্কে

অন্যদিকে, relu-এর একটি ডেরিভেটিভ 1 আছে, অন্তত ডান দিকে। RELU সক্রিয়করণের মাধ্যমে, কিছু নিউরন থেকে আসা গ্রেডিয়েন্ট শূন্য হলেও, অন্যরা সর্বদা একটি স্পষ্ট অ-শূন্য গ্রেডিয়েন্ট প্রদান করবে এবং প্রশিক্ষণ একটি ভাল গতিতে চলতে পারে।

আরও ভালো অপ্টিমাইজার

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

এলোমেলোভাবে শুরু করা

প্রশিক্ষণের আগে ওজনের পক্ষপাত শুরু করার শিল্প নিজেই গবেষণার একটি ক্ষেত্র, এই বিষয়ে অসংখ্য গবেষণাপত্র প্রকাশিত হয়েছে। আপনি এখানে কেরাসে উপলব্ধ সমস্ত ইনিশিয়ালাইজারগুলি দেখতে পারেন। সৌভাগ্যবশত, কেরাস ডিফল্টভাবে সঠিক কাজটি করে এবং 'glorot_uniform' ইনিশিয়ালাইজার ব্যবহার করে যা প্রায় সব ক্ষেত্রেই সেরা।

তোমার করার কিছু নেই, কারণ কেরাস ইতিমধ্যেই সঠিক কাজটি করে।

নান ???

ক্রস-এনট্রপি সূত্রে একটি লগারিদম জড়িত এবং log(0) একটি সংখ্যা নয় (NaN, যদি আপনি চান তাহলে একটি সংখ্যাসূচক ক্র্যাশ)। ক্রস-এনট্রপিতে ইনপুট কি 0 হতে পারে? ইনপুটটি সফটম্যাক্স থেকে আসে যা মূলত একটি সূচকীয় এবং সূচকীয় কখনও শূন্য হয় না। তাই আমরা নিরাপদ!

সত্যিই? গণিতের সুন্দর জগতে আমরা নিরাপদ থাকতাম, কিন্তু কম্পিউটার জগতে, float32 ফর্ম্যাটে উপস্থাপিত exp(-150), যতই শূন্য হোক না কেন এবং ক্রস-এনট্রপি ক্র্যাশ করে।

সৌভাগ্যবশত, এখানেও আপনার করার কিছু নেই, যেহেতু কেরাস এটির যত্ন নেয় এবং সংখ্যাসূচক স্থিতিশীলতা নিশ্চিত করতে এবং ভয়ঙ্কর NaN গুলি এড়াতে বিশেষভাবে সতর্কতার সাথে সফটম্যাক্সের পরে ক্রস-এনট্রপি গণনা করে।

সাফল্য?

e1521c9dd936d9bc.png

তোমার এখন ৯৭% নির্ভুলতা অর্জন করা উচিত। এই কর্মশালায় লক্ষ্য হল ৯৯% এর উপরে উল্লেখযোগ্যভাবে পৌঁছানো, তাই চলুন এগিয়ে যাই।

যদি আপনি আটকে থাকেন, তাহলে এই মুহূর্তে সমাধান এখানে:

c3df49e90e5a654f.png সম্পর্কে keras_02_mnist_dense.ipynb

৮. শেখার হারের ক্ষয়

হয়তো আমরা দ্রুত প্রশিক্ষণের চেষ্টা করতে পারি? অ্যাডাম অপ্টিমাইজারে ডিফল্ট শেখার হার 0.001। আসুন এটি বাড়ানোর চেষ্টা করি।

দ্রুত যাওয়াটা খুব একটা কাজে আসবে বলে মনে হচ্ছে না, আর এই সব গোলমালের কারণ কী?

d4fd66346d7c480e.png সম্পর্কে

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

ধীর গতিতে.png

ভালো সমাধান হলো দ্রুত শুরু করা এবং শেখার হার দ্রুত হ্রাস করা। কেরাসে, আপনি tf.keras.callbacks.LearningRateScheduler কলব্যাক দিয়ে এটি করতে পারেন।

কপি-পেস্ট করার জন্য দরকারী কোড:

# lr decay function
def lr_decay(epoch):
  return 0.01 * math.pow(0.6, epoch)

# lr schedule callback
lr_decay_callback = tf.keras.callbacks.LearningRateScheduler(lr_decay, verbose=True)

# important to see what you are doing
plot_learning_rate(lr_decay, EPOCHS)

আপনার তৈরি করা lr_decay_callback ব্যবহার করতে ভুলবেন না। model.fit এর কলব্যাকের তালিকায় এটি যোগ করুন:

model.fit(...,  callbacks=[plot_training, lr_decay_callback])

এই ছোট্ট পরিবর্তনের প্রভাব অসাধারণ। আপনি দেখতে পাচ্ছেন যে বেশিরভাগ শব্দ চলে গেছে এবং পরীক্ষার নির্ভুলতা এখন টেকসইভাবে ৯৮% এর উপরে।

8c1ae90976c4a0c1.png সম্পর্কে

৯. ড্রপআউট, ওভারফিটিং

মডেলটি এখন সুন্দরভাবে একত্রিত হচ্ছে বলে মনে হচ্ছে। আসুন আরও গভীরে যাওয়ার চেষ্টা করি।

এটা কি সাহায্য করে?

e36c09a3088104c6.png

Not really, the accuracy is still stuck at 98% and look at the validation loss. It is going up! The learning algorithm works on training data only and optimises the training loss accordingly. It never sees validation data so it is not surprising that after a while its work no longer has an effect on the validation loss which stops dropping and sometimes even bounces back up.

This does not immediately affect the real-world recognition capabilities of your model, but it will prevent you from running many iterations and is generally a sign that the training is no longer having a positive effect.

dropout.png

This disconnect is usually called "overfitting" and when you see it, you can try to apply a regularisation technique called "dropout". The dropout technique shoots random neurons at each training iteration.

এটা কি কাজ করেছে?

43fd33801264743f.png

Noise reappears (unsurprisingly given how dropout works). The validation loss does not seem to be creeping up anymore, but it is higher overall than without dropout. And the validation accuracy went down a bit. This is a fairly disappointing result.

It looks like dropout was not the correct solution, or maybe "overfitting" is a more complex concept and some of its causes are not amenable to a "dropout" fix?

What is "overfitting"? Overfitting happens when a neural network learns "badly", in a way that works for the training examples but not so well on real-world data. There are regularisation techniques like dropout that can force it to learn in a better way but overfitting also has deeper roots.

overfitting.png

Basic overfitting happens when a neural network has too many degrees of freedom for the problem at hand. Imagine we have so many neurons that the network can store all of our training images in them and then recognise them by pattern matching. It would fail on real-world data completely. A neural network must be somewhat constrained so that it is forced to generalise what it learns during training.

If you have very little training data, even a small network can learn it by heart and you will see "overfitting". Generally speaking, you always need lots of data to train neural networks.

Finally, if you have done everything by the book, experimented with different sizes of network to make sure its degrees of freedom are constrained, applied dropout, and trained on lots of data you might still be stuck at a performance level that nothing seems to be able to improve. This means that your neural network, in its present shape, is not capable of extracting more information from your data, as in our case here.

Remember how we are using our images, flattened into a single vector? That was a really bad idea. Handwritten digits are made of shapes and we discarded the shape information when we flattened the pixels. However, there is a type of neural network that can take advantage of shape information: convolutional networks. Let us try them.

If you are stuck, here is the solution at this point:

c3df49e90e5a654f.png keras_03_mnist_dense_lrdecay_dropout.ipynb

10. [INFO] convolutional networks

সংক্ষেপে

If all the terms in bold in the next paragraph are already known to you, you can move to the next exercise. If your are just starting out with convolutional neural networks, please read on.

convolutional.gif

Illustration: filtering an image with two successive filters made of 4x4x3=48 learnable weights each.

This is how a simple convolutional neural network looks in Keras:

model = tf.keras.Sequential([
    tf.keras.layers.Reshape(input_shape=(28*28,), target_shape=(28, 28, 1)),
    tf.keras.layers.Conv2D(kernel_size=3, filters=12, activation='relu'),
    tf.keras.layers.Conv2D(kernel_size=6, filters=24, strides=2, activation='relu'),
    tf.keras.layers.Conv2D(kernel_size=6, filters=32, strides=2, activation='relu'),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(10, activation='softmax')
])

688858c21e3beff2.png

In a layer of a convolutional network, one "neuron" does a weighted sum of the pixels just above it, across a small region of the image only. It adds a bias and feeds the sum through an activation function, just as a neuron in a regular dense layer would. This operation is then repeated across the entire image using the same weights. Remember that in dense layers, each neuron had its own weights. Here, a single "patch" of weights slides across the image in both directions (a "convolution"). The output has as many values as there are pixels in the image (some padding is necessary at the edges though). It is a filtering operation. In the illustration above, it uses a filter of 4x4x3=48 weights.

However, 48 weights will not be enough. To add more degrees of freedom, we repeat the same operation with a new set of weights. This produces a new set of filter outputs. Let's call it a "channel" of outputs by analogy with the R,G,B channels in the input image.

Screen Shot 2016-07-29 at 16.02.37.png

The two (or more) sets of weights can be summed up as one tensor by adding a new dimension. This gives us the generic shape of the weights tensor for a convolutional layer. Since the number of input and output channels are parameters, we can start stacking and chaining convolutional layers.

d1b557707bcd1cb9.png

Illustration: a convolutional neural network transforms "cubes" of data into other "cubes" of data.

Strided convolutions, max pooling

By performing the convolutions with a stride of 2 or 3, we can also shrink the resulting data cube in its horizontal dimensions. There are two common ways of doing this:

  • Strided convolution: a sliding filter as above but with a stride >1
  • Max pooling: a sliding window applying the MAX operation (typically on 2x2 patches, repeated every 2 pixels)

2b2d4263bb8470b.gif

Illustration: sliding the computing window by 3 pixels results in fewer output values. Strided convolutions or max pooling (max on a 2x2 window sliding by a stride of 2) are a way of shrinking the data cube in the horizontal dimensions.

The final layer

After the last convolutional layer, the data is in the form of a "cube". There are two ways of feeding it through the final dense layer.

The first one is to flatten the cube of data into a vector and then feed it to the softmax layer. Sometimes, you can even add a dense layer before the softmax layer. This tends to be expensive in terms of the number of weights. A dense layer at the end of a convolutional network can contain more than half the weights of the whole neural network.

Instead of using an expensive dense layer, we can also split the incoming data "cube" into as many parts as we have classes, average their values and feed these through a softmax activation function. This way of building the classification head costs 0 weights. In Keras, there is a layer for this: tf.keras.layers.GlobalAveragePooling2D() .

a44aa392c7b0e32a.png

Jump to the next section to build a convolutional network for the problem at hand.

11. A convolutional network

Let us build a convolutional network for handwritten digit recognition. We will use three convolutional layers at the top, our traditional softmax readout layer at the bottom and connect them with one fully-connected layer:

e1a214a170957da1.png

Notice that the second and third convolutional layers have a stride of two which explains why they bring the number of output values down from 28x28 to 14x14 and then 7x7.

Let's write the Keras code.

Special attention is needed before the first convolutional layer. Indeed, it expects a 3D 'cube' of data but our dataset has so far been set up for dense layers and all the pixels of the images are flattened into a vector. We need to reshape them back into 28x28x1 images (1 channel for grayscale images):

tf.keras.layers.Reshape(input_shape=(28*28,), target_shape=(28, 28, 1))

You can use this line instead of the tf.keras.layers.Input layer you had up to now.

In Keras, the syntax for a 'relu'-activated convolutional layer is:

140f80336b0e653b.png

tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu')

For a strided convolution, you would write:

tf.keras.layers.Conv2D(kernel_size=6, filters=24, padding='same', activation='relu', strides=2)

To flatten a cube of data into a vector so that it can be consumed by a dense layer:

tf.keras.layers.Flatten()

And for dense layer, the syntax has not changed:

tf.keras.layers.Dense(200, activation='relu')

Did your model break the 99% accuracy barrier? Pretty close... but look at the validation loss curve. Does this ring a bell?

ecc5972814885226.png

Also look at the predictions. For the first time, you should see that most of the 10,000 test digits are now correctly recognized. Only about 4½ rows of misdetections remain (about 110 digits out of 10,000)

37e4cbd3f390c89e.png

If you are stuck, here is the solution at this point:

c3df49e90e5a654f.png keras_04_mnist_convolutional.ipynb

12. Dropout again

The previous training exhibits clear signs of overfitting (and still falls short of 99% accuracy). Should we try dropout again?

How did it go this time?

63e0cc982cee2030.png

It looks like dropout has worked this time. The validation loss is not creeping up anymore and the final accuracy should be way above 99%. Congratulations!

The first time we tried to apply dropout, we thought we had an overfitting problem, when in fact the problem was in the architecture of the neural network. We could not go further without convolutional layers and there is nothing dropout could do about that.

This time, it does look like overfitting was the cause of the problem and dropout actually helped. Remember, there are many things that can cause a disconnect between the training and validation loss curves, with the validation loss creeping up. Overfitting (too many degrees of freedom, used badly by the network) is only one of them. If your dataset is too small or the architecture of your neural network is not adequate, you might see a similar behavior on the loss curves, but dropout will not help.

13. Batch normalization

oggEbikl2I6_sOo7FlaX2KLdNeaYhJnVSS8GyG8FHXid75PVJX73CRiOynwpMZpLZq6_xAy69wgyez5T-ZlpuC2XSlcmjk7oVcOzefKKTFhTEoLO3kljz2RDyKcaFtHvtTey-I4VpQ

Finally, let's try to add batch normalization.

That's the theory, in practice, just remember a couple of rules:

Let's play by the book for now and add a batch norm layer on each neural network layer but the last. Do not add it to the last "softmax" layer. It would not be useful there.

# Modify each layer: remove the activation from the layer itself.
# Set use_bias=False since batch norm will play the role of biases.
tf.keras.layers.Conv2D(..., use_bias=False),
# Batch norm goes between the layer and its activation.
# The scale factor can be turned off for Relu activation.
tf.keras.layers.BatchNormalization(scale=False, center=True),
# Finish with the activation.
tf.keras.layers.Activation('relu'),

How is the accuracy now?

ea48193334c565a1.png

With a little bit of tweaking (BATCH_SIZE=64, learning rate decay parameter 0.666, dropout rate on dense layer 0.3) and a bit of luck, you can get to 99.5%. The learning rate and dropout adjustments were done following the "best practices" for using batch norm:

  • Batch norm helps neural networks converge and usually allows you to train faster.
  • Batch norm is a regularizer. You can usually decrease the amount of dropout you use, or even not use dropout at all.

The solution notebook has a 99.5% training run:

c3df49e90e5a654f.png keras_05_mnist_batch_norm.ipynb

14. Train in the cloud on powerful hardware: AI Platform

d7d0282e687bdad8.png

You will find a cloud-ready version of the code in the mlengine folder on GitHub , along with instructions for running it on Google Cloud AI Platform . Before you can run this part, you will have to create a Google Cloud account and enable billing. The resources necessary to complete the lab should be less than a couple of dollars (assuming 1h of training time on one GPU). To prepare your account:

  1. Create a Google Cloud Platform project ( http://cloud.google.com/console ).
  2. Enable billing.
  3. Install the GCP command line tools ( GCP SDK here ).
  4. Create a Google Cloud Storage bucket (put in the region us-central1 ). It will be used to stage the training code and store your trained model.
  5. Enable the necessary APIs and request the necessary quotas (run the training command once and you should get error messages telling you what to enable).

১৫. অভিনন্দন!

You have built your first neural network and trained it all the way to 99% accuracy. The techniques learned along the way are not specific to the MNIST dataset, actually they are widely used when working with neural networks. As a parting gift, here is the "cliff's notes" card for the lab, in cartoon version. You can use it to remember what you have learned:

cliffs notes tensorflow lab.png

পরবর্তী পদক্ষেপ

  • After fully-connected and convolutional networks, you should have a look at recurrent neural networks .
  • To run your training or inference in the cloud on a distributed infrastructure, Google Cloud provides AI Platform .
  • Finally, we love feedback. Please tell us if you see something amiss in this lab or if you think it should be improved. We handle feedback through GitHub issues [ feedback link ].

HR.png

Martin Görner ID small.jpg The author: Martin GörnerTwitter: @martin_gorner

All cartoon images in this lab copyright: alexpokusay / 123RF stock photos