2016-06-27 14 views
7

Mam problem, z którym się zmagałem. Jest to związane z tf.matmul() i jego brakiem emisji.Brak emisji dla tf.matmul w TensorFlow

Jestem świadomy podobnego problemu na https://github.com/tensorflow/tensorflow/issues/216, ale tf.batch_matmul() nie wygląda jak rozwiązanie dla mojej sprawy.

muszę zakodować moich danych wejściowych jako 4D tensora: X = tf.placeholder(tf.float32, shape=(None, None, None, 100)) Pierwszy wymiar jest wielkość partii, druga liczba wpisów w partii. Możesz wyobrazić sobie każdy wpis jako kompozycję wielu obiektów (trzeci wymiar). Wreszcie, każdy obiekt jest opisany przez wektor 100 wartości zmiennoprzecinkowych.

Należy zauważyć, że użyłem Brak dla drugiego i trzeciego wymiaru, ponieważ rzeczywiste rozmiary mogą się zmieniać w każdej partii. Jednakże, dla uproszczenia, niech kształtować tensor z rzeczywistymi liczbami: X = tf.placeholder(tf.float32, shape=(5, 10, 4, 100))

Są etapy mojego obliczeń:

  1. obliczyć funkcję każdego wektora 100 wartości float (np funkcja liniowa) W = tf.Variable(tf.truncated_normal([100, 50], stddev=0.1)) Y = tf.matmul(X, W) problemem: brak transmisji dla tf.matmul() i bez sukcesu z tf.batch_matmul() oczekiwany kształt Y: (5, 10, 4, 50)

  2. stosując średnią łączenia dla każdego wpisu w partii (na obiektach każdego wpisu): Y_avg = tf.reduce_mean(Y, 2) oczekiwanego kształtu Y_avg (5, 10, 50)

, że oczekuje się, że tf.matmul() byłoby wspierałem nadawanie. Potem znalazłem tf.batch_matmul(), ale nadal wygląda tak, jak nie ma to zastosowania w mojej sprawie (np. W musi mieć przynajmniej 3 wymiary, nie jest jasne, dlaczego).

BTW, powyżej użyłem prostej funkcji liniowej (której waga jest przechowywana w W). Ale w moim modelu mam zamiast tego głęboką sieć. Tak więc, bardziej ogólnym problemem, jaki mam, jest automatyczne obliczanie funkcji dla każdego wycinka tensora. Dlatego spodziewałem się, że tf.matmul() będzie miało zachowanie nadawcze (jeśli tak, być może tf.batch_matmul() nie będzie nawet konieczne).

Czekamy na informacje od Ciebie! Alessio

Odpowiedz

5

Można to osiągnąć poprzez przekształcanie X kształtować [n, d], gdzie d jest wymiarowości jednego „instancji” obliczeń (100 w swoim przykładzie) i n jest liczba tych przypadkach, w swojej wielowymiarowego obiektu (5*10*4=200 w twoim przykładzie). Po przekształceniu możesz użyć tf.matmul, a następnie zmienić kształt z powrotem na żądany kształt. Fakt, że pierwsze trzy wymiary mogą się różnić, sprawia, że ​​jest to trochę trudne, ale można użyć tf.shape, aby określić rzeczywiste kształty podczas pracy. Na koniec możesz wykonać drugi krok obliczeń, który powinien być prosty w stosunku do odpowiedniego wymiaru. W sumie wyglądałoby to tak:

X = tf.placeholder(tf.float32, shape=(None, None, None, 100)) 
W = tf.Variable(tf.truncated_normal([100, 50], stddev=0.1)) 
X_ = tf.reshape(X, [-1, 100]) 
Y_ = tf.matmul(X_, W) 
X_shape = tf.gather(tf.shape(X), [0,1,2]) # Extract the first three dimensions 
target_shape = tf.concat(0, [X_shape, [50]]) 
Y = tf.reshape(Y_, target_shape) 
Y_avg = tf.reduce_mean(Y, 2) 
+0

Dzięki za odpowiedź.Niestety, twoje rozwiązanie ma dwie kwestie: 1. Średnie * wszystkie * wektory, które nie są poprawne 2. Zmiana kształtu jest ważna tylko w przypadku tensora o ustalonym kształcie, natomiast mam partie, w których pierwsze 3 wymiary różnią się (ustalone w każdej partii, różne w różnych partiach) –

+0

Dlaczego jest średnia dla wszystkich wektorów? '' X [i, j, k,:] '' stanowi pojedynczy wektor, prawda? Przekształcając w sposób, jaki zaproponowałem, układamy te wektory w dużą macierz (każdy rząd posiada jeden z wektorów). Jeśli teraz wykonujemy multiplikację macierzy, każdy wiersz zostanie pomnożony przez macierz oddzielnie. Teraz możemy zrobić z każdym rzędem to, co jest pożądane (np. Biorąc średnią, jak w twoim przykładzie), a następnie zmienić aranżację na kształt, który chcemy mieć. Nie widzę, skąd czerpiemy średnią z wektorów, ale być może czegoś mi brakuje. – lballes

+0

Jeśli chodzi o drugi problem, tak długo jak wymiarowość wektorów (100 w twoim przykładzie) jest stała, '' tf.reshape (X, [-1, 100]) '' powinno działać poprawnie? Używając '' -1'', nie ma potrzeby, aby teraz inne wymiary a priori. – lballes

Powiązane problemy