অধ্যায় 2 · ভেক্টর ও ম্যাট্রিক্স
ম্যাট্রিক্স গুণ ও শেপ
- পৃষ্ঠা 5 / 17
- 3 মিনিট পড়া
দুটো ম্যাট্রিক্স গুণ করাই সেই কাজ, যা দ্রুত করার জন্য GPU বানানো হয়েছে, আর মডেলের হিসাবের বেশিরভাগ সময় এখানেই যায়। হাতে প্রায় কখনোই করবেন না, কিন্তু যে একটা নিয়ম ঠিক করে গুণটা চলবে কিনা, সেটা জানতেই হবে।
শেপের নিয়ম
(m × n) @ (n × p) → (m × p)
ভেতরের মাপ মিলতে হবে: n আর nimport numpy as np
A = np.ones((2, 3)) # 2 × 3
B = np.ones((3, 4)) # 3 × 4
print((A @ B).shape) # ভেতরের মাপ মেলে (3 আর 3): ফলাফল 2 × 4
try:
B @ A # 3 × 4 গুণ 2 × 3: ভেতরের মাপ 4 আর 2 আলাদা
except ValueError as error:
print("ValueError:", error)(2, 4)
ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 4)এরর মেসেজটা লম্বা, কিন্তু শেষ অংশেই সব বলা আছে: size 2 is different from 4। এটা পেলে দুই পাশের .shape প্রিন্ট করুন, পাশাপাশি লিখুন, আর ভেতরের মাপ মিলিয়ে দেখুন। প্রায়ই সমাধান একটা ট্রান্সপোজ (.T)।
ফলাফলের প্রতিটা উপাদান একটা ডট প্রোডাক্ট: বাম ম্যাট্রিক্সের সারি i আর ডান ম্যাট্রিক্সের কলাম j। সাধারণ সংখ্যার মতো নয়, এখানে ক্রম গুরুত্বপূর্ণ — A @ B সাধারণত B @ A-এর সমান নয়, আর প্রায়ই এদের একটা অনুমোদিতই নয়।
এক ধাপে পুরো ব্যাচ
মডেল একবারে একটা উদাহরণ প্রসেস করে না। অনেকগুলো ইনপুট একটা ম্যাট্রিক্সে সাজায়, প্রতি সারিতে একটা, আর একটা ম্যাট্রিক্স গুণেই পুরো ব্যাচ একটা লেয়ারের মধ্য দিয়ে পাঠায়:
import numpy as np
W = np.array([[0.2, 0.8, -0.5],
[1.0, -0.3, 0.4]]) # আগের সেই 2 × 3 লেয়ার
b = np.array([0.1, -0.2])
X = np.array([[0.5, -1.0, 2.0], # একটা ব্যাচ: ৪টা ইনপুট, প্রতি সারিতে একটা
[1.0, 0.0, 0.0],
[0.0, 1.0, 1.0],
[2.0, 2.0, 2.0]])
Z = X @ W.T + b # (4 × 3) @ (3 × 2) = 4 × 2
print(Z.shape)
print(Z)(4, 2)
[[-1.6 1.4]
[ 0.3 0.8]
[ 0.4 -0.1]
[ 1.1 2. ]]প্রথম সারিটা আগের পাতার একক-ইনপুটের ফলাফলের সাথে মেলে। চারটা ইনপুট, এক লাইন কোড, আর GPU-তে খরচ প্রায় একটার সমান। মডেল ট্রেন আর চালানো যে সাশ্রয়ী, তার কারণ ব্যাচিং।
এমবেডিং লুকআপ একটা ম্যাট্রিক্স গুণ
একটা ল্যাঙ্গুয়েজ মডেল প্রতিটা টোকেনের জন্য একটা বড় ম্যাট্রিক্সে এক সারি এমবেডিং রাখে। একটা টোকেনের সারি বেছে নেওয়াকে লেখা যায় একটা ওয়ান-হট ভেক্টর (সব শূন্য, একটা ১) গুণ সেই ম্যাট্রিক্স:
import numpy as np
vocab = ["the", "cat", "sat", "mat"]
E = np.array([[0.1, 0.3], # প্রতি শব্দে এক সারি (এমবেডিং)
[0.9, 0.2],
[0.4, 0.8],
[0.7, 0.1]])
one_hot = np.array([0, 1, 0, 0]) # "cat"
print(one_hot @ E) # ম্যাট্রিক্স গুণ সারি 1 বেছে নেয়
print(E[vocab.index("cat")]) # তাই লাইব্রেরিগুলো সরাসরি সারিটা ইনডেক্স করে[0.9 0.2]
[0.9 0.2]গাণিতিকভাবে এটা গুণ; বাস্তবে লাইব্রেরিগুলো সরাসরি সারিটা পড়ে নেয়, যা অনেক দ্রুত। পেপারে যখন পড়বেন "ইনপুটকে এমবেডিং ম্যাট্রিক্স দিয়ে গুণ করা হয়", এখন জানেন এর মানে "প্রতিটা টোকেনের ভেক্টর খুঁজে আনা"।
নিজে চেষ্টা করুন
(5 × 2) @ (2 × 7)-এর শেপ কী?(2 × 7) @ (5 × 2)কি চলবে?AআরBদুটোই 2 × 3 বানিয়েA @ B.Tগুণ করুন। কোন শেপ আসে?- একটা ওয়ান-হট ভেক্টর দিয়ে "mat"-এর এমবেডিং খুঁজে বের করুন।