Məzmuna keç
Educora
Universitet22 dəq37 / 42

PyTorch: tenzorlar

PyTorch-u quraşdır və onun əsas verilənlər tipini öyrən: tenzorun yaradılması, dtype və shape, reshape/view, indeksləmə, yayımlama (broadcasting), @ ilə matris hasili, GPU və NumPy ilə əlaqə.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • PyTorch-u virtual mühitdə quraşdırmaq və CPU ilə CUDA versiyalarını fərqləndirmək
  • Tenzor yaratmaq, onun shape və dtype xassələrini oxumaq və dəyişmək
  • Yayımlama qaydalarını və matris hasilini tətbiq edərək nəticənin ölçüsünü əvvəlcədən demək
  • Tenzorları CPU və GPU arasında köçürmək, NumPy massivlərinə çevirmək

NumPy massivləri ədədi hesablamalar üçün əladır, amma dərin öyrənmə üçün onlara iki şey çatmır: onlar GPU-da işləmir və törəmələri avtomatik hesablaya bilmir. PyTorch məhz bu iki boşluğu doldurur. Onun əsas obyekti — tenzor — NumPy massivinə çox bənzəyir, lakin videokartda işləyə və öz qradiyentlərini izləyə bilir. Bu dərsdə tenzorlarla sərbəst işləməyi öyrənəcəyik; növbəti dərs isə avtomatik törəmələrə həsr olunub.

PyTorch nədir və necə quraşdırılır

PyTorch — Meta (keçmiş Facebook) şirkətinin süni intellekt laboratoriyasında yaradılmış açıq mənbəli dərin öyrənmə kitabxanasıdır; 2022-ci ildən Linux Foundation nəzdindəki PyTorch Foundation tərəfindən idarə olunur. Tədqiqatçılar və şirkətlər onu neyron şəbəkələri yaratmaq, öyrətmək və tətbiq etmək üçün geniş istifadə edir. PyTorch brauzerdə işləmir, ona görə bu moduldakı PyTorch kodlarını öz kompüterində işə salmalısan; nəticələri isə hər kodun altında görə bilərsən.

  1. 1
    Virtual mühit yarat

    Layihə qovluğunda python -m venv .venv yaz və mühiti aktivləşdir. Belə olduqda PyTorch digər layihələrinə qarışmır.

  2. 2
    CPU və ya CUDA versiyasını seç

    NVIDIA videokartın yoxdursa, CPU versiyası bu modul üçün tamamilə kifayətdir. GPU (CUDA) versiyası üçün dəqiq əmri pytorch.org saytındakı seçicidən — əməliyyat sistemini və CUDA versiyasını seçərək — götür.

  3. 3
    Quraşdır və yoxla

    pip install torch əmrini icra et, sonra Python-da import torch yazıb versiyanı çap et.

Terminal
python -m venv .venv
# Windows: .venv\Scripts\activate    macOS/Linux: source .venv/bin/activate
pip install torch numpy
# CPU-only build (smaller download):
pip install torch --index-url https://download.pytorch.org/whl/cpu
Python
import torch

print(torch.__version__)
print(torch.cuda.is_available())
Gözlənilən nəticə
2.14.0+cpu
False
Versiya nömrəsi səndə fərqli ola bilər. NVIDIA GPU və CUDA versiyası quraşdırılıbsa, ikinci sətir True olacaq.
Tərif
Tenzor

Eyni tipli ədədlərdən ibarət çoxölçülü massiv. Ölçülərin sayı (ndim) 0 olanda skalyar, 1 — vektor, 2 — matris, 3 və daha çox — ümumi tenzordur. Hər tenzorun shape (hər ölçü üzrə uzunluq), dtype (elementlərin tipi) və device (CPU və ya GPU) xassələri var.

Verilənshapeİzah
itkinin qiyməti()skalyar, 0 ölçü
cədvəl verilənləri(N, D)N nümunə, D əlamət
rəngli şəkil(3, H, W)RGB kanalları, hündürlük, en
şəkillər paketi(N, C, H, W)PyTorch-da şəkillər üçün standart düzülüş
mətnlər paketi(N, T, E)T token, hər biri E ölçülü vektor

Tenzor yaratmaq: shape və dtype

Python
import torch

a = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(a)
print(a.shape, a.ndim, a.dtype)
print(torch.tensor([1.5, 2.0]).dtype)
print(torch.zeros(2, 3))
print(torch.arange(0, 10, 3))
torch.manual_seed(42)
print(torch.rand(2, 2))
print(a.float().dtype, a.to(torch.float16).dtype)
Gözlənilən nəticə
tensor([[1, 2, 3],
        [4, 5, 6]])
torch.Size([2, 3]) 2 torch.int64
torch.float32
tensor([[0., 0., 0.],
        [0., 0., 0.]])
