【问题标题】:OOM error even after clearing GPU Session即使在清除 GPU 会话后也会出现 OOM 错误
【发布时间】:2019-06-19 11:16:23
【问题描述】:

我正在将 CNN 应用于包含 4684 张大小为 2000*102 的图像的数据集。我在 keras 中使用 5 折交叉验证来记录性能指标。我正在使用del.model()del.histroyK.clear_session(),但在运行 2 次后,它给出了 OOM 错误。请参阅下面开发的算法。在 11GB 内存的 1080Ti 上运行。电脑内存 32GB

kf = KFold(n_splits=5, shuffle=True)
kf.get_n_splits(data_new)

AUC_SCORES = []
KAPPA_SCORES = []
MSE = []
Accuracy = []
for train, test in kf.split(data_new):
    Conf_model = None
    Conf_model = Sequential()
    Conf_model.add(Conv2D(32, (20,102),activation='relu',input_shape=(img_rows,img_cols,1),padding='same',data_format='channels_last'))
    Conf_model.add(MaxPooling2D((2,2),padding='same',dim_ordering="th"))
    Conf_model.add(Dropout(0.2))
    Conf_model.add(Flatten())     
    Conf_model.add(Dense(64, activation='relu'))  
    Conf_model.add(Dropout(0.5))        
    Conf_model.add(Dense(num_classes, activation='softmax'))
    Conf_model.compile(loss=keras.losses.binary_crossentropy, optimizer=keras.optimizers.Adam(),metrics=['accuracy'])

    data_train = data_new[train]
    data_train.shape
    labels_train = labels[train]

    data_test = data_new[test]
    data_test_Len = len(data_test)
    data_train = data_train.reshape(data_train.shape[0],img_rows,img_cols,1)
    data_test = data_test.reshape(data_test.shape[0],img_rows,img_cols,1)
    data_train = data_train.astype('float32')
    data_test = data_test.astype('float32')
    labels_test = labels[test]
    test_lab = list(labels_test)#test_lab.append(labels_test)
    labels_train = to_categorical(labels_train,num_classes)
    labels_test_Shot = to_categorical(labels_test,num_classes)
    print("Running Fold")
    history = Conf_model.fit(data_train, labels_train, batch_size=batch_size,epochs=epochs,verbose=1)
    Conf_predicted_classes=Conf_model.predict(data_test)
    Conf_predict=Conf_model.predict_classes(data_test)
    Conf_Accuracy = accuracy_score(labels_test, Conf_predict)
    Conf_Mean_Square = mean_squared_error(labels_test, Conf_predict)
    Label_predict = list(Conf_predict)#Label_predict.append(Conf_predict)
    Conf_predicted_classes = np.argmax(np.round(Conf_predicted_classes),axis=1)
    Conf_Confusion = confusion_matrix(labels_test, Conf_predicted_classes)
    print(Conf_Confusion)
    Conf_AUC = roc_auc_score(labels_test, Conf_predict)
    print("AUC value for Conf Original Data: ", Conf_AUC)
    Conf_KAPPA = cohen_kappa_score(labels_test, Conf_predict)
    print("Kappa value for Conf Original Data: ", Conf_KAPPA)
    AUC_SCORES.append(Conf_AUC)
    KAPPA_SCORES.append(abs(Conf_KAPPA))
    MSE.append(Conf_Mean_Square)
    Accuracy.append(Conf_Accuracy)
    del history
    del Conf_model
    K.clear_session()

以下错误

ResourceExhaustedError: OOM when allocating tensor with shape[1632000,64] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc
     [[{{node training/Adam/gradients/dense_1/MatMul_grad/MatMul_1}} = MatMul[T=DT_FLOAT, transpose_a=true, transpose_b=false, _device="/job:localhost/replica:0/task:0/device:GPU:0"](flatten_1/Reshape, training/Adam/gradients/dense_1/Relu_grad/ReluGrad)]]
Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.

我尝试了下面的代码,似乎它有效。

  def clear_mem():
     try: tf.sess.close()
     except: pass
     sess = tf.InteractiveSession()
     K.set_session(sess)
     return

【问题讨论】:

  • 愚蠢的问题,但你能看看nvidia-smi 并全程监控吗?特别是当第一个模型被杀死时,执行time.sleep() 以查看内存是否在创建第二个模型之前被释放。如果我没有错(可能是),内存将不会被释放。我假设您使用的是 tf-kerastensorflow 后端?
  • 感谢您的回复,我在 Windows 上运行,所以我使用 GPU-Z 来监控内存。关于如何在每次折叠后清除 GPU 内存的任何建议。我正在使用 TensorFlow 后端。但问题是它以前使用相同的代码工作。现在它开始抛出错误。
  • 运行 GPU-Z 是我的假设正确,因为它没有在实例化之间被释放?
  • 你能在运行第一个火车步骤之前运行tf.get_default_graph().finalize()吗?它会引发任何错误吗?或者它仍然完成给定时期的训练?
  • gabirele,我在 model.fit 之前添加了您的建议,但它抛出了错误。 raise RuntimeError("Graph is finalized and cannot be modified.") RuntimeError: Graph is finalized and cannot be modified.

标签: tensorflow gpu conv-neural-network cross-validation


【解决方案1】:

考虑到 cmets 中的更新的一些建议:

1) 创建一个单独启动 python 脚本的 bash 脚本(在进程终止后,内存被释放),并让它们将结果写入单独的文件,您以后可以处理这些文件并将它们连接在一起。例如,使用 bash 脚本迭代并提供 1)种子和 2)python 脚本的当前索引。使用种子,您可以确保折叠拆分没有泄漏,并且使用索引您可以抓住相关部分

2) 使用 python 进程对结果进行多处理

在我推荐方法 1 之前,我曾在 python 多处理中使用过 tensorflow。我在实现这个过程中遇到了很多问题

这些方法有意义吗?

【讨论】:

  • 嗨,我使用了我编辑的代码。这解决了错误。我在交叉验证之外定义了该函数并在交叉验证中调用它。现在我没有遇到任何错误。你能说这有什么不对吗?
  • 嗯,我不确定,抱歉:/我并没有真正使用 keras,而且我使用的 tensorflow 版本有点旧,所以我不确定我所掌握的知识是否真的可以继承.不过,我不太了解您使用的方法是如何起作用的,因为从tf github issues list 看来,似乎没有内置的方法来释放内存。话虽如此,如果它有效,它就有效。我会说一定要验证模型是否正确训练(在训练错误高之前,预测 v 不好,但在训练错误低并且预测更好之后)
  • 当然谢谢。我在 fast.ai forums.fast.ai/t/gpu-garbage-collection/1976/2 中找到了这个
  • Keras Github Issue: clear_session() doesn't clear memory from GPU 可能值得研究。抱歉,我帮不上忙了——我什至不知道这是现在的事情。但如果它不起作用,请记住我提到的方法,它可能会起作用(为我的公司工作)
  • 这很棒。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 2013-04-14
  • 1970-01-01
  • 1970-01-01
  • 2021-01-02
相关资源
最近更新 更多