2017-02-14 2 views
3

Я делаю пример для повышения (4 слоя DNN до 5 слоев DNN) через Tensorflow. Я делаю это с сеансом сохранения и восстановления в TF, потому что в TF есть короткий абзац: «Например, вы можете обучить нейронную сеть с 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/Variable» и «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

Вы можете восстановить модель с помощью 'параметр var_list' в' tf.Saver' [конструктор] (https://www.tensorflow.org/api_docs/python/state_ops/saving_and_restoring_variables). После этого вы будете должным образом инициализировать уровень 5. – drpng

ответ

5

В этом случае не следует читать значения для повышения с контрольной точки, и я думаю, что это не то, что вы хотите сделать. Очевидно, что вы получаете ошибку, так как при восстановлении переменных вы сначала перехватываете список всех переменных в своей модели, а затем вы ищете соответствующие переменные в вашей контрольной точке, которая их не имеет.

Вы можете восстановить только часть своей модели, определив подмножество переменных модели. Например, вы можете сделать это с помощью библиотеки tf.slim. Получение списка переменных в моделях:

variables = slim.get_variables_to_restore() 

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

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

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