কেরাস এবং আধুনিক কনভনেট, টিপিইউতে

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

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

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

অনুসরণ

তুমি কি শিখবে

  • আপনার কাস্টম মডেলগুলি দ্রুত তৈরি করতে কেরাস এবং টেনসর প্রসেসিং ইউনিট (টিপিইউ) ব্যবহার করতে।
  • প্রশিক্ষণ ডেটা দক্ষতার সাথে লোড করার জন্য tf.data.Dataset API এবং TFRecord ফর্ম্যাট ব্যবহার করতে।
  • প্রতারণা করার জন্য 😈, নিজস্ব মডেল তৈরির পরিবর্তে ট্রান্সফার লার্নিং ব্যবহার করা।
  • কেরাসের ক্রমিক এবং কার্যকরী মডেল শৈলী ব্যবহার করতে।
  • একটি সফটম্যাক্স স্তর এবং ক্রস-এনট্রপি লস দিয়ে আপনার নিজস্ব কেরাস ক্লাসিফায়ার তৈরি করতে।
  • কনভোলিউশনাল লেয়ারের একটি ভালো পছন্দের মাধ্যমে আপনার মডেলটিকে সূক্ষ্ম-সুরকরণ করতে।
  • মডিউল, গ্লোবাল এভারেজ পুলিং ইত্যাদির মতো আধুনিক কনভনেট আর্কিটেকচারের ধারণাগুলি অন্বেষণ করা।
  • স্কুইজনেট আর্কিটেকচার ব্যবহার করে একটি সহজ আধুনিক কনভনেট তৈরি করা।

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

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

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

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

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

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

8832c6208c99687d.png সম্পর্কে

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

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

76d05caa8b4db6da.png সম্পর্কে

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

সুচিপত্র

429f106990037ec4.png সম্পর্কে

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

লুকানো কোষ

edc3dba45d26f12a.png সম্পর্কে

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

প্রমাণীকরণ

cdd4b41413100543.png সম্পর্কে

একটি অনুমোদিত অ্যাকাউন্টের মাধ্যমে প্রমাণীকরণ করলে, Colab আপনার ব্যক্তিগত Google Cloud Storage বাকেট অ্যাক্সেস করতে পারবে। উপরের কোড স্নিপেটটি একটি প্রমাণীকরণ প্রক্রিয়া শুরু করবে।

৩. [তথ্য] টেনসর প্রসেসিং ইউনিট (TPU) কী?

সংক্ষেপে

f88cf6facfc70166.png সম্পর্কে

কেরাসে TPU-তে মডেল প্রশিক্ষণের কোড (এবং TPU উপলব্ধ না থাকলে GPU বা CPU-তে ফিরে যান):

try: # detect TPUs
    tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
    strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
    strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines

# use TPUStrategy scope to define model
with strategy.scope():
  model = tf.keras.Sequential( ... )
  model.compile( ... )

# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)

আমরা আজ TPU ব্যবহার করে ইন্টারেক্টিভ গতিতে (প্রতি প্রশিক্ষণ রানে মিনিট) একটি ফুলের শ্রেণিবিন্যাসকারী তৈরি এবং অপ্টিমাইজ করব।

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

টিপিইউ কেন?

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

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

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

হার্ডওয়্যার

MXU এবং VPU

একটি TPU v2 কোর একটি Matrix Multiply Unit (MXU) দিয়ে তৈরি যা ম্যাট্রিক্স গুণন এবং একটি Vector Processing Unit (VPU) পরিচালনা করে অন্যান্য সমস্ত কাজের জন্য যেমন অ্যাক্টিভেশন, সফটম্যাক্স ইত্যাদি। VPU float32 এবং int32 গণনা পরিচালনা করে। অন্যদিকে MXU একটি মিশ্র নির্ভুলতা 16-32 বিট ফ্লোটিং পয়েন্ট ফর্ম্যাটে কাজ করে।

7d68944718f76b18.png সম্পর্কে

মিশ্র স্পষ্টতা ভাসমান বিন্দু এবং bfloat16

MXU bfloat16 ইনপুট এবং float32 আউটপুট ব্যবহার করে ম্যাট্রিক্স গুণ গণনা করে। মধ্যবর্তী সঞ্চয় float32 নির্ভুলতার সাথে সম্পাদিত হয়।

19c5fc432840c714.png সম্পর্কে

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

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

সিস্টোলিক অ্যারে

MXU হার্ডওয়্যারে ম্যাট্রিক্স গুণন প্রয়োগ করে একটি তথাকথিত "সিস্টোলিক অ্যারে" আর্কিটেকচার ব্যবহার করে যেখানে ডেটা উপাদানগুলি হার্ডওয়্যার গণনা ইউনিটের একটি অ্যারের মধ্য দিয়ে প্রবাহিত হয়। (চিকিৎসাবিদ্যায়, "সিস্টোলিক" বলতে হৃদপিণ্ডের সংকোচন এবং রক্ত ​​প্রবাহকে বোঝায়, এখানে ডেটা প্রবাহকে বোঝায়।)

একটি ম্যাট্রিক্স গুণনের মৌলিক উপাদান হল একটি ম্যাট্রিক্সের একটি রেখা এবং অন্য ম্যাট্রিক্সের একটি কলামের মধ্যে একটি বিন্দু গুণফল (এই বিভাগের শীর্ষে চিত্রটি দেখুন)। একটি ম্যাট্রিক্স গুণের জন্য Y=X*W, ফলাফলের একটি উপাদান হবে:

Y[2,0] = X[2,0]*W[0,0] + X[2,1]*W[1,0] + X[2,2]*W[2,0] + ... + X[2,n]*W[n,0]

