Гузариш ба мундариҷа
Мавзӯи 6 аз 6

Маълумот ва шинохти рақамҳо

Чаро маълумотро аз модел ҷудо мекунем

Дар мисолҳои аввал ҳама маълумот дар як тензор ҷой мегирифт. Маҷмӯи воқеӣ метавонад ҳазорҳо файл дошта бошад: онҳоро хондан, омода кардан ва бо ҷавобҳои дуруст пайвастан лозим аст. Dataset як намуна ва DataLoader ҷамъкунии намунаҳоро ба бастаҳо тавсиф мекунад. Ҳамин тавр модел новобаста аз тарзи нигоҳдорӣ як формати вуруд мегирад.

Натиҷаи курс маълумот, бастаҳо, шабака ва омӯзишро барои шинохти рақамҳо мепайвандад. Аз мисолҳои хурди ададӣ оғоз мекунем.

1. Тензорҳои тайёр: TensorDataset

Аломатҳо (features) қиматҳои вуруд ва барчасп (label) ҷавоби дуруст аст. Дар TensorDataset(x, y) дарозии меҳвари аввали тензорҳо бояд якхела бошад. Муроҷиат бо индекс унсурҳои мувофиқро якбора аз ҳар ду тензор медиҳад.

import torch
from torch.utils.data import TensorDataset
x = torch.tensor([[0.0, 1.0], [2.0, 3.0], [4.0, 5.0]])
y = torch.tensor([0, 1, 0])
ds = TensorDataset(x, y)
features, label = ds[1]
print(len(ds), features.tolist(), label.item())

Натиҷа:

3 [2.0, 3.0] 1

Индекси 1 намунаи дуюмро гирифт, на аломати дуюмро. Робитаи аломатҳо бо барчаспҳоро нигоҳ доред: алоҳида омехтани x ва y ҷавобҳои омӯзиширо вайрон мекунад.

2. Dataset-и худ

Барои маҷмӯи дорои дастрасӣ бо индекс __len__, шумораи намунаҳо, ва __getitem__, омодасозии як намуна, лозиманд. Дар маҷмӯи ченкуниҳо ададҳои аслиро нигоҳ дошта, танҳо ҳангоми муроҷиат табдил медиҳем. Индексро ҳамчун барчасп мегирем, то мувофиқат намоён бошад.

import torch
from torch.utils.data import Dataset
class Readings(Dataset):
    def __init__(self, values):
        self.values = values

    def __len__(self):
        return len(self.values)

    def __getitem__(self, i):
        return torch.tensor([self.values[i] / 10], dtype=torch.float32), i

ds = Readings([10, 20, 30])
features, label = ds[2]
print(len(ds), features.tolist(), label)

Натиҷа:

3 [3.0] 2

Дар маҷмӯи воқеӣ __getitem__ метавонад файлро хонад ва табдилҳо кунад. Боркунии ҳангоми дархост (lazy loading) маънои хондани маълумотро ҳангоми зарурат дорад, на ҳамаашро якбора. Формати ҳар намуна бояд яксон бошад: масалан тензори аломатҳои float32 ва барчаспи бутун. DataLoader бо танзимоти пешфарз тасвирҳои андозаашон гуногунро бе коркарди иловагӣ ба як тензори одӣ ҷамъ карда наметавонад.

3. Бастаҳо ва бақияи охир

batch_size шумораи намунаҳоро дар баста муайян мекунад. DataLoader чанд ҷуфтро аз Dataset гирифта, тензорҳоро дар меҳвари нави 0 якҷо ва барчаспҳоро ҷамъ мекунад. Аз ин рӯ, аломатҳои шакли (1,) ба (B, 1) табдил меёбанд, ки B андозаи воқеии баста аст.

import torch
from torch.utils.data import DataLoader, TensorDataset
ds = TensorDataset(torch.arange(5).float().reshape(5, 1), torch.arange(5))
loader = DataLoader(ds, batch_size=2, shuffle=False)
for xb, yb in loader:
    print(tuple(xb.shape), yb.tolist())
print(len(loader))
print(len(DataLoader(ds, batch_size=2, drop_last=True)))

Натиҷа:

(2, 1) [0, 1]
(2, 1) [2, 3]
(1, 1) [4]
3
2

