我试图循环训练1000倍的顺序模型。在每个循环中,我的程序都会泄漏内存,直到用尽并收到OOM异常。
之前我已经问过类似的问题(连续训练多个顺序模型会减慢速度)
并看到其他人也遇到类似的问题(Keras:执行超参数网格搜索时内存不足)
解决方案始终K.clear_session()是在使用完模型后添加到代码中。所以我在上一个问题中做到了,但我仍在泄漏内存
这是重现此问题的代码。
import random
import time
from keras.models import Sequential
from keras.layers import Dense
from keras import backend as K
import tracemalloc
def run():
tracemalloc.start()
num_input_nodes = 12
num_hidden_nodes = 8
num_output_nodes = 1
random_numbers = random.sample(range(1000), 50)
train_x, train_y = create_training_dataset(random_numbers, num_input_nodes)
for i in range(100):
snapshot = tracemalloc.take_snapshot()
for j in range(10):
start_time = time.time()
nn = Sequential()
nn.add(Dense(num_hidden_nodes, input_dim=num_input_nodes, activation='relu'))
nn.add(Dense(num_output_nodes))
nn.compile(loss='mean_squared_error', optimizer='adam')
nn.fit(train_x, train_y, nb_epoch=300, batch_size=2, verbose=0)
K.clear_session()
print("Iteration {iter}. Current time {t}. Took {elapsed} seconds".
format(iter=i*10 + j + 1, t=time.strftime('%H:%M:%S'), elapsed=int(time.time() - start_time)))
top_stats = tracemalloc.take_snapshot().compare_to(snapshot, 'lineno')
print("[ Top 5 differences ]")
for stat in top_stats[:5]:
print(stat)
def create_training_dataset(dataset, input_nodes):
"""
Outputs a training dataset (train_x, train_y) as numpy arrays.
Each item in train_x has 'input_nodes' number of items while train_y items are of size 1
:param dataset: list of ints
:param input_nodes:
:return: (numpy array, numpy array), train_x, train_y
"""
data_x, data_y = [], []
for i in range(len(dataset) - input_nodes - 1):
a = dataset[i:(i + input_nodes)]
data_x.append(a)
data_y.append(dataset[i + input_nodes])
return numpy.array(data_x), numpy.array(data_y)
run()
这是我从第一个内存调试打印中获得的输出
/tensorflow/python/framework/ops.py:121:大小= 3485 KiB(+3485 KiB),计数= 42343(+42343)/tensorflow/python/framework/ops.py:1400:大小= 998 KiB(+998 KiB),计数= 8413(+8413)/tensorflow/python/framework/ops.py:116:size = 888 KiB(+888 KiB),计数= 32468(+32468)/tensorflow/python/framework/ops.py :1185:大小= 795 KiB(+795 KiB),计数= 3179(+3179)/tensorflow/python/framework/ops.py:2354:大小= 599 KiB(+599 KiB),计数= 5886(+5886)
系统信息:
python 3.5 keras(1.2.2) tensorflow(1.0.0)
内存泄漏源于Keras和TensorFlow,它们使用单个“默认图”存储网络结构,网络结构的大小随内部for循环的每次迭代而增加。
调用会K.clear_session()在迭代之间释放与默认图相关联的某些(后端)状态,但是需要额外的调用tf.reset_default_graph()才能清除Python状态。
请注意,可能有一个更有效的解决方案:由于nn不依赖于任何一个循环变量,因此可以在循环外部定义它,并在循环内部重用相同的实例。如果这样做,则无需清除会话或重置默认图,并且性能会提高,因为您可以受益于两次迭代之间的缓存。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。