Периодические издержки при использовании набора данных 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 устраняет эти периодические издержки. Тем не менее, я не уверен, что набор данных полностью прочитан с использованием этой команды.