2016-01-21 2 views
7

Есть ли способ увеличить размер переменной Tensorflow? Например, предположим, что я хотел добавить нейрон к слою нейронной сети в середине тренировки. Как мне это сделать? Ответ в This question рассказал мне, как изменить форму переменной, чтобы расширить ее, чтобы она соответствовала другой строке весов, но я не знаю, как инициализировать эти новые веса.Как расширить переменную Tensorflow

Я полагаю, что другой способ обойти это может включать объединение переменных, как при инициализации весов сначала во второй переменной, а затем добавление этого в качестве новой строки или столбца первой переменной, но я ничего не могу найти что позволяет мне это делать.

ответ

1

Выяснил это. Это своего рода обходной процесс, но это единственный, который я могу сказать, что на самом деле функционирует. Вам нужно сначала распаковать переменные, а затем добавить новую переменную до конца, а затем собрать обратно.

Если вы расширяетесь по первому измерению, оно довольно короткое: всего 7 строк фактического кода.

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

Если вы хотите развернуть по второму измерению, он будет несколько дольше.

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

Я не знаю, если есть более эффективный способ сделать это, но это работает, насколько это идет. При изменении дополнительных размеров потребуется, по мере необходимости, больше слоев списков.

+3

Обратите внимание, что tf.concat() объединяет тензоры. Например, ваш пример 1 может быть: v1 = tf.variable (... [5, 3] ...) v2 = tf.variable (... [1, 3] ...) final = tf ,concat (0, [v1, v2]) Второй пример может быть выполнен: v1 = tf.variable (... [5, 3] ...) v2 = tf.variable (... [5 , 1] ...) final = tf.concat (1, [v1, v2]) Я думаю, это то, что предложил vrv. – zfc

9

Существуют различные способы достижения этой цели.

1) Второй ответ в этом сообщении (https://stackoverflow.com/a/33662680/5548115) объясняет, как вы можете изменить форму переменной, вызвав 'assign' с validate_shape = False. Например, вы могли бы сделать что-то вроде

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

Тогда при запуске resize_var, данные на который указывает «вар» теперь будет иметь обновленные данные.

2) Вы также можете создать большую начальную переменную и вызвать tf.slice в разных областях переменной по мере прогрессирования обучения, поскольку вы можете динамически изменять атрибуты «begin» и «size» для среза.

+0

Если бы я добавил новую переменную формы [m, 1], конечная форма была бы [m, n + 1]? – Beez

+0

И не собирался ли просто создавать переменную с третьим измерением? Это то, что говорит API, и я получаю ошибки при запуске пакета, говоря, что размеры несовместимы, если я не делаю размеры одного и того же размера, и в этом случае он добавляет третье измерение размера 2. – Beez

+0

Ах, вы правы пак. Я думаю, вы могли бы сделать tf.concat (0, [... тензоры ...]) (или объединить в зависимости от того размера, которое вы хотели бы создать желаемую форму) Я отредактировал ответ, чтобы отразить это , – vrv

4

Просто используя tf.concat для расширения переменной Tensorflow, вы можете увидеть 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]) 
Смежные вопросы