RL & Generative AIপড়তে ১০ মিনিট লাগবে

কিউ-লার্নিং (Q-Learning)

কোন চালটি কত ভালো, তার একটি চিট শিট (cheat sheet) তৈরি করা
scope:কোর কনসেপ্ট (মূল ধারণা)difficulty:ইন্টারমিডিয়েট (Intermediate)

চিট শিট (The Cheat Sheet)

কল্পনা করুন, আপনি প্রথমবারের মতো একটি ভিডিও গেম খেলছেন। আপনি বিভিন্ন ঘরের ভেতর দিয়ে এলোমেলোভাবে হাঁটছেন, কখনো গর্তে পড়ে যাচ্ছেন, আবার কখনো বা গুপ্তধন খুঁজে পাচ্ছেন। এভাবে ডজনখানেকবার চেষ্টা করার পর আপনি হয়তো কিছু নোট লেখা শুরু করলেন:

  • "রুম A-তে গিয়ে বামে গেলে +10 পয়েন্ট পাওয়া যায়"
  • "রুম A-তে গিয়ে ডানে গেলে গর্তে পড়তে হয় (-5 পয়েন্ট)"
  • "রুম B-তে গিয়ে ওপরের দিকে গেলে গুপ্তধন পাওয়া যায় (+100 পয়েন্ট!)"

সময় যাওয়ার সাথে সাথে আপনার এই নোটবুকটি একটি চিট শিট (cheat sheet)-এ পরিণত হবে — অর্থাৎ প্রতিটি ঘরের (যেগুলোকে আমরা স্টেট বা state বলতে পারি) জন্য এবং প্রতিটি দিকের বা চালের (যেগুলোকে অ্যাকশন বা action বলা যায়) জন্য আপনি মোটামুটি জানতে পারবেন যে সেখান থেকে ঠিক কতটুকু রিওয়ার্ড বা পুরস্কার আশা করা যায়। এই চিট শিটটিই মূলত একটি কিউ-টেবিল (Q-table), আর এটি তৈরি করার যে প্রক্রিয়া, তাকেই কিউ-লার্নিং (Q-learning) বলা হয়।

কিউ (Q) মানে কী?

এই কিউ (Q) অক্ষরটি মূলত ইংরেজিতে "কোয়ালিটি (quality)" বা গুণমান বোঝায়। Q(state, action) বলতে বোঝায় নির্দিষ্ট কোনো অবস্থায় (state) নির্দিষ্ট কোনো কাজ (action) করলে এবং এরপর থেকে পারফেক্ট কৌশল মেনে চললে ভবিষ্যতে সর্বমোট কতটুকু পুরস্কার (expected total future reward) পাওয়া যেতে পারে।

উচ্চ কিউ-ভ্যালু থাকার অর্থ হলো: "এটি দারুণ একটি চাল।" অন্যদিকে কিউ-ভ্যালু কম থাকার অর্থ হলো: "এই চাল দিলে পরিণতি খুব একটা ভালো হবে না।" একটি নিখুঁত কিউ-টেবিল যেকোনো পরিস্থিতিতে আপনাকে সবচেয়ে সেরা চালটি সম্পর্কে বলে দিতে পারে — আর তার জন্য আপনাকে কেবল সেই টেবিল থেকে সবচেয়ে বেশি কিউ-ভ্যালু থাকা কাজটিকে বেছে নিতে হবে!

কিউ-লার্নিং কীভাবে নিজেকে আপডেট করে (The Update Rule)

কিউ-লার্নিংকে কাজ করানোর পেছনে যে জাদুকরী ফর্মুলাটি কাজ করে, তা হলো:

Q(s, a) ← Q(s, a) + α * [reward + γ * max Q(s', a') - Q(s, a)]

চলুন এটিকে একটু ভেঙে দেখা যাক:

  • Q(s, a)s স্টেটে থাকা অবস্থায় a কাজটি করা কতটা ভালো হবে তার বর্তমান অনুমান।
  • α (আলফা বা alpha) — লার্নিং রেট (learning rate)। অর্থাৎ পুরনো অনুমানের তুলনায় নতুন আবিষ্কার করা তথ্যকে কতটা বিশ্বাস করা উচিত। এটি সাধারণত ০.১ বা 0.1 হয়ে থাকে।
  • reward — বা রিওয়ার্ড, অর্থাৎ a কাজটি করার ঠিক পরপরই তাৎক্ষণিকভাবে পাওয়া পুরস্কার বা পয়েন্ট।
  • γ (গামা বা gamma) — ডিসকাউন্ট ফ্যাক্টর (discount factor)। তাৎক্ষণিক পুরস্কারের তুলনায় ভবিষ্যতের পুরস্কারগুলোকে কতটা মূল্য দেওয়া উচিত। এটি সাধারণত ০.৯ বা 0.9 হয়ে থাকে।
  • max Q(s', a') — এর ঠিক পরের স্টেট s' থেকে পাওয়া সম্ভাব্য সেরা কিউ-ভ্যালুটি।

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