tensor([0, 3, 6, 9])
tensor([[0.8823, 0.9150],
        [0.3829, 0.9593]])
torch.float32 torch.float16
  • torch.tensor(...) tipi özü müəyyən edir: tam ədədlər → int64, kəsr ədədlər → float32. NumPy-da isə kəsr ədədlər üçün susmaya görə float64 olur!
  • torch.zeros, torch.ones, torch.arange, torch.linspace hazır tenzorlar yaradır; torch.rand (0 ilə 1 arasında bərabər paylanma) və torch.randn (standart normal paylanma) isə təsadüfi tenzorlar.
  • torch.manual_seed(42) təsadüfi ədədlər generatorunu sabitləyir — nəticələri təkrarlamaq mümkün olur.
  • .float(), .long() və ya .to(torch.float16) tipi dəyişir və yeni tenzor qaytarır.
dtypeBaytHarada işlədilir
torch.float324çəkilər, girişlər, itkilər — susmaya görə tip
torch.float16 / torch.bfloat162GPU-da qarışıq dəqiqlikli (mixed precision) sürətli öyrətmə
torch.int648sinif nişanları, indekslər, token nömrələri
torch.bool1maskalar (məsələn, x > 0)
numel = d₁ · d₂ · … · dₖ memory = numel · s
burada:
  • d₁ … dₖshape-in ölçüləri
  • numelelementlərin sayı (x.numel())
  • sbir elementin ölçüsü, bayt (x.element_size())
Nümunə 1: şəkillər paketi yaddaşda nə qədər yer tutur?

224 × 224 ölçülü 64 rəngli şəkildən ibarət paket float32 tipində saxlanılır. Tenzorun shape-i nədir və o, neçə bayt tutur? float16 olsa necə?

Həllini göstər
Shape: (64, 3, 224, 224).
numel = 64 · 3 · 224 · 224 = 9 633 792.
Yaddaş = 9 633 792 · 4 = 38 535 168 bayt ≈ 38,5 MB.
float16-da hər element 2 bayt olduğundan yaddaş iki dəfə azdır: ≈ 19,3 MB. Qarışıq dəqiqlik GPU yaddaşına məhz buna görə qənaət edir.

Formanın dəyişdirilməsi və indeksləmə

Python
import torch

m = torch.arange(12).reshape(3, 4)
print(m)
print(m[0], m[:, 1])
print(m[1, 2].item())
print(m[m > 8])
v = m.view(2, 6)
print(v.shape, m.T.shape)
print(m.unsqueeze(0).shape, m.flatten().shape)
v[0, 0] = 100
print(m[0, 0])
Gözlənilən nəticə
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]])
tensor([0, 1, 2, 3]) tensor([1, 5, 9])
6
tensor([ 9, 10, 11])
torch.Size([2, 6]) torch.Size([4, 3])
torch.Size([1, 3, 4]) torch.Size([12])
tensor(100)
  • İndeksləmə NumPy-dakı kimidir: m[0] — birinci sətir, m[:, 1] — ikinci sütun, m[m > 8] — maska ilə seçmə. .item() bir elementli tenzoru adi Python ədədinə çevirir.
  • reshape(2, 6) və view(2, 6) elementlərin sayını dəyişmədən formanı dəyişir; bir ölçünün yerinə -1 yazsan, PyTorch onu özü hesablayar: x.view(-1, 784).
  • view verilənləri kopyalamır, eyni yaddaşa başqa «pəncərədən» baxır. Buna görə v[0, 0] = 100 əməliyyatı m-i də dəyişdi!
  • unsqueeze(0) ölçüsü 1 olan yeni ox əlavə edir (məsələn, tək şəkli paketə çevirmək üçün), squeeze() belə oxları silir, .T matrisi transponə edir, permute isə oxların yerini istənilən qaydada dəyişir.

Əməliyyatlar: yayımlama və matris hasili

+, -, *, /, ** operatorları elementlər üzrə işləyir. sum, mean, max kimi reduksiyalar dim arqumenti ilə müəyyən ox boyunca hesablanır: a.mean(dim=0) sütunların orta qiymətidir. Formaları fərqli olan tenzorlar yayımlama (broadcasting) qaydaları ilə uyğunlaşdırılır:

  1. Formalar sağdan sola müqayisə olunur; qısa formanın solundan ölçüsü 1 olan oxlar əlavə edilmiş sayılır.
  2. İki ölçü bərabərdirsə və ya onlardan biri 1-dirsə, onlar uyğundur.
  3. Ölçüsü 1 olan ox digərinin uzunluğuna qədər «uzadılır» (verilənlər kopyalanmadan).
Python
import torch

