iPython 笔记本 - 加载 CIFAR - 10 数据集时出现内存错误

Posted

技术标签:

【中文标题】iPython 笔记本 - 加载 CIFAR - 10 数据集时出现内存错误【英文标题】:iPython notebook - Memory Error when loading CIFAR - 10 dataset 【发布时间】:2016-05-27 23:11:30 【问题描述】:

我目前正在关注斯坦福大学的卷积神经网络课程:http://cs231n.github.io/。我在具有 2GB 内存的联想 SL500 上运行任务。但是当我使用以下代码加载 Cifar-10 数据集时:

import cPickle as pickle
import numpy as np
import os
from scipy.misc import imread

def load_CIFAR_batch(filename):
  """ load single batch of cifar """
  with open(filename, 'rb') as f:
    datadict = pickle.load(f)
    X = datadict['data']
    Y = datadict['labels']
    X = X.reshape(10000, 3, 32, 32).transpose(0,2,3,1).astype("float")
    Y = np.array(Y)
    return X, Y

def load_CIFAR10(ROOT):
  """ load all of cifar """
  xs = []
  ys = []
  for b in range(1,6):
    f = os.path.join(ROOT, 'data_batch_%d' % (b, ))
    X, Y = load_CIFAR_batch(f)
    xs.append(X)
    ys.append(Y)    
  Xtr = np.concatenate(xs)
  Ytr = np.concatenate(ys)
  del X, Y
  Xte, Yte = load_CIFAR_batch(os.path.join(ROOT, 'test_batch'))
  return Xtr, Ytr, Xte, Yte

其实这里是调用函​​数的部分:

# Load the raw CIFAR-10 data.
cifar10_dir = 'cs231n/datasets/cifar-10-batches-py'
X_train, y_train, X_test, y_test = load_CIFAR10(cifar10_dir)

# As a sanity check, we print out the size of the training and test data.
print 'Training data shape: ', X_train.shape
print 'Training labels shape: ', y_train.shape
print 'Test data shape: ', X_test.shape
print 'Test labels shape: ', y_test.shape

我收到此错误:

MemoryError                               Traceback (most recent call last)
<ipython-input-3-76ab1121c87e> in <module>()
      1 # Load the raw CIFAR-10 data.
      2 cifar10_dir = 'cs231n/datasets/cifar-10-batches-py'
----> 3 X_train, y_train, X_test, y_test = load_CIFAR10(cifar10_dir)
      4 
      5 # As a sanity check, we print out the size of the training and test data.

C:\Users\son\assignment1\cs231n\data_utils.py in load_CIFAR10(ROOT)
     20   for b in range(1,6):
     21     f = os.path.join(ROOT, 'data_batch_%d' % (b, ))
---> 22     X, Y = load_CIFAR_batch(f)
     23     xs.append(X)
     24     ys.append(Y)

C:\Users\son\assignment1\cs231n\data_utils.py in load_CIFAR_batch(filename)
     10     X = datadict['data']
     11     Y = datadict['labels']
---> 12     X = X.reshape(10000, 3, 32, 32).transpose(0,2,3,1).astype("float")
     13     Y = np.array(Y)
     14     return X, Y

MemoryError: 

问题是内存使用量迅速上升到 2GB !即使 CIFAR-10 数据集只有大约 177MB!

我曾尝试只加载一个批次,它确实有效,但我必须非常小心不要弄乱任何步骤(不要两次运行同一个单元格,即使它似乎没有运行,。 ..)。有人对此有解决方案吗?非常感谢!

更新:在load_CIFAR_batch 函数中,如果我注释掉重塑行:# X = X.reshape(10000, 3, 32, 32).transpose(0,2,3,1).astype("float") 然后程序能够加载: 所以也许我的程序无法运行的原因是因为 reshape 线,它创建了 X 和 Y 的副本,因此数据加倍。这个假设是否正确,如果正确,我该怎么办?

【问题讨论】:

【参考方案1】:

查看数据的大小,这一行

X = X.reshape(10000, 3, 32, 32).transpose(0,2,3,1).astype("float")

告诉我们,每批数据都是10000*3*32*32,略多于 3000 万个浮点数。 float 数据类型实际上与 float64 相同,这意味着每个数字 8 个字节。 这意味着每个批次至少占用 240 MB。 您加载其中的 6 个(5 个训练 + 1 个测试),总共产生接近 1.4 GB 的数据。 如果数据集在磁盘上确实接近 180 MB,那么它似乎被压缩得很好:)

在我看来,您有两个(非相互)选项:

    如果可能,一次运行一批训练。你暗示你已经尝试过了。

    根据问题的类型,双精度(64 位浮点数)可能超出您的需要。因此,您可以尝试将上面的行更改为float32 而不是float。这将有效地将内存需求减少一半。 但它也可能会搞砸计算,除非你不小心。

    购买更多 RAM 或在另一台机器上运行。如果你在机器学习方面走得更远,这在某些时候会给你带来麻烦。从几乎任何标准来看,2GB 都很弱,而在机器学习领域,它几乎为零。

【讨论】:

我不能使用虚拟内存吗? (我试过但没用,我不知道为什么:() 我已经更新了答案,你能告诉我我的想法是否正确吗?非常感谢【参考方案2】:

我遇到了同样的问题。

我通过修改 data_utils.py 中的 load_CIFAR10() 来减少数据集来解决这个问题。

def load_CIFAR10(ROOT):
  """ load all of cifar """
  xs = []
  ys = []
  for b in range(1, 2): 
    # not to load all the data files, just 3 or less to test
    f = os.path.join(ROOT, 'data_batch_%d' % (b, ))
    X, Y = load_CIFAR_batch(f)
    # other codes...

【讨论】:

以上是关于iPython 笔记本 - 加载 CIFAR - 10 数据集时出现内存错误的主要内容,如果未能解决你的问题,请参考以下文章

Jupyter ipython 内核在大文件加载时死机

Pyspark 连接到 ipython 笔记本中的 Postgres 数据库

如何重置Jupyter / IPython输入提示编号?

如何重置 Jupyter/IPython 输入提示编号?

无法加载 CIFAR-10 数据集:加载键“\x1f”无效

从 cifar-10 数据集加载图像