একটি GPU-তে, এই ডট প্রোডাক্টটিকে একটি GPU "কোর"-এ প্রোগ্রাম করা হবে এবং তারপর সমান্তরালভাবে যতগুলি "কোর" পাওয়া যাবে তার উপর এটি চালানো হবে যাতে ফলাফলের ম্যাট্রিক্সের প্রতিটি মান একবারে গণনা করার চেষ্টা করা যায়। যদি ফলাফলের ম্যাট্রিক্স 128x128 বড় হয়, তাহলে 128x128=16K "কোর" উপলব্ধ থাকতে হবে যা সাধারণত সম্ভব নয়। বৃহত্তম GPU-তে প্রায় 4000 কোর থাকে। অন্যদিকে, একটি TPU MXU-তে কম্পিউট ইউনিটগুলির জন্য ন্যূনতম হার্ডওয়্যার ব্যবহার করে: কেবল bfloat16 x bfloat16 => float32 গুণ-সঞ্চয়কারী, অন্য কিছু নয়। এগুলি এত ছোট যে একটি TPU একটি 128x128 MXU-তে 16K প্রয়োগ করতে পারে এবং একবারে এই ম্যাট্রিক্স গুণন প্রক্রিয়া করতে পারে।

অনুসরণ

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

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

ক্লাউড টিপিইউ

যখন আপনি গুগল ক্লাউড প্ল্যাটফর্মে একটি " ক্লাউড TPU v2" অনুরোধ করেন, তখন আপনি একটি ভার্চুয়াল মেশিন (VM) পাবেন যার একটি PCI-সংযুক্ত TPU বোর্ড রয়েছে। TPU বোর্ডে চারটি ডুয়াল-কোর TPU চিপ রয়েছে। প্রতিটি TPU কোরে একটি VPU (ভেক্টর প্রসেসিং ইউনিট) এবং একটি 128x128 MXU (MatriX মাল্টিপ্লাই ইউনিট) রয়েছে। এই "ক্লাউড TPU" সাধারণত নেটওয়ার্কের মাধ্যমে অনুরোধ করা VM-এর সাথে সংযুক্ত থাকে। তাই সম্পূর্ণ ছবিটি এইরকম দেখাচ্ছে:

dfce5522ed644ece.png

উদাহরণ: আপনার VM একটি নেটওয়ার্ক-সংযুক্ত "ক্লাউড TPU" অ্যাক্সিলারেটর সহ। "ক্লাউড TPU" নিজেই একটি VM দিয়ে তৈরি যার একটি PCI-সংযুক্ত TPU বোর্ড রয়েছে যার উপর চারটি ডুয়াল-কোর TPU চিপ রয়েছে।

টিপিইউ পড

গুগলের ডেটা সেন্টারগুলিতে, টিপিইউগুলি একটি উচ্চ-কর্মক্ষমতা সম্পন্ন কম্পিউটিং (এইচপিসি) ইন্টারকানেক্টের সাথে সংযুক্ত থাকে যা এগুলিকে একটি খুব বড় অ্যাক্সিলারেটর হিসাবে দেখাতে পারে। গুগল এগুলিকে পড বলে এবং এগুলি 512 টিপিইউ ভি2 কোর বা 2048 টিপিইউ ভি3 কোর পর্যন্ত ধারণ করতে পারে।

2ec1e0d341e7fc34.jpeg সম্পর্কে

চিত্র: একটি TPU v3 পড। HPC ইন্টারকানেক্টের মাধ্যমে সংযুক্ত TPU বোর্ড এবং র্যাক।

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

অনুসরণ

উদাহরণ: Google TPU-এর 2-D টরয়েডাল মেশ HPC নেটওয়ার্কে অল-রিডুস অ্যালগরিদম ব্যবহার করে প্রশিক্ষণের সময় গ্রেডিয়েন্টের সিঙ্ক্রোনাইজেশন।

সফটওয়্যারটি

বড় ব্যাচ সাইজের প্রশিক্ষণ

TPU-এর জন্য আদর্শ ব্যাচ সাইজ হল প্রতি TPU কোরে ১২৮টি ডেটা আইটেম, কিন্তু হার্ডওয়্যারটি ইতিমধ্যেই প্রতি TPU কোরে ৮টি ডেটা আইটেম থেকে ভালো ব্যবহার দেখাতে পারে। মনে রাখবেন যে একটি ক্লাউড TPU-তে ৮টি কোর থাকে।

এই কোড ল্যাবে, আমরা Keras API ব্যবহার করব। Keras-এ, আপনি যে ব্যাচটি নির্দিষ্ট করবেন তা হল সমগ্র TPU-এর জন্য বিশ্বব্যাপী ব্যাচের আকার। আপনার ব্যাচগুলি স্বয়ংক্রিয়ভাবে 8টিতে বিভক্ত হবে এবং TPU-এর 8টি কোরে চলবে।

da534407825f01e3.png সম্পর্কে

অতিরিক্ত পারফরম্যান্স টিপসের জন্য TPU পারফরম্যান্স গাইড দেখুন। খুব বড় ব্যাচ সাইজের জন্য, কিছু মডেলে বিশেষ যত্নের প্রয়োজন হতে পারে, আরও বিস্তারিত জানার জন্য LARSOptimizer দেখুন।

হুডের নিচে: XLA

টেনসরফ্লো প্রোগ্রামগুলি গণনা গ্রাফ সংজ্ঞায়িত করে। TPU সরাসরি পাইথন কোড চালায় না, এটি আপনার টেনসরফ্লো প্রোগ্রাম দ্বারা সংজ্ঞায়িত গণনা গ্রাফ চালায়। হুডের নীচে, XLA (অ্যাক্সিলারেটেড লিনিয়ার অ্যালজেব্রা কম্পাইলার) নামক একটি কম্পাইলার কম্পিউটেশন নোডের টেনসরফ্লো গ্রাফকে TPU মেশিন কোডে রূপান্তরিত করে। এই কম্পাইলারটি আপনার কোড এবং আপনার মেমোরি লেআউটে অনেক উন্নত অপ্টিমাইজেশনও করে। TPU-তে কাজ পাঠানোর সাথে সাথে কম্পাইলেশনটি স্বয়ংক্রিয়ভাবে ঘটে। আপনার বিল্ড চেইনে আপনাকে স্পষ্টভাবে XLA অন্তর্ভুক্ত করতে হবে না।

edce61112cd57972.png সম্পর্কে

উদাহরণ: TPU তে চালানোর জন্য, আপনার Tensorflow প্রোগ্রাম দ্বারা সংজ্ঞায়িত গণনা গ্রাফটি প্রথমে একটি XLA (accelerated Linear Algebra compiler) উপস্থাপনায় অনুবাদ করা হয়, তারপর XLA দ্বারা TPU মেশিন কোডে কম্পাইল করা হয়।