Барои панҷ намуна ва андозаи бастаи ду андозаҳои 2, 2 ва 1 ҳосил мешаванд. len(dataset) шумораи намунаҳо ва len(loader) шумораи бастаҳост. Бақия бо танзимоти пешфарз мемонад; drop_last=True онро мепартояд. Дар санҷиш ин метавонад як қисми маълумотро аз меъёр хориҷ кунад. Код набояд фарз кунад, ки ҳар баста ҳатман пурра аст.

4. Омехтакунӣ ва такрорпазирӣ

Агар маълумот аз рӯи синф ҷобаҷо шуда бошад, бастаҳои ҳамсоя метавонанд хеле монанд шаванд. shuffle=True пеш аз гузариш тартиби индексҳоро иваз карда, ҷуфтҳои аломат ва барчаспро нигоҳ медорад. Ин барои омӯзиш аксар вақт муфид аст; барои санҷиш одатан тартиби устуворро интихоб мекунанд.

import torch
from torch.utils.data import DataLoader, TensorDataset
ds = TensorDataset(torch.arange(6))
for _ in range(2):
    g = torch.Generator().manual_seed(12)
    loader = DataLoader(ds, batch_size=3, shuffle=True, generator=g)
    print([batch[0].tolist() for batch in loader])

Натиҷа:

[[4, 3, 1], [5, 2, 0]]
[[4, 3, 1], [5, 2, 0]]

Генераторҳои нав бо як seed тартибро такрор мекунанд. Як генератор дар эпохаҳои нав ҳолаташро пеш бурда, одатан тартибро иваз мекунад; онро ҳар эпоха аз нав насозед. Дар ин ҷо num_workers=0-и пешфарз бе равандҳои кории иловагӣ истифода мешавад.

5. Эпохаҳо ва ба назар гирифтани андозаи баста

Ҳангоми омӯзиш давраи берунӣ эпохаҳо ва дохилӣ ҷуфтҳои xb, yb-ро аз loader мегузарад. Барои ҳар баста қадами шиноси оптимизатор иҷро мешавад. Ин талаботи хотираро кам мекунад: қиматҳои мобайнии граф танҳо барои бастаи ҷорӣ лозиманд.

Ҳангоми арзёбии хатои миёна андозаи бастаи охирро ба назар гиред. Агар миёнаҳои се бастаро одӣ миёна кунем, бастаи якнамунагӣ ҳамвазни бастаи дунамунагӣ мешавад. Мисоли зерин MSE-и умумии модели собитро ҳисоб мекунад: хатои ҳар баста бо шумораи намунаҳояш вазн дода мешавад.

import torch
from torch import nn
from torch.utils.data import DataLoader, TensorDataset
x = torch.tensor([[1.0], [2.0], [3.0], [4.0], [5.0]])
y = 2 * x
ds = TensorDataset(x, y)
loader = DataLoader(ds, batch_size=2, shuffle=False)
model = nn.Linear(1, 1, bias=False)
with torch.no_grad():
    model.weight.fill_(1.0)
model.eval()
total, count = 0.0, 0
with torch.no_grad():
    for xb, yb in loader:
        loss = nn.functional.mse_loss(model(xb), yb)
        total += loss.item() * len(xb)
        count += len(xb)
print(count, total / count)

Натиҷа:

5 11.0

Қиматҳои мутлақи фарқҳо дар ин ҷо 1, 2, 3, 4, 5 мебошанд. Миёнаи квадратҳо (1 + 4 + 9 + 16 + 25) / 5 = 11 аст. Санҷиш backward ё step-ро даъват намекунад ва вазнҳоро тағйир намедиҳад.

6. Аз логитҳо ба эҳтимолҳо

Логитҳо баҳоҳои дорои миқёси озоданд. Softmax онҳоро ба қиматҳои мусбат бо ҷамъи 1 табдил медиҳад. Барои як вектори синфҳо dim=0, барои ҷадвали (N, C) меҳвари синфҳоро интихоб кунед. Ба ҳамаи логитҳо илова кардани як собит тақсимотро тағйир намедиҳад.

import torch
logits = torch.tensor([0.0, 0.0, 0.0])
p = torch.softmax(logits, dim=0)
print([round(v, 3) for v in p.tolist()])
print(round(p.sum().item(), 3), p.argmax().item())
print(p.max().item() >= 0.5)
print(torch.allclose(p, torch.softmax(logits + 100, dim=0)))

