2017-01-31 2 views
1

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

with tf.variable_scope('sc1'): 
    a1 = tf.Variable(0, name='test_var1') 
    b1 = tf.Variable(1, name='test_var2') 
with tf.variable_scope('sc2'): 
    a2 = tf.Variable(2, name='test_var1') 
    b2 = tf.Variable(3, name='test_var2') 

Я хочу установить a2 к 0, b2 1, a1 до 2 и b1 до 3.

Я думал о получении необходимых переменных с tf.get_collection_ref, но я не могу видеть, как Я могу изменить область действия переменной, поэтому, вероятно, мне нужно изменить значения переменных. В этом случае мне нужно сохранить одно значение во временной переменной, а затем удалить эту временную переменную. Я не уверен, что это сработает, и это кажется слишком сложным. Есть ли простой способ сделать это?

UPD1: Также мне нужно установить все переменные в одну коллекцию из другой коллекции. Я думаю, что это аналогичная проблема. Например, в приведенном выше коде установите a2 равным 0 и b2 1.

UPD2: Этот код не работает:

with tf.variable_scope('sc1'): 
    a1 = tf.get_variable(name='test_var1', initializer=0.) 
    b1 = tf.Variable(0, name='test_var2') 

with tf.variable_scope('sc2'): 
    a2 = tf.get_variable(name='test_var1', initializer=1.) 
    b2 = tf.Variable(1, name='test_var2') 


def swap_tf_scopes(col1, col2): 
    col1_dict = {} 
    col2_dict = {} 
    for curr_var in col1: 
     curr_var_name = curr_var.name.split('/')[-1] 
     col1_dict[curr_var_name] = curr_var 

    for curr_var in col2: 
     curr_var_name = curr_var.name.split('/')[-1] 
     curr_col1_var = col1_dict[curr_var_name] 
     tmp_t = tf.identity(curr_col1_var) 
     assign1 = curr_col1_var.assign(curr_var) 
     assign2 = curr_var.assign(tmp_t) 
    return [assign1, assign2] 


col1 = tf.get_collection(tf.GraphKeys.VARIABLES, scope='sc1') 
col2 = tf.get_collection(tf.GraphKeys.VARIABLES, scope='sc2') 

tf_ops_t = swap_tf_collections(col1, col2) 
sess = tf.Session() 
sess.run(tf.initialize_all_variables()) 
sess.run(tf_ops_t) 
print sess.run(col1) #prints [0.0, 1] but I expect [1.0, 1] 
print sess.run(col2) #prints [1.0, 1] but I expect [0.0, 0] 
+0

Предполагается, что на основе быстрого считывания: запись в одну переменную перезаписывает ввод другой записи. 'tf.identity' недостаточно для принудительной копии данных Тензора. Попробуйте что-то вроде 'tmp_t = curr_col1_var + 0.0'. Надеюсь, это поможет! –

ответ

0

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

def swap_tf_collections(col1, col2, tmp_col): 
    col2_dict = {} 
    for i in xrange(len(col1)): 
     curr_var_name = col2[i].name.split('/')[-1] 
     col2_dict[curr_var_name] = col2[i] 

    col1_dict = {} 
    for i in xrange(len(col1)): 
     curr_var_name = col1[i].name.split('/')[-1] 
     col1_dict[curr_var_name] = col1[i] 

    # set values from second scope to tmp_dict 
    tmp_dict = {} 
    assigns_arr = [] 
    for i in xrange(len(tmp_col)): 
     curr_var_name = tmp_col[i].name.split('/')[-1] 
     tmp_dict[curr_var_name] = tmp_col[i] 
     assign0 = tmp_dict[curr_var_name].assign(col2_dict[curr_var_name]) 
     assigns_arr.append(assign0) 

    for i in xrange(len(col2)): 
     curr_var_name = col2[i].name.split('/')[-1] 
     curr_col1_var = col1_dict[curr_var_name] 
     tmp_t = tmp_dict[curr_var_name] 
     with tf.control_dependencies(assigns_arr): 
      assign1 = col2[i].assign(curr_col1_var) 
      assigns_arr.append(assign1) 
      with tf.control_dependencies(assigns_arr): 
       assign2 = curr_col1_var.assign(tmp_t) 
       assigns_arr.append(assign2) 
    return assigns_arr 



# first scope 
with tf.variable_scope('sc1'): 
    a1 = tf.get_variable(name='test_var1', initializer=0.) 
    b1 = tf.Variable(0, name='test_var2') 
# second scope  
with tf.variable_scope('sc2'): 
    a2 = tf.get_variable(name='test_var1', initializer=1.) 
    b2 = tf.Variable(1, name='test_var2') 

# getting them as collections 
col1 = tf.get_collection(tf.GraphKeys.VARIABLES, scope='sc1') 
col2 = tf.get_collection(tf.GraphKeys.VARIABLES, scope='sc2') 

# creating temporary scope. It MUST have same variables names as our scopes but it doesn't have to have same data as second scope 
with tf.variable_scope('tmp_scope_for_scopes_swap'): 
    for i in xrange(len(col2)): 
     col2_var = col2[i] 
     col2_var_name = col2[i].name.split('/')[-1].split(':')[0] 
     var = tf.Variable(col2_var.initialized_value(), name=col2_var_name) 
     tmp_col.append(var) 

# exec 
sess = tf.Session() 
with sess.as_default(): 
    sess.run(tf.initialize_all_variables()) 
    tf_ops_t = swap_tf_collections(col1, col2, tmp_col) 
    sess.run(tf_ops_t) # swap will not work without this line 

col1_dict = {i.name:i for i in col1} 
col2_dict = {i.name:i for i in col2} 
print sess.run(col1_dict) 
print sess.run(col2_dict) 

Обратите внимание, что я использую управление зависимостями! Без этого результаты функции будут неопределенными.

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

Смежные вопросы