a = torch.tensor([[1., 2.], [3., 4.]])
b = torch.tensor([10., 20.])
print(a + b)
print(a * a)
print(a @ a)
print(a.sum(), a.mean(dim=0))
X = torch.ones(64, 3)
W = torch.ones(3, 5)
print((X @ W).shape)
print((torch.ones(4, 1) + torch.ones(3)).shape)
Gözlənilən nəticə
tensor([[11., 22.],
        [13., 24.]])
tensor([[ 1.,  4.],
        [ 9., 16.]])
tensor([[ 7., 10.],
        [15., 22.]])
tensor(10.) tensor([2., 3.])
torch.Size([64, 5])
torch.Size([4, 3])
C = A @ B, Cᵢⱼ = ∑ₖ Aᵢₖ · Bₖⱼ, (m × n) @ (n × p) → (m × p)
burada:
  • A, Bölçüləri m × n və n × p olan matrislər
  • ndaxili ölçü — hər iki matrisdə eyni olmalıdır
  • CᵢⱼA-nın i-ci sətri ilə B-nin j-ci sütununun skalyar hasili

Matris hasili neyron şəbəkələrin əsas əməliyyatıdır: (N, D) ölçülü girişləri (D, K) çəkilər matrisinə vurmaqla bütün paketi bir anda emal edirik. Daha çox ölçülü tenzorlarda @ son iki oxa tətbiq olunur, qalan oxlar isə paket oxları sayılır.

Nümunə 2: nəticənin formasını əvvəlcədən de

Hər əməliyyatın nəticəsinin formasını tap və ya xəta olacağını göstər: a) (64, 3) @ (3, 5); b) (4, 1) + (3,); c) (32, 10) + (10,); d) (2, 3) @ (2, 3); e) (8, 1, 6) + (7, 1).

Həllini göstər
a) Daxili ölçülər 3 = 3, «yox olur»: (64, 5).
b) (3,) → (1, 3); 4 ilə 1, 1 ilə 3 uyğundur: (4, 3).
c) (10,) → (1, 10), hər sətrə əlavə olunur (sürüşmə vektoru belə işləyir): (32, 10).
d) Daxili ölçülər 3 ≠ 2 — xəta. Lazım olan A @ B.T idi: (2, 2).
e) (7, 1) → (1, 7, 1); oxlar üzrə: 8 və 1 → 8, 1 və 7 → 7, 6 və 1 → 6: (8, 7, 6).

GPU və NumPy ilə iş

Videokartda minlərlə sadə nüvə var və matris hasilini paralel hesablayır; böyük modellərin GPU-da öyrədilməsi çox vaxt CPU ilə müqayisədə bir neçə dəfədən onlarla dəfəyə qədər sürətli olur. Standart üsul: kodun əvvəlində device seçmək, sonra modeli və verilənləri .to(device) ilə ora köçürmək. Apple Silicon kompüterlərdə GPU üçün 'mps' qurğusu var.

Python
import numpy as np
import torch

device = 'cuda' if torch.cuda.is_available() else 'cpu'
x = torch.ones(2, 2, device=device)
print(device, x.device)
arr = np.array([1.0, 2.0, 3.0])
t = torch.from_numpy(arr)
arr[0] = 99
print(t)
back = (t * 2).numpy()
print(back, type(back).__name__)
Gözlənilən nəticə
cpu cpu
tensor([99.,  2.,  3.], dtype=torch.float64)
[198.   4.   6.] ndarray
GPU olmayan kompüterdə nəticə belədir; CUDA olan kompüterdə birinci sətir cuda cuda:0 olacaq.

torch.from_numpy(arr) massivin yaddaşını paylaşır: arr[0] = 99 dəyişikliyi tenzorda da göründü. Diqqət et ki, dtype float64 qaldı — öyrətmədən əvvəl .float() ilə float32-yə çevirmək lazımdır. Əks istiqamətdə .numpy() yalnız CPU-dakı tenzorlar üçün işləyir: GPU-dakı tenzoru əvvəlcə .cpu() ilə geri gətir, qradiyent izlənirsə, əvvəlcə .detach() çağır: t.detach().cpu().numpy().

Əsas fikirlər

  • Tenzor — shape, dtype və device xassələri olan çoxölçülü massivdir; PyTorch-da şəkillər (N, C, H, W) formasında saxlanılır.
  • Kəsr ədədlər üçün susmaya görə tip float32, nişanlar və indekslər üçün int64-dür.
  • view yaddaşı paylaşır və ardıcıl yaddaş tələb edir; əmin deyilsənsə, reshape işlət.
  • Yayımlama formaları sağdan müqayisə edir: ölçülər bərabər və ya biri 1 olmalıdır. @ matris hasilidir: (m × n) @ (n × p) → (m × p).
  • Model və verilənlər .to(device) ilə eyni qurğuya köçürülür; from_numpy və .numpy() yaddaşı paylaşır.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
torch.tensor([1.5, 2.0]).dtype nəyə bərabərdir?