কেরাসে টিপিইউ ব্যবহার

Tensorflow 2.1 থেকে Keras API এর মাধ্যমে TPU গুলি সমর্থিত। Keras সাপোর্ট TPU এবং TPU পডগুলিতে কাজ করে। এখানে একটি উদাহরণ দেওয়া হল যা TPU, GPU(গুলি) এবং CPU-তে কাজ করে:

try: # detect TPUs
    tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
    strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
    strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines

# use TPUStrategy scope to define model
with strategy.scope():
  model = tf.keras.Sequential( ... )
  model.compile( ... )

# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)

এই কোড স্নিপেটে:

  • TPUClusterResolver().connect() নেটওয়ার্কে TPU খুঁজে বের করে। এটি বেশিরভাগ Google ক্লাউড সিস্টেমে (AI Platform jobs, Colaboratory, Kubeflow, 'ctpu up' ইউটিলিটির মাধ্যমে তৈরি Deep Learning VM) প্যারামিটার ছাড়াই কাজ করে। এই সিস্টেমগুলি TPU_NAME এনভায়রনমেন্ট ভেরিয়েবলের জন্য তাদের TPU কোথায় তা জানে। আপনি যদি হাতে একটি TPU তৈরি করেন, তাহলে হয় আপনি যে VM থেকে এটি ব্যবহার করছেন তাতে TPU_NAME env. var. সেট করুন, অথবা স্পষ্ট প্যারামিটার সহ TPUClusterResolver কল করুন: TPUClusterResolver(tp_uname, zone, project)
  • TPUStrategy হল সেই অংশ যা বিতরণ এবং "অল-রিডুস" গ্রেডিয়েন্ট সিঙ্ক্রোনাইজেশন অ্যালগরিদম বাস্তবায়ন করে।
  • কৌশলটি একটি স্কোপের মাধ্যমে প্রয়োগ করা হয়। মডেলটি অবশ্যই স্ট্র্যাটেজি স্কোপের মধ্যে সংজ্ঞায়িত করা উচিত()।
  • tpu_model.fit ফাংশনটি TPU প্রশিক্ষণের জন্য ইনপুটের জন্য একটি tf.data.Dataset অবজেক্ট আশা করে।

সাধারণ TPU পোর্টিং কাজগুলি

  • টেনসরফ্লো মডেলে ডেটা লোড করার অনেক উপায় থাকলেও, TPU-এর জন্য tf.data.Dataset API ব্যবহার করা প্রয়োজন।
  • TPU গুলি খুব দ্রুত কাজ করে এবং এগুলি চালানোর সময় ডেটা গ্রহণ করা প্রায়শই বাধা হয়ে দাঁড়ায়। TPU পারফরম্যান্স গাইডে ডেটা বাধা এবং অন্যান্য পারফরম্যান্স টিপস সনাক্ত করার জন্য আপনি কিছু সরঞ্জাম ব্যবহার করতে পারেন।
  • int8 বা int16 সংখ্যাগুলিকে int32 হিসাবে বিবেচনা করা হয়। TPU তে 32 বিটের কম সংখ্যক পূর্ণসংখ্যার হার্ডওয়্যার নেই।
  • কিছু টেনসরফ্লো অপারেশন সমর্থিত নয়। তালিকাটি এখানে । সুখবর হল যে এই সীমাবদ্ধতা শুধুমাত্র প্রশিক্ষণ কোডের ক্ষেত্রে প্রযোজ্য, অর্থাৎ আপনার মডেলের মধ্য দিয়ে ফরোয়ার্ড এবং ব্যাকওয়ার্ড পাস। আপনি এখনও আপনার ডেটা ইনপুট পাইপলাইনে সমস্ত টেনসরফ্লো অপারেশন ব্যবহার করতে পারেন কারণ এটি CPU-তে কার্যকর করা হবে।
  • tf.py_func TPU তে সমর্থিত নয়।

৪. ডেটা লোড হচ্ছে

c0ecb860e4cad0a9.jpeg সম্পর্কেcc4781a7739c49ae.jpeg সম্পর্কে81236b00f8bbf39e.jpeg সম্পর্কে961e2228974076bb.jpeg সম্পর্কে7517dc163bdffcd5.jpeg সম্পর্কে96392df4767f566d.png সম্পর্কে

আমরা ফুলের ছবির একটি ডেটাসেট নিয়ে কাজ করব। লক্ষ্য হল ফুলগুলিকে ৫ ধরণের ফুলে ভাগ করা শেখা। tf.data.Dataset API ব্যবহার করে ডেটা লোড করা হয়। প্রথমে, আসুন API সম্পর্কে জেনে নেওয়া যাক।

হাতে-কলমে

অনুগ্রহ করে নিচের নোটবুকটি খুলুন, কোষগুলি (Shift-ENTER) চালান এবং যেখানেই "কাজের প্রয়োজন" লেবেল দেখতে পাবেন সেখানে নির্দেশাবলী অনুসরণ করুন।

c3df49e90e5a654f.png সম্পর্কে Fun with tf.data.Dataset (playground).ipynb

অতিরিক্ত তথ্য

"ফুল" ডেটাসেট সম্পর্কে

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

gs://flowers-public/sunflowers/5139971615_434ff8ed8b_n.jpg
gs://flowers-public/daisy/8094774544_35465c1c64.jpg
gs://flowers-public/sunflowers/9309473873_9d62b9082e.jpg
gs://flowers-public/dandelion/19551343954_83bb52f310_m.jpg
gs://flowers-public/dandelion/14199664556_188b37e51e.jpg
gs://flowers-public/tulips/4290566894_c7f061583d_m.jpg
gs://flowers-public/roses/3065719996_c16ecd5551.jpg
gs://flowers-public/dandelion/8168031302_6e36f39d87.jpg
gs://flowers-public/sunflowers/9564240106_0577e919da_n.jpg
gs://flowers-public/daisy/14167543177_cd36b54ac6_n.jpg

কেন tf.data.Dataset?

Keras এবং Tensorflow তাদের সকল প্রশিক্ষণ এবং মূল্যায়ন ফাংশনে ডেটাসেট গ্রহণ করে। একবার আপনি একটি ডেটাসেটে ডেটা লোড করলে, API নিউরাল নেটওয়ার্ক প্রশিক্ষণ ডেটার জন্য কার্যকর সমস্ত সাধারণ কার্যকারিতা প্রদান করে:

dataset = ... # load something (see below)
dataset = dataset.shuffle(1000) # shuffle the dataset with a buffer of 1000
dataset = dataset.cache() # cache the dataset in RAM or on disk
dataset = dataset.repeat() # repeat the dataset indefinitely
dataset = dataset.batch(128) # batch data elements together in batches of 128
AUTOTUNE = tf.data.AUTOTUNE
dataset = dataset.prefetch(AUTOTUNE) # prefetch next batch(es) while training

এই প্রবন্ধে আপনি পারফর্ম্যান্স টিপস এবং ডেটাসেটের সেরা অনুশীলনগুলি পেতে পারেন। রেফারেন্স ডকুমেন্টেশনটি এখানে

tf.data.Dataset এর মূল বিষয়গুলি

ডেটা সাধারণত একাধিক ফাইলে আসে, এখানে ছবি। আপনি নিম্নলিখিত নম্বরে কল করে ফাইলের নামের একটি ডেটাসেট তৈরি করতে পারেন:

filenames_dataset = tf.data.Dataset.list_files('gs://flowers-public/*/*.jpg')
# The parameter is a "glob" pattern that supports the * and ? wildcards.

তারপর আপনি প্রতিটি ফাইলের নামের সাথে একটি ফাংশন "ম্যাপ" করবেন যা সাধারণত ফাইলটিকে মেমরিতে প্রকৃত ডেটাতে লোড এবং ডিকোড করবে:

def decode_jpeg(filename):
  bits = tf.io.read_file(filename)
  image = tf.io.decode_jpeg(bits)
  return image

image_dataset = filenames_dataset.map(decode_jpeg)
# this is now a dataset of decoded images (uint8 RGB format)

একটি ডেটাসেটে পুনরাবৃত্তি করতে:

for data in my_dataset:
  print(data)

টিপলের ডেটাসেট

তত্ত্বাবধানে থাকা শিক্ষায়, একটি প্রশিক্ষণ ডেটাসেট সাধারণত প্রশিক্ষণ ডেটা এবং সঠিক উত্তরের জোড়া দিয়ে তৈরি হয়। এটি করার জন্য, ডিকোডিং ফাংশনটি টিপলগুলি ফেরত দিতে পারে। এরপর আপনার কাছে টিপলগুলির একটি ডেটাসেট থাকবে এবং আপনি যখন এটিতে পুনরাবৃত্তি করবেন তখন টিপলগুলি ফেরত দেওয়া হবে। ফেরত দেওয়া মানগুলি হল Tensorflow tensors যা আপনার মডেল দ্বারা ব্যবহারের জন্য প্রস্তুত। আপনি raw মানগুলি দেখতে .numpy() কল করতে পারেন:

def decode_jpeg_and_label(filename):
  bits = tf.read_file(filename)
  image = tf.io.decode_jpeg(bits)
  label = ... # extract flower name from folder name
  return image, label

image_dataset = filenames_dataset.map(decode_jpeg_and_label)
# this is now a dataset of (image, label) pairs 

for image, label in dataset:
  print(image.numpy().shape, label.numpy())

উপসংহার: একের পর এক ছবি লোড করা ধীর গতির!

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

সমাধান

এখানে সমাধান নোটবুক। যদি আপনি আটকে যান তবে আপনি এটি ব্যবহার করতে পারেন।

c3df49e90e5a654f.png সম্পর্কে Fun with tf.data.Dataset (solution).ipynb

আমরা যা কভার করেছি

  • 🤔 tf.data.Dataset.list_files
  • 🤔 tf.data.Dataset.map
  • 🤔 টিপলের ডেটাসেট
  • 😀 ডেটাসেটের মাধ্যমে পুনরাবৃত্তি করা হচ্ছে

অনুগ্রহ করে একটু সময় নিয়ে এই চেকলিস্টটি আপনার মাথায় ঢোকান।

৫. দ্রুত ডেটা লোড হচ্ছে

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

পঠনযোগ্য

যে কোডটি ইমেজ ফাইল লোড করে, সেগুলিকে একটি সাধারণ আকারে পরিবর্তন করে এবং তারপর ১৬টি TFRecord ফাইলে সংরক্ষণ করে তা নিম্নলিখিত নোটবুকে রয়েছে। দয়া করে দ্রুত এটি পড়ুন। এটি কার্যকর করার প্রয়োজন নেই কারণ কোডল্যাবের বাকি অংশের জন্য সঠিকভাবে TFRecord-ফর্ম্যাট করা ডেটা সরবরাহ করা হবে।

c3df49e90e5a654f.png সম্পর্কে Flower pictures to TFRecords.ipynb

সর্বোত্তম GCS থ্রুপুটের জন্য আদর্শ ডেটা লেআউট

TFRecord ফাইল ফর্ম্যাট

ডেটা সংরক্ষণের জন্য Tensorflow-এর পছন্দের ফাইল ফর্ম্যাট হল protobuf- ভিত্তিক TFRecord ফর্ম্যাট। অন্যান্য সিরিয়ালাইজেশন ফর্ম্যাটগুলিও কাজ করবে তবে আপনি TFRecord ফাইলগুলি থেকে সরাসরি একটি ডেটাসেট লোড করতে পারেন:

filenames = tf.io.gfile.glob(FILENAME_PATTERN)
dataset = tf.data.TFRecordDataset(filenames)
dataset = dataset.map(...) # do the TFRecord decoding here - see below

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

AUTOTUNE = tf.data.AUTOTUNE
ignore_order = tf.data.Options()
ignore_order.experimental_deterministic = False

filenames = tf.io.gfile.glob(FILENAME_PATTERN)
dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTOTUNE)
dataset = dataset.with_options(ignore_order)
dataset = dataset.map(...) # do the TFRecord decoding here - see below

TFRecord চিট শিট

