Python: Vectorize Výpočet Realizovať pomocou Iteračný Prístup

0

Otázka

Snažím sa realizovať nejaký výpočet, ale nemôžem prísť ako vectorize moje kódu, a nie pomocou slučky.

Dovoľte mi to vysvetliť: mám matice M[N,C] buď 0 alebo 1. Ďalší matrix Y[N,1] obsahujú hodnoty [0,C-1] (Môj triedy). Ďalší matrix ds[N,M] čo je môj dataset.

Môj výstup matice je z veľkosť grad[M,C] a mali by sa vypočíta nasledovne: ja ti to vysvetlím na grad[:,0], tú istú logiku, pre iného stĺpca.

Pre každý riadok(vzorky) v ds,, ak Y[that sample] != 0 (Aktuálny stĺpec výstup matrix) a M[that sample, 0] > 0 potom grad[:,0] += ds[that sample]

Ak Y[that sample] == 0potom grad[:,0] -= (ds[that sample] * <Num of non zeros in M[that sample,:]>)

Tu je môj iteračný postup:

    for i in range(M.size(dim=1)):
        for j in range(ds.size(dim=0)):
            if y[j] == i:
                grad[:,i] = grad[:,i] - (ds[j,:].T * sum(M[j,:]))
            else:
                if M[j,i] > 0:
                    grad[:,i] = grad[:,i] + ds[j,:].T 
python pytorch vectorization
2021-11-23 15:58:15
1

Najlepšiu odpoveď

1

Keďže ste sa zaoberajú tri rozmery n, ma c (malé, aby sa predišlo nejednoznačnosti), môže to byť užitočné, ak chcete zmeniť tvar všetky vaše ansi na (n, m, c)tým , replikácia ich hodnoty nad chýba rozmer (napr. M(m, c) stáva M(n, m, c)).

Avšak, môžete preskočiť explicitné replikácie a použitie vysielania, tak to je dostatočný na unsqueeze chýbajúci rozmer (napr. M(m, c) stáva M(1, m, c).

Vzhľadom na tieto úvahy vectorization of váš kód sa stáva takto

cond = y.unsqueeze(2) == torch.arange(M.size(dim=1)).unsqueeze(0)
pos = ds.unsqueeze(2) * M.unsqueeze(1) * cond
neg = ds.unsqueeze(2) * M.unsqueeze(1).sum(dim=0, keepdim=True) * ~cond
grad += (pos - neg).sum(dim=0)

Tu je malý test na overenie platnosti riešenie

import torch

n, m, c = 11, 5, 7

y = torch.randint(c, size=(n, 1))
ds = torch.rand(n, m)
M = torch.randint(2, size=(n, c))
grad = torch.rand(m, c)


def slow_grad(y, ds, M, grad):
    for i in range(M.size(dim=1)):
        for j in range(ds.size(dim=0)):
            if y[j] == i:
                grad[:,i] = grad[:,i] - (ds[j,:].T * sum(M[j,:]))
            else:
                if M[j,i] > 0:
                    grad[:,i] = grad[:,i] + ds[j,:].T
    return grad


def fast_grad(y, ds, M, grad):
    cond = y.unsqueeze(2) == torch.arange(M.size(dim=1)).unsqueeze(0)
    pos = ds.unsqueeze(2) * M.unsqueeze(1) * cond
    neg = ds.unsqueeze(2) * M.unsqueeze(1).sum(dim=0, keepdim=True) * ~cond
    grad += (pos - neg).sum(dim=0)
    return grad
  
# Assert equality of all elements function outputs, throws an exception if false
assert torch.all(slow_grad(y, ds, M, grad) == fast_grad(y, ds, M, grad))

Neváhajte test v ostatných prípadoch, ako dobre!

2021-11-24 12:14:50

Ďakujem vám veľmi pekne!
sagi

V iných jazykoch

Táto stránka je v iných jazykoch

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................