使用 SigmoidFocalCrossEntropy 计算损失时内存不足

数据挖掘 Python 张量流 损失函数 记忆
2022-03-03 12:32:00

代码版本:

python == 3.8
tensorflow == 2.2.0
tensorflow-addons == 0.11.2

最近我一直在为我的一个模型使用 tensorflow 插件的焦点损失函数。为了更好地理解/演示正在发生的事情,我一直在尝试从原始论文中重新创建一些图表- 具体来说,图 4,它显示了少数和多数损失的累积总和图,分别使用不同的伽马收敛模型。

def calcCSP(pred, Y_test, g, label):

    true = np.asarray(Y_test)
    idsPos = np.where(true == 1)
    idsNeg = np.where(true == 0)

    pPos = pred[idsPos]
    yPos = true[idsPos]

    pNeg = pred[idsNeg]
    yNeg = true[idsNeg]

    if label == 1:
        p = pPos
        y = yPos
        title = "Positive Loss Distribution"
    else:
        p = pNeg
        y = yNeg
        title = "Negative Loss Distribution"

    p = tf.convert_to_tensor(p)
    y = tf.cast(y, tf.float32)

    fl = tfa.losses.SigmoidFocalCrossEntropy(alpha=PARAMS['alpha'], gamma=g)

    loss = fl(y, p)

    x = np.sort(loss)

    # Normalized Data
    x = x/sum(x)

    cdf = np.cumsum(x)
    n = len(x)
    share_of_population = np.arange(1, n + 1) / n


    cdf_materials = {"shares": share_of_population,
                     "cusum": cdf}

    return cdf_materials


cdfListPos = []
cdfListNeg = []

gammas = [0, 2, 4, 6, 8]

for g in gammas:
    # will need to store all this
    cdf_matPos = calcCDF(preds, y_test, g, 1)
    cdf_matNeg = calcCDF(preds, y_test, g, 0)
    cdfListPos.append(cdf_matPos)
    cdfListNeg.append(cdf_matNeg)

posplot = plt.figure()
for i in range(len(gammas)):
    plt.plot(cdfListPos[i]['shares'], cdfListPos[i]['cusum'], label= r'$\gamma$ = ' + str(gammas[i]))
    plt.title('Positive Points CSP')
    plt.ylabel('Cumulative Normalized Loss')
    plt.legend()

negplot = plt.figure()
for i in range(len(gammas)):
    plt.plot(cdfListNeg[i]['shares'], cdfListNeg[i]['cusum'], label=r'$\gamma$ = ' + str(gammas[i]))
    plt.title('Negative Points CSP')
    plt.ylabel('Cumulative Normalized Loss')
    plt.legend()

我已经设法在较小的数据集上运行我的代码 - 但是,一旦数据集变得太大,我似乎内存不足。

W tensorflow/core/common_runtime/bfc_allocator.cc:434] Allocator (mklcpu) ran out of memory trying to allocate 4.47GiB (rounded to 4804430848)
Current allocation summary follows.

为简洁起见,我省略了摘要,但如有必要,可以添加。我不确定如何解决这个问题。我尝试使用tf.split将预测值和真实值划分为较小的张量,然后将它们分别传递给损失函数并连接,但是使用较小的数据集进行测试表明,当我比较它们时结果不匹配完整版本。老实说,我不知道如何最好地解决这个问题,并且愿意接受任何建议。

1个回答

一种选择是使用降低精度。代替y = tf.cast(y, tf.float32),使用y = tf.cast(y, tf. float16)y = tf.cast(y, tf.bfloat16)