【问题标题】:How come the input pickle file for my neural network is 19GB?为什么我的神经网络的输入 pickle 文件是 19GB?
【发布时间】:2020-12-31 22:26:26
【问题描述】:

所以我正在尝试为背包问题训练神经网络,因此我创建了一个包含 5,000 个元素的输入 pickle 文件。每个元素有 100 个权重和浮点值。还有以 int 表示的项目的总重量。还有一个解决方案是 1 和 0 的列表,其中 1 表示袋中项目的索引。每个元素的格式为:

( (tensor(weights), tensor(values), tensor(total weight), int(capacity percentage) ), (list(solution), float(solution time)) )

Here is what an element looks like。出于某种原因,该文件为 19 GB,对于只有 5,000 个元素的东西来说,这异常大。进行更深入的挖掘后,我在其中一个返回 56 字节值的元素上使用了 sys.getsizeof(),这意味着 5,000 个元素应该仅相当于 280 KB。但是,我确实尝试腌制一个大小为 3.9 MB 的元素,这意味着如果我分别腌制所有 5,000 个元素,它将加起来 19 GB。为什么泡菜文件这么大?有什么办法可以减小文件的大小吗?

【问题讨论】:

  • 请发布一个生成此类泡菜文件的最小示例。当我序列化一个包含 5000 个此类条目的列表时,它总共占用了大约 9.4MB。 (例如 len(pickle.dumps([((100*torch.randn(100), 100*torch.randn(100), torch.tensor((10000.0,)), 1), ([int(i == 10) for i in range(100)], 0.00078)) for _ in range(5000)])) / 2**20 计算结果为 9.3

标签: python machine-learning pytorch size pickle


【解决方案1】:

在为所有 5,000 个元素的输入和输出创建 pickle 文件时,我会将每个输入元素文件与其解决方案文件合并到一个大文件中。我已经意识到每个元素的输入文件大约 4 MB,而输出只有大约 2 KB,所以我假设输入文件归因于 pickle 文件的巨大大小。

所以这是创建数据集的函数:

def uniform_data_set(minimum=80, maximum=120, size=(5000,100)):
    values = (((maximum - minimum) * torch.rand(size)).floor() + minimum)
    weights = (((maximum - minimum) * torch.rand(size)).floor() + minimum)
    total_weights = torch.ones(size=(size[0],1)) * (((maximum-minimum)/2 + minimum) * size[1])
    return (weights, values, total_weights) 

这个程序是创建单个元素输入文件:

from data_generator import uniform_data_set
import argparse
import pickle

def data_generator(in_dir, out_dir, submit_file_path):
    capacity_percentages = [1, 5, 10, 25, 50, 75, 90, 95, 99]

    for capacity_percentage in capacity_percentages:
        submit_file = open(submit_file_path, 'a+')
        uni_weights, uni_values, uni_total_weights = uniform_data_set()

        num_samples = len(uni_weights)

        for i in range(num_samples):
            pickle.dump((uni_weights[i], uni_values[i], uni_total_weights[i], capacity_percentage), open(f'{in_dir}/data_{capacity_percentage}_{i}.p', 'wb'))
            submit_file.write(f'uni_{i}, {in_dir}/data_{capacity_percentage}_{i}.p, {out_dir}/data_{capacity_percentage}_{i}.p\n')

if __name__ == "__main__":
    parser = argparse.ArgumentParser()

    parser.add_argument('in_dir', type=str, help="Input directory")
    parser.add_argument('out_dir', type=str, help="Output directory")
    parser.add_argument('submit_file_path', type=str, help="Condor submit file path")
    args = parser.parse_args()
    
    in_dir = args.in_dir
    out_dir = args.out_dir
    submit_file_path = args.submit_file_path

    data_generator(in_dir, out_dir, submit_file_path)

上面显示的程序将权重、值和总权重存储为火炬张量。但是,我测试了使用 tensor.tolist() 方法将张量转换为列表,并且单个输入元素 pickle 文件最终只有 2 KB。我应该从一开始就将权重、值和总重量存储为一个列表,因为在将 pickle 文件加载到求解程序时,无论如何我都必须将它们转换为列表。

为什么将数据集存储在 Torch 张量中会导致 pickle 文件变大?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 2018-01-26
    • 2014-04-11
    • 2012-10-05
    • 1970-01-01
    相关资源
    最近更新 更多