深度学习中具有大数据帧的MemoryError

时间:2019-11-30 19:17:30

标签: python-3.x dataframe deep-learning bigdata graph-theory

序言

大家好,

我正在尝试使用StellarGraph软件包创建一个几何深度学习模型。使用较小的数据集,它可以很好地工作,但是不幸的是,它不能扩展到较大的数据集。有关机器,环境,使用的数据以及由此产生的错误的信息,如下所示。

机器规格:

  • CPU:英特尔酷睿i5-8350U
  • RAM: 8GB DDR4
  • SWAP:4 GB + 4 GB(分为两个SSD,分别位于不同的SSD中)
  • SSD:250 GB + 250 GB(2280和2242 NVMe)

环境:

  • Linux 5.3.11_1 64位
  • Python 3.6.9

使用的数据(从sys.getsizeof()获取的大小):

  • 稀疏块对角矩阵(形状:158,950 x 158,950;大小:56)
  • 密集特征矩阵(形状:158,950 x 14,450;大小:9,537,152)

模块:

  • networkx 2.3
  • numpy 1.15.4
  • pandas 0.25.3
  • scipy 1.1.0
  • scikit-learn 0.21.3
  • stellargraph 0.8.2
  • tensorflow 1.14.0

问题描述

我的目的是基于从静止状态功能MRI获得的邻接矩阵,创建一种几何深度学习,以对主题进行分类。邻接矩阵假设有55个感兴趣的区域,因此所有受试者的矩阵为55x55。在构建深度学习模型时,我使用了StellarGraph的频谱图卷积网络模型,该模型以图对象和节点特征为输入。我根据稀疏块对角线矩阵创建了图形对象,该对角线矩阵是通过合并所有主题的邻接矩阵而获得的。节点特征是每个节点的特征(1个节点具有5个特征值),构造成密集块对角矩阵。

之前,我使用总体样本的子集(大约170个)来制作模型。它运行得很完美,我想我可以使用更大的数据集来做同样的事情。不幸的是,使用相同的代码注册MemoryError对象时得到了StellarGraph。代码和错误在以下部分中介绍。

代码和错误

# Data parsing with scipy.io as sio and pandas as pd
data = sio.mmread('_data/sparse.mtx')
feature = sio.mmread('_data/sparse-feature.mtx')
feature = pd.DataFrame.sparse.from_spmatrix(feature)

# Create graph object using networkx as nx
g = nx.from_scipy_sparse_matrix(data)

# Create StellarGraph object and its generator
gs = StellarGraph(g, node_features=feature) # MemoryError
generator = FullBatchNodeGenerator(gs)

由于机密性原因,我不提供sparse.mtxsparse-feature.mtx文件,对此感到抱歉,但是我希望前面有关数据形状和大小的描述可以帮助您理解其结构。使用上面的代码,python给了我以下错误:

>>> gs = StellarGraph(g, node_features=feature) # MemoryError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/lam/.local/lib/python3.6/site-packages/stellargraph/core/graph.py", line 786, in __init__
    super().__init__(incoming_graph_data, **attr)
  File "/home/lam/.local/lib/python3.6/site-packages/stellargraph/core/graph.py", line 381, in __init__
    node_features, type_for_node, node_types, dtype
  File "/home/lam/.local/lib/python3.6/site-packages/stellargraph/core/graph.py", line 216, in _convert_from_node_data
    {node_type: data}, node_type_map, node_types, dtype
  File "/home/lam/.local/lib/python3.6/site-packages/stellargraph/core/graph.py", line 182, in _convert_from_node_data
    data_arr = arr.values.astype(dtype)
  File "/home/lam/.local/lib/python3.6/site-packages/pandas/core/generic.py", line 5443, in values
    return self._data.as_array(transpose=self._AXIS_REVERSED)
  File "/home/lam/.local/lib/python3.6/site-packages/pandas/core/internals/managers.py", line 822, in as_array
    arr = mgr._interleave()
  File "/home/lam/.local/lib/python3.6/site-packages/pandas/core/internals/managers.py", line 840, in _interleave
    result = np.empty(self.shape, dtype=dtype)
MemoryError

在监视内存消耗时,我观察到RAM仅使用了其总容量的55%,并且根本没有使用交换。在运行代码时,我仅在运行tmuxvimtop会话的情况下使用TTY + python。此外,我还确保在后台没有其他占用内存的进程在运行。因此,我确定内存瓶颈很可能是由python引起的。

我尝试过的

为了利用内存消耗,我尝试使用dask来管理密集的feature数据帧。不幸的是,StellarGraph函数只能将pandas数组,pandas数据框,字典,元组或其他可迭代对象作为其输入。

除了dask之外,我还尝试使用稀疏矩阵(因为几乎80%的数据集都是零值)。但是,它给了我TypeError,因为StellarGraph不能拥有稀疏矩阵作为其node_features

我还阅读了一些有关管理大型数据集的解决方案,(大多数情况下)建议将数据迭代地解析为python会话。但是,在这种方法的StellarGraph中我找不到任何文件。

另一个选择是使用硬件更好的计算机,令我遗憾的是,由于资金有限,我无法这样做。我是一名学生,目前买不起更好的机器。

潜在解决方案

  • 升级RAM。我将尝试从其他计算机上回收RAM,但当前的最大大小为16 GB。我不确定是否足够。
  • 使用feature数据集的较小块。我设法采用了该解决方案,但模型的准确性确实很差(50%左右)。

问题

  1. 为什么python仅使用总RAM的55%而没有动态交换分配?
  2. 我应如何有效管理大型数据帧?
  3. 在创建MemoryError对象时如何处理StellarGraph
  4. 我实际上需要多少RAM? 32GB足够了吗?

1 个答案:

答案 0 :(得分:0)

Python运行正常。这是StellarGraph引起的实现问题。

我认为到目前为止,StellarGraph不支持巨大的矩阵。

File "/home/lam/.local/lib/python3.6/site-packages/stellargraph/core/graph.py", line 182, in _convert_from_node_data
data_arr = arr.values.astype(dtype)

从代码的开头到此处,所有数据都存储为稀疏数组,这不会占用太多内存。在这里,arr应该是一个带有pandas.SparseArray列的DataFrame。这行代码将数据结构转换为普通的numpy数组,从而导致内存使用崩溃。

import numpy as np
a = np.empty((158950,14450),float)
print(a.nbytes/2**30)
17.112698405981064

一个空的numpy数组实际上占用17 G内存。我可以在16 G计算机上初始化3个类似的数组。然后,如果尝试获取大于3的内存,则会出现内存错误。而且我无法初始化158,950 x 158,950 numpy数组。