【发布时间】:2020-07-15 14:33:03
【问题描述】:
考虑以下代码,该代码适用于 CIFAR-10 数据集上的 Keras Sequential 模型。背景在文末给出:
import tensorflow as tf
from sklearn.datasets import fetch_openml
from sklearn.utils import shuffle
data, targets = shuffle(*fetch_openml('CIFAR_10', version=1, return_X_y=True))
train_sz = 50000
X_train, X_test, y_train, y_test = data[:train_sz, :], data[train_sz:, :], np.asarray(targets[:train_sz], dtype=np.int), np.asarray(targets[train_sz:], dtype=np.int)
model = tf.keras.Sequential()
model.add(tf.keras.Input(shape=(X_train.shape[1],)))
model.add(tf.keras.layers.Dense(64, activation='relu'))
model.add(tf.keras.layers.Dense(10))
model.compile(loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), optimizer='adam')
s = 0
for _ in range(500):
for i in range(100):
layers = []
for layer in model.get_weights():
layers.append(np.random.normal(0, 1, layer.shape))
model.set_weights(layers)
eval = model.evaluate(X_train, y_train)
s += eval
print(f'Done {i}')
print(s)
在外部 for 循环大约 1 次(有时在此之前,有时在之后)迭代之后,Python 崩溃并出现退出代码 137,这通常意味着内存不足 AFAIK。我的系统上有 16 GB 的内存,其中大约 20% 在运行之前使用。运行后,它会稳步增长到
大约 80%-90% 的内存使用率,然后下降到 60%-70%(GC 启动?),然后再次增加,以此类推,持续 2-3 次,直到最终崩溃。
我在无头 Ubuntu 18.04 服务器机器上,在 Anaconda 中使用 Python 3.7,在 Tensorflow 2.2 上使用 Titan X GTX GPU,该 GPU 没有用于其他任何事情(因此那里大约有 11GB 的可用内存)。
我的计算(当然,非常悲观):
- 运行此程序时,我有大约 12 GB 可用空间。
- 存储数据使用
60000*32*32*3浮点数,这对于float64s 大约是1500 MB。由于我正在制作的所有副本,让我们在此处放下 6 GB。不管怎样,这似乎是占用内存最多的地方。 - 此时层大小可以忽略不计:
X_train.shape[1]为 3072 (32*32*3),64 个隐藏单元算不了什么。 -
model.evaluate的默认批量大小为 32,因此在其中,它应该使用大约32*32*32*3*64float64s 作为中间层的输出。那是 50 MB,让我们在此处输入 1 GB 以再次确定。 -
model.evaluate可能还需要存储预测,所以这是50000*10float64s,又是 4 MB。让我们在此处再添加一个 1 GB。
总计:6 + 1 + 1 = 8 GB。我的内存使用绝对不应该超过 80%,而且我高估了很多。
为什么要使用这么多内存,我可以优化管理数据的方式吗?
我尝试使用np.asarray 将X 强制为np.int,float64s 没有意义,但这只会让它崩溃得更快——就像它将float64s 和ints 都保留在内存中一样。
背景
我正在研究一种训练人工神经网络的遗传算法。我已经将崩溃追溯到适应度的计算,这涉及将存储在每个个体中的训练权重应用于神经网络并评估网络(内部 i 循环,我的人口中有 100 个人)。这对每一代重复(最外层的 for 循环)。那里使用了更多的内存,但仍然很少。
这就是为什么这里没有进行拟合,权重由我的遗传算法确定并应用于网络。
这个简化的代码重现了这个问题。
【问题讨论】:
-
Related: github.com/keras-team/keras/issues/13118 or github.com/tensorflow/tensorflow/issues/33030 只是在模型上重复调用
evaluate或predict会导致OOM,使用的数据或操纵权重似乎无关紧要。 -
@IVIAd 我知道了,你看到我最后的三个厘米了吗
-
不使用GPU是否存在问题?我没有任何特别的期望,但是如果 CPU 出现这种情况,那将排除这是 GPU 问题的可能性。禁用 GPU 的前导代码:
import os; os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"; os.environ["CUDA_VISIBLE_DEVICES"] = "" -
@dannyadam 是的,确实如此。请注意,超出了系统内存,而不是 GPU 内存。
-
解决方法和讨论在这里:github.com/tensorflow/tensorflow/issues/41428 - 如果有人建议其他解决方法或可以提供解释,我会暂时保留它,然后决定如何处理赏金。
标签: python python-3.x numpy tensorflow keras