首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Keras在每一个时代都占据着无限大的内存。

Keras在每一个时代都占据着无限大的内存。
EN

Stack Overflow用户
提问于 2018-12-08 13:48:18
回答 4查看 6.4K关注 0票数 12

我正在运行一个遗传超参数搜索算法,它可以快速地饱和所有可用的内存。

经过几次测试,看起来在不同的时期之间和在训练不同的模型时,keras所需的内存都会增加。随着小批处理规模的增加,问题变得更加严重,1~5的小批处理至少给了我足够的时间来看到内存使用量在最初的几次调整中快速上升,然后缓慢而稳定地随着时间的推移而增加。

我已经检查了keras预测内存交换无限期增加Keras:执行超参数网格搜索时内存不足Keras (TensorFlow,CPU):循环中的顺序模型训练,所以每次迭代之后,我已经在清除keras会话并重置tensorflow的图形。

我还尝试显式删除模型和历史对象,并运行gc.collect(),但没有结果。

我在CPU上运行Keras2.2.4、tensorflow 1.12.0、Python3.7.0。我为每个基因运行的代码以及用于度量内存使用情况的回调:

代码语言:javascript
复制
import tensorflow as tf
import keras as K

class MemoryCallback(K.callbacks.Callback):
    def on_epoch_end(self, epoch, log={}):
        print(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)


def Rateme(self,loss,classnum,patience,epochs,DWIshape,Mapshape,lr,TRAINDATA,TESTDATA,TrueTrain, TrueTest,ModelBuilder,maxthreads):

K.backend.set_session(K.backend.tf.Session(config=K.backend.tf.ConfigProto(intra_op_parallelism_threads=maxthreads, inter_op_parallelism_threads=maxthreads)))

#Early Stopping
STOP=K.callbacks.EarlyStopping(monitor='val_acc', min_delta=0.001,
                               patience=patience, verbose=0, mode='max')
#Build model
Model=ModelBuilder(DWIshape, Mapshape, dropout=self.Dropout,
                      regularization=self.Regularization,
                      activ='relu', DWIconv=self.nDWI, DWIsize=self.sDWI,
                      classes=classnum, layers=self.nCNN,
                      filtersize=self.sCNN,
                      FClayers=self.FCL, last=self.Last)
#Compile
Model.compile(optimizer=K.optimizers.Adam(lr,decay=self.Decay), loss=loss, metrics=['accuracy'])
#Fit
his=Model.fit(x=TRAINDATA,y=TrueTrain,epochs=epochs,batch_size=5, shuffle=True, validation_data=(TESTDATA,TrueTest), verbose=0, callbacks=[STOP, MemoryCallback()]) #check verbose and callbacks
#Extract 
S=Model.evaluate(x=TESTDATA, y=TrueTest,verbose=1)[1]
del his
del Model
del rateme
K.backend.clear_session()
tf.reset_default_graph()
gc.collect()

return S
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2021-04-17 12:17:10

由于内存泄漏似乎仍然存在于TensorFlow 2.4.1中,所以在使用内置函数(如model.fit() )时,这里是我的看法。

发行

  • 负载的内存使用,即使我是运行NVIDIA GeForce RTX 2080 TI GPU。
  • 随着训练的进行而增加。
  • 某种记忆泄漏(感觉有点线性)。

解决方案

  • run_eagerly=True参数添加到model.compile()函数中。然而,这样做可能会导致TensorFlow的图形优化不再工作,从而导致性能下降(参考文献)。
  • 创建一个自定义回调,在每个时代(参考文献)结束时,垃圾收集并清除Keras后端。
  • 不要在activation内部使用tf.keras.layers参数。将激活函数作为分离层(参考文献)。
  • 使用LeakyReLU而不是ReLU作为激活函数(参考文献)。

注意:因为所有的要点都可以单独实现,所以您可以混合和匹配它们,直到得到对您有用的结果。无论如何,下面是一个代码片段,显示了所有解决方案:

代码语言:javascript
复制
import gc
from tensorflow.keras import backend as k
from tensorflow.keras.layers import Conv2D, BatchNormalization, ReLU
from tensorflow.keras.callbacks import Callback


class CovNet:
    ...
    x = Conv2d(
        ...,
        activation=None
    )(x)
    x = BatchNormalization()(x)
    x = ReLU()(x)  # or LeakyReLU
    ...

#--------------------------------------------------------------------------------

class ClearMemory(Callback):
    def on_epoch_end(self, epoch, logs=None):
        gc.collect()
        k.clear_session()

#--------------------------------------------------------------------------------

model.compile(
    ...,
    run_eagerly=True
)

#--------------------------------------------------------------------------------

model.fit(
    ...,
    callbacks=ClearMemory()
)

有了这些解决方案,我现在能够训练占用较少的RAM,保持不变,如果仍然存在内存泄漏,这是可以忽略不计的。

感谢@洪涛杨致远提供了一个相关的GitHub问题链接,并为他的评论在GitHub提供了新的链接。

Notes

  • 如果上述任何一个都不适合您,您可能希望尝试用TensorFlow编写您自己的培训循环。这是一个关于如何做它的指南
  • 人们也一直在报道使用tcmalloc代替默认的malloc分配程序在一定程度上减轻了内存泄漏。有关参考资料,请参阅这里这里

我希望这也能帮助到其他人,并为你节省一些在互联网上进行研究的时间。

票数 9
EN

Stack Overflow用户

发布于 2018-12-08 17:13:12

消耗整个可用内存是TF的默认行为。

可以使用以下代码限制TF中的内存量:

代码语言:javascript
复制
import tensorflow as tf
from keras.backend.tensorflow_backend import set_session

config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.9 # fraction of memory
config.gpu_options.visible_device_list = "0"

set_session(tf.Session(config=config))
票数 2
EN

Stack Overflow用户

发布于 2019-01-22 13:37:19

最后,我只是用bash脚本重新启动了每个培训班之间的python会话,找不到更好的方法来避免爆炸性的内存占用。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53683164

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档