TFRecords-এ তিন ধরণের ডেটা সংরক্ষণ করা যেতে পারে: বাইট স্ট্রিং (বাইটের তালিকা), 64 বিট পূর্ণসংখ্যা এবং 32 বিট ফ্লোট । এগুলি সর্বদা তালিকা হিসাবে সংরক্ষণ করা হয়, একটি একক ডেটা উপাদান আকার 1 এর একটি তালিকা হবে। TFRecords-এ ডেটা সংরক্ষণ করতে আপনি নিম্নলিখিত সহায়ক ফাংশনগুলি ব্যবহার করতে পারেন।

বাইট স্ট্রিং লেখা

# warning, the input is a list of byte strings, which are themselves lists of bytes
def _bytestring_feature(list_of_bytestrings):
  return tf.train.Feature(bytes_list=tf.train.BytesList(value=list_of_bytestrings))

পূর্ণসংখ্যা লেখা

def _int_feature(list_of_ints): # int64
  return tf.train.Feature(int64_list=tf.train.Int64List(value=list_of_ints))

লেখা ভাসমান

def _float_feature(list_of_floats): # float32
  return tf.train.Feature(float_list=tf.train.FloatList(value=list_of_floats))

উপরের সাহায্যকারীদের ব্যবহার করে একটি TFRecord লেখা

# input data in my_img_bytes, my_class, my_height, my_width, my_floats
with tf.python_io.TFRecordWriter(filename) as out_file:
  feature = {
    "image": _bytestring_feature([my_img_bytes]), # one image in the list
    "class": _int_feature([my_class]),            # one class in the list
    "size": _int_feature([my_height, my_width]),  # fixed length (2) list of ints
    "float_data": _float_feature(my_floats)       # variable length  list of floats
  }
  tf_record = tf.train.Example(features=tf.train.Features(feature=feature))
  out_file.write(tf_record.SerializeToString())

TFRecords থেকে ডেটা পড়ার জন্য, আপনাকে প্রথমে আপনার সংরক্ষিত রেকর্ডের লেআউট ঘোষণা করতে হবে। ঘোষণায়, আপনি যেকোনো নামযুক্ত ক্ষেত্রকে একটি নির্দিষ্ট দৈর্ঘ্যের তালিকা বা একটি পরিবর্তনশীল দৈর্ঘ্যের তালিকা হিসাবে অ্যাক্সেস করতে পারেন:

TFRecords থেকে পড়া

def read_tfrecord(data):
  features = {
    # tf.string = byte string (not text string)
    "image": tf.io.FixedLenFeature([], tf.string), # shape [] means scalar, here, a single byte string
    "class": tf.io.FixedLenFeature([], tf.int64),  # shape [] means scalar, i.e. a single item
    "size": tf.io.FixedLenFeature([2], tf.int64),  # two integers
    "float_data": tf.io.VarLenFeature(tf.float32)  # a variable number of floats
  }

  # decode the TFRecord
  tf_record = tf.io.parse_single_example(data, features)

  # FixedLenFeature fields are now ready to use
  sz = tf_record['size']

  # Typical code for decoding compressed images
  image = tf.io.decode_jpeg(tf_record['image'], channels=3)

  # VarLenFeature fields require additional sparse.to_dense decoding
  float_data = tf.sparse.to_dense(tf_record['float_data'])

  return image, sz, float_data

# decoding a tf.data.TFRecordDataset
dataset = dataset.map(read_tfrecord)
# now a dataset of triplets (image, sz, float_data)

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

একক ডেটা উপাদান পড়া

tf.io.FixedLenFeature([], tf.string)   # for one byte string
tf.io.FixedLenFeature([], tf.int64)    # for one int
tf.io.FixedLenFeature([], tf.float32)  # for one float

নির্দিষ্ট আকারের উপাদানের তালিকা পড়া

tf.io.FixedLenFeature([N], tf.string)   # list of N byte strings
tf.io.FixedLenFeature([N], tf.int64)    # list of N ints
tf.io.FixedLenFeature([N], tf.float32)  # list of N floats

পরিবর্তনশীল সংখ্যক ডেটা আইটেম পড়া

tf.io.VarLenFeature(tf.string)   # list of byte strings
tf.io.VarLenFeature(tf.int64)    # list of ints
tf.io.VarLenFeature(tf.float32)  # list of floats

একটি VarLenFeature একটি স্পার্স ভেক্টর প্রদান করে এবং TFRecord ডিকোড করার পরে একটি অতিরিক্ত পদক্ষেপ প্রয়োজন:

dense_data = tf.sparse.to_dense(tf_record['my_var_len_feature'])

TFRecords-এ ঐচ্ছিক ক্ষেত্র থাকাও সম্ভব। যদি আপনি একটি ক্ষেত্র পড়ার সময় একটি ডিফল্ট মান নির্দিষ্ট করেন, তাহলে ক্ষেত্রটি অনুপস্থিত থাকলে ত্রুটির পরিবর্তে ডিফল্ট মানটি ফেরত পাঠানো হয়।

tf.io.FixedLenFeature([], tf.int64, default_value=0) # this field is optional

আমরা যা কভার করেছি

  • 🤔 GCS থেকে দ্রুত অ্যাক্সেসের জন্য ডেটা ফাইল ভাগ করা
  • 😓 TFRecords কিভাবে লিখবেন। (আপনি কি ইতিমধ্যেই বাক্য গঠন ভুলে গেছেন? ঠিক আছে, এই পৃষ্ঠাটিকে একটি চিট শিট হিসেবে বুকমার্ক করুন)
  • 🤔 TFRecordDataset ব্যবহার করে TFRecords থেকে একটি ডেটাসেট লোড করা হচ্ছে

অনুগ্রহ করে একটু সময় নিয়ে এই চেকলিস্টটি আপনার মাথায় ঢোকান।

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

সংক্ষেপে

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

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

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[192, 192, 3]),
    tf.keras.layers.Dense(500, activation="relu"),
    tf.keras.layers.Dense(50, activation="relu"),
    tf.keras.layers.Dense(5, activation='softmax') # classifying into 5 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 সম্পর্কে

ঘন নিউরাল নেটওয়ার্ক

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

c21bae6dade487bc.png সম্পর্কে

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

নিউরন, সক্রিয়করণ, RELU

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

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

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

সফটম্যাক্স অ্যাক্টিভেশন

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

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

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

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

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

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

7bdf8753d20617fb.png সম্পর্কে

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

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

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

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

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

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

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

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

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

