Периодические издержки при использовании набора данных tenorflow для обучения модели на графическом процессоре

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

Но я могу наблюдать период времени на этапе оптимизации (в моем коде это sess.run (train)).

Как вы можете видеть здесь, каждые 5 шагов для оптимизации требуется 3 с, а не 0,5.

Продолжительность шага 105: 3.5233473777770996

Продолжительность шага 106: 0,5653283596038818

Продолжительность шага 107: 0,5391891002655029

Продолжительность шага 108: 0,5480048656463623

Продолжительность шага 109: 0,0415492057800293

Продолжительность шага 110: 3.032115936279297

Продолжительность шага 111: 0,5407207012176514

Продолжительность шага 112: 0,5276811122894287

Продолжительность шага 113: 0,5448746681213379

Продолжительность шага 114: 0,04253268241882324

Продолжительность шага 115: 3.1273345947265625

Более того, мой GPU почти все время использует 0% и использует около 90% используемой памяти.

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

Я использую Python 3.6 с Tensorflow 1.4 на Ubuntu 16.04.

У вас есть идеи, как я могу ускорить мои тренировки?

Лучший,

import tensorflow as tf
import numpy as np
import os, time, multiprocessing
import matplotlib.pyplot as plt

def _floats_feature(value):
    return tf.train.Feature(float_list=tf.train.FloatList(value=value.reshape(-1)))


def parser(record):
    num_features = 2000
    size_group = 300
    num_classes= 10
    class_indice = 0
    keys_to_features={
                'X': tf.FixedLenFeature([size_group*num_features],tf.float32),
                'label' : tf.FixedLenFeature([num_classes],tf.float32)}
    parsed = tf.parse_single_example(record, keys_to_features)

    label = parsed['label']
    label = tf.slice(label,[class_indice],[1])
    label = tf.squeeze(label) # To get a vector one dimension
    X = parsed['X']
    X= tf.reshape(X, [size_group,num_features])
    return X, label


def test_train_w_dataset():

    # Definition of the size 
    num_features = 2000
    num_ex = 2000
    size_group = 300
    num_classes = 10
    batch_size= 480
    max_iters = 300
    buffer_size = 10000

# Creation of the Dataset 
filename_tfrecords = 'tmp.tfrecords'
if not(os.path.isfile(filename_tfrecords)): # If the file doesn't exist we will create it
    print("Start creating the Dataset")
    writer = tf.python_io.TFRecordWriter(filename_tfrecords)

    for i in range(num_ex):
        if i % 1000 == 0: print("Step :",i)
        X = np.random.normal(size=(size_group,num_features))
        vectors =  2*np.random.randint(0,2,(num_classes,1))-1
        features=tf.train.Features(feature={
                    'X': _floats_feature(X),
                    'label' : _floats_feature(vectors)})
        example = tf.train.Example(features=features)       
        writer.write(example.SerializeToString())
    writer.close()
else:
    print("The dataset tfrecords already exist")

train_dataset = tf.data.TFRecordDataset(filename_tfrecords)
num_proc = multiprocessing.cpu_count()
train_dataset = train_dataset.map(parser,
                                    num_parallel_calls=num_proc)
dataset_shuffle = train_dataset.shuffle(buffer_size=buffer_size,
                                             reshuffle_each_iteration=True) 
dataset_shuffle = dataset_shuffle.batch(batch_size)
dataset_shuffle = dataset_shuffle.repeat() 
dataset_shuffle = dataset_shuffle.prefetch(batch_size) 
shuffle_iterator = dataset_shuffle.make_initializable_iterator()
X_, y_ = shuffle_iterator.get_next()

W=tf.Variable(tf.random_normal([num_features], stddev=1.),name="weights")
W=tf.reshape(W,(1,1,num_features))
Prod=tf.reduce_sum(tf.multiply(W,X_),axis=2)
Max=tf.reduce_max(Prod,axis=1)
Tan= tf.reduce_sum(tf.multiply(tf.tanh(Max),y_))
loss= tf.add(Tan,tf.reduce_sum(tf.multiply(W,W)))

LR = 0.01
restarts = 1
optimizer = tf.train.GradientDescentOptimizer(LR) 
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
train = optimizer.minimize(loss)  
print("The graph is defined")
sess = tf.Session(config=config)

durationTab = []

for essai in range(restarts+1):
    # To do need to reinitialiszed
    t0 = time.time()
    sess.run(tf.global_variables_initializer())
    sess.run(tf.local_variables_initializer())
    sess.run(shuffle_iterator.initializer)
    t1 = time.time()
    duration = t1 - t0
    print('Duration of initialization : ',duration)
    for step in range(max_iters):
        t0 = time.time()
        sess.run(train)
        t1 = time.time()
        duration = t1 - t0
        print("Step ",str(step),' duration : ',duration)
        durationTab += [duration]


plt.plot(durationTab)
plt.ylabel('Duration')
plt.xlabel('Iteration')
plt.show()

if __name__ == '__main__':

    test_train_w_dataset()

2 ответа

Для использования графического процессора убедитесь, что вы используете оптимизированный двоичный файл gpu. Проверьте расположение операции (например, на тензорной доске). Принудительное размещение операций на графическом процессоре (см. Tf.device).

Для периодических всплесков может быть несколько причин:

  • Другие процессы блокируют доступ к CPU/GPU/RAM/Disk, и вам нужно подождать, пока это пройдет. Вы можете попытаться убить другие лишние задачи, которые могут выполняться в вашей системе.
  • У тебя кончился баран. Проверьте, сколько пространства подкачки используется. Если он растет, когда вы бегаете, то шипы могут быть просто перебоями в системе, хотя для этого он выглядит слишком хорошо.
  • Доступ к диску Вы упомянули, что это связано с циклическим изменением данных. Возможно, системе просто нужно снова прочитать данные, поэтому вам нужно подождать диск, хотя обычно это не видно. Вы можете ускорить его, убедившись, что данные находятся на одном жестком диске, переместите его на SSD или RAM.

Поскольку многие причины связаны с оперативной памятью, вам, вероятно, следует попробовать меньшую модель (меньшие партии, меньше слоев, меньше узлов / слой) и посмотреть, исчезнет ли она. Если это так, то вам нужно выйти и купить больше оперативной памяти.

Похоже, что добавление dataset_shuffle = dataset_shuffle.cache() между функцией batch и repeat устраняет эти периодические издержки. Тем не менее, я не уверен, что набор данных полностью прочитан с использованием этой команды.

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