NumPy পরিচিতি — ndarray কী
এই পাঠে যা শিখবেন
- NumPy কী এবং AI-তে কেন এত গুরুত্বপূর্ণ
- ndarray বনাম Python list — speed ও memory পার্থক্যের কারণ
- Array তৈরি —
np.array,zeros,arange,linspace,random - Array attributes — shape, dtype, ndim, size, itemsize, nbytes
- Reshape, ravel, transpose — shape পরিবর্তন
- Vectorization — loop ছেড়ে array operation
- Aggregation — sum/mean/std সহ axis parameter
- AI-এ ndarray কোথায় ব্যবহার — image, batch, embedding, weight
১ · NumPy কী এবং কেন
NumPyNumPy"Numerical Python" — Travis Oliphant ২০০৬-এ প্রকাশ করেন। Python-এ সংখ্যাগত গণনার ভিত্তি লাইব্রেরি। C ও Fortran-এ implemented; PyTorch, TensorFlow, scikit-learn, Pandas — সবই NumPy-র উপর গড়া। হলো Python-এ সংখ্যাগত গণনার ভিত্তি লাইব্রেরি। এর কেন্দ্রে আছে ndarrayndarray"N-dimensional array" — একই dtype-এর সংখ্যার contiguous memory block। NumPy-র কেন্দ্রীয় data structure। ছবি, audio, embedding, weight — সব এতে রাখা হয়। — N-মাত্রিক একক একটি data structure যেখানে একই type-এর সংখ্যা পাশাপাশি সাজানো থাকে।
AI-তে সব কিছু — ছবি, শব্দ, embedding, model weight, gradient — শেষ পর্যন্ত সংখ্যার তালিকা। সেই তালিকা দ্রুত process করার জন্য Python-এর built-in list যথেষ্ট নয়। NumPy এই শূন্যস্থান পূরণ করে — C-তে লেখা, SIMDSIMD"Single Instruction, Multiple Data" — একটি CPU instruction একসাথে অনেক সংখ্যায় কাজ করে। NumPy-র অভ্যন্তরীণ ops (BLAS, LAPACK) এই hardware feature ব্যবহার করে $O(n)$ হলেও ১০× constant factor কমায়। ব্যবহারকারী, BLAS/LAPACK-এর সাথে যুক্ত।
১) Speed: C-implemented, SIMD-aware → list-এর চেয়ে ১০-১০০× দ্রুত।
২) Memory: homogeneous dtype, contiguous block → ৪-৮× কম জায়গা।
৩) API: পুরো PyData ecosystem (PyTorch, TF, scikit-learn, Pandas) — NumPy convention অনুসরণ করে।
২ · ndarray বনাম Python list
Python-এর list একটি generic container — যেকোনো object রাখা যায়। ভেতরে list এক একটি pointer-এর array; প্রতিটি pointer আলাদা স্থানে থাকা PyObject-এ যায়। তাই [1, 2, 3]-এ ১, ২, ৩ — তিনটি আলাদা Python int object — memory-তে scattered।
ndarray উল্টো — সব element একই dtypedtype"data type" — array-এর প্রতিটি element কোন type-এ encoded। int8, int32, int64, float16, float32, float64, bool, complex — common। AI training-এ float32 default, inference-এ float16/int8। (যেমন float32) এবং memory-তে পাশাপাশি (contiguous)। তাই CPU pipeline, cache, SIMD — সব efficient ব্যবহার হয়।
৩ · Array তৈরি — অনেক উপায়
import numpy as np
# Python list থেকে
a = np.array([1, 2, 3, 4])
print("a =", a)
# Predefined patterns
zeros = np.zeros(5) # [0. 0. 0. 0. 0.]
ones = np.ones((2, 3)) # 2×3 matrix of 1.0
full = np.full((2, 2), 7) # সব 7
eye = np.eye(3) # 3×3 identity matrix
# Range-style
r = np.arange(0, 10, 2) # [0 2 4 6 8]
l = np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1.]
# Random — AI-তে weight init-এ অপরিহার্য
np.random.seed(42)
rand_u = np.random.rand(3) # uniform [0,1)
rand_n = np.random.randn(3) # normal (mean 0, std 1)
print("zeros:", zeros)
print("ones:\n", ones)
print("eye:\n", eye)
print("arange:", r)
print("linspace:", l)
print("uniform:", rand_u)
print("normal :", rand_n)
np.zeros/ones AI-তে weight initialization-এ; arange/linspace grid তৈরিতে; random.randn normal distribution-এ — যা neural network weight init-এ default (Xavier, He init এর ভিত্তি)। seed দিলে reproducibility।
৪ · Array attributes — পাঁচ চাবি
import numpy as np
# একটি 2×3×4 ছবি-আকৃতির array (3 channel, 4 width, etc.)
x = np.zeros((2, 3, 4), dtype=np.float32)
print("shape :", x.shape) # (2, 3, 4)
print("ndim :", x.ndim) # 3
print("size :", x.size) # 24 = 2*3*4
print("dtype :", x.dtype) # float32
print("itemsize :", x.itemsize) # 4 bytes (float32)
print("nbytes :", x.nbytes) # 96 = 24 * 4
# Type রূপান্তর
y = x.astype(np.float16)
print("\nfloat16 nbytes:", y.nbytes) # 48 — অর্ধেক
# Boolean array
mask = np.array([True, False, True])
print("bool itemsize:", mask.itemsize)
১) shape — প্রতিটি axis-এর দৈর্ঘ্য (tuple)।
২) ndim — axis-এর সংখ্যা (= len(shape))।
৩) size — মোট element সংখ্যা।
৪) dtype — প্রতিটি element-এর type।
৫) nbytes — মোট memory (= size × itemsize)।
৫ · Reshape, ravel, transpose
import numpy as np
a = np.arange(12) # 1-D, 12 element
print("original :", a, "shape", a.shape)
# 3×4-এ reshape
b = a.reshape(3, 4)
print("\nreshaped 3x4:\n", b)
# -1 = "তুমি হিসাব করো"
c = a.reshape(2, -1) # 2×6
print("\n2 x -1 →", c.shape)
# ravel = 1-D করো (view সাধারণত)
flat = b.ravel()
print("\nravel :", flat)
# Transpose
t = b.T # 4×3
print("\nb.T shape:", t.shape)
# 3-D transpose — axis স্পষ্ট দিতে হয়
img = np.zeros((224, 224, 3)) # H × W × C
chw = img.transpose(2, 0, 1) # C × H × W (PyTorch-এ লাগে)
print("HWC → CHW:", img.shape, "→", chw.shape)
reshape data move করে না — শুধু "view" বদলায়। HWC → CHW transpose — image processing-এ TF (channels last) থেকে PyTorch (channels first) convert-এ ব্যবহৃত।
৬ · Vectorization — গতি-গাণিতিক নীতি
একই কাজ — দু'ভাবে করা যায়। Python for-loop, অথবা NumPy vectorized op। সময়ের পার্থক্য অবিশ্বাস্য — complexity একই $O(n)$ হলেও constant factor ১০-১০০×।
import numpy as np
import time
n = 1_000_000
xs = list(range(n))
arr = np.arange(n)
# পদ্ধতি ১ — Python for-loop
t0 = time.time()
sq_loop = [x * x for x in xs]
t_loop = time.time() - t0
# পদ্ধতি ২ — NumPy vectorized
t0 = time.time()
sq_np = arr * arr # পুরো array একসাথে
t_np = time.time() - t0
print(f"Python loop : {t_loop*1000:.2f} ms")
print(f"NumPy vec : {t_np*1000:.2f} ms")
print(f"Speedup : {t_loop / max(t_np, 1e-9):.1f}x")
# একই idea — element-wise math
v = np.array([1.0, 4.0, 9.0, 16.0])
print("\nsqrt :", np.sqrt(v))
print("exp :", np.exp(np.array([0, 1, 2])))
print("sin :", np.sin(np.array([0, np.pi/2, np.pi])))
np.where, broadcasting ব্যবহার করুন।
৭ · Aggregation — sum, mean, std সহ axis
import numpy as np
# একটি 3×4 মার্ক sheet — 3 ছাত্র, 4 বিষয়
marks = np.array([
[80, 70, 90, 60],
[50, 65, 75, 85],
[95, 88, 70, 92],
])
# পুরো array-এ
print("মোট sum :", marks.sum())
print("গড় :", marks.mean())
print("std :", marks.std())
print("min/max:", marks.min(), marks.max())
# axis=0 → column বরাবর (প্রতি বিষয়)
print("\nবিষয়-ওয়ারি গড় :", marks.mean(axis=0))
# axis=1 → row বরাবর (প্রতি ছাত্র)
print("ছাত্র-ওয়ারি গড় :", marks.mean(axis=1))
# argmax — সর্বোচ্চ কোথায়?
print("\nপ্রতি ছাত্রের সেরা বিষয়:", marks.argmax(axis=1))
axis = "যে dimension collapse করব"। axis=0 → row collapse, column গড় থাকে। axis=1 → column collapse, row গড় থাকে। AI-তে batch-wise loss (axis=0), feature-wise mean (axis=0), per-sample sum (axis=1) — সব এই pattern-এ।
৮ · AI-তে ndarray কোথায় ব্যবহার
- Image: 224×224 RGB ছবি =
(224, 224, 3)uint8 ndarray = ~150 KB। - Batch tensor: ৩২টি ছবি একসাথে =
(32, 3, 224, 224)float32 — GPU-তে এক passa-এ process। - Embedding: ১০,০০০ শব্দ × ৭৬৮-D embedding =
(10000, 768)matrix। - Weight matrix: একটি Linear layer (in=768, out=512) =
(768, 512)— প্রায় ৪ লাখ parameter। - Gradient: backprop-এ — প্রতি weight-এর gradient সমান shape-এর ndarray।
- Audio: ১ সেকেন্ড mono audio =
(16000,)float32; spectrogram =(time, freq)2-D।
tensor, TensorFlow-এর Tensor, JAX-এর Array — সবাই NumPy-র ndarray-র descendant। API প্রায় একই। NumPy ভালো শিখলে ML framework-এ ঢুকতে দিন তিনেক লাগে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ Python list কেন NumPy array-এর তুলনায় ১০-১০০× ধীর? Memory layout, type dispatch, C vs interpreted — তিন দৃষ্টিতে বিশ্লেষণ করুন।
প্রশ্নটি শুধু "speed" নয় — Python-এর design philosophy ও C-extension-এর সম্পর্ক বুঝতে সাহায্য করে। তিনটি ভিন্ন কারণে এই গতির পার্থক্য তৈরি — কোনোটিই algorithm-এর জন্য নয়; দুটি একই কাজে $O(n)$ হলেও constant factor-এ ১০-১০০× তফাত।
(১) Memory layout — scattered বনাম contiguous:
- Python list = pointer-এর array। প্রতিটি pointer আলাদা স্থানে থাকা PyObject-এ যায়। CPU-কে memory-র এদিক-ওদিক jump করতে হয় — cache miss বেশি।
- ndarray = একই dtype-এর সংখ্যার একটানা block। CPU-র L1/L2 cache prefetch করতে পারে। এক cache line (৬৪ bytes) = ৮টি float64 বা ১৬টি float32 — সব একসাথে আসে।
- Cache-friendly access alone ৩-৫× speedup দিতে পারে।
(২) Type dispatch overhead:
- Python-এ
a + b= সাধারণ method call। interpreter দেখবে —a-র type কী,b-র type কী,__add__খুঁজবে, call করবে, result PyObject wrap করবে। - প্রতিটি element-এ এই overhead ~50-100 ns।
- NumPy
arr1 + arr2= একটি C function call। ভেতরে সরাসরিfloat* + float*add — কোনো type lookup নেই, কোনো object boxing নেই।
(৩) C vs interpreted execution:
- Python bytecode interpreter-এ চলে — প্রতিটি op ~১০-১০০ ns overhead।
- NumPy-র core loop C-তে compiled, GCC দ্বারা optimized।
- উপরে SIMD (SSE, AVX, NEON) — একটি instruction ৪-১৬টি element একসাথে।
- BLAS/LAPACK linkage — Intel MKL, OpenBLAS, Apple Accelerate — multi-threaded matrix op।
# বাস্তব benchmark — ১ মিলিয়ন element add
# list comprehension : ~80 ms
# np.array + np.array: ~1.5 ms
# speedup : ~50×
মূল উপলব্ধি: NumPy "magic" নয় — তিনটি engineering decision-এর ফল: homogeneous dtype + contiguous memory + C/SIMD execution। AI-তে data বিশাল হওয়ায় এই ৫০× কেবল gimmick না — practical viability-র শর্ত। Without NumPy — ChatGPT train করতে দশগুণ সময় ও খরচ।
প্র ০২
dtype কেন গুরুত্বপূর্ণ — float32 vs float64, int8 vs int64? AI training-এ memory ও precision-এর trade-off কীভাবে কাজ করে?
dtype নির্বাচন AI engineering-এ "secret hyperparameter"। সঠিক dtype = ২× কম memory, ২× দ্রুত training, GPU-তে ৪× বেশি batch — কিন্তু ভুল dtype = NaN explosion, training failure।
Common floating-point dtype:
- float64 (double, 8 bytes): ~১৫-১৬ digit precision। Scientific computing default।
- float32 (single, 4 bytes): ~৭ digit। AI training-এ default — যথেষ্ট precision, অর্ধেক memory।
- float16 (half, 2 bytes): ~৩-৪ digit। Inference ও mixed-precision training-এ।
- bfloat16 (Google, 2 bytes): float32-র range কিন্তু কম mantissa। LLM training-এ এখন standard।
- float8 / FP8 (1 byte, H100+): সবচেয়ে নতুন — extreme efficiency।
Integer dtype:
- uint8 (0-255): image pixel-এ আদর্শ।
- int32 / int64: index, label, count।
- int8: quantized inference — float32 model কে int8-এ convert করলে ৪× ছোট, ২-৪× দ্রুত।
Memory impact — বাস্তব হিসাব:
# GPT-3 175B parameter
# float32 → 700 GB
# float16 → 350 GB
# int8 → 175 GB (quantized)
# int4 → 87 GB (extreme quant)
# 80 GB H100-এ চালানো যায় কি না — dtype-এ নির্ভর
Precision-এর trade-off:
- Forward pass: float16/bfloat16-এ usually ঠিক। inference-এ লোক float16 ব্যবহার করে।
- Gradient: ছোট সংখ্যা — float16 underflow হতে পারে (~$10^{-8}$ এর নিচে → 0)। loss scaling দরকার।
- Optimizer state (Adam moments): usually float32 রাখা — accumulation-এ precision important।
- Mixed precision (AMP): compute float16, weight master copy float32। PyTorch
torch.cuda.amp।
Dtype-related bug — common:
- uint8 image-এ
img + 5overflow (250 + 10 = 4, না 260)। - int division — Python 3-এ
/float, কিন্তু NumPy int array-এ সাবধান। - Implicit upcast —
float32 + float64 = float64, memory দ্বিগুণ unnoticed।
মূল উপলব্ধি: dtype = "memory × precision × speed" এর পদক্ষেপ। AI-তে — training-এ float32/bfloat16, inference-এ float16/int8, image-এ uint8, label-এ int64। ভুল dtype "শুধু slow" নয় — wrong result বা NaN।
প্র ০৩ Vectorization কেন AI-এর মেরুদণ্ড? GPU-তে এই concept কীভাবে scale করে — CUDA, tensor core পর্যন্ত?
Vectorization = "একসাথে অনেক কাজ" — সফটওয়্যার design থেকে hardware architecture পর্যন্ত AI-র সব স্তরে এই ধারণা গাঁথা। বুঝলে — কেন GPU AI-র জন্য এত perfect তাও পরিষ্কার হয়।
স্তরে স্তরে vectorization:
- Algorithmic (Python-level): for-loop ছেড়ে whole-array op। complexity একই $O(n)$ কিন্তু interpreter overhead ০।
- SIMD (CPU-level): SSE/AVX — একটি 256-bit register-এ ৮টি float32 একসাথে add। NumPy এটা use করে।
- Multi-threaded (BLAS-level): OpenBLAS, MKL — matrix op multiple core-এ vector।
- SIMT (GPU-level): CUDA — হাজারো thread একই instruction চালায় ভিন্ন data-তে। NVIDIA-র "warp" = ৩২ thread একসাথে।
- Tensor core (specialized hardware): NVIDIA Volta (২০১৭+) — একটি cycle-এ একটি ৪×৪ matrix multiply। H100-তে প্রতি cycle ~১০২৪ FLOP।
কেন GPU AI-র জন্য perfect:
- CPU ~৮-৬৪ core, প্রতিটি smart (branch prediction, OoO execution)।
- GPU ~১০,০০০ tiny core — সব একই instruction চালায় (SIMT)।
- AI workload — same op (matrix mul, conv) on huge data = perfect vectorization fit।
- একটি matrix multiply = লক্ষ-কোটি independent multiply-add → GPU-তে parallel।
Real numbers:
# GPT-3 training
# Python loop: feasible না (years)
# NumPy CPU : ~মাস
# CUDA GPU : ~সপ্তাহ
# Tensor core: ~দিন
Vectorization-এর শর্ত:
- Independent operations: $y_i = f(x_i)$ — $y_{i-1}$-এর উপর নির্ভর করলে vectorize কঠিন।
- Regular memory access: stride pattern simple।
- Same operation: branching কম — branch mismatch → SIMT efficiency ৫০% হারায়।
AI architecture vectorization-friendly করে:
- Matrix multiply — embarrassingly parallel।
- Convolution — same kernel, ভিন্ন position।
- Attention — Q@K matmul, softmax, V@... — সব dense matmul।
- RNN sequential — তাই Transformer ৪× বেশি GPU-friendly, ফলে winner।
মূল উপলব্ধি: NumPy-তে শেখা vectorization habit — এক skill যা GPU programming, CUDA, JAX, এমনকি future neuromorphic chip-এ পর্যন্ত transfer হয়। "Avoid loops, embrace arrays" — AI engineer-এর প্রথম mantra। আজকের LLM revolution মূলত vectorization revolution-এর extension।
প্র ০৪ NumPy আজও কেন প্রাসঙ্গিক — PyTorch/TensorFlow থাকা সত্ত্বেও? Interop, prototyping, ecosystem — তিন দৃষ্টিতে।
২০০৬-এ Travis Oliphant-এর তৈরি NumPy আজও AI stack-এর মূল। ১৮ বছর পর — DL framework-এর যুগে — কেন এটা মরে যায়নি? কারণ NumPy কেবল লাইব্রেরি না; এটি একটি convention।
(১) Interop — সবার সাধারণ ভাষা:
- PyTorch tensor-কে NumPy-তে:
tensor.numpy() - NumPy থেকে PyTorch:
torch.from_numpy(arr) - TensorFlow, JAX, CuPy — সবাই NumPy API mimic করে।
- Pandas DataFrame-এর underlying = NumPy array।
- scikit-learn input/output = NumPy array।
- Matplotlib plot input = NumPy array।
- OpenCV image = NumPy uint8 array।
- PIL image →
np.asarray(img)= standard bridge।
NumPy = PyData ecosystem-এর "lingua franca"। যেকোনো দু'টি library-কে যুক্ত করতে — মাঝে NumPy।
(২) Prototyping — দ্রুত পরীক্ষা:
- GPU দরকার নেই — CPU-তে চলে।
- Eager execution — কোনো graph compile না।
- Jupyter-এ instant feedback।
- Algorithm prototype করতে — Pure NumPy-তে লেখা সবচেয়ে clear।
- সব ML paper-এর pseudocode কাছাকাছি = NumPy syntax।
একটি নতুন idea — NumPy-তে first prototype, তারপর PyTorch port — এই workflow আজও standard।
(৩) Ecosystem — ২০ বছরের dependency tree:
- SciPy — scientific computing, NumPy-র উপর।
- Pandas — DataFrame, সব underlying NumPy।
- scikit-learn — classical ML, NumPy-centric।
- statsmodels, NetworkX, Astropy, Biopython — সবাই NumPy।
- হাজার hazaar paper-এর code repository — NumPy-র উপর।
এই ecosystem replace করা practically impossible।
NumPy-র সীমা — যেখানে DL framework দরকার:
- GPU support নেই (CuPy/JAX এই গর্ত পূরণ করে)।
- Automatic differentiation নেই (autograd dorkar)।
- Production deployment — torch script, TF SavedModel।
- Distributed training।
NumPy 2.0 (২০২৪) — নতুন প্রাণ:
- Cleaner API, bool/string dtype improvements।
- Array API standard — JAX/PyTorch/CuPy compatible interface।
- "Array API" = সব framework-এর জন্য common subset → portable code।
মূল উপলব্ধি: NumPy "old" না — "foundational"। PyTorch ছাড়া AI possible, NumPy ছাড়া না। নতুন framework আসে, পুরোনো যায় — NumPy থাকে। AI engineer হিসেবে — আগে NumPy ভালো করে শিখুন, তারপর যেকোনো DL framework দিন তিনেক-এ।
অনুশীলন
-
Array তৈরি ও attribute: একটি $4 \times 5$ float32 array তৈরি করুন যা সব
3.14-এ পূর্ণ। তারপরshape,dtype,nbytesprint করুন।import numpy as np arr = np.full((4, 5), 3.14, dtype=np.float32) print("shape :", arr.shape) # (4, 5) print("dtype :", arr.dtype) # float32 print("nbytes:", arr.nbytes) # 80 = 4*5*4 print("size :", arr.size) # 20 -
Vectorization বনাম loop: ১ থেকে ১,০০,০০০ পর্যন্ত সংখ্যার বর্গের যোগফল দু'ভাবে — Python loop ও NumPy দিয়ে — হিসাব করুন।
import numpy as np import time n = 100_000 # Python loop t0 = time.time() s_loop = sum(i * i for i in range(1, n + 1)) print(f"loop : {s_loop}, {(time.time()-t0)*1000:.2f} ms") # NumPy vectorized t0 = time.time() arr = np.arange(1, n + 1) s_np = (arr * arr).sum() print(f"numpy: {s_np}, {(time.time()-t0)*1000:.2f} ms")NumPy version ১০-৫০× দ্রুত হবে। দু'টি একই উত্তর দেবে।
-
Reshape ও aggregation:
np.arange(24)থেকে $2 \times 3 \times 4$ shape-এর array বানান। প্রতিটি axis-এsumবের করুন।import numpy as np a = np.arange(24).reshape(2, 3, 4) print("shape :", a.shape) # (2, 3, 4) print("sum total :", a.sum()) # 276 print("axis=0 :", a.sum(axis=0).shape, a.sum(axis=0)) print("axis=1 :", a.sum(axis=1).shape) print("axis=2 :", a.sum(axis=2).shape) # axis=0 → (3, 4) # axis=1 → (2, 4) # axis=2 → (2, 3)মনে রাখবেন: axis collapse হয় — যে axis দিচ্ছেন সেটা output shape থেকে চলে যাবে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পাঠ ১০ · NumPy indexing ও slicing পরবর্তী পাঠ ndarray-এর element access, slice, fancy indexing, boolean mask।
- পাঠ ০৮ · Error handling ও exception আগের পাঠ Robust pipeline-এ try/except — মডিউল ১-এর শেষ পাঠ।
- পাঠ ১১ · Broadcasting — ভিন্ন shape-এ অপারেশন এই পাঠের সাথে NumPy-র "magic" — ভিন্ন shape-এর array কীভাবে একসাথে যোগ হয়।
- সব AI Courses দেখুন ABCL TECH Python, ML, DL, NLP, CV, GenAI, RL, MLOps — সব AI কোর্স একসাথে।