52e824fe4716c4a0.png সম্পর্কে

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

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

শব্দকোষ

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

হাতে-কলমে

অনুগ্রহ করে নিচের নোটবুকটি খুলুন, কোষগুলি (Shift-ENTER) কার্যকর করুন এবং যেখানেই "কাজের প্রয়োজন" লেবেলটি দেখবেন সেখানে নির্দেশাবলী অনুসরণ করুন।

c3df49e90e5a654f.png সম্পর্কে Keras Flowers transfer learning (playground).ipynb

অতিরিক্ত তথ্য

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

b8fc1efd2001f072.png সম্পর্কে

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

কেরাসে স্থানান্তর শিক্ষা

Keras-এ, আপনি tf.keras.applications.* সংগ্রহ থেকে একটি পূর্ব-প্রশিক্ষিত মডেল তৈরি করতে পারেন। উদাহরণস্বরূপ, MobileNet V2 একটি খুব ভালো কনভোলিউশনাল আর্কিটেকচার যা আকারে যুক্তিসঙ্গত থাকে। include_top=False নির্বাচন করে, আপনি চূড়ান্ত softmax স্তর ছাড়াই পূর্ব-প্রশিক্ষিত মডেলটি পাবেন যাতে আপনি আপনার নিজস্ব যোগ করতে পারেন:

pretrained_model = tf.keras.applications.MobileNetV2(input_shape=[*IMAGE_SIZE, 3], include_top=False)
pretrained_model.trainable = False

model = tf.keras.Sequential([
    pretrained_model,
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(5, activation='softmax')
])

এছাড়াও pretrained_model.trainable = False সেটিংটি লক্ষ্য করুন। এটি প্রি-ট্রেনড মডেলের ওজন এবং পক্ষপাতগুলিকে স্থির করে দেয় যাতে আপনি কেবল আপনার সফটম্যাক্স স্তরকে প্রশিক্ষণ দিতে পারেন। এতে সাধারণত তুলনামূলকভাবে কম ওজন থাকে এবং এটি দ্রুত এবং খুব বড় ডেটাসেটের প্রয়োজন ছাড়াই করা যেতে পারে। তবে যদি আপনার কাছে প্রচুর ডেটা থাকে, তাহলে ট্রান্সফার লার্নিং pretrained_model.trainable = True দিয়ে আরও ভালভাবে কাজ করতে পারে। প্রি-ট্রেনড ওজনগুলি তখন চমৎকার প্রাথমিক মান প্রদান করে এবং আপনার সমস্যার সাথে আরও ভালভাবে মানানসই করার জন্য প্রশিক্ষণের মাধ্যমে এখনও সামঞ্জস্য করা যেতে পারে।

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

এই পদ্ধতির মাধ্যমে আপনার প্রায় ৭৫% নির্ভুলতা অর্জন করা উচিত।

সমাধান

এখানে সমাধান নোটবুক। যদি আপনি আটকে যান তবে আপনি এটি ব্যবহার করতে পারেন।

c3df49e90e5a654f.png সম্পর্কে Keras Flowers transfer learning (solution).ipynb

আমরা যা কভার করেছি

  • 🤔 কেরাসে কিভাবে ক্লাসিফায়ার লিখবেন
  • 🤓 একটি সফটম্যাক্স শেষ স্তর এবং ক্রস-এনট্রপি ক্ষতির সাথে কনফিগার করা হয়েছে
  • 😈 Transfer learning
  • 🤔 Training your first model
  • 🧐 Following its loss and accuracy during training

Please take a moment to go through this checklist in your head.

8. [INFO] Convolutional neural 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 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([
  # input: images of size 192x192x3 pixels (the three stands for RGB channels)
  tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu', input_shape=[192, 192, 3]),
  tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=6, padding='same', activation='relu'),
  tf.keras.layers.Flatten(),
  # classifying into 5 categories
  tf.keras.layers.Dense(5, activation='softmax')
])

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

688858c21e3beff2.png

Convolutional neural nets 101

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, using 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.

C onvolutional classifier

Finally, we attach a classification head by flattening the last data cube and feeding it through a dense, softmax-activated layer. A typical convolutional classifier can look like this:

4a61aaffb6cba3d1.png

Illustration: an image classifier using convolutional and softmax layers. It uses 3x3 and 1x1 filters. The maxpool layers take the max of groups of 2x2 data points. The classification head is implemented with a dense layer with softmax activation.

In Keras

The convolutional stack illustrated above can be written in Keras like this:

model = tf.keras.Sequential([
  # input: images of size 192x192x3 pixels (the three stands for RGB channels)    
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu', input_shape=[192, 192, 3]),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=16, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=8, padding='same', activation='relu'),
  tf.keras.layers.Flatten(),
  # classifying into 5 categories
  tf.keras.layers.Dense(5, activation='softmax')
])

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

9. Your custom convnet

হাতে-কলমে

Let us build and train a convolutional neural network from scratch. Using a TPU will allow us to iterate very fast. Please open the following notebook, execute the cells (Shift-ENTER) and follow the instructions wherever you see a "WORK REQUIRED" label.

c3df49e90e5a654f.png Keras_Flowers_TPU (playground).ipynb

The goal is to beat the 75% accuracy of the transfer learning model. That model had an advantage, having been pre-trained on a dataset of millions of images while we only have 3670 images here. Can you at least match it?

অতিরিক্ত তথ্য

How many layers, how big?

Selecting layer sizes is more of an art than a science. You have to find the right balance between having too few and too many parameters (weights and biases). With too few weights, the neural network cannot represent the complexity of flower shapes. With too many, it can be prone to "overfitting", ie specializing in the training images and not being able to generalize. With a lot of parameters, the model will also be slow to train. In Keras, the model.summary() function displays the structure and parameter count of your model:

Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 192, 192, 16)      448       
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 192, 192, 30)      4350      
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 96, 96, 30)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 96, 96, 60)        16260     
_________________________________________________________________
 ... 
