如何在Colab中释放内存?

4

我正在尝试通过遍历不同的超参数来构建最佳模型。但是在完成1次迭代(训练1个模型)后,当第2次迭代开始时,我会因内存耗尽而失败。

ResourceExhaustedError: OOM when allocating tensor with shape[5877,200,200,3] and type double on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc [Op:GatherV2]

我尝试使用ops.reset_default_graph(),但它没有任何作用。

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras import regularizers
from tensorflow.keras.layers import Dense,Activation,Flatten,Conv2D,MaxPooling2D,Dropout
import os
import cv2
import random
import pickle
import time
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.callbacks import TensorBoard
from google.colab import files
from tensorflow.python.framework import ops
p1=open("/content/tfds.pickle","rb")
def prepare_ds():
    dir="drive//My Drive//dataset//"
    cat=os.listdir(dir)
    i=1
    td=[]
    for x in cat:
        d=dir+x
        y1=cat.index(x)
        for img in os.listdir(d):
            im=cv2.imread(d+"//"+img)
            print(i)
            i=i+1     
            im=cv2.resize(im,(200,200))
            td.append([im,y1])
    ##      im[:,:,0],im[:,:,2]=im[:,:,2],im[:,:,0].copy()
    ##      plt.imshow(im)
    ##      plt.show()
    random.shuffle(td)
    X=[]
    Y=[]
    for a1,a2 in td:
        X.append(a1)
        Y.append(a2)
    X=np.array(X).reshape(-1,200,200,3)
    Y=np.array(Y).reshape(-1,1)
    pickle.dump([X,Y],p1)
##prepare_ds()
X,Y=pickle.load(p1)
X=X/255.0
def learn():
    model=tf.keras.models.Sequential()
    model.add(Conv2D(lsi,(3,3),input_shape=X.shape[1:]))
    model.add(Activation("relu"))
    model.add(MaxPooling2D(pool_size=(2,2)))

    for l in range(cli-1):
      model.add(Conv2D(lsi,(3,3)))
      model.add(Activation("relu"))
      model.add(MaxPooling2D(pool_size=(2,2)))

    model.add(Flatten())
    for l in range(dli):
      model.add(Dense(lsi))
      model.add(Activation("relu"))

    model.add(Dropout(0.5))
    model.add(Dense(10))
    model.add(Activation('softmax'))

    model.compile(loss="sparse_categorical_crossentropy",optimizer="adam",metrics=['accuracy'])
    model.fit(X,Y,batch_size=16,validation_split=0.1,epochs=3,verbose=2,callbacks=[tb])
    model.save('tm1.h5')
    ops.reset_default_graph()

dl=[0,1,2]
ls=[32,64,128]
cl=[1,2,3]
for dli in dl:
  for lsi in ls:
    for cli in cl:
      ops.reset_default_graph()
      NAME = "{}-conv-{}-nodes-{}-dense".format(cli, lsi, dli)
      tb=TensorBoard(log_dir="logs//{}".format(NAME))
      print(NAME)
      learn()

p1.close()
!zip -r /content/file.zip /content/logs
!cp file.zip "/content/drive/My Drive/"
3个回答

16

你好。

你可以使用Python内置的垃圾回收库。我经常在每个epoch结束时创建一个自定义回调,使用这个库。你可以把它看作是清除你不再需要的缓存信息。

# Garbage Collector - use it like gc.collect()
import gc

# Custom Callback To Include in Callbacks List At Training Time
class GarbageCollectorCallback(tf.keras.callbacks.Callback):
    def on_epoch_end(self, epoch, logs=None):
        gc.collect()

此外,尝试单独运行命令gc.collect()以查看结果并了解其工作原理。 这里有一些有关其工作方式的文档。 我经常在只有内核的 Kaggle 竞赛中使用它来保持内核大小较小。


希望这可以帮助你!


非常有用的答案,谢谢。有人知道为什么我只能在第一次运行Google Colab单元格时才能工作吗? - David Streuli

3

虽然这可能是对问题的一个迟到的答案,但希望有人能发现它有用。

在Google Colab中释放一些内存的方法可以通过删除不再需要的变量来实现。 点击左侧的变量检查器窗口。 enter image description here

查看您不需要的变量,然后将其删除。 enter image description here


1
我怀疑仅仅打开那个变量检查器就会占用大量内存。目前正在调查如何清除它。 - kawingkelvin

0
如果您的数据占用了大量的内存,您可以使用tf.Dataset结构来节省内存,而不是使用列表。有一些Keras辅助方法,比如tf.keras.utils.image_dataset_from_directory,它可以按需惰性加载图像的批次。
您可以从Keras数据加载网页了解更多相关信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接