You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

加载大量npy文件时np.load()内存占用过高的问题求助

加载大量npy文件时np.load()内存占用过高的问题求助

嘿,刚接触Python和机器学习就碰到这种内存炸锅的问题,太能理解你的崩溃了!我当初做类似项目的时候也踩过一模一样的坑,咱们来一步步拆解问题解决它~

问题根源

你用了mmap_mode='r'本来是想延迟加载、避免一次性读进内存,但最后那句features = np.asarray(features_list)直接把所有内存映射的数组都实打实读到RAM里了!咱们算笔账:每个npy文件是(298,32,32,3),如果是float32类型的话,每个文件大概占3.6MB,9221个加起来就是30多GB,远远超过你的16G内存,不爆才怪呢😅

实用解决方案

1. 用生成器/分批加载(最推荐)

核心思路是永远只在内存里保留一批训练数据,不要一次性加载所有文件。可以写个自定义生成器,训练的时候每次加载指定数量的文件:

import numpy as np
from sklearn.model_selection import train_test_split

# 先拆分索引,而不是直接加载所有数据
indices = np.arange(9221)
train_idx, test_idx = train_test_split(indices, test_size=0.25, shuffle=True, random_state=42)

# 自定义数据生成器
def data_generator(indices, df, batch_size=32):
    while True:
        # 每次循环打乱索引(保证训练随机性)
        np.random.shuffle(indices)
        # 按批次截取索引
        for start in range(0, len(indices), batch_size):
            batch_indices = indices[start:start+batch_size]
            batch_features = []
            batch_labels = []
            for idx in batch_indices:
                # 仅加载当前批次的单个文件
                frames_array = np.load(f'E:/padFrames/video_{idx}.npy')
                batch_features.append(frames_array)
                # 读取对应标签
                labels = df.iloc[idx][categoryEmotions].values
                batch_labels.append(labels)
            # 返回当前批次的特征和标签数组
            yield np.array(batch_features), np.array(batch_labels)

# 创建训练/测试生成器
train_generator = data_generator(train_idx, df, batch_size=32)
test_generator = data_generator(test_idx, df, batch_size=32)

之后训练模型时(比如用Keras),直接传入生成器即可:model.fit(train_generator, epochs=10, validation_data=test_generator),这样内存占用只会维持在一个批次的大小,完全不会爆。

2. 用大内存映射文件替代全量数组

如果你一定要用完整的numpy数组格式,可以创建一个超大的磁盘内存映射文件,把每个npy的数据写入对应位置,全程不占内存:

# 定义总数据的形状和类型
total_shape = (9221, 298, 32, 32, 3)
dtype = np.float32  # 根据你的实际数据类型调整

# 创建磁盘上的内存映射文件
features_mmap = np.memmap('total_features.npy', dtype=dtype, mode='w+', shape=total_shape)

# 循环写入每个npy的数据
for i in range(9221):
    frames_array = np.load(f'E:/padFrames/video_{i}.npy')
    features_mmap[i] = frames_array
    # 写入后释放当前数组的内存
    del frames_array

# 写完后可以重新以只读模式打开,后续使用和普通numpy数组一样,但数据存在磁盘上
features_mmap = np.memmap('total_features.npy', dtype=dtype, mode='r', shape=total_shape)

这种方式的好处是你可以像操作普通数组一样处理数据,但实际数据存在磁盘,不会占用大量RAM。

3. 预处理时压缩数据

如果你的模型允许,对每个视频帧做降维/压缩:

  • 比如把32x32的帧下采样到16x16,直接减少75%的体积
  • 对帧特征做PCA降维,保留主要信息的同时缩小维度
  • 把数据类型从float32改成float16(如果模型支持),直接减半内存占用

额外提醒

以后处理大文件时,一定要避免把所有数据都塞进一个numpy数组里,分批处理或者用内存映射才是高效的方式~

备注:内容来源于stack exchange,提问作者zhenru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 10:44:34