To pytanie skupia się na numpy.wydajnie obliczanie produktu PARAPAC/CP w numpy
Mam zestaw macierzy, które wszystkie mają taką samą liczbę kolumn i mają różną liczbę wierszy. Nazwijmy je A, B, C, D, itd. Niech ich wymiary będą takie jak IaxK IbxK, IcxK, itp.
To, czego chcę, to wydajnie obliczyć IaxIbxIc ... tensor P zdefiniowany następująco: P (ia, ib, ic, id, ie, ...) = \ sum_k A (ia, k) B (ib, k) C (ic, k) ...
Więc jeśli mam dwa czynniki, kończę z prostym produktem matrycowym.
Oczywiście mogę obliczyć to „ręcznie” przez produktów zewnętrznych, coś jak:
def parafac(factors,components=None):
ndims = len(factors)
ncomponents = factors[0].shape[1]
total_result=array([])
if components is None:
components=range(ncomponents)
for k in components:
#for each component (to save memory)
result = array([])
for dim in range(ndims-1,-1,-1):
#Augments model with next dimension
current_dim_slice=[slice(None,None,None)]
current_dim_slice.extend([None]*(ndims-dim-1))
current_dim_slice.append(k)
if result.size:
result = factors[dim].__getitem__(tuple(current_dim_slice))*result[None,...]
else:
result = factors[dim].__getitem__(tuple(current_dim_slice))
if total_result.size:
total_result+=result
else:
total_result=result
return total_result
Still, chciałbym coś znacznie bardziej obliczeniowo wydajne, jak opierając się na wbudowane funkcje NumPy, ale nie mogę znaleźć odpowiednie funkcje, czy ktoś może mi pomóc?
Cheers, dzięki
To rzeczywiście potężny voodoo, a nawet działa dwa razy szybciej niż to, co wyprodukowałem. – Jaime
Nice. Czy porównywałeś prędkość tej wersji z oryginałem? Próbowałem obu używając czterech tablic z kształtami (10,3), (24,3), (15,3) i (75,3). Oryginalna wersja zajmuje około 2ms, a wersja używająca 'einsum' zajmuje około 7,5ms. –
Wygląda na to, że einsum korzysta z wielordzeniowych architektur, podczas gdy moje oryginalne rzeczy nie. Co więcej, eksperymentalnie zauważyłem, że robi to lepiej (prawdziwe przypadki są raczej dla macierzy kilku tysięcy linii i około 50 kolumn). Spróbuję tego, – antoine