ডিসকাউন্ট ফ্যাক্টর (Discount Factor): ধৈর্য বনাম অধৈর্য

এই গামা (γ) মূলত নিয়ন্ত্রণ করে যে একটি এজেন্ট ভবিষ্যৎ নিয়ে কতক্ষণ পর্যন্ত ভাববে:

  • γ = 0 — এটি পুরোপুরি দূরদৃষ্টিহীন। এর ভাবগতি অনেকটা এমন যে, সে কেবল তাৎক্ষণিক পুরস্কার নিয়েই ভাবে। ঠিক এমন একটি বাচ্চার মতো যে সবসময় এখনই ক্যান্ডি পেতে চায়।
  • γ = 0.99 — সে খুবই ধৈর্যশীল। সে তাৎক্ষণিক পুরস্কারের প্রায় সমানভাবেই ভবিষ্যতের পুরস্কারগুলোকেও মূল্য দেয়। ব্যাপারটা অনেকটা রিটায়ারমেন্ট বা অবসরের জন্য বিনিয়োগ করার মতো।
  • γ = 0.9 — এটি একটি ব্যালান্সড বা ভারসাম্যপূর্ণ অবস্থা। আমাদের বাস্তব জীবনের বেশিরভাগ কাজের ক্ষেত্রেই এটিকে ব্যবহার করা হয়ে থাকে।

কিউ-লার্নিং: শূন্য থেকে সেরা পলিসি (policy) পর্যন্ত

import random
class TreasureHunt:
"""সাধারণ পরিবেশ: গুপ্তধন খুঁজুন, ফাঁদ এড়িয়ে চলুন।"""
# গ্রিড: . = খালি, T = গুপ্তধন (+10), X = ফাঁদ (-10)
grid = [
['.', '.', 'X', 'T'],
['.', 'X', '.', '.'],
['.', '.', '.', 'X'],
['.', '.', '.', '.']
]
def __init__(self):
self.reset()
def reset(self):
self.pos = (0, 3) # নিচের-বামে
return self.pos
def step(self, action):
x, y = self.pos
moves = {0: (0,-1), 1: (0,1), 2: (-1,0), 3: (1,0)} # ওপরে, নিচে, বামে, ডানে
dx, dy = moves[action]
nx, ny = max(0,min(3,x+dx)), max(0,min(3,y+dy))
self.pos = (nx, ny)
cell = self.grid[ny][nx]
if cell == 'T': return self.pos, 10, True
if cell == 'X': return self.pos, -10, True
return self.pos, -0.1, False # ছোট ধাপের পেনাল্টি বা শাস্তি
def q_learning(episodes=1000):
env = TreasureHunt()
actions = [0, 1, 2, 3] # ওপরে, নিচে, বামে, ডানে
Q = {}
alpha, gamma, epsilon = 0.2, 0.9, 0.2
for ep in range(episodes):
state = env.reset()
for _ in range(20):
if state not in Q:
Q[state] = [0.0] * 4
# এপসাইলন-গ্রিডি (Epsilon-greedy)
if random.random() < epsilon:
action = random.choice(actions)
else:
action = max(actions, key=lambda a: Q[state][a])
next_state, reward, done = env.step(action)
if next_state not in Q:
Q[next_state] = [0.0] * 4
# কিউ-লার্নিং আপডেট (Q-learning update)
best_next = max(Q[next_state])
Q[state][action] += alpha * (reward + gamma * best_next - Q[state][action])
state = next_state
if done:
break
return Q
random.seed(42)
Q = q_learning()
arrows = ['^', 'v', '<', '>']
print("শেখা কিউ-ভ্যালু এবং সেরা চালগুলো:")
print("গ্রিড: . = নিরাপদ, X = ফাঁদ, T = গুপ্তধন\n")
for y in range(4):
row_str = ""
for x in range(4):
cell = TreasureHunt.grid[y][x]
if cell in ('T', 'X'):
row_str += f" {cell} "
elif (x,y) in Q:
best = arrows[max(range(4), key=lambda a: Q[(x,y)][a])]
row_str += f" {best} "
else:
row_str += " ? "
print(row_str)
Output
শেখা কিউ-ভ্যালু এবং সেরা চালগুলো:
গ্রিড: . = নিরাপদ, X = ফাঁদ, T = গুপ্তধন

  >    >    X    T  
  ^    X    ^    <  
  >    >    ^    X  
  ^    >    >    ^  
