Keras/Tensorflow:在同一个 GPU 上循环或使用 Process 训练多个模型
Keras/Tensorflow: Train multiple models on the same GPU in a loop or using Process
我有多个模型要在 Keras/Tensorflow 中一个接一个地训练,无需手动调用 train.py
,所以我做到了:
for i in range(0, max_count):
model = get_model(i) # returns ith model
model.fit(...)
model.save(...)
它 运行 对于 i=0
很好(事实上 运行 当 运行 分开时是完美的)。问题是当第二次加载模型时,我得到ResourceExhaustedError OOM
,所以我试图在for循环结束时释放内存
del model
keras.backend.clear_session()
tf.clear_session()
tf.reset_default_graph()
gc.collect()
none 其中单独或集体工作。
我进一步查找,发现释放GPU内存的唯一方法是结束进程。
还有这个keras issue
Update (2018/08/01): Currently only TensorFlow
backend supports proper cleaning up of the session. This can be done
by calling K.clear_session(). This will remove EVERYTHING from memory
(models, optimizer objects and anything that has tensors internally).
So there is no way to remove a specific stale model. This is not a bug
of Keras but a limitation of the backends.
很明显,方法是每次我加载一个模型并等待它结束时创建一个进程,然后在一个新的进程中创建另一个进程,如下所示:
import multitasking
def train_model_in_new_process(model_module, kfold_object, x, y, x_test, y_test, epochs, model_file_count):
training_process = multiprocessing.Process(target=train_model, args=(x, y, x_test, y_test, epochs, model_file_count, ))
training_process.start()
training_process.join()
但随后会抛出此错误:
File "train.py", line 110, in train_model_in_new_process
training_process.start()
File "F:\Python\envs\tensorflow\lib\multiprocessing\process.py", line 105, in start
self._popen = self._Popen(self)
File "F:\Python\envs\tensorflow\lib\multiprocessing\context.py", line 223, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "F:\Python\envs\tensorflow\lib\multiprocessing\context.py", line 322, in _Popen
return Popen(process_obj)
File "F:\Python\envs\tensorflow\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
reduction.dump(process_obj, to_child)
File "F:\Python\envs\tensorflow\lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
TypeError: can't pickle module objects
Using TensorFlow backend.
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "F:\Python\envs\tensorflow\lib\multiprocessing\spawn.py", line 105, in spawn_main
exitcode = _main(fd)
File "F:\Python\envs\tensorflow\lib\multiprocessing\spawn.py", line 115, in _main
self = reduction.pickle.load(from_parent)
EOFError: Ran out of input
我真的无法利用错误中显示的信息来查看我做错了什么。它显然指向 training_process.start()
行,但我似乎无法理解导致问题的原因。
感谢使用 for
循环或 Process
训练模型的任何帮助。
显然,Multiprocessing
不喜欢 modules
或更准确地说 importlib
模块。我使用 importlib
从编号 .py
文件加载模型
model_module = importlib.import_module(model_file)
因此麻烦。
我在 Process
里面做了同样的事情,一切都很好:)
但我仍然找不到不用 Process
es,使用 for
s 来做到这一点的方法。如果您有答案,请 post 在这里,不客气。但无论如何,我将继续处理进程,因为我认为进程在某种程度上更干净,因为它们是隔离的,并在完成后清除为该特定进程分配的所有内存。
我有多个模型要在 Keras/Tensorflow 中一个接一个地训练,无需手动调用 train.py
,所以我做到了:
for i in range(0, max_count):
model = get_model(i) # returns ith model
model.fit(...)
model.save(...)
它 运行 对于 i=0
很好(事实上 运行 当 运行 分开时是完美的)。问题是当第二次加载模型时,我得到ResourceExhaustedError OOM
,所以我试图在for循环结束时释放内存
del model
keras.backend.clear_session()
tf.clear_session()
tf.reset_default_graph()
gc.collect()
none 其中单独或集体工作。
我进一步查找,发现释放GPU内存的唯一方法是结束进程。
还有这个keras issue
Update (2018/08/01): Currently only TensorFlow backend supports proper cleaning up of the session. This can be done by calling K.clear_session(). This will remove EVERYTHING from memory (models, optimizer objects and anything that has tensors internally). So there is no way to remove a specific stale model. This is not a bug of Keras but a limitation of the backends.
很明显,方法是每次我加载一个模型并等待它结束时创建一个进程,然后在一个新的进程中创建另一个进程,如下所示:
import multitasking
def train_model_in_new_process(model_module, kfold_object, x, y, x_test, y_test, epochs, model_file_count):
training_process = multiprocessing.Process(target=train_model, args=(x, y, x_test, y_test, epochs, model_file_count, ))
training_process.start()
training_process.join()
但随后会抛出此错误:
File "train.py", line 110, in train_model_in_new_process
training_process.start()
File "F:\Python\envs\tensorflow\lib\multiprocessing\process.py", line 105, in start
self._popen = self._Popen(self)
File "F:\Python\envs\tensorflow\lib\multiprocessing\context.py", line 223, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "F:\Python\envs\tensorflow\lib\multiprocessing\context.py", line 322, in _Popen
return Popen(process_obj)
File "F:\Python\envs\tensorflow\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
reduction.dump(process_obj, to_child)
File "F:\Python\envs\tensorflow\lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
TypeError: can't pickle module objects
Using TensorFlow backend.
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "F:\Python\envs\tensorflow\lib\multiprocessing\spawn.py", line 105, in spawn_main
exitcode = _main(fd)
File "F:\Python\envs\tensorflow\lib\multiprocessing\spawn.py", line 115, in _main
self = reduction.pickle.load(from_parent)
EOFError: Ran out of input
我真的无法利用错误中显示的信息来查看我做错了什么。它显然指向 training_process.start()
行,但我似乎无法理解导致问题的原因。
感谢使用 for
循环或 Process
训练模型的任何帮助。
显然,Multiprocessing
不喜欢 modules
或更准确地说 importlib
模块。我使用 importlib
.py
文件加载模型
model_module = importlib.import_module(model_file)
因此麻烦。
我在 Process
里面做了同样的事情,一切都很好:)
但我仍然找不到不用 Process
es,使用 for
s 来做到这一点的方法。如果您有答案,请 post 在这里,不客气。但无论如何,我将继续处理进程,因为我认为进程在某种程度上更干净,因为它们是隔离的,并在完成后清除为该特定进程分配的所有内存。