_________________________________________________________________
global_average_pooling2d (Gl (None, 130)               0         
_________________________________________________________________
dense (Dense)                (None, 90)                11790     
_________________________________________________________________
dense_1 (Dense)              (None, 5)                 455       
=================================================================
Total params: 300,033
Trainable params: 300,033
Non-trainable params: 0
_________________________________________________________________

A couple of tips:

  • Having multiple layers is what makes "deep" neural networks effective. For this simple flower recognition problem, 5 to 10 layers make sense.
  • Use small filters. Typically 3x3 filters are good everywhere.
  • 1x1 filters can be used too and are cheap. They do not really "filter" anything but compute linear combinations of channels. Alternate them with real filters. (More about "1x1 convolutions" in the next section.)
  • For a classification problem like this, downsample frequently with max-pooling layers (or convolutions with stride >1). You do not care where the flower is, only that it is a rose or a dandelion so losing x and y information is not important and filtering smaller areas is cheaper.
  • The number of filters usually becomes similar to the number of classes at the end of the network (why? see "global average pooling" trick below). If you classify into hundreds of classes, increase the filter count progressively in consecutive layers. For the flower dataset with 5 classes, filtering with only 5 filters would not be enough. You can use the same filter count in most layers, for example 32 and decrease it towards the end.
  • The final dense layer(s) is/are expensive. It/they can have more weights than all the convolutional layers combined. For example, even with a very reasonable output from the last data cube of 24x24x10 data points, a 100 neuron dense layer would cost 24x24x10x100=576,000 weights !!! Try to be thoughtful, or try global average pooling (see below).

Global average pooling

Instead of using an expensive dense layer at the end of a convolutional neural network, you can split the incoming data "cube" into as many parts as you 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, the syntax is tf.keras.layers.GlobalAveragePooling2D().

93240029f59df7c2.png

সমাধান

Here is the solution notebook. You can use it if you are stuck.

c3df49e90e5a654f.png Keras_Flowers_TPU (solution).ipynb

আমরা যা কভার করেছি

  • 🤔 Played with convolutional layers
  • 🤓 Experimented with max pooling, strides, global average pooling, ...
  • 😀 iterated on a real-world model fast, on TPU

Please take a moment to go through this checklist in your head.

10. [INFO] Modern convolutional architectures

সংক্ষেপে

7968830b57b708c0.png

Illustration: a convolutional "module". What is best at this point ? A max-pool layer followed by a 1x1 convolutional layer or a different combination of layers ? Try them all, concatenate the results and let the network decide. On the right: the " inception " convolutional architecture using such modules.

In Keras, to create models where the data flow can branch in and out, you have to use the "functional" model style. Here is an example:

l = tf.keras.layers # syntax shortcut

y = l.Conv2D(filters=32, kernel_size=3, padding='same',
             activation='relu', input_shape=[192, 192, 3])(x) # x=input image

# module start: branch out
y1 = l.Conv2D(filters=32, kernel_size=1, padding='same', activation='relu')(y)
y3 = l.Conv2D(filters=32, kernel_size=3, padding='same', activation='relu')(y)
y = l.concatenate([y1, y3]) # output now has 64 channels
# module end: concatenation

# many more layers ...

# Create the model by specifying the input and output tensors.
# Keras layers track their connections automatically so that's all that's needed.
z = l.Dense(5, activation='softmax')(y)
model = tf.keras.Model(x, z)

688858c21e3beff2.png

Other cheap tricks

Small 3x3 filters

40a7b15fb7dbe75c.png

In this illustration, you see the result of two consecutive 3x3 filters. Try to trace back which data points contributed to the result: these two consecutive 3x3 filters compute some combination of a 5x5 region. It is not exactly the same combination that a 5x5 filter would compute but it is worth trying because two consecutive 3x3 filters are cheaper than a single 5x5 filter.

1x1 convolutions ?

fd7cac16f8ecb423.png

In mathematical terms, a "1x1" convolution is a multiplication by a constant, not a very useful concept. In convolutional neural networks however, remember that the filter is applied to a data cube, not just a 2D image. Therefore, a "1x1" filter computes a weighted sum of a 1x1 column of data (see illustration) and as you slide it across the data, you will obtain a linear combination of the channels of the input. This is actually useful. If you think of the channels as the results of individual filtering operations, for example a filter for "pointy ears", another one for "whiskers" and a third one for "slit eyes" then a "1x1" convolutional layer will be computing multiple possible linear combinations of these features, which might be useful when looking for a "cat". On top of that, 1x1 layers use fewer weights.

11. Squeezenet

A simple way of putting these ideas together has been showcased in the "Squeezenet" paper . The authors suggest a very simple convolutional module design, using only 1x1 and 3x3 convolutional layers.

1730ac375379269b.png

Illustration: squeezenet architecture based on "fire modules". They alternate a 1x1 layer that "squeezes" the incoming data in the vertical dimension followed by two parallel 1x1 and 3x3 convolutional layers that "expand" the depth of the data again.

হাতে-কলমে

Continue in your previous notebook and build a squeezenet-inspired convolutional neural network. You will have to change the model code to the Keras "functional style".

c3df49e90e5a654f.png Keras_Flowers_TPU (playground).ipynb

অতিরিক্ত তথ্য

It will be useful for this exercise to define a helper function for a squeezenet module:

def fire(x, squeeze, expand):
  y = l.Conv2D(filters=squeeze, kernel_size=1, padding='same', activation='relu')(x)
  y1 = l.Conv2D(filters=expand//2, kernel_size=1, padding='same', activation='relu')(y)
  y3 = l.Conv2D(filters=expand//2, kernel_size=3, padding='same', activation='relu')(y)
  return tf.keras.layers.concatenate([y1, y3])

# this is to make it behave similarly to other Keras layers
def fire_module(squeeze, expand):
  return lambda x: fire(x, squeeze, expand)

# usage:
x = l.Input(shape=[192, 192, 3])
y = fire_module(squeeze=24, expand=48)(x) # typically, squeeze is less than expand
y = fire_module(squeeze=32, expand=64)(y)
...
model = tf.keras.Model(x, y)

The objective this time is to hit 80% accuracy.

Things to try

Start with a single convolutional layer, then follow with " fire_modules ", alternating with MaxPooling2D(pool_size=2) layers. You can experiment with 2 to 4 max pooling layers in the network and also with 1, 2 or 3 consecutive fire modules between the max pooling layers.

In fire modules, the "squeeze" parameter should typically be smaller than the "expand" parameter. These parameters are actually numbers of filters. They can range from 8 to 196, typically. You can experiment with architectures where the number of filters gradually increases through the network, or straightforward architectures where all fire modules have the same number of filters.

Here is an example:

x = tf.keras.layers.Input(shape=[*IMAGE_SIZE, 3]) # input is 192x192 pixels RGB

y = tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu')(x)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.GlobalAveragePooling2D()(y)
y = tf.keras.layers.Dense(5, activation='softmax')(y)

model = tf.keras.Model(x, y)

At this point, you might notice that your experiments are not going so well and that the 80% accuracy objective seems remote. Time for a couple more cheap tricks.

Batch Normalization

Batch norm will help with the convergence problems you are experiencing. There will be detailed explanations about this technique in the next workshop, for now, please use it as a black box "magic" helper by adding this line after every convolutional layer in your network, including the layers inside of your fire_module function:

y = tf.keras.layers.BatchNormalization(momentum=0.9)(y)
# please adapt the input and output "y"s to whatever is appropriate in your context

The momentum parameter has to be decreased from its default value of 0.99 to 0.9 because our dataset is small. Never mind this detail for now.

Data augmentation

You will get a couple more percentage points by augmenting the data with easy transformations like left-right flips of saturation changes:

4ed2958e09b487ca.png

ad795b70334e0d6b.png

This is very easy to do in Tensorflow with the tf.data.Dataset API. Define a new transformation function for your data:

def data_augment(image, label):
    image = tf.image.random_flip_left_right(image)
    image = tf.image.random_saturation(image, lower=0, upper=2)
    return image, label

Then use it in you final data transformation (cell "training and validation datasets", function "get_batched_dataset"):

dataset = dataset.repeat() # existing line
# insert this
if augment_data:
  dataset = dataset.map(data_augment, num_parallel_calls=AUTO)
dataset = dataset.shuffle(2048) # existing line

Do not forget to make the data augmentation optional and to add the necessary code to make sure only the training dataset is augmented . It makes no sense to augment the validation dataset.

80% accuracy in 35 epochs should now be within reach.

সমাধান

Here is the solution notebook. You can use it if you are stuck.

c3df49e90e5a654f.png Keras_Flowers_TPU_squeezenet.ipynb

আমরা যা কভার করেছি

  • 🤔 Keras "functional style" models
  • 🤓 Squeezenet architecture
  • 🤓 Data augmentation with tf.data.datset

Please take a moment to go through this checklist in your head.

12. Xception fine-tuned

Separable convolutions

A different way of implementing convolutional layers had been gaining popularity recently: depth-separable convolutions. I know, it's a mouthful, but the concept is quite simple. They are implemented in Tensorflow and Keras as tf.keras.layers.SeparableConv2D .

A separable convolution also runs a filter on the image but it uses a distinct set of weights for each channel of the input image. It follows with a "1x1 convolution", a series of dot products resulting in a weighted sum of the filtered channels. With new weights each time, as many weighted recombinations of the channels are computed as necessary.

615720b803bf8dda.gif

Illustration: separable convolutions. Phase 1: convolutions with a separate filter for each channel. Phase 2: linear recombinations of channels. Repeated with a new set of weights until the desired number of output channels is reached. Phase 1 can be repeated too, with new weights each time but in practice it is rarely so.

Separable convolutions are used in most recent convolutional networks architectures: MobileNetV2, Xception, EfficientNet. By the way, MobileNetV2 is what you used for transfer learning previously.

They are cheaper than regular convolutions and have been found to be just as effective in practice. Here is the weight count for the example illustrated above:

Convolutional layer: 4 x 4 x 3 x 5 = 240

Separable convolutional layer: 4 x 4 x 3 + 3 x 5 = 48 + 15 = 63

It is left as an exercise for the reader to compute than number of multiplications required to apply each style of convolutional layer scales in a similar way. Separable convolutions are smaller and much more computationally effective.

হাতে-কলমে

Restart from the "transfer learning" playground notebook but this time select Xception as the pre-trained model. Xception uses separable convolutions only. Leave all weights trainable. We will be fine-tuning the pre-trained weights on our data instead of using the pre-trained layers as such.

c3df49e90e5a654f.png Keras Flowers transfer learning (playground).ipynb

Goal: accuracy > 95% (No, seriously, it is possible!)

This being the final exercise, it requires a bit more code and data science work.

Additional info on fine-tuning

Xception is available in the standard pre-trained models in tf.keras.application.* Do not forget to leave all weights trainable this time.

pretrained_model = tf.keras.applications.Xception(input_shape=[*IMAGE_SIZE, 3],
                                                  include_top=False)
pretrained_model.trainable = True

To get good results when fine-tuning a model, you will need to pay attention to the learning rate and use a learning rate schedule with a ramp-up period. Like this:

9b1af213b2b36d47.png

Starting with a standard learning rate would disrupt the pre-trained weights of the model. Starting progressively preserves them until the model has latched on your data is able to modify them in a sensible way. After the ramp, you can continue with a constant or an exponentially decaying learning rate.

In Keras, the learning rate is specified through a callback in which you can compute the appropriate learning rate for each epoch. Keras will pass the correct learning rate to the optimizer for each epoch.

def lr_fn(epoch):
  lr = ...
  return lr

lr_callback = tf.keras.callbacks.LearningRateScheduler(lr_fn, verbose=True)

model.fit(..., callbacks=[lr_callback])

সমাধান

Here is the solution notebook. You can use it if you are stuck.

c3df49e90e5a654f.png 07_Keras_Flowers_TPU_xception_fine_tuned_best.ipynb

আমরা যা কভার করেছি

  • 🤔 Depth-separable convolution
  • 🤓 Learning rate schedules
  • 😈 Fine-tuning a pre-trained model.

Please take a moment to go through this checklist in your head.

13. Congratulations!

You have built your first modern convolutional neural network and trained it to 90% + accuracy, iterating on successive training runs in only minutes thanks to TPUs.

TPUs in practice

TPUs and GPUs are available on Google Cloud's Vertex AI :

Finally, we love feedback. Please tell us if you see something amiss in this lab or if you think it should be improved. Feedback can be provided through GitHub issues [ feedback link ].

HR.png

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