- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在训练一个神经网络,其中大约 5 GB 的数据存储为 numpy
数组。数据被分成 100000 行的 block ,我已经以随机顺序对所有 block 进行了六个周期的训练。不幸的是,网络已经开始过度拟合。我认为它仍然有能力更紧密地拟合数据;我怀疑每个 block 内的内部规律开始相互矛盾,我需要更彻底地洗牌数据,以便它可以训练不同的组合。我想在麻烦获得更多训练数据之前尝试一下。
有谁知道生成 360 万(很长)行 numpy 数据的新排列的好方法?我考虑过使用 one of these技术,但是使用 numpy.savetxt
编写这些数组会产生令人难以置信 巨大的文件,而且我不知道如何从标准 npy
以有助于解决此问题的方式归档。
现在,我最好的想法是在数据中创建成对索引 (c, r)
的排列,其中 c
选择一个 block ,而 r
从该 block 中选择一行。我可以将每一行存储在一个新的预分配数组中,然后保存它。但我想知道是否有不那么可怕的 I/O 绑定(bind)解决方案。是否有一些原则性的方法可以将随机的 block 对洗牌在一起,直到您得到一个在统计上独立于起始排列的排列?
最佳答案
到目前为止,在我尝试过的方法中,PyTables 解决方案目前是最好的,其次是使用 numpy
对内存映射数组的支持的解决方案。 PyTables 解决方案并不简单。如果使用打乱的整数数组直接索引 PyTables 数组,速度会非常慢。以下两步过程要快得多:
此过程产生的排列与正常的洗牌过程一样随机。如果这看起来不是很明显,考虑一下:(n choose x) * x! = x! * n!/(x! * (n - x)!) = n!/(n - x)!
。这种方法足够快,可以为每个训练周期进行加载随机播放。它还能够将数据压缩到约 650M —— 接近 90% 的紧缩。
这是我当前的实现;语料库中的每个训练 block 都会调用一次。 (返回的数组在别处洗牌。)
def _h5_fast_bool_ix(self, h5_array, ix, read_chunksize=100000):
'''Iterate over an h5 array chunkwise to select a random subset
of the array. `h5_array` should be the array itself; `ix` should
be a boolean index array with as many values as `h5_array` has
rows; and you can optionally set the number of rows to read per
chunk with `read_chunksize` (default is 100000). For some reason
this is much faster than using `ix` to index the array directly.'''
n_chunks = h5_array.shape[0] / read_chunksize
slices = [slice(i * read_chunksize, (i + 1) * read_chunksize)
for i in range(n_chunks)]
a = numpy.empty((ix.sum(), h5_array.shape[1]), dtype=float)
a_start = 0
for sl in slices:
chunk = h5_array[sl][ix[sl]]
a_end = a_start + chunk.shape[0]
a[a_start:a_end] = chunk
a_start = a_end
return a
在这种情况下,O(n^2) 方法(为每个 block 迭代整个 PyTables 数组)比 O(n) 方法(一次随机选择每一行)更快,这对我来说有点疯狂。但是,嘿,它有效。稍微间接一点,这可以适用于加载任意非随机排列,但这增加了比这里值得的更多的复杂性。
mmap
解决方案仅供引用,适用于出于任何原因需要纯 numpy 解决方案的人。它在大约 25 分钟内打乱所有数据,而上述解决方案在不到一半的时间内管理相同的数据。这也应该线性扩展,因为 mmap
允许(相对)高效的随机访问。
import numpy
import os
import random
X = []
Y = []
for filename in os.listdir('input'):
X.append(numpy.load(os.path.join('input', filename), mmap_mode='r'))
for filename in os.listdir('output'):
Y.append(numpy.load(os.path.join('output', filename), mmap_mode='r'))
indices = [(chunk, row) for chunk, rows in enumerate(X)
for row in range(rows.shape[0])]
random.shuffle(indices)
newchunks = 50
newchunksize = len(indices) / newchunks
for i in range(0, len(indices), newchunksize):
print i
rows = [X[chunk][row] for chunk, row in indices[i:i + newchunksize]]
numpy.save('X_shuffled_' + str(i), numpy.array(rows))
rows = [Y[chunk][row] for chunk, row in indices[i:i + newchunksize]]
numpy.save('Y_shuffled_' + str(i), numpy.array(rows))
关于python - 统一洗牌 5 GB 的 numpy 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27049810/
#include typedef std::vector vc; typedef std::vector vvc; vvc f() { const int N = (1 不把它还给操作系统。 因
我正在尝试训练 Dlib's train_shape_predictor_ex.cpp与 Halen数据集。我在 Release模式 中使用 Visual Studio 将代码编译为 64 位平台 作
当我试图解决this 时想到了这个问题。问题。 我有一个容量为 120 GB 的硬盘,其中 100 GB 被一个巨大的文件占用。所以 20 GB 仍然是免费的。 我的问题是,我们如何将这个巨大的文件拆
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Can you allocate a very large single chunk of memory (
我有一台运行 Linux (3.19.5-200.fc21.x86_64) 的 128 GB RAM 的计算机。但是,我不能在单个进程中分配超过 ~30 GB 的 RAM。除此之外,malloc 失败
我需要为 808704000 个 float 分配内存,大约是 3085 MB。我的电脑有 32 GB 内存,运行 64 位 Linux (CentOS 6.6)。每次我尝试分配内存时,malloc
很抱歉这个愚蠢的问题,但是当reading about 32 bits limitation ,我发现由于 Memory-Mapped 方法,MongoDB 不能存储超过 2 GB,但是: 2^32
假设我们有一个 32 位地址,那么每一位可以是 1 或 0。 所以组合总数等于2^32。 所以我们可以表示 2^32 个地址(没有单位)。 但为什么人们说 32 位地址可以表示 2^32 字节地址(为
好吧,这个问题确实是一个挑战! 背景 我正在从事一个涉及比正常数字更大的基于算术的项目。我是新手,我打算使用 4 GB 文件大小的最坏情况(我什至希望将其扩展到 5GB 上限,因为我之前看到文件大小大
我在文件系统上有大约 12 个大小为 1 GB 到 10 GB 的存储库,我需要为所有这些存储库设置自动备份(我们的旧备份脚本在计算机出现故障时丢失了) XP 64 位机器。 看完this quest
我尝试调整 Linux VM 上的操作系统磁盘大小,该 VM 通常由 azure 自动创建。我无法创建自定义操作系统磁盘 - 请告知我该怎么做? enter image description her
我在 .NET 中遇到了一个问题,我的数组受到我拥有的 RAM 数量的限制,并且我需要可以容纳至少 40 GB 字节的数组。我正在考虑使用硬盘驱动器作为虚拟数组的想法不在乎它是否慢。 我正在研究这个想
我尝试调整 Linux VM 上的操作系统磁盘大小,该 VM 通常由 azure 自动创建。我无法创建自定义操作系统磁盘 - 请告知我该怎么做? enter image description her
我的目标是看看当使用比物理 GPU 内存所能容纳的更多纹理数据时会发生什么。我的第一次尝试是加载多达 40 个 DDS 纹理,导致内存占用比 GPU 内存高得多。但是,我的场景在 9500 GT 上仍
Windows 上的 JDK 最多需要 2 GB 左右的 RAM。即使我们为 JDK 分配更多 RAM;它不接受它。如果我需要在 Windows 上运行需要 8 GB RAM 的进程;我怎样才能实现它
我有一个程序需要分配2个15亿长度的整数数组。这是一个编码挑战( https://projecteuler.net/problem=282 ),并且没有办法使用如此大的数组(如果有,请不要告诉我;我应
假设我有一个 32 位内核。 4 Gb RAM,10 Gb 交换分区。 我有一个在无限循环中有 malloc 的进程。因此,最终系统的 OOM 将终止该进程。这里有两个论点。 参数 1:因为它是 32
我有一个可以大于 4GB 的文件。我正在使用 linux split 命令按行拆分它(这是要求)。但是拆分原始文件后,我希望拆分文件的大小始终小于 2GB。原始文件大小可能在 3-5 GB 之间。我想
我有一台带有 32GB RAM 的 Mac 服务器(雪豹)。当我尝试在 Perl (v 5.10.0) 中分配超过 1.1GB 的 RAM 时,出现内存不足错误。这是我使用的脚本: #!/usr/bi
我们正在尝试运行.NET 4 Web应用程序(在8 GB,8核心Windows 2008 R2 64位Webedition服务器上),该应用程序使用Spire.doc创建Word mailmerge文
我是一名优秀的程序员,十分优秀!