2017-02-14 92 views
3

我正在做一个通过Tensorflow增强(4层DNN到5层DNN)的例子。我正在保存会话并在TF中恢复,因为TF tute中有一个简短的段落: '例如,您可能已经训练了一个4层的神经网络,现在您想要训练5层的新模型,将来自先前训练模型的4层的参数恢复到新模型的前4层。',其中张量流通启动于https://www.tensorflow.org/how_tos/variables/恢复Tensorflow中新模型子集的变量?

但是,我发现当检查点保存4层参数时,没有人询问如何使用“恢复”,但我们需要将它放入5层,引发红旗。

使这在实际的代码,我做了

with tf.name_scope('fcl1'): 
    hidden_1 = fully_connected_layer(inputs, train_data.inputs.shape[1], num_hidden)    
with tf.name_scope('fcl2'): 
    hidden_2 = fully_connected_layer(hidden_1, num_hidden, num_hidden)     
with tf.name_scope('fclf'): 
    hidden_final = fully_connected_layer(hidden_2, num_hidden, num_hidden)  
with tf.name_scope('outputl'): 
    outputs = fully_connected_layer(hidden_final, num_hidden, train_data.num_classes, tf.identity) 
    outputs = tf.nn.softmax(outputs) 
with tf.name_scope('boosting'): 
    boosts = fully_connected_layer(outputs, train_data.num_classes, train_data.num_classes, tf.identity) 

其中内部变量(或称为)“FCL1” - 这样我有“FCL1 /变量”和“FCL1/Variable_1”的重量和偏见 - 'fcl2','fclf'和'outputl'由saver.save()存储在脚本中,没有'boosting'图层。然而,正如我们现在已经“助推”层,saver.restore(SESS,“saved_models/model_list.ckpt”)不工作作为

NotFoundError: Key boosting/Variable_1 not found in checkpoint 

我真的很希望听到这个问题。谢谢。下面的代码是我陷入困境的代码的主要部分。

def fully_connected_layer(inputs, input_dim, output_dim, nonlinearity=tf.nn.relu): 
    weights = tf.Variable(
     tf.truncated_normal(
      [input_dim, output_dim], stddev=2./(input_dim + output_dim)**0.5), 
     'weights') 
    biases = tf.Variable(tf.zeros([output_dim]), 'biases') 
    outputs = nonlinearity(tf.matmul(inputs, weights) + biases)  

    return outputs 

inputs = tf.placeholder(tf.float32, [None, train_data.inputs.shape[1]], 'inputs') 
targets = tf.placeholder(tf.float32, [None, train_data.num_classes], 'targets') 

with tf.name_scope('fcl1'): 
    hidden_1 = fully_connected_layer(inputs, train_data.inputs.shape[1], num_hidden)    
with tf.name_scope('fcl2'): 
    hidden_2 = fully_connected_layer(hidden_1, num_hidden, num_hidden)     
with tf.name_scope('fclf'): 
    hidden_final = fully_connected_layer(hidden_2, num_hidden, num_hidden)  
with tf.name_scope('outputl'): 
    outputs = fully_connected_layer(hidden_final, num_hidden, train_data.num_classes, tf.identity) 

with tf.name_scope('error'):  
    error = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(outputs, targets)) 
with tf.name_scope('accuracy'): 
    accuracy = tf.reduce_mean(tf.cast(
     tf.equal(tf.argmax(outputs, 1), tf.argmax(targets, 1)), 
     tf.float32)) 
with tf.name_scope('train'): 
    train_step = tf.train.AdamOptimizer().minimize(error) 

init = tf.global_variables_initializer() 
saver = tf.train.Saver() 

with tf.Session() as sess: 
    sess.run(init) 
    saver.restore(sess, "saved_models/model.ckpt") 
    print("Model restored") 

    print("Optimization Starts!") 
    for e in range(training_epochs): 
     ... 

    #Save model - save session   
    save_path = saver.save(sess, "saved_models/model.ckpt") 
    ### I once saved the variables using var_list, but didn't work as well... 
    print("Model saved in file: %s" % save_path) 

为了清楚起见,检查点文件具有

fcl1/Variable:0 

fcl1/Variable_1:0 

fcl2/Variable:0 

fcl2/Variable_1:0 

fclf/Variable:0 

fclf/Variable_1:0 

outputl/Variable:0 

outputl/Variable_1:0 

由于原来的4层模型不具有 '升压' 层。

+0

可以恢复使用'tf.Saver' [构造]的'var_list'参数(https://www.tensorflow.org/api_docs/python模型/ state_ops/saving_and_restoring_variables)。 之后您将负责正确初始化第5层。 – drpng

回答

5

在这种情况下,从检查点读取提升值并不正确,我认为这不是您想要做的。很明显,你会遇到错误,因为在恢复变量时,首先要捕捉模型中所有变量的列表,然后在检查点中查找相应的变量,但没有变量。

您可以通过定义模型变量的子集来仅恢复部分模型。例如,你可以使用tf.slim库来完成。获取模型中的变量列表:

variables = slim.get_variables_to_restore() 

现在变量是张量列表,但是对于每个元素,您可以访问其名称属性。使用它你可以指定你只想恢复增强以外的图层,例如:

variables_to_restore = [v for v in variables if v.name.split('/')[0]!='boosting'] 
model_path = 'your/model/path' 

saver = tf.train.Saver(variables_to_restore) 

with tf.Session() as sess: 
    saver.restore(sess, model_path) 

这样你就可以恢复4层。理论上,你可以尝试通过创建另一个服务器来捕获变量中某个变量的值,这些服务器只会在变量列表中提升并从检查点重命名所选变量,但我真的不认为这是您需要的。

由于这是您的模型的自定义层,并且您没有任何位置的此变量,只需在工作流中初始化它,而不是尝试导入它。你可以通过这个参数,例如做,而调用函数fully_connected:

weights_initializer = slim.variance_scaling_initializer() 

你需要检查自己的细节,虽然,因为我不知道你的进口是什么,您使用的这些在这里的功能。

一般来说,我建议你看看苗条库,这将使你更容易为图层定义模型和范围(而不是通过定义它,而可以调用范围参数功能)。它看起来像与苗条:

boost = slim.fully_connected(input, number_of_outputs, activation_fn=None, scope='boosting', weights_initializer=slim.variance_scaling_initializer()) 
+0

谢谢。有用!其实,我的情况并不需要“苗条”。 – sdr2002