CNN训练系统记忆体问题

时间:2019-08-13 20:54:40

标签: python tensorflow keras conv-neural-network

我试图在CPU上训练CNN,输入尺寸为(102480,40,40,2),输出尺寸为(40,40)。在我使用(102480,40,40)输入训练模型之前,它工作得很好。现在,当我运行脚本时,内存使用量会增加,直到需要更多时,我的电脑才会冻结。我只有8 GB的内存。

我尝试将此行添加到我的代码中,但这根本没有帮助。

sess = tf.Session(config=tf.ConfigProto(inter_op_parallelism_threads=1, intra_op_parallelism_threads=1))

这是我的模特

model = Sequential()
model.add(Conv2D(64,(3,3), input_shape = train_data.shape[1:]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(64,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))


model.add(Dense(1600))
model.add(Reshape((40,40)))
model.add(Activation('sigmoid'))

model.compile(loss='MSE',
             optimizer='SGD',
             metrics=['MAE'])

history = model.fit(train_data, train_target,
          batch_size=256,
          epochs=100,
          validation_split=0.1,
          callbacks = [cp_callback])

我能以某种方式减少系统内存使用而不会损失准确性吗?

2 个答案:

答案 0 :(得分:0)

模型内存的计算取决于批处理大小。实际上,您可以通过将批处理大小乘以输入形状来粗略估计内存使用情况。就像您的情况下,输入大小是256倍。您可以尝试减小批量大小,但这可能会影响您的准确性。将此问题最小化的方法如下:https://datascience.stackexchange.com/a/12533

  

如果您确实需要更大的批次大小,但不适合   您的GPU,您可以喂一小批,保存梯度估算值并   喂一批或多批,然后进行体重更新。这样你   获得了更稳定的渐变,因为您增加了虚拟批次   大小。

最后,您可以使用我在下面给出的ZFTurbo的答案https://stackoverflow.com/a/46216013/6598433的解决方案来计算近似的内存使用情况:

def get_model_memory_usage(batch_size, model):
    import numpy as np
    from keras import backend as K

    shapes_mem_count = 0
    for l in model.layers:
        single_layer_mem = 1
        for s in l.output_shape:
            if s is None:
                continue
            single_layer_mem *= s
        shapes_mem_count += single_layer_mem

    trainable_count = np.sum([K.count_params(p) for p in set(model.trainable_weights)])
    non_trainable_count = np.sum([K.count_params(p) for p in set(model.non_trainable_weights)])

    number_size = 4.0
    if K.floatx() == 'float16':
         number_size = 2.0
    if K.floatx() == 'float64':
         number_size = 8.0

    total_memory = number_size*(batch_size*shapes_mem_count + trainable_count + non_trainable_count)
    gbytes = np.round(total_memory / (1024.0 ** 3), 3)
    return gbytes

答案 1 :(得分:0)

我没有减小批处理大小(这可能会影响准确性),我只是将数据类型从float64更改为float32。这将内存使用量减少了一半。