Chapter 13 of 18
Bidirectional, stacked, Seq2Seq, attention, GRU, and Transformers
TensorFlow/Keras চ্যাপ্টারে আমরা বাইডাইরেকশনাল (Bidirectional) এবং স্ট্যাকড (Stacked) LSTM সম্পর্কে জেনেছিলাম। এই চ্যাপ্টারে আমরা LSTM সেলের ওপর ভিত্তি করে তৈরি বাকি প্রধান আর্কিটেকচারাল আইডিয়াগুলো নিয়ে আলোচনা করবো: সিকোয়েন্স-টু-সিকোয়েন্স (Seq2Seq) মডেল, অ্যাটেনশন মেকানিজম (attention mechanism), জিআরইউ (GRU) বিকল্প এবং আধুনিক যুগের ট্রান্সফরমার (Transformer) আর্কিটেকচারের সাথে এর একটি ধারণাগত তুলনা (যা পূর্বে LSTM-এর করা অধিকাংশ কাজই এখন দখল করে নিয়েছে)।
বাস্তব জীবনের অনেক কাজই একটি সিকোয়েন্সকে সম্পূর্ণ ভিন্ন দৈর্ঘ্যের আরেকটি সিকোয়েন্সে রূপান্তর করে — যেমন: এক ভাষা থেকে অন্য ভাষায় অনুবাদ করা (translation), দীর্ঘ ডকুমেন্টের সারসংক্ষেপ তৈরি করা (summarization), কিংবা অডিও কথাকে টেক্সটে রূপান্তর করা। একটি সাধারণ LSTM-এর ইনপুট ও আউটপুট ওয়ান-টু-ওয়ান (one-to-one) সারিবদ্ধ থাকে — অর্থাৎ এটি ভিন্ন দৈর্ঘ্যের ইনপুট ও আউটপুট সিকোয়েন্স সহজে হ্যান্ডেল করতে পারে না।
Seq2Seq এই সমস্যার সমাধান করে দুটি আলাদা LSTM ব্যবহার করে:
এনকোডার এলএসটিএম (Encoder LSTM)
এটি পুরো ইনপুট সিকোয়েন্সটি পড়ে এবং সেটিকে একটি চূড়ান্ত হিডেন ও সেল স্টেটে সংকুচিত করে — যা মূলত পুরো ইনপুটের একটি ফিক্সড-সাইজ সারসংক্ষেপ।
কনটেক্সট ভেক্টর (Context Vector - h_T, C_T)
এনকোডারের চূড়ান্ত স্টেট। ডিকোডার ইনপুট সম্পর্কে যা কিছু জানবে তা কেবল এই ভেক্টরের ভেতরেই সংরক্ষিত থাকে। এটি ডিকোডারের initial_state হিসেবে পাঠানো হয়।
ডিকোডার এলএসটিএম (Decoder LSTM)
কনটেক্সট ভেক্টর দিয়ে এটি ইনিশিয়ালাইজ হয় এবং এক ধাপ করে আউটপুট সিকোয়েন্স তৈরি করে। প্রতি পদক্ষেপে এটি তার আগের নিজের তৈরি আউটপুটকে পরবর্তী ইনপুট হিসেবে গ্রহণ করে।
একজন মানুষের দোভাষী বা অনুবাদকের কথা ভাবুন: তিনি প্রথমে অন্য ভাষার একটি পুরো বাক্য মনোযোগ দিয়ে শোনেন (বাক্যটি মাথার ভেতর অনুবাদ করে অর্থটি সংকুচিত করে রাখেন) এবং কেবল তখনই অনুবাদ বলা শুরু করেন (ডিকোডিং) — প্রতিটি শব্দ শোনার সাথে সাথে ওয়ান-টু-ওয়ান অনুবাদ করেন না।
from tensorflow import keras
from tensorflow.keras import layers
n_x, n_h = 12, 16
# এনকোডার (Encoder)
encoder_inputs = keras.Input(shape=(None, n_x))
encoder_lstm = layers.LSTM(n_h, return_state=True)
_, state_h, state_c = encoder_lstm(encoder_inputs) # আউটপুট ফেলে দিয়ে কেবল চূড়ান্ত স্টেট রাখা হচ্ছে
encoder_states = [state_h, state_c]
# ডিকোডার (Decoder)
decoder_inputs = keras.Input(shape=(None, n_x))
decoder_lstm = layers.LSTM(n_h, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states)
decoder_dense = layers.Dense(n_x, activation="softmax")
decoder_outputs = decoder_dense(decoder_outputs)
model = keras.Model([encoder_inputs, decoder_inputs], decoder_outputs)এনকোডার তার সম্পূর্ণ ইনপুটটিকে একটি নির্দিষ্ট আকারের ভেক্টর জোড়া -তে সংকুচিত করে, ইনপুটটি ৫টি টোকেনের হোক কিংবা ৫০০টি টোকেনের। দীর্ঘ সিকোয়েন্সের ক্ষেত্রে এটি একটি বড় তথ্য বোতলনেক (information bottleneck) তৈরি করে। ঠিক এই সীমাবদ্ধতা দূর করার জন্যই অ্যাটেনশন মেকানিজম (attention mechanism) আবিষ্কৃত হয়েছিল।
অ্যাটেনশন মেকানিজম ডিকোডারকে তার প্রতি পদক্ষেপে কেবল শেষ স্টেটটির ওপর নির্ভর না করে এনকোডারের প্রতিটি হিডেন স্টেটকে সরাসরি দেখার সুযোগ করে দেয়। একটি একক সংকুচিত সারসংক্ষেপের ওপর ভরসা করার বদলে ডিকোডার নিজে নিজে শিখে নেয় যে আউটপুট তৈরি করার সময় ইনপুটের ঠিক কোন কোন অংশে বেশি মনোযোগ (attention) দিতে হবে।
ডিকোডারের প্রতিটি টাইম স্টেপ -এর জন্য: ১. বর্তমান ডিকোডার স্টেট এবং এনকোডারের প্রতিটি স্টেট -এর মধ্যে একটি স্কোর হিসাব করা হয়। ২. সফটম্যাক্স (softmax) ব্যবহার করে স্কোরগুলোকে ওয়েটে (weights) রূপান্তর করা হয়: ৩. একটি কনটেক্সট ভেক্টর হিসাব করা হয় — যা মূলত এনকোডার স্টেটগুলোর একটি ওয়েটেড এভারেজ বা গড়। ৪. আউটপুট তৈরি করার আগে এই ভেক্টরটিকে ডিকোডারের ইনপুটের সাথে কনক্যাটেন বা যুক্ত করা হয়।
অ্যাটেনশন মেকানিজম দীর্ঘ বাক্যের অনুবাদের মানকে নাটকীয়ভাবে উন্নত করেছে এবং এটিই পরবর্তী সময়ে ট্রান্সফরমার (Transformer) আর্কিটেকচারের মূল ভিত্তি হিসেবে কাজ করেছে।
২০১৪ সালে চো (Cho) প্রবর্তিত GRU আর্কিটেকচারটি মূলত LSTM-এর ফরগেট গেট ও ইনপুট গেটকে একত্রিত করে একটি একক আপডেট গেট (update gate) তৈরি করে এবং সেল স্টেট ও হিডেন স্টেটকে মিলিয়ে একটি একক স্টেট বানায়। এর ফলে প্যারামিটার সংখ্যা উল্লেখযোগ্যভাবে কমে যায় অথচ কাজের দক্ষতা প্রায় LSTM-এর কাছাকাছিই থাকে।
| বৈশিষ্ট্য | LSTM | GRU |
|---|---|---|
| স্টেট (States) | দুটি: hₜ এবং Cₜ | একটি: কেবল h ₜ |
| গেট (Gates) | তিনটি: forget, input, output | দুটি: update, reset |
| প্যারামিটার সংখ্যা | 4n_h(nₓ + n_h + 1) | 3n_h(nₓ + n_h + 1) |
| তুলনামূলক সাইজ | 100% (বেসলাইন) | LSTM-এর প্রায় ৭৫% |
| কখন পছন্দ করবেন | দীর্ঘ দূরত্বের নির্ভরশীলতা এবং যেখানে মডেলে অতিরিক্ত ক্যাপাসিটি প্রয়োজন | সীমাবদ্ধ কম্পিউটেশনাল রিসোর্স; সহজ কাজের ক্ষেত্রে GRU কম খরচে LSTM-এর সমান পারফর্ম করে |
# Keras-এ GRU ব্যবহার করা — একদম LSTM-এর মতোই
model = keras.Sequential([
layers.Input(shape=(20, 64)),
layers.GRU(32, return_sequences=True),
layers.GRU(16),
layers.Dense(1),
])
model.summary()GRU-তে সমমানের LSTM-এর চেয়ে ২৫% কম প্যারামিটার থাকে। বাস্তব জীবনের অনেক সাধারণ কাজেই (সেন্টিমেন্ট বিশ্লেষণ, ছোট টাইম সিরিজ ফোরকাস্টিং) GRU অনেক কম ট্রেনিং খরচে LSTM-এর সমান ফলাফল দেয়। অতিরিক্ত ক্যাপাসিটির প্রয়োজন আছে — এমন স্পষ্ট প্রমাণ থাকলেই কেবল LSTM-এ সুইচ করুন।
ট্রান্সফরমার (Vaswani et al., 2017) হলো BERT, GPT এবং আধুনিক সময়ের প্রায় সব বড় বড় লার্জ ল্যাঙ্গুয়েজ মডেলের (LLMs) পেছনের মূল আর্কিটেকচার। এদের মধ্যকার পার্থক্য জানলে আপনি বুঝতে পারবেন কখন কোনটি ব্যবহার করা উচিত।
| বৈশিষ্ট্য | LSTM | ট্রান্সফরমার (Transformer) |
|---|---|---|
| প্রসেসিং | সিকোয়েন্সিয়াল — ধাপে ধাপে (ধীরগতির) | প্যারালাল — সব পজিশন একসাথে (দ্রুতগতির) |
| দীর্ঘ মেমরি | ভালো কিন্তু দূরত্বের সাথে ক্ষয় হয় | চমৎকার — যেকোনো পজিশন থেকে যেকোনো পজিশনে সরাসরি কানেকশন |
| ট্রেনিং স্পিড | দীর্ঘ সিকোয়েন্সে ধীরগতির | অত্যন্ত দ্রুত (জিপিইউ-তে প্যারালালাইজড) |
| মেমরি ব্যবহার | O(sequence length) স্টেট | O(sequence length²) অ্যাটেনশন ম্যাট্রিক্স |
| লাইভ/স্ট্রিমিং ব্যবহার | অত্যন্ত প্রাকৃতিক — ধাপে ধাপে কাজ করে | পুরো সিকোয়েন্স প্রয়োজন হয়; লাইভে ব্যবহার করা কঠিন |
| ডেটা দক্ষতা | ছোট ডেটাসেটের ক্ষেত্রে ভালো কাজ করে | ভালো পারফর্ম করতে বিশাল ডেটা প্রয়োজন |
| ব্যাখ্যাযোগ্যতা | গেট এবং সেল স্টেটের একটি স্পষ্ট ভূমিকা আছে | অ্যাটেনশন ওয়েট সহজে ভিজ্যুয়ালাইজ করা যায় |
অফলাইন সিকোয়েন্স মডেলিং এবং প্রচুর ডেটা থাকা কাজের জন্য ট্রান্সফরমার সবখানেই রাজত্ব করছে। কিন্তু রিয়েল-টাইম স্ট্রিমিং সিনারিও (সীমাবদ্ধ মেমরিতে ধাপে ধাপে প্রসেস করা), মেমরির সীমাবদ্ধতা থাকা এম্বেডেড সিস্টেম এবং ছোট ডেটাসেটের ক্ষেত্রে (যেখানে ট্রান্সফরমার সহজেই ওভারফিট করে) LSTM-ই এখনো ডেভেলপারদের প্রথম পছন্দ।
এই চ্যাপ্টারের আর্কিটেকচারগুলো — Seq2Seq, attention, GRU — আপনারা মেশিন লার্নিংয়ের বাস্তব বিভিন্ন পেপার ও প্রজেক্টে প্রতিনিয়ত দেখতে পাবেন। মেশিন ট্রান্সলেশন, স্পিচ রিকগনিশন, অ্যাক্টিভিটি ডিটেকশন কিংবা রিয়েল-টাইম অ্যানোমালি ডিটেকশন প্রজেক্টগুলো সরাসরি এই চ্যাপ্টারের ধারণার ওপর ভিত্তি করেই তৈরি করা হয়।