Время выполнения вывода модели возрастает после повторных выводов

Xitcod13 спросил: 13 июня 2018 в 11:37 в: python

Я кодирую проект tensorflow, в котором я редактирую каждый вес и смещение вручную, поэтому я устанавливаю весы и смещения, например, в старом тензорном потоке со словарями, а затем используя tf.layers.dense и позволяя shadoworflow заботиться об обновлении весов. (Это самый чистый способ, с которым я столкнулся, хотя он может быть не идеален)

Я подаю фиксированную модель на одни и те же данные на каждой итерации, но время выполнения увеличивается во время выполнения программы.

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

---Games took   2.6591222286224365 seconds ---
---Games took   3.290001153945923 seconds ---
---Games took   4.250034332275391 seconds ---
---Games took   5.190149307250977 seconds ---

Изменить: мне удалось чтобы сократить время работы, используя местозаполнитель, который не добавляет дополнительные узлы к графику, но время работы все равно увеличивается с меньшей скоростью. Я бы хотел удалить этот рост времени. (От 0,1 до более 1 секунды через некоторое время)

Вот мой весь код:

import numpy as np
import tensorflow as tf
import timen_inputs = 9
n_class = 9n_hidden_1 = 20population_size = 10
weights = []
biases = []
game_steps = 20 #so we can see performance loss faster# 2 games per individual
games_in_generation = population_size/2def generate_initial_population(my_population_size):
    my_weights = []
    my_biases = []    for key in range(my_population_size):
        layer_weights = {
            'h1': tf.Variable(tf.truncated_normal([n_inputs, n_hidden_1], seed=key)),
            'out': tf.Variable(tf.truncated_normal([n_hidden_1, n_class], seed=key))
        }
        layer_biases = {
            'b1': tf.Variable(tf.truncated_normal([n_hidden_1], seed=key)),
            'out': tf.Variable(tf.truncated_normal([n_class], seed=key))
        }
        my_weights.append(layer_weights)
        my_biases.append(layer_biases)
    return my_weights, my_biasesweights, biases = generate_initial_population(population_size)
data = tf.placeholder(dtype=tf.float32) #will add shape laterdef model(x):
    out_layer = tf.add(tf.matmul([biases[1]['b1']], weights[1]['out']),  biases[1]['out'])
    return out_layerdef play_game():     model_input = [0] * 9
     model_out = model(data)     for game_step in range(game_steps):        move = sess.run(model_out, feed_dict={data: model_input})[0]sess = tf.Session()
sess.run(tf.global_variables_initializer())
while True:
    start_time = time.time()
    for _ in range(int(games_in_generation)):
        play_game()
    print("---Games took   %s seconds ---" % (time.time() - start_time))

2 ответа

Есть решение
Justin Fletcher ответил: 13 июня 2018 в 02:55

Я добавляю еще один ответ, потому что последнее редактирование вопроса вызвало существенное изменение. Вы по-прежнему наблюдаете рост времени работы, потому что вы все еще вызываете model более одного раза в sess. Вы просто уменьшили частоту, с которой вы добавили узлы в график. Что вам нужно сделать, так это создать новый сеанс для каждой модели, которую вы хотите построить, и закрыть каждый сеанс, когда вы закончите с ним. Я изменил ваш код, чтобы сделать это, здесь:

import numpy as np
import tensorflow as tf
import timen_inputs = 9
n_class = 9n_hidden_1 = 20population_size = 10
weights = []
biases = []
game_steps = 20 #so we can see performance loss faster# 2 games per individual
games_in_generation = population_size/2def generate_initial_population(my_population_size):
    my_weights = []
    my_biases = []    for key in range(my_population_size):
        layer_weights = {
            'h1': tf.Variable(tf.truncated_normal([n_inputs, n_hidden_1], seed=key)),
            'out': tf.Variable(tf.truncated_normal([n_hidden_1, n_class], seed=key))
        }
        layer_biases = {
            'b1': tf.Variable(tf.truncated_normal([n_hidden_1], seed=key)),
            'out': tf.Variable(tf.truncated_normal([n_class], seed=key))
        }
        my_weights.append(layer_weights)
        my_biases.append(layer_biases)
    return my_weights, my_biasesdef model(x):
    out_layer = tf.add(tf.matmul([biases[1]['b1']], weights[1]['out']),  biases[1]['out'])
    return out_layerdef play_game(sess):    model_input = [0] * 9    model_out = model(data)    for game_step in range(game_steps):        move = sess.run(model_out, feed_dict={data: model_input})[0]while True:    for _ in range(int(games_in_generation)):        # Reset the graph.
        tf.reset_default_graph()        weights, biases = generate_initial_population(population_size)
        data = tf.placeholder(dtype=tf.float32) #will add shape later        # Create session.
        with tf.Session() as sess:            sess.run(tf.global_variables_initializer())            start_time = time.time()            play_game(sess)            print("---Games took   %s seconds ---" % (time.time() - start_time))            sess.close()

