Part 01 · Mathematics for AI

Vectors and Matrices

Linear AlgebraVectorsDot productMatrix multiplicationNumPy

Model এর কাছে একটা শব্দ, ছবি বা user মানে শুধু কিছু সংখ্যার list। Vector, দুইটা vector কতটা কাছাকাছি সেটা মাপার dot product, আর প্রতিটা layer যে matrix multiply চালায়।

⏱ 1-2 ঘণ্টা · Station 1 / 92

জিনিসটা কী, কেন দরকার

একটা streaming app তোমাকে একটা movie suggest করতে চায়। "আমার action ভালো লাগে, একটু romance চলে, ভাঁড়ামি না" এই কথা সে বোঝে না। সে বোঝে শুধু সংখ্যা। তাই প্রতিটা movie কে কয়েকটা সংখ্যা দিয়ে লিখে রাখে, যেমন কতটা action, কতটা comedy, কতটা romance। তোমার পছন্দও লেখে ঠিক ওই তিনটা ঘরে:

Dhaka Attack  [0.9, 0.1, 0.2]
your taste    [0.8, 0.0, 0.4]

এরকম সংখ্যার list কে বলে vector। সব AI system এর প্রথম ধাপ এটাই: একটা শব্দ, ছবি, গান বা customer কে vector বানানো। একবার vector হয়ে গেলে "এই দুইটা কতটা একরকম?" প্রশ্নটা সোজা অঙ্ক হয়ে যায়।

পুরো course এ দুইটা operation সবচেয়ে বেশি কাজ করবে:

  • Dot product মাপে দুইটা vector কতটা মিলে।
  • Matrix multiplication একসাথে অনেকগুলো dot product চালায়। Neural network এর প্রতিটা layer, LLM এর প্রতিটা attention step, ভেতরে মূলত এটাই।

ভেতরে কীভাবে চলে

Dot product. একই ঘরের সংখ্যা গুণ করো, তারপর সব যোগ করো:

[0.9, 0.1, 0.2] · [0.8, 0.0, 0.4]
= 0.9×0.8 + 0.1×0.0 + 0.2×0.4
= 0.72 + 0 + 0.08 = 0.80

যে ঘরে দুইজনেরই সংখ্যা বড় (action: 0.9 আর 0.8), সেখানে গুণফলও বড়। যে ঘরে একজন শূন্য (comedy তে তুমি দিয়েছ 0.0), সেই ঘর কিছুই যোগ করে না। মানে dot product বড় হলে বুঝবে দুইটা vector একই দিকে মুখ করে আছে।

Length আর cosine similarity. Vector লম্বা হলেও dot product বাড়ে। একটা movie এর সব সংখ্যা দ্বিগুণ করে দিলে score দ্বিগুণ হবে, অথচ সেটা তোমার পছন্দের বেশি কাছে আসেনি। শুধু দিকটা তুলনা করতে চাইলে দুইটার length দিয়ে ভাগ করো:

length(a) = √(a·a)
cosine(a, b) = (a·b) / (length(a) × length(b))      between -1 and 1

Cosine 1 মানে একই দিক, 0 মানে কোনো সম্পর্ক নেই, -1 মানে উল্টো দিক। Search engine আর RAG system (Part 5) document গুলোকে ঠিক এই সংখ্যা দিয়েই সাজায়।

Matrix. Movie vector গুলোকে row হিসেবে একটার নিচে একটা রাখলে পাও একটা matrix, shape (3, 3): 3 টা row, 3 টা column। এটাকে তোমার taste vector দিয়ে গুণ করলে প্রতি row তে একটা করে dot product হয়, মানে প্রতি movie র একটা score, এক operation এ।

Shape এর নিয়ম। (m × n) কে (n × p) দিয়ে গুণ করা যায় শুধু তখনই যখন ভেতরের দুইটা সংখ্যা মিলে, আর result হয় (m × p)। Matrix নিয়ে বেশিরভাগ আসল bug আসলে shape এর bug। তাই সবার আগে shape check করার অভ্যাস করো।

আগে অনুমান করো

32 টা token এর একটা batch, প্রতিটা 768 সংখ্যার vector, এমন একটা layer এ ঢুকল যার weight matrix (768, 3072)। বের হবে কোন shape?

ছবিতে দেখো

user tastemovies matrix (3 × 3)scores[0.8, 0.0, 0.4][0.9, 0.1, 0.2]Dhaka Attack[0.1, 0.3, 0.9]Monpura[0.6, 0.2, 0.5]Hawa0.800.440.68uuuΣΣΣ0.9×0.8 + 0.1×0.0 + 0.2×0.4 = 0.800.1×0.8 + 0.3×0.0 + 0.9×0.4 = 0.440.6×0.8 + 0.2×0.0 + 0.5×0.4 = 0.68one dot product per row; the biggest score wins
তোমার taste vector একে একে প্রতিটা movie row এর সাথে দেখা করে। প্রতিবার একটা dot product: ঘর ধরে গুণ, তারপর যোগ, আর result গিয়ে বসে scores column এ। Dhaka Attack পায় 0.80, সবচেয়ে বেশি, তাই ওটাই suggest হয়।

Code এ movie suggest

