2016-01-21 9 views
7

Czy istnieje sposób na zwiększenie zmiennej Tensorflow? Na przykład, powiedzmy, że chciałbym dodać neuron do warstwy sieci neuronowej w trakcie treningu. Jak mam to zrobić? Odpowiedź w This question powiedziała mi, jak zmienić kształt zmiennej, aby rozszerzyć go, aby pasował do innego szeregu wag, ale nie wiem, jak zainicjować te nowe wagi.Jak rozszerzyć zmienną Tensorflowa

Myślę, że innym sposobem radzenia sobie z tym może być łączenie zmiennych, tak jak przy inicjowaniu wag najpierw w drugiej zmiennej, a następnie dodawanie jej jako nowego wiersza lub kolumny pierwszej zmiennej, ale nie mogę znaleźć niczego to też pozwala mi to robić.

Odpowiedz

1

Wyliczyłem to. To rodzaj okrężnego procesu, ale to jedyny, jaki mogę stwierdzić, że faktycznie działa. Najpierw należy rozpakować zmienne, a następnie dopisać nową zmienną do końca, a następnie spakować je ponownie.

Jeśli rozwijacie się wzdłuż pierwszego wymiaru, jest on krótki: tylko 7 linii rzeczywistego kodu.

#the first variable is 5x3 
v1 = tf.Variable(tf.zeros([5, 3], dtype=tf.float32), "1") 

#the second variable is 1x3 
v2 = tf.Variable(tf.zeros([1, 3], dtype=tf.float32), "2") 

#unpack the first variable into a list of size 3 tensors 
#there should be 5 tensors in the list 
change_shape = tf.unpack(v1) 

#unpack the second variable into a list of size 3 tensors 
#there should be 1 tensor in this list 
change_shape_2 = tf.unpack(v2) 

#for each tensor in the second list, append it to the first list 
for i in range(len(change_shape_2)): 
    change_shape.append(change_shape_2[i]) 

#repack the list of tensors into a single tensor 
#the shape of this resultant tensor should be [6, 3] 
final = tf.pack(change_shape) 

Jeśli chcesz rozwinąć wzdłuż drugiego wymiaru, będzie on nieco dłuższy.

#First variable, 5x3 
v3 = tf.Variable(tf.zeros([5, 3], dtype=tf.float32)) 

#second variable, 5x1 
v4 = tf.Variable(tf.zeros([5, 1], dtype=tf.float32)) 

#unpack tensors into lists of size 3 tensors and size 1 tensors, respectively 
#both lists will hold 5 tensors 
change = tf.unpack(v3) 
change2 = tf.unpack(v4) 

#for each tensor in the first list, unpack it into its own list 
#this should make a 2d array of size 1 tensors, array will be 5x3 
changestep2 = [] 
for i in range(len(change)): 
    changestep2.append(tf.unpack(change[i])) 

#do the same thing for the second tensor 
#2d array of size 1 tensors, array will be 5x1 
change2step2 = [] 
for i in range(len(change2)): 
    change2step2.append(tf.unpack(change2[i])) 

    #for each tensor in the array, append it onto the corresponding array in the first list 
    for j in range(len(change2step2[i])): 
    changestep2[i].append(change2step2[i][j]) 

    #pack the lists in the array back into tensors 
    changestep2[i] = tf.pack(changestep2[i]) 

#pack the list of tensors into a single tensor 
#the shape of this resultant tensor should be [5, 4] 
final2 = tf.pack(changestep2) 

Nie wiem, czy jest na to skuteczniejszy sposób, ale działa to tak daleko, jak to tylko możliwe. Zmiana dalszych wymiarów wymagałaby w razie potrzeby większej liczby warstw.

+3

Należy zauważyć, że tf.concat() konkatenuje tensory. Np. Twój przykład 1 może być: v1 = tf.variable (... [5, 3] ...) v2 = tf.variable (... [1, 3] ...) końcowy = tf .concat (0, [v1, v2]) Możesz zrobić drugi przykład: v1 = tf.variable (... [5, 3] ...) v2 = tf.variable (... [5 , 1] ...) final = tf.concat (1, [v1, v2]) Myślę, że to właśnie zasugerował vrv. – zfc

9

Istnieje wiele sposobów na osiągnięcie tego celu.

1) Druga odpowiedź w tym poście (https://stackoverflow.com/a/33662680/5548115) wyjaśnia, w jaki sposób można zmienić kształt zmiennej, wywołując "assign" with validate_shape = False. Na przykład, można zrobić coś takiego

# Assume var is [m, n] 
# Add the new 'data' of shape [1, n] with new values 
new_neuron = tf.constant(...) 

# If concatenating to add a row, concat on the first dimension. 
# If new_neuron was [m, 1], you would concat on the second dimension. 
new_variable_data = tf.concat(0, [var, new_neuron]) # [m+1, n] 

resize_var = tf.assign(var, new_variable_data, validate_shape=False) 

Następnie po uruchomieniu resize_var, dane wskazywane przez „var” będzie teraz zaktualizowane dane.

2) Można również utworzyć dużą zmienną początkową i wywołać tf.slice w różnych regionach zmiennej w miarę postępu szkolenia, ponieważ można dynamicznie zmieniać atrybuty "początek" i "rozmiar" plasterka.

+0

Jeśli dodałem nową zmienną kształtu [m, 1], czy ostateczny kształt będzie [m, n + 1]? – Beez

+0

I nie chciałbym spakować po prostu utworzyć zmienną z trzecim wymiarem? Tak mówi API i dostaję błędy po uruchomieniu pakietu, mówiąc, że wymiary nie są kompatybilne, chyba że zrobię wymiary tego samego rozmiaru, w którym to przypadku dodaje trzeci wymiar rozmiaru 2. – Beez

+0

Ach, masz rację Pakiet. Sądzę, że mógłbyś zrobić tf.concat (0, [... tensors ...]) (lub konkatenować w zależności od wymiaru, który chciałbyś utworzyć pożądany kształt) Edytowałem odpowiedź, aby to odzwierciedlić . – vrv

4

Po prostu używając tf.concat do rozwinięcia zmiennej Tensorflow, można zobaczyć szczegóły api_docs .

v1 = tf.Variable(tf.zeros([5,3]),dtype=tf.float32) 
    v2 = tf.Variable(tf.zeros([1,3]),dtype=tf.float32) 
    v3 = tf.concat(0,[v1, v2])