Note: কিউ-লার্নিং হলো অফ-পলিসি (off-policy): কিউ-লার্নিংয়ের সবচেয়ে দারুণ দিক হলো এটি খোঁজার বা এক্সপ্লোর (explore) করার সময় এজেন্ট বর্তমানে যে নিয়ম বা পলিসিই মেনে চলুক না কেন, এটি নিজে নিজে ঠিকই 100% সঠিক বা অপ্টিমাল (optimal) পলিসিটি শিখে নিতে পারে। এজেন্ট ভুল পথে পা বাড়ালেও কিংবা এলোমেলো কাজ করলেও, এই কিউ-টেবিলটি দিনের শেষে ঠিকঠাক ভ্যালুই জমায়েত (converge) করে। এটিকে "অফ-পলিসি লার্নিং (off-policy learning)" বলা হয়, আর এ কারণেই কিউ-লার্নিং এত বেশি বিশ্বস্ত এবং যুগান্তকারী একটি ব্যাপার।

কিউ-টেবিল থেকে ডিপ কিউ-নেটওয়ার্ক (DQN)

ছোট ছোট সমস্যার জন্য (যেমন একটি 4x4 গ্রিড, যেখানে মাত্র ১৬টি স্টেট থাকে) কিউ-টেবিলগুলো দারুণ কাজ করে। কিন্তু এমন একটি ভিডিও গেমের কথা ভাবুন তো, যার স্ক্রিনে লাখ লাখ বা মিলিয়ন মিলিয়ন বিভিন্ন ধরনের কনফিগারেশন থাকে! এত বিশাল জিনিসের জন্য আপনি কখনোই একটি সাধারণ টেবিল ব্যবহার করতে পারবেন আধুনিক।

২০১৩ সালে ডিপমাইন্ড (DeepMind) একটি যুগান্তকারী পরিবর্তন নিয়ে আসে: তারা এই সাধারণ কিউ-টেবিলকে নিউরাল নেটওয়ার্ক (neural network) দিয়ে প্রতিস্থাপন করে দেয়। এই নেটওয়ার্ক যেকোনো স্টেটকে ইনপুট হিসেবে নেয় এবং তার সব কয়টি অ্যাকশনের জন্য কিউ-ভ্যালুর ফলাফল বা আউটপুট জানিয়ে দেয়। আর এরই নাম হলো ডিপ কিউ-নেটওয়ার্ক (Deep Q-Network বা DQN)

এই ডিকিউএন (DQN)-ই পরবর্তীতে মানুষের চেয়ে সফলভাবে ৪৯টি আটারি গেম (Atari games) খেলা শেখার জন্য ব্যাপক সাড়া ফেলেছিল — যার জন্য গেমের কোনো নিয়মই তাকে আলাদা করে শেখানো হয়নি, বরং সে স্ক্রিনের ফ্রেমে থাকা পিক্সেল (pixels) ব্যবহার করেই সব শিখে নিয়েছিল। এই একই অ্যালগরিদম ঠিক একইভাবে কেবল লাখ লাখ বার গেমটি খেলে এবং কোন চালগুলো সবচেয়ে বেশি পয়েন্ট দিচ্ছে তা বুঝে নিয়েই পং (Pong), ব্রেকআউট (Breakout), এবং স্পেস ইনভেডারস (Space Invaders)-এর মতো বিখ্যাত সব ক্লাসিক গেম খেলা শিখে ফেলেছিল!

বর্তমানে রোবোটিক্স (robotics), রেকমেন্ডেশন সিস্টেম (recommendation system), এমনকি গুগলেও চিপ ডিজাইনিংয়ের (chip design) মতো কাজে এই DQN এবং এর বংশধরদের ব্যবহার করা হয়ে থাকে।

ছোট কুইজ

Q(s, a) মূলত কী প্রকাশ করে?
Challenge

পড়া চালিয়ে যান