একই recommendation, code এ। NumPy তে @ operator matrix multiply করে। Go version এ loop গুলো হাতে লেখা, যাতে দেখতে পাও ভেতরে কোনো জাদু নেই।

import numpy as np

# Each movie as 3 numbers: [action, comedy, romance], each 0 to 1.
names = ["Dhaka Attack", "Monpura", "Hawa"]
movies = np.array([
    [0.9, 0.1, 0.2],
    [0.1, 0.3, 0.9],
    [0.6, 0.2, 0.5],
])
# One user's taste, in the same 3 slots.
user = np.array([0.8, 0.0, 0.4])

print("shapes:", movies.shape, "@", user.shape)

# One matrix multiply = one dot product per movie (row).
scores = movies @ user
for name, s in zip(names, scores):
    print(f"{name:<13} score {s:.2f}")
print("recommend:", names[int(np.argmax(scores))])

# Cosine similarity: dot product of the two directions, ignoring length.
def cosine(a, b):
    return float(a @ b / (np.linalg.norm(a) * np.linalg.norm(b)))

print(f"cos(Dhaka Attack, Hawa)    = {cosine(movies[0], movies[2]):.3f}")
print(f"cos(Dhaka Attack, Monpura) = {cosine(movies[0], movies[1]):.3f}")

Output (দুইটা program একই জিনিস print করে):

shapes: (3, 3) @ (3,)
Dhaka Attack  score 0.80
Monpura       score 0.44
Hawa          score 0.68
recommend: Dhaka Attack
cos(Dhaka Attack, Hawa)    = 0.883
cos(Dhaka Attack, Monpura) = 0.339

কী দেখলাম:

  • shapes: (3, 3) @ (3,) হলো shape check: 3 টা movie, প্রতিটায় 3 টা সংখ্যা, গুণ হচ্ছে 3 সংখ্যার একটা vector দিয়ে। ভেতরের 3 মিলে গেছে।
  • তিনটা score হলো diagram এর তিনটা dot product। Dhaka Attack 0.80 নিয়ে জিতেছে।
  • Cosine বলছে Dhaka Attack আর Hawa কাছাকাছি (0.883, দুইটাতেই action বেশি), আর Dhaka Attack আর Monpura অনেক দূরে (0.339, একটা action, আরেকটা romance)। হাতে কোনো rule না লিখেই "একরকম movie" পেয়ে গেলাম।

Production এ যা মাথায় রাখবে

  • সবার আগে ভাঙে shape। Code যেখানে (1, 768) আশা করছে সেখানে (768,) দিলে NumPy আর PyTorch চুপচাপ broadcast করে ভুল answer দেয়, কোনো error ছাড়াই। Function এর শুরুতে আর শেষে shape assert করো।
  • Memory খুব দ্রুত বাড়ে। দশ লাখ document, প্রতিটা 768 সংখ্যার float32 vector (4 byte করে), মানে 1,000,000 × 768 × 4 ≈ 3 GB। Vector database (Part 5) এই হিসাবের কারণেই আছে।
  • একবারেই normalise করো। Save করার সময়ই প্রতিটা vector কে তার length দিয়ে ভাগ করে রাখলে পরে cosine similarity শুধু একটা dot product, query তে খরচ কম।
  • শূন্য vector। খালি document থেকে সব শূন্যের vector আসতে পারে। তার length 0, cosine এ শূন্য দিয়ে ভাগ, ফলে NaN, আর সেটা পুরো ranking নষ্ট করে। আগে থেকে check রাখো।
  • Speed। Matrix multiply মানে লাখ লাখ আলাদা গুণ-যোগ, যেগুলো একটা আরেকটার জন্য অপেক্ষা করে না। এজন্যই হাজার হাজার ছোট core এর GPU (Part 10) এটা CPU র চেয়ে অনেক দ্রুত করে।

এক কথায়

জিনিস vector হয়; dot product মাপে দুইটা vector কতটা মিলে; matrix multiply একসাথে অনেক dot product, আর shape মিলতে হয় এভাবে: (m × n)(n × p) → (m × p)।

নিজে করে দেখো

চতুর্থ একটা movie যোগ করো, "Aynabaji" [0.7, 0.1, 0.3], আর দ্বিতীয় একজন user যে romance পাগল, [0.1, 0.1, 0.9]। দুইজন user কে একটা (2, 3) matrix এ রাখো, তারপর এক গুণেই সব user-movie score বের করো। Result এর shape কী, আর কে কোন movie পাবে?

Answer

Users (2 × 3) @ movies এর transpose (3 × 4) = (2 × 4) এর একটা score table: প্রতি user এর একটা row, প্রতি movie র একটা column। NumPy তে: users @ movies.T। User 1 পায় Dhaka Attack 0.80, Monpura 0.44, Hawa 0.68, Aynabaji 0.68, তাই এখনো Dhaka Attack। User 2 পায় 0.28, 0.85, 0.53, 0.35, তাই Monpura।

Station stamp

Chapter শেষ করো

পড়া শেষ হলে Complete চাপো, progress save হবে। XP শুধু Pro তে — Pro থাকলে এই chapter এ +10 XP পেতে।

Pro নিয়ে XP পাও →