Построение нескольких моделей в одном графике

Я пытаюсь построить две похожие модели, предсказывающие разные типы вывода. Один прогнозирует между двумя категориями, а другой имеет шесть выходных категорий. Их входы одинаковы, и они оба LSTM RNN.

Я разделил обучение и прогнозирование на отдельные функции в каждом из своих файлов, model1.py, model2.py.

Я сделал ошибку, называя переменные в каждой модели одним и тем же, так что когда я вызываю предикат1 и прогноз2 из модели1 и модель2 соответственно, я получаю следующую ошибку пространства имен: ValueError: Переменная W уже существует, запрещено. Вы хотели установить reuse=True в VarScope? Первоначально определено в:

Где W - название матрицы весов.

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

ValueError: Variable RNN/BasicLSTMCell/Linear/Matrix already exists

РЕДАКТИРОВАТЬ: После обзора модели1pred и model2pred в файле прогнозов я получаю следующую ошибку при вызове model1pred() затем model2pred()

tensorflow.python.framework.errors.NotFoundError: Tensor name model1/model1/BasicLSTMCell/Linear/Matrix" not found in checkpoint files './variables/model1.chk

РЕДАКТИРОВАТЬ: код включен здесь. Код в model2.py отсутствует, но эквивалентен в model1.py, за исключением того, что n_classes=2, а внутри функции dynamicRNN и внутри предопределенной области видимости установлено значение "model2".

РЕШЕНИЕ. Проблема заключалась в том, что граф пытался восстановить включенные переменные из первого выполнения pred (). Мне удалось обернуть вызовы функций pred в разные графики, чтобы решить проблему, избавив от необходимости изменять область видимости.

В файле сбора прогнозов:

def model1pred(test_x, test_seqlen):
    from model1 import pred
    with tf.Graph().as_default():
        return pred(test_x, test_seqlen)

def model2pred(test_x, test_seqlen):
    from model2 import pred
    with tf.Graph().as_default():
        return pred(test_x, test_seqlen)

##Import test_x, test_seqlen

probs1, preds1 = model1pred(test_x, test_seq)
probs2, cpreds2 = model2Pred(test_x, test_seq)

В model1.py

def dynamicRNN(x, seqlen, weights, biases):
    n_steps = 10
    n_input = 14
    n_classes = 6
    n_hidden = 100

    # Prepare data shape to match `rnn` function requirements
    # Current data input shape: (batch_size, n_steps, n_input)
    # Required shape: 'n_steps' tensors list of shape (batch_size, n_input)

    # Permuting batch_size and n_steps
    x = tf.transpose(x, [1, 0, 2])
    # Reshaping to (n_steps*batch_size, n_input)
    x = tf.reshape(x, [-1,n_input])
    # Split to get a list of 'n_steps' tensors of shape (batch_size, n_input)
    x = tf.split(0, n_steps, x)

    # Define a lstm cell with tensorflow
    lstm_cell = rnn_cell.BasicLSTMCell(n_hidden, forget_bias=1.0)

    # Get lstm cell output, providing 'sequence_length' will perform dynamic calculation.
    outputs, states = tf.nn.rnn(lstm_cell, x, dtype=tf.float32, sequence_length=seqlen)

    # When performing dynamic calculation, we must retrieve the last
    # dynamically computed output, i.e, if a sequence length is 10, we need
    # to retrieve the 10th output.
    # However TensorFlow doesn't support advanced indexing yet, so we build
    # a custom op that for each sample in batch size, get its length and
    # get the corresponding relevant output.

    # 'outputs' is a list of output at every timestep, we pack them in a Tensor
    # and change back dimension to [batch_size, n_step, n_input]
    outputs = tf.pack(outputs)
    outputs = tf.transpose(outputs, [1, 0, 2])

    # Hack to build the indexing and retrieve the right output.
    batch_size = tf.shape(outputs)[0]
    # Start indices for each sample
    index = tf.range(0, batch_size) * n_steps + (seqlen - 1)
    # Indexing
    outputs = tf.gather(tf.reshape(outputs, [-1, n_hidden]), index)

    # Linear activation, using outputs computed above
    return tf.matmul(outputs, weights['out']) + biases['out']

def pred(test_x, test_seqlen):
     with tf.Session() as sess:
        n_steps = 10
        n_input = 14
        n_classes = 6
        n_hidden = 100
        weights = {'out': tf.Variable(tf.random_normal([n_hidden, n_classes]), name='W1')}
        biases = {'out': tf.Variable(tf.random_normal([n_classes]), name='b1')}
        x = tf.placeholder("float", [None, n_steps, n_input])
        y = tf.placeholder("float", [None, n_classes])
        seqlen = tf.placeholder(tf.int32, [None])

        pred = dynamicRNN(x, seqlen, weights, biases)
        saver = tf.train.Saver(tf.all_variables())
        y_p =tf.argmax(pred,1)

        init = tf.initialize_all_variables()
        sess.run(init)

        saver.restore(sess,'./variables/model1.chk')
        y_prob, y_pred= sess.run([pred, y_p], feed_dict={x: test_x, seqlen: test_seqlen})
        y_prob = np.array([softmax(x) for x in y_prob])
        return y_prob, y_pred

'

1 ответ

Решение

Вы можете сделать это, добавив with tf.variable_scope(): блоки вокруг двух частей кода построения модели. Это дает эффект префикса имен переменных с другим префиксом, что позволяет избежать конфликта.

Например (используя model1pred() а также model2pred() функции, определенные в вашем вопросе):

with tf.variable_scope('model1'):
  # Variables created in here will be named 'model1/W', etc.
  probs1, preds1 = model1pred(test_x, test_seq)

with tf.variable_scope('model2'):
  # Variables created in here will be named 'model2/W', etc.
  probs2, cpreds2 = model2Pred(test_x, test_seq)

Для получения дополнительной информации см. Подробное руководство по совместному использованию переменных в TensorFlow.

Другие вопросы по тегам