Натиҷа:

[0.333, 0.333, 0.333]
1.0 0
False
True

Ҳангоми баҳоҳои баробар ҳар яке аз се синф тақрибан сеяк гирифт. argmax индекси аввалро интихоб кард, вале ин эътимоди баландро намефаҳмонад. Остона имкон медиҳад, ки ҳангоми хеле хурд будани эҳтимоли калонтарин аз ҷавоб даст кашем. Дар мисол санҷиши остонаи 0.5 натиҷаи False дод.

Эҳтимоли softmax баҳои худи модел аст, на кафолати дурустӣ: ҳатто намунаи нодуруст ё ношинос метавонад баҳои баланд гирад. Даст кашидан аз ҷавоби номуайян барои рақамҳои пурғавғо муфид аст, вале сифат ва остонаро бояд дар маълумоти ҷудогона санҷид. Омӯзиш бо CrossEntropyLoss ҳамоно логитҳоро истифода мебарад; softmax барои хондани эҳтимолҳост.

Қисмҳо дар дохил чӣ гуна мепайванданд

Dataset шарти як намунаро муайян мекунад. DataLoader индексҳоро интихоб карда, натиҷаҳоро якҷо мекунад. Модел баста гирифта, баҳои синфҳоро медиҳад; хато баҳоҳоро бо барчаспҳо мепайвандад. Ҳангоми омӯзиш autograd ва оптимизатор вазнҳоро тағйир медиҳанд. Дар шинохт ҳолати eval ва сабти хомӯши градиентҳо пешгӯиро бе омӯзиш медиҳанд.

Барои тасвирҳо омодасозӣ бояд яксон бошад: андозаҳо, тартиби пикселҳо ва фосилаи равшанӣ. Вагарна ҳатто шабакаи дуруст омӯхташуда маълумотро дар намоиши дигар мебинад. Маҷмӯаҳои омӯзишӣ ва санҷиширо пеш аз арзёбии сифат ҷудо кунед.

Хатоҳои маъмул ва ислоҳи онҳо

  1. Дарозии аз ҳақиқат хурд. return len(self.values) - 1 намунаи охирро пинҳон мекунад. Шумораи воқеии унсурҳоро баргардонед; дарозӣ ва дастрасӣ ба индекси охирини дурустро муқоиса кунед.

  2. Бақияи гумшуда. drop_last=True бастаи нопурраро мебардорад. Агар ҳама пешгӯиҳо лозим бошанд, онро нигоҳ доред ва барои меъёрҳо len(xb)-и воқеиро истифода баред.

  3. Омехтани аломатҳо бе барчаспҳо. Ҷойивазкуниҳои мустақил ҷуфтҳои нодуруст медиҳанд. Тензорҳои вобастаро дар як Dataset нигоҳ дошта, интихоби индексҳоро ба DataLoader супоред.

  4. Остона барои логитҳо. Муқоисаи баҳои аслӣ бо 0.5 ба ҷойивазкунии ихтиёрии логитҳо вобаста аст. Аввал баромадро ҳамчун тақсимоти синфҳо тафсир кунед; мисоли боло устувории онро ба ҷойивазкунӣ нишон медиҳад.

  5. Softmax аз рӯи баста. Барои ҷадвали (N, C) меҳвари dim=0 ба ҷойи синфҳои як тасвир тасвирҳои гуногунро мепайвандад. Меҳвари синфҳоро интихоб карда, ҷамъи эҳтимолҳои ҳар намунаро наздик ба 1 санҷед.

Ёддошт

Қисм Чиро санҷидан лозим
TensorDataset Шумораи яксони намунаҳо дар тензорҳои вобаста
Dataset __len__, __getitem__, формати доимии намуна
DataLoader batch_size, shuffle, drop_last, генератор
Эпоха Як гузариш аз loader, чанд навсозӣ
Меъёри миёна Вазни баста мутаносиб ба шумораи намунаҳо
Эҳтимолҳо Softmax аз рӯи синфҳо, ҷамъ наздик ба 1
Шинохт eval() ва no_grad(), омодасозии яксони маълумот

Баъдан тасвирҳои воқеии MNIST ва қабатҳои печишии nn.Conv2d меоянд. Аввал роҳи як тасвирро аз тензор то баҳои синф пайгирӣ кунед.