То, что я сделал здесь, - это перенос вызова play_game в сеанс, определенный в with и вышла из этого сеанса с помощью sess.close после вызова play_game. Я также сбросил график по умолчанию. Я запустил это несколько сот итераций и не видел увеличения времени работы.

Xitcod13 ответил: 13 июня 2018 в 04:29
Огромное спасибо. И спасибо, что не злились на это. Я все еще пытаюсь учиться, и это очень помогает
Justin Fletcher ответил: 13 июня 2018 в 04:33
Всегда пожалуйста! Я желаю вам всего лишь успеха, и я рад, что это немного помогло вам.
Justin Fletcher ответил: 13 июня 2018 в 12:53

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

import numpy as np
import tensorflow as tf
import timen_inputs = 9
n_class = 9n_hidden_1 = 20population_size = 10
weights = []
biases = []
game_steps = 20 #so we can see performance loss faster# 2 games per individual
games_in_generation = population_size/2def generate_initial_population(my_population_size):
    my_weights = []
    my_biases = []    for key in range(my_population_size):
        layer_weights = {
            'h1': tf.Variable(tf.truncated_normal([n_inputs, n_hidden_1], seed=key)),
            'out': tf.Variable(tf.truncated_normal([n_hidden_1, n_class], seed=key))
        }
        layer_biases = {
            'b1': tf.Variable(tf.truncated_normal([n_hidden_1], seed=key)),
            'out': tf.Variable(tf.truncated_normal([n_class], seed=key))
        }
        my_weights.append(layer_weights)
        my_biases.append(layer_biases)
    return my_weights, my_biasesweights, biases = generate_initial_population(population_size)def model(x):
    out_layer = tf.add(tf.matmul([biases[1]['b1']], weights[1]['out']),  biases[1]['out'])
    return out_layerdef play_game():    # Extract input pattern generation.
    model_input = np.float32([[0]*9])
    model_out = model(model_input)    for game_step in range(game_steps):            start_time = time.time()
            move = sess.run(model_out)[0]            # print("---Step took   %s seconds ---" % (time.time() - start_time))sess = tf.Session()
sess.run(tf.global_variables_initializer())
for _ in range(5):
    start_time = time.time()
    for _ in range(int(games_in_generation)):
        play_game()
    print("---Games took   %s seconds ---" % (time.time() - start_time))

Если он запущен, этот код должен указывать вам что-то вроде:

---Games took   0.42223644256591797 seconds ---
---Games took   0.13168787956237793 seconds ---
---Games took   0.2452383041381836 seconds ---
---Games took   0.20023465156555176 seconds ---
---Games took   0.19905781745910645 seconds ---

Ясно, что это устраняет рост времени выполнения, который вы наблюдаете. Это также уменьшает максимальное наблюдаемое время работы на порядок! Причина, по которой это произошло, заключается в том, что каждый раз, когда вы вызывали model, вы на самом деле создавали кучу объектов tf.Tensor, которые вы пытались добавить к графику. Это недоразумение является обычным явлением и вызвано тем фактом, что вы пытаетесь использовать тензоры в императивном коде python, как если бы они были переменными python. Я рекомендую просмотреть все руководства по графику, прежде чем продолжить.

Также важно отметить, что это неверный способ передать значение в график в TensorFlow. Я вижу, что вы хотите передать другое значение своей модели во время каждой итерации игры, но вы не можете этого сделать, передав значение в функцию python. Вы должны создать tf.placeholder в вашем графике модели и загрузить значение, которое вы хотите, чтобы ваша модель обрабатывалась на этом заполнителе. Есть много способов сделать это, но вы можете найти один пример здесь . Надеюсь, вы найдете это полезным!

Xitcod13 ответил: 13 июня 2018 в 12:58
Благодаря! Я знал, что должен был пройти заполнитель, но в этом случае это не повлияло на производительность в этом случае?
Justin Fletcher ответил: 13 июня 2018 в 01:00
Нет, вы на самом деле влияли на время работы игрового шага, потому что ваш вызов model создавал tf.Tensor s, что требует времени.
Justin Fletcher ответил: 13 июня 2018 в 01:02
Если вы реорганизуете свой код для использования аргумента feed_dict для sess.run и заполнителя для ввода модели, все должно выполняться так, как вы ожидаете.
Xitcod13 ответил: 13 июня 2018 в 01:20
Спасибо, что я удалил местозаполнитель при сокращении моего кода. Все еще есть проблема с кодом, который приводит к потере производительности. (хотя потеря не столь значительна, поэтому требуется больше времени, чтобы заметить)

Дополнительное видео по вопросу: Время выполнения вывода модели возрастает после повторных выводов

Week 1, continued

Week 9, continued

Supersection 1, More Comfortable