2016-01-21 15 views
7

Esiste un modo per aumentare una variabile di Tensorflow? Come, diciamo che volevo aggiungere un neurone a uno strato di una rete neurale nel mezzo dell'allenamento. Come potrei fare per farlo? Una risposta in This question mi ha detto come modificare la forma della variabile, per espanderla per adattarla a un'altra riga di pesi, ma non so come inizializzare quei nuovi pesi.Come espandere una variabile di Tensorflow

Immagino che un altro modo per aggirare questo potrebbe riguardare la combinazione di variabili, come l'inizializzazione dei pesi prima in una seconda variabile e quindi l'aggiunta come una nuova riga o colonna della prima variabile, ma non riesco a trovare nulla questo mi consente di farlo anche io.

risposta

1

Capito. È una specie di processo di rotatoria, ma è l'unico che posso dire che funzioni effettivamente. È necessario prima decomprimere le variabili, quindi aggiungere la nuova variabile alla fine, quindi raggrupparle nuovamente.

Se si sta espandendo lungo la prima dimensione, è piuttosto breve: solo 7 righe di codice effettivo.

#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) 

Se si desidera espandere la seconda dimensione, si allunga leggermente.

#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) 

Non so se c'è un modo più efficiente di fare questo, ma questo funziona, per quanto va. Cambiare ulteriori dimensioni richiederebbe più livelli di elenchi, se necessario.

+3

Si noti che tf.concat() concatena i tensori. Ad esempio, il tuo esempio 1 può essere: v1 = tf.variable (... [5, 3] ...) v2 = tf.variable (... [1, 3] ...) final = tf .concat (0, [v1, v2]) Il secondo esempio può essere fatto: v1 = tf.variable (... [5, 3] ...) v2 = tf.variable (... [5 , 1] ...) final = tf.concat (1, [v1, v2]) Penso che sia quello che vrv suggeriva. – zfc

9

Ci sono vari modi per farlo.

1) La seconda risposta in questo post (https://stackoverflow.com/a/33662680/5548115) spiega come è possibile modificare la forma di una variabile chiamando 'assign' con validate_shape = False. Ad esempio, si potrebbe fare qualcosa di simile

# 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) 

Poi, quando si esegue resize_var, i dati indicavano da 'var' avranno ora i dati aggiornati.

2) È anche possibile creare una grande variabile iniziale e chiamare tf.slice su diverse regioni della variabile mentre l'allenamento procede, poiché è possibile modificare dinamicamente gli attributi 'begin' e 'size' della slice.

+0

Se aggiungessi una nuova variabile di forma [m, 1], la forma finale sarebbe [m, n + 1]? – Beez

+0

E non confezionare semplicemente creare una variabile con una terza dimensione? Questo è quello che dice l'API, e sto ricevendo errori quando il pacchetto viene eseguito dicendo che le dimensioni non sono compatibili a meno che non crei le dimensioni della stessa dimensione, nel qual caso aggiunge una terza dimensione di dimensione 2. – Beez

+0

Ah, hai ragione confezione. Immagino tu possa fare tf.concat (0, [... tensori ...]) (o concatenare su qualsiasi dimensione desideri creare la forma che desideri) Ho modificato la risposta per riflettere questo . – vrv

4

Semplicemente usando tf.concat per espandere una variabile Tensorflow, è possibile vedere api_docs per i dettagli.

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]) 
Problemi correlati