问题
I have different scopes and they have variables with same names but with different values. I want to swap values of these variables between scopes. Example:
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')
I want to set a2 to 0, b2 to 1, a1 to 2 and b1 to 3.
I was thinking about getting needed variables with tf.get_collection_ref but I can't see how I can change scope of the variable, so probably I need to change values of variables. In this case I need to store one value in temporary variable and then remove that temporary variable.
I don't sure that it will work and this seems too complicated.
Is there simple way to do it?
UPD1: Also I need to set all variables in one collection from another collection. I think that it's similar issue.
For example in code above set a2 equal to 0 and b2 to 1.
UPD2: This code doesn't work:
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]
回答1:
I want to swap relatively small scopes, so it's not a problem have temporary scope for swapping. I made working prototype. It doesn't look cool and actually ugly but works.
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)
Note that I use dependency control! Without it function results will be undefined.
Also despite that function name is swap_tf_collections I think that it will not work for arbitrary collections (to be fair I doubt even about scopes).
回答2:
import tensorflow as tf
import numpy as np
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 = {}
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.Variable(curr_col1_var.initialized_value())
sess.run(tmp_t.initializer)
sess.run(tf.assign(curr_col1_var,curr_var))
sess.run(tf.assign(curr_var,tmp_t))
col1 = tf.get_collection(tf.GraphKeys.VARIABLES, scope='sc1')
col2 = tf.get_collection(tf.GraphKeys.VARIABLES, scope='sc2')
sess = tf.Session()
sess.run(tf.initialize_all_variables())
swap_tf_scopes(col1, col2)
print(sess.run(col1))
print(sess.run(col2))
Hello!Try this one. I guess it will work.
来源:https://stackoverflow.com/questions/41949633/tensorflow-how-to-swap-variables-between-scopes-and-